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

时间秒杀一切 提交于 2021-02-05 07:48:06

问题


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.


回答1:


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;
        }
    }
}



回答2:


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;
}


来源:https://stackoverflow.com/questions/61617307/moving-from-one-place-to-another-over-time-or-rotating-in-unity

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!