Move GameObject over time
gjttt1's answer is close but is missing important functions and the use of WaitForSeconds()
for moving GameObject is unacceptable. You should use combination of Lerp
, Coroutine
and Time.deltaTime
. You must understand these stuff to be able to do animation from Script in Unity.
public GameObject objectectA;
public GameObject objectectB;
void Start()
{
StartCoroutine(moveToX(objectectA.transform, objectectB.transform.position, 1.0f));
}
bool isMoving = false;
IEnumerator moveToX(Transform fromPosition, Vector3 toPosition, float duration)
{
//Make sure there is only one instance of this function running
if (isMoving)
{
yield break; ///exit if this is still running
}
isMoving = true;
float counter = 0;
//Get the current position of the object to be moved
Vector3 startPos = fromPosition.position;
while (counter < duration)
{
counter += Time.deltaTime;
fromPosition.position = Vector3.Lerp(startPos, toPosition, counter / duration);
yield return null;
}
isMoving = false;
}
Similar Question: SKAction.scaleXTo
How to continuously move a GameObject between two positions?
Calling MoveTowards
once only moves the game object once during that iteration of the game loop. Calling MoveTowards
once doesn't move the game object all the way to its target (unless the maxDistanceDelta
parameter is big enough to move the game object to its target in one iteration).
If the boss is instantly appearing at the target, I'm guessing your chargeSpeed
is too big.
What you want to do is call MoveTowards
once per Update
cycle. However, the way you're doing your coroutine, the coroutine will only move the game object once and then exit. Normally coroutines will have a loop within them (otherwise the coroutine will exit after running once). Something like this:
IEnumerator TankCharge()
{
while (Vector3.Distance(transform.position, chargeTarget.position) > Mathf.Epsilon)
{
// Adjust this so this game object doesn't move the entire
// distance in one iteration
float distanceToMove = Time.deltaTime * chargeSpeed;
transform.position = Vector3.MoveTowards(transform.position, chargeTarget.position, distanceToMove)
yield return null;
}
}
However, for your situation, you don't really need a coroutine. You can just do this directly in Update()
private bool returnToStart = false;
private float timer;
void Update
{
float distanceToMove = Time.deltaTime * chargeSpeed;
if (timer <= 0)
{
if (!returnToStart)
{
transform.position = Vector3.MoveTowards(transform.position, chargeTarget.position, distanceToMove)
// Target reached? If so, start moving back to the original position
if (Vector3.Distance(transform.position, chargeTarget.position) <= Mathf.Epsilon)
{
returnToStart = true;
this.timer = this.chargeRate;
}
}
else
{
transform.position = Vector3.MoveTowards(transform.position, tankStartPosition.position, distanceToMove)
// Original position reached? If so, start moving to the target
if (Vector3.Distance(transform.position, tankStartPosition.position) <= Mathf.Epsilon)
{
returnToStart = false;
this.timer = this.chargeRate;
}
}
}
else
{
this.timer -= Time.time;
}
}
Unity move an object to a point(transform) within a certain number of seconds
Unless you're 90 years old, just use a tweeng.
It's this easy
StartCoroutine(5f.Tweeng( (p)=>transform.position=p,
startHere,
endHere) );
it goes from startHere
to endHere
in 5 seconds.
That's all there is to it.
A tweeng extension is only a few lines of code, example: https://stackoverflow.com/a/37228628/294884
You can do anything with a tweeng, fade volume, twist objects, animate the size of type, fade images, whatever.
Every single large project you'll ever work on, they already use tweeng. It couldn't be simpler.
How to make a game object move to the opposite direction of a constantly moving object? Unity 2D
So this:
playerRb.velocity = -rotatingPropellant.transform.position * impulseForce * Time.deltaTime;
relies on rotatingPropellant
position relative to World's zero position (Vector3.zero
), which might work only if the propellant revolves around this zero point.
What you should probably do instead is get the difference:
Vector3 dir = (rotatingPropellant.transform.position - transform.position).normalized;
playerRb.velocity = dir * impulseForce * Time.deltaTime;
Also, instead of changing velocity, you can add force instead:
Vector3 dir = (rotatingPropellant.transform.position - transform.position).normalized;
playerRb.AddForce(dir * impulseForce, ForceMode2D.Impulse);
Unity 3D Move object over specific time on GetButtonDown
Try .Lerp, it runs as a coroutine interpolating a value over some amount of time Vector3.Lerp(Vector3 start, Vector3 end, float time)
See documentation here
This should give you a rough idea of whats going on
Vector3 Distance = End - Start;
// this will return the difference
this.transform.position += Distance/time.deltatime * Movetime
// this divides the Distance equal to the time.deltatime.. (Use Movetime to make the movement take more or less then 1 second
IE: If the Distance is 1x.1y.1z, and time.deltatime is .1 and Movetime is 1.... you get a movement of .1xyz per tick, taking 1 second to reach the end point
FYI: transform.Translate works as a fancy .position +=, for this purpose you can use them interchangeably
EDIT
Here are a few solutions
Easy ::
Vector3 amountToMove = new Vector3(0,1,0); // Vector3.up is short hand for (0,1,0) if you want to use that instead
if (Input.GetButtonDown ("VerticalFwd"))
{
transform.position = Vector3.Lerp(transform.position ,transform.position + amountToMove, 1);
}
Hard and probably unnecessary ::
Write a Coroutine that does a kind of Linear interpolation for your specific application See documentation here
Best way to move my Gameobject smoothly?
Its better to use a tween engine , like http://dotween.demigiant.com/.
If you install Dotween then you can simply use
transform.DOMove(new vector3(1 ,0 , 1) , duration);
You can also set Ease for tweens. or use Oncomplete fucntions;
transform.DOMove(new vector3(1 ,0 , 1) , duration)
.SetEase(Ease.OutCubic)
.OnCompelete(() => { shouldClose = true; });
Related Topics
.Net Httpclient. How to Post String Value
Cross-Platform File Name Handling in .Net Core
How to Post Data to Specific Url Using Webclient in C#
Is It Better to Return Null or Empty Collection
Deserializing Json to .Net Object Using Newtonsoft (Or Linq to Json Maybe)
Odbcconnection Returning Chinese Characters as ""
Metadataexception: Unable to Load the Specified Metadata Resource
Using Parameters Inserting Data into Access Database
How to Associate a File Extension to the Current Executable in C#
C# Constructor Execution Order
Deserialize Json to C# Classes
How to Double Buffer .Net Controls on a Form
How to Remove a Lambda Event Handler