该代码实现了一个可旋转的物品展示界面,用户可以通过拖动界面进行旋转,在界面上呈现出一圈圆形排列的物品。具体实现方法是通过设置圆的半径和物品个数来计算每个物品的位置,当用户拖动界面时,计算出偏移量后重新计算每个物品的位置进行更新。同时,在用户拖动结束后,界面将根据用户拖动的速度缓慢减速到停止,并将位于第一个的物品移到屏幕中央显示。
该代码使用了DOTween插件实现物品旋转和减速动画效果,同时也使用了Unity的事件系统来响应用户的拖动事件。
这段代码可以用于游戏中的物品展示、商场中的商品展示等场景,具有良好的交互性和视觉效果。
using System.Collections;
using System.Collections.Generic;
using DG.Tweening; //引用DOTween插件
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
//实现IDragHandler和IEndDragHandler接口,以便响应用户拖动事件
public class RotaryFigure : MonoBehaviour, IDragHandler, IEndDragHandler {
private float des; //des表示当前目标值
private List<GameObject> list = new List<GameObject>(); //存储生成的物体列表
private int num = 10; //圆上需要摆放的物体数量
private List<Transform> trlist = new List<Transform>(); //存储生成的物体的Transform组件
private float speed = 1; //旋转缓慢减速的速度
public RadarMap rm; //雷达地图控制管理组件
private float r; //圆的半径
// Start is called before the first frame update
void Start() {
Move(); //初始化界面并生成物体
}
// Update is called once per frame
void Update() {
}
//响应用户拖动事件
public void OnDrag(PointerEventData eventData) {
des -= eventData.delta.x / Screen.width; //根据用户拖动的偏移量更新目标值
Move(); //更新界面
}
//更新界面方法
public void Move() {
float movesc = (des / num) * (2 * Mathf.PI); //计算当前偏移角度
r = num / (2 * Mathf.PI); //计算圆的半径
float ang = (2 * Mathf.PI) / num; //计算一份角度
for (int i = 0; i < num; i++) { //循环初始化每个物体的位置
float x = Mathf.Sin(ang * i + movesc) * r; //计算物体在X轴上的位置
float z = Mathf.Cos(ang * i + movesc) * r; //计算物体在Z轴上的位置
if (list.Count <= i) { //如果该物体未被生成,则先生成
list.Add(Instantiate(Resources.Load<GameObject>("player/player_" + i))); //从资源文件夹中加载物体并实例化
trlist.Add(list[i].transform); //将该物体的Transform组件加入trlist中
}
list[i].transform.position = new Vector3(x, 0, z); //更新物体的位置
}
}
//响应用户拖动结束事件
public void OnEndDrag(PointerEventData eventData) {
//根据用户拖动的速度计算减速所需时间
float time = Mathf.Abs(eventData.delta.x) / speed;
time = time > 2 ? 2 : time; //时间最大限制为2秒
//缓慢减速到停止
DOTween.To((float a) => {
des -= a / Screen.width;
Move(); //更新界面
}, eventData.delta.x, 0, time).SetEase(Ease.InOutQuad).OnComplete(() => { //动画完成后执行的操作
//将物体按照Z轴位置排序,以便将第一个物体置于中央
trlist.Sort((a, b) => {
if (a.position.z > b.position.z) {
return 1;
}
else if (a.position.z == b.position.z) {
return 0;
}
else {
return -1;
}
});
//将第一个物体移到屏幕中央
float moveAng = Mathf.Asin(trlist[0].position.x / r); //计算需要旋转的角度
float dis = (moveAng / (Mathf.PI * 2)) * num; //计算需要移动的距离
float ti = Mathf.Abs(dis) / speed; //计算移动所需时间
//缓慢移动物体
DOTween.To((float b) => {
des = b; //更新目标值
Move(); //更新界面
}, des, des + dis, ti).OnComplete(() => { }); //移动完成后执行的