unity2D以最小的角度旋轉到目標方向(y方向為角色的主方向)


 

一.使用向量原理轉換到目標方向

 

為了讓角色的自身y轉向目標方向,並且以最小角度旋轉,要點是獲得當前方向與目標方向的叉值,從而判斷應該旋轉的方向

float rotateSpeed;

//相對目標位置運動
void trackPosition02(Vector3 tarPosition)
{
Vector3 targetDir = tarPosition - transform.position;
Vector3 up = transform.up;
float angle = Vector3.Angle(targetDir, up);
if (angle <= Time.fixedDeltaTime * rotateSpeed) return;//判斷角度是否小於臨界值,如果小於,那么不需要旋轉,此處用於避免旋轉抖動
Vector3 cross = Vector3.Cross(up, targetDir);
if (cross.z > 0) transform.Rotate(new Vector3(0, 0, rotateSpeed0* Time.deltaTime)); else transform.Rotate(new Vector3(0, 0, -rotateSpeed0* Time.deltaTime));
}

可能unity提供了更簡單的判定方式,知道的老兄留個評論

 

二.利用角度符號判斷轉到目標方向

這里原理和一相同,只是判斷角度的方式是使用判斷兩者的角度差,而不是向量的叉值

float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime));

 

三.有角度限制的轉到目標方向

這里角度限制是指在局部坐標系內的角度限制,比如某個TD坦克,它的炮塔只能在正方向的-30度到正30度之間旋轉,

但是除了計算局部旋轉,還要加上父物體的旋轉角度

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateTest : MonoBehaviour
{
    // The target marker.
    public Transform target;

    // Angular speed in radians per sec.
    public float speed;

    //Vector3.up方向為0角度方向
    //局部坐標系內的最小角度和最大角度
    public float minAngle;
    public float maxAngle;

    //局部坐標系內的最小角度和最大角度轉換到直接坐標系的值
    public float minAngleInWorld;
    public float maxAngleInWorld;

    void Update()
    {
        //父親物體的當前角度
        float offsetAngle = Vector3.SignedAngle(Vector3.up, transform.parent.transform.up,Vector3.forward);

        minAngleInWorld = minAngle + offsetAngle;
        maxAngleInWorld = maxAngle + offsetAngle;

        //當前的目標方向相對世界坐標Up方向的角度,用於判斷是否在設定的范圍內
        float angle = Vector3.SignedAngle(Vector3.up, target.position - transform.position, Vector3.forward);
        //當前自身與目標的角度方向差,用於決定旋轉方向
        float signAngle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
        if (angle > minAngleInWorld && angle < maxAngleInWorld) transform.Rotate(new Vector3(0, 0, Mathf.Sign(signAngle)*speed * Time.deltaTime));
        
        /*
        float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
        transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime));
        */
    }
}

 

四.利用unity的接口旋轉

//數學意義的轉到目標方向
    protected void RotateToDir(Vector3 dir)
    {
        float angle = Vector3.SignedAngle(Vector3.up, dir, Vector3.forward);
        Quaternion rotation00 = Quaternion.Euler(0, 0, angle);
        transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation00, Time.fixedDeltaTime * computeRotateSpeed);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM