Colinovsky
Colinovsky

Reputation: 48

Moving from one place to another over time (or rotating) in Unity

I have a problem with moving from one place to another in Unity over time. I would like my character to move from current position to current + 1 on Y. Unfortunately, looks like it does not get the current position properly or something, since if I debug what I wrote, it says that the magnitude is always 1, so the point is moving with me. Shouldn't it just check the current position and add 1 to Y, move to that position and then check again? I have no idea what's wrong with this code, or if it's strictly connected with how Unity checks positions and things in real time?

 public bool moving = false;
 private Vector3 dir;
 void FrontMovement()
 {
     Vector3 movement = new Vector3(-Mathf.Sin(transform.eulerAngles.z * Mathf.PI / 180), Mathf.Cos(transform.eulerAngles.z * Mathf.PI / 180), 0f); // always moving front, even after rotation

     if (moving == false)
     {
         dir = movement - transform.position;
         moving = true;
         return;
     }
     transform.Translate(dir.normalized * Time.deltaTime);
     if(dir.magnitude <= Time.deltaTime)
     {
         Debug.Log("Finished movement");
         moving = false;
     }
 }
 void FixedUpdate()
 {
     Debug.Log(dir.magnitude);
     FrontMovement();
 }

I would also like to know how to do rotations over time.

Upvotes: 1

Views: 1368

Answers (2)

Frenchy
Frenchy

Reputation: 16997

You could use Coroutine + Vector3.Lerp to move with a specified amount of time:

public IEnumerator MoveToPosition(Transform transform, Vector3 position, float timeToMove)
{
      var currentPos = transform.position;
      var t = 0f;
      while(t <= 1f)
      {
             t += Time.deltaTime / timeToMove;
             transform.position = Vector3.Lerp(currentPos, position, t);
             yield return null;
      }
      transform.position = position;
}

you call the coroutine in Start Method

StartCoroutine(MoveToPosition(transform, newposition, timeToMove))

You could use the same logic for Rotating, with Quaternion.Lerp or Slerp and Quaternion.LookRotation, of course you have lot of sample with rotation over time on WEB!! google is your friend...

public IEnumerator RotateToDirection(Transform transform, Vector3 position, float timeToRotate)
{
    var startRotation = transform.rotation;
    var direction = position - transform.position;
    var finalRotation = Quaternion.LookRotation(direction);
    var t = 0f;
    while (t <= 1f)
    {
        t += Time.deltaTime / timeToRotate;
        transform.rotation = Quaternion.Lerp(startRotation, finalRotation, t);
        yield return null;
    }
    transform.rotation = finalRotation;
}

Upvotes: 2

vasmos
vasmos

Reputation: 2586

https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

lerp also works for rotations

// Movement speed in units per second.
public float speed = 1.0F;

// Time when the movement started.
private float startTime;

// Total distance between the markers.
private float journeyLength;

void StartMoving() {
    // Keep a note of the time the movement started.
    startTime = Time.time;

    Vector3 modifiedPosition = transform.position;
    transform.position.y += 1.0f;

    // Calculate the journey length.
    journeyLength = Vector3.Distance(transform.position, modifiedPosition.position);

    moving = true;
}

// Move to the target end position.
void Update()
{
    if (moving) {
    // Distance moved equals elapsed time times speed..
    float distCovered = (Time.time - startTime) * speed;

    // Fraction of journey completed equals current distance divided by total distance.
    float fractionOfJourney = distCovered / journeyLength;

    // Set our position as a fraction of the distance between the markers.
    transform.position = Vector3.Lerp(startMarker.position, endMarker.position, fractionOfJourney);

        if (fractionOfJourney >= 1.0f) {
        moving = false;
        }
    }
}

Upvotes: 1

Related Questions