需要用到DoTween插件
1.创建空对象,声明预制体,数量,半径,角度,游戏性对象和transform(用于对其)的集合
public GameObject prefabs;
public int num;
public float r;
public float angle;
public List<GameObject> list = new List<GameObject>();
public List<Transform> sort = new List<Transform>();
这里的prefab用了默认生成的球体
2. 在预制体上添加脚本Item,脚本内声明先前空物体上的脚本(这里是CreatRoll)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Item : MonoBehaviour
{
public CreatRoll creat;
private void OnMouseDrag()//鼠标拖拽中
{
Vector3 pos=Camera.main.WorldToScreenPoint(transform.position);
Vector3 next = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y,
pos.z));
float dis= transform.position.x-next.x;
creat.OnDrag(dis);
}
private void OnMouseUp()//鼠标结束拖拽
{
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 next = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y,
pos.z));
float dis = transform.position.x - next.x;
creat.Inertia(dis);
}
}
3.在空物体的脚本中写Start方法,根据数字生成预制体,以及设置预制体的父类,位置,脚本内的Creat等
void Start()
{
angle = 2 * Mathf.PI / num;
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(i * angle) * r;
float z = Mathf.Cos(i * angle) * r;
GameObject go = Instantiate(prefabs);
go.transform.SetParent(transform);
go.transform.localPosition = new Vector3(x, 0, z);
go.GetComponent<Item>().creat = this;
list.Add(go);
sort.Add(go.transform);
}
}
4.在空对象里设置allang,为拖拽时需要旋转的弧度
float angall = 0;
5.设置OnDrag脚本,在拖拽物体时调用(预制体的 OnMouseDrag)
public void OnDrag(float dis)
{
float ang = dis / r;
angall += ang;
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(i * angle + angall) * r;
float z = Mathf.Cos(i * angle + angall) * r;
list[i].transform.localPosition = new Vector3(x, 0, z);
}
}
6.设置OnDrag脚本,在松开时调用(预制体的 OnMouseUp)
public void Inertia(float dis)
{
DOTween.To(() => dis, t => OnDrag(t), 0, 2).SetEase(Ease.Linear).OnComplete(() =>
{
sort.Sort((a, b) => (int)(a.localPosition.z - b.localPosition.z));
float ang = Mathf.Asin(sort[0].transform.localPosition.x/r);
DOTween.To(() => angall, t =>
{
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(i * angle + t) * r;
float z = Mathf.Cos(i * angle + t) * r;
list[i].transform.localPosition = new Vector3(x, 0, z);
}
}
, angall+ang, 1);
});
}
完成DOTween移动以后,通过对比排序获得预制体中位置z值最小的一个,用Asin获得弧度,再用DoTween实现回到应在的位置