private float rotSpeed = 1000; //旋轉速度
private float rotState = -1; //旋轉狀態 -1 停止 0 開始 1 結束
private float endAngle = 0; //結束角度
private readonly float AcceleateTime = 1f; //加速度持續時間
private float rotTime = 0f; //旋轉持續時間
private float rotFactor = 0f; //旋轉速度變化因子
private float minTime = 3f; //旋轉最小持續時間
private float _tmpAngle = 0f; //開始減速物體的角度
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
RotMath();
}
/// <summary>
/// 旋轉方法 再update裏面更新
/// </summary>
public void RotMath()
{
if(rotState == -1)
{
return;
}
rotTime += Time.deltaTime; //記錄時間
if (rotState == 0)
{
//開始旋轉 先加速計算速度
rotFactor = rotTime / AcceleateTime;
rotFactor = rotFactor > 1 ? 1 : rotFactor;
transform.Rotate(Vector3.back, -rotFactor * rotSpeed * Time.deltaTime, Space.Self);
}
else
{
//減速旋轉一段時間再慢慢變停止
//通過差值運算實現精準地旋轉到指定角度(球型插值無法實現大於360°的計算)
float k = 1f; //如果嫌減速太慢,可以加個係數修正一下
_tmpAngle = Mathf.Lerp(_tmpAngle, endAngle, Time.deltaTime * k);
//這裏只存在一個方向的旋轉,所以不存在歐拉角萬向節的問題,所以使用歐拉角和四元數直接賦值都是可以的
transform.rotation = Quaternion.Euler(0, 0, -_tmpAngle);
//node.eulerAngles = new Vector3(0, 0, _tmpAngle);
if (1 >= Mathf.Abs(_tmpAngle - endAngle))
{
//重新設置狀態 數據 顯示獎勵等
rotState = -1;
endAngle = 0;
rotTime = 0;
}
}
//修改旋轉狀態
if(rotState == 0 && rotTime > minTime && endAngle !=0 )
{
rotState = 1;
// 將當前指針的歐拉角轉換成順時針統計角度
//由於讀取到的值是[0, 180] U [-180, 0],左邊由0至180遞增,右邊由180轉變成-180,然後遞增至0,所以需要轉相應的轉換
_tmpAngle = (1) * (360 - transform.eulerAngles.z) % 360;
}
}
public void OnStartRot()
{
rotState = 0;
rotTime = 0;
endAngle = UnityEngine.Random.Range(0f, 360f);
endAngle = Mathf.Abs(endAngle);
print("End Angle: " + endAngle);
endAngle = endAngle % 360; //將角度限定在[0, 360]這個區間
endAngle = -endAngle - 360 * 4; //多N圈並取反,圈數能使減速階段變得更長,顯示更自然,逼真
}