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圈并取反,圈數能使減速階段變得更長,顯示更自然,逼真
}