如何在移动时保持变换高度?

How can i keep the transform height while it's moving?

bool flying = false; // shows when FlyTo is running
                         // coroutine that moves to the specified point:
    IEnumerator FlyTo(Vector3 targetPos)
    {
        flying = true; // flying is true while moving to the target
        Vector3 startPos = transform.position;
        Vector3 dir = targetPos - startPos;
        float distTotal = dir.magnitude;
        dir /= distTotal; // normalize vector dir
                          // calculate accDist even for short distances
        float accDist = Mathf.Min(accDistance, distTotal / 2);
        do
        {
            float dist1 = Vector3.Distance(transform.position, startPos);
            float dist2 = distTotal - dist1;
            float speed = maxVel; // assume cruise speed
            if (dist1 < accDist)
            { // but if in acceleration range...
              // accelerate from startVel to maxVel
                speed = Mathf.Lerp(startVel, maxVel, dist1 / accDist);
            }
            else
            if (dist2 < accDist)
            { // or in deceleration range...
              // fall from maxVel to stopVel
                speed = Mathf.Lerp(stopVel, maxVel, dist2 / accDist);
            }
            // move according to current speed:
            transform.position = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
            yield return 0; // let Unity breathe till next frame
        } while (transform.position != targetPos); // finish when target reached
        flying = false; // shows that flight has finished
    }

问题是,如果变换开始时的高度为 200,当它到达 targetPos 时它的高度为 0。

但我希望它以相同的高度到达它上方的 targetPos,而不是高度 0。当它到达 targetPos 时它会做什么并不重要,但我想要的是它会到达那里同样的身高水平。

这是完整的脚本:

using UnityEngine;
using System.Collections;

public class ControlShip : MonoBehaviour
{

    public float maxVel = 30; // cruise speed
    public float startVel = 5; // speed at the starting point
    public float stopVel = 0.5f; // speed at the destination
    public float accDistance = 20; // acceleration/deceleration distance
    public float factor = 0.25f; // max inclination
    public float turnSpeed = 0.8f; // speed to turn/bank in the target direction
    Vector3 lastPos; // used to calculate current velocity
    Transform baseTarget;
    private Rigidbody _rigidbody;

    void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
        baseTarget = GameObject.Find("Base").transform;
        lastPos = transform.position;
        StartCoroutine(Fly()); // demo routine
    }
    // calculate bank/turn rotation at Update
    void Update()
    {
        // calculate the displacement since last frame:
        Vector3 dir = transform.position - lastPos;
        lastPos = transform.position; // update lastPos
        float dist = dir.magnitude;
        if (dist > 0.001f)
        { // if moved at least 0.001...
            dir /= dist; // normalize dir...
            float vel = dist / Time.deltaTime; // and calculate current velocity
                                               // bank in the direction of movement according to velocity
            Quaternion bankRot = Quaternion.LookRotation(dir + factor * Vector3.down * vel / maxVel);

            Vector3 rotation = Quaternion.Lerp(transform.rotation, bankRot, turnSpeed * Time.deltaTime).eulerAngles;
            rotation.x = 0;
            transform.rotation = Quaternion.Euler(rotation);
        }
    }

    bool flying = false; // shows when FlyTo is running
                         // coroutine that moves to the specified point:
    IEnumerator FlyTo(Vector3 targetPos)
    {
        flying = true; // flying is true while moving to the target
        Vector3 startPos = transform.position;
        Vector3 dir = targetPos - startPos;
        float distTotal = dir.magnitude;
        dir /= distTotal; // normalize vector dir
                          // calculate accDist even for short distances
        float accDist = Mathf.Min(accDistance, distTotal / 2);
        do
        {
            float dist1 = Vector3.Distance(transform.position, startPos);
            float dist2 = distTotal - dist1;
            float speed = maxVel; // assume cruise speed
            if (dist1 < accDist)
            { // but if in acceleration range...
              // accelerate from startVel to maxVel
                speed = Mathf.Lerp(startVel, maxVel, dist1 / accDist);
            }
            else
            if (dist2 < accDist)
            { // or in deceleration range...
              // fall from maxVel to stopVel
                speed = Mathf.Lerp(stopVel, maxVel, dist2 / accDist);
            }
            // move according to current speed:

            Vector3 pos = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
            pos.y = lastPos.y;
            transform.position = pos;
            yield return 0; // let Unity breathe till next frame
        } while (transform.position != targetPos); // finish when target reached
        flying = false; // shows that flight has finished        
    }
    // example routine: fly to 3 different points in sequence
    IEnumerator Fly()
    {
        Vector3 p0 = baseTarget.position;

        while (true)
        {
            StartCoroutine(FlyTo(p0));
            while (flying)
            {
                yield return 0;
            }
            yield return new WaitForSeconds(5);
        }
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.name == "Base")
        {

        }
    }
}

如我的评论所述,不要两次更新位置,这会导致开销,通过在循环之前更改目标的 Y 坐标可以轻松避免。

 IEnumerator FlyTo(Vector3 targetPos)
    {
        flying = true; // flying is true while moving to the target
        Vector3 startPos = transform.position;

        //Insert this line right here.
        targetPos.y = startPos.y;
        Vector3 dir = targetPos - startPos;
        //The rest of your code remains the same...

在你的 DO 中找到这一行,靠近结尾并将其删除

       Vector3 pos = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
    //pos.y = lastPos.y; ~ REMOVE THIS LINE~

假设Y是高度轴,也许它实际上是Z轴,试试看。