轮转图主体是实现旋转之后的惯性和停下来之后的对齐
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class RotateModel : MonoBehaviour
{
public float spacng;
public int n;
float c, r, ang, distance=0;
List<GameObject> Model_List=new List<GameObject>();
List<Transform> sortList=new List<Transform>();
// Start is called before the first frame update
void Start()
{
c = (1 + spacng) * n;
r = c / (2 * Mathf.PI);
ang = 2 * Mathf.PI / n;
for (int i = 0; i < n; i++)
{
float x = Mathf.Sin(ang * i) * r;
float z = Mathf.Cos(ang * i) * r;
GameObject model = Instantiate(Resources.Load<GameObject>("player/player_" + i),transform);
model.transform.localPosition = new Vector3(x, 0, z);
Model_List.Add(model);
model.AddComponent<ModelDrag>();
sortList.Add(model.transform);
}
}
/// <summary>
/// 轮转图旋转
/// </summary>
/// <param name="dis"></param>
public void Move(float dis)
{
distance +=dis;
float moveAng = distance / r;
for (int i = 0; i < Model_List.Count; i++)
{
float x = Mathf.Sin(ang * i+moveAng) * r;
float z = Mathf.Cos(ang * i+moveAng) * r;
Model_List[i].transform.localPosition = new Vector3(x, 0, z);
}
}
/// <summary>
/// 惯性滑动
/// </summary>
/// <param name="endSpeed"></param>
public void Inertia(float endSpeed)
{
float time = Mathf.Abs(endSpeed) / 3;
DOTween.To((float a) =>
{
Move(a);
}, endSpeed, 0, time).OnComplete(() => { Align(); });
}
/// <summary>
/// 轮转结束对齐
/// </summary>
public void Align()
{
sortList.Sort((a, b) => {
if(a.localPosition.z<b.localPosition.z)
{
return 1;
}
else if(a.localPosition.z == b.localPosition.z)
{
return 0;
}
else
{
return -1;
}
});//排序直接找面前的第一个,此时拥有面前第一个角色的坐标
float AlignAng = Mathf.Atan(sortList[0].localPosition.x / sortList[0].localPosition.z);//通过反向tan用x和z算出弧度
float AlignDis = AlignAng * r;//弧度*半径获取弧长
float time = Mathf.Abs(AlignDis) / 1;
DOTween.To((float a) => {
Move(a - distance);
},distance,distance-AlignDis,time);
}