簡體   English   中英

unity旋轉Object改變方向

[英]Unity Rotate Object to Change Direction

我有一條魚在屏幕上游來游去。 當它到達屏幕邊緣的 10% 以內時,我希望它開始轉身,直到它完全反轉並且現在朝相反的方向游動。 這應該更漸進,就像魚會游泳一樣。 我不希望它在自己的軸上旋轉。

我沒有任何運氣讓它轉身。 它只是部分轉動。

更新這是魚在此處輸入圖像描述

public class FishSwim : MonoBehaviour
{
    public enum Direction { LeftToRight, RightToLeft };

    public Direction moveDirection;
    [SerializeField]
    private float speedMin = 0.5f;
    [SerializeField]
    private float speedMax = 1f;

    [SerializeField]
    private bool useOnlySpeedMax = false;
    private float speed;

    [HideInInspector]
    public float removeBeyond;

    private void Start()
    {
        var dist = (transform.position - Camera.main.transform.position).z;
        if (moveDirection == Direction.RightToLeft)
            removeBeyond = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, dist)).x;
        else
            removeBeyond = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, dist)).x + FindObjectOfType<SkinnedMeshRenderer>().bounds.size.x;
    }

    private void OnEnable()
    {
        speed = Random.Range(speedMin, speedMax);
        if (useOnlySpeedMax)
        {
            speed = speedMax;
        }
        if (moveDirection == Direction.RightToLeft)
        {
            speed = -speed;
        }
    }

    // Update is called once per frame
    void Update()
    {
        float realSpeed = speed * Time.deltaTime;
        transform.position += Vector3.right * realSpeed;
        if (moveDirection == Direction.RightToLeft && transform.position.x < -Mathf.Abs(removeBeyond))
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Vector3.right), Time.deltaTime * 40f);
            moveDirection = Direction.LeftToRight;
        }
        else if (moveDirection == Direction.LeftToRight && transform.position.x > Mathf.Abs(removeBeyond))
        {
            
        }
    }
}

我會使用協程來做到這一點。 評論中的解釋:

bool isTurning = false;
[SerializeField] float turnPeriod = 0.5f; // how long it takes to turn, smaller=faster

private void OnEnable()
{
    speed = Random.Range(speedMin, speedMax);
    if (useOnlySpeedMax)
    {
        speed = speedMax;
    }
    // Get rid of negative speed
}

void Update()
{
    float realDistance = speed * Time.deltaTime;
    transform.position += transform.right * realDistance;

    // Surely there is a better way than calculating 
    // Mathf.Abs(removeBeyond) every frame... but that is off-topic
    if (!isTurning && ( 
        (moveDirection == Direction.RightToLeft 
            && transform.position.x < -Mathf.Abs(removeBeyond) 
        ) || (moveDirection == Direction.LeftToRight
            && transform.position.x > Mathf.Abs(removeBeyond) 
    ) ) )
    {
        // If we aren't already turning and we should be, start turning:
        StartCoroutine(Turn());
    }
}

IEnumerator Turn()
{
    isTurning = true;
    Vector3 startForward = transform.forward;

    // find end speed and direction
    Direction endDirection = moveDirection == Direction.RightToLeft ?
            Direction.LeftToRight:Direction.RightToLeft; 

    // keep track of how much of our turning time has elapsed
    float elapsedTimePortion = Time.deltaTime/turnPeriod;

    // turn until you've spent enough time turning
    while (elapsedTimePortion < 1f)
    {
        // by whatever portion we've spent time turning, turn starting forward
        // 180 degrees around up axis
        float angle = 180f * elapsedTimePortion;
        Vector3 newForward = Quaternion.AngleAxis(angle, Vector3.up) * startForward;
        transform.rotation = Quaternion.LookRotation(newForward);
        yield return null;
 
        // next frame - update how long we've been turning
        float newElapsedTimePortion = elapsedTimePortion + Time.deltaTime/turnPeriod;

        if (newElapsedTimePortion >= 0.5f && elapsedTimePortion < 0.5f)
        {
            // If we've just passed 50% of the turn, 
            // make fish move opposite direction
            moveDirection = endDirection; 
        }
        elapsedTimePortion = newElapsedTimePortion;
    } 

    // we're done turning, just set the rotation to the end rotation.
    isTurning = false;
    transform.rotation = Quaternion.LookRotation(-startForward);

    // Does removeBeyond need to be updated here? There are a few lines in Start()
    // which would suggest that.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM