Move Gameobject Over Time

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



Leave a reply



Submit