using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using DG.Tweening;
public class Carousel :MonoBehaviour,IDragHandler,IEndDragHandler
{
public GameObject prefab;
public int spacing;
public int speed;
public float max;
public float min;
int num;
float girth;
float distance;
float r;
float ang;
public List<GameObject> prefabs = new List<GameObject>();
public List<Transform> sorts = new List<Transform>();
public GameObject ShowMonster;
public void OnDrag(PointerEventData eventData)
{
distance += eventData.delta.x;
Move();
}
public void OnEndDrag(PointerEventData eventData)
{
float endTime = Mathf.Abs(eventData.delta.x / speed);
DOTween.To((b) =>
{
distance += b;
Move();
}, eventData.delta.x, 0, endTime).OnComplete(() =>
{
Aling(prefabs.IndexOf(sorts[num - 1].gameObject));
});
}
void Start()
{
num = UserData.Ins.datas.Count;
girth = (prefab.transform.GetComponent<RectTransform>().rect.width + spacing) * num;
r = girth / (2 * Mathf.PI);
ang = (2 * Mathf.PI) / num;
Move();
}
private void Aling(int v)
{
int myindex = prefabs.IndexOf(sorts[num - 1].gameObject);
int a = v - myindex;
int b = num - Mathf.Abs(a);
b = a > 0 ? -b : b;
int count = Mathf.Abs(a) < Mathf.Abs(b) ? a : b;
float countAng = count * ang;
float x = sorts[num - 1].GetComponent<RectTransform>().anchoredPosition.x;
float moveAng = Mathf.Asin(x / r) + countAng;
float moveDis = moveAng * r;
float time = Mathf.Abs(moveDis / speed);
DOTween.To((m) =>
{
distance = m;
Move();
}, distance, distance - moveDis, time).OnComplete(() => {
UserData.Ins.MapId = v;
});
}
private void Move()
{
float moveang = distance / r;
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(ang * i + moveang) * r;
float y = Mathf.Cos(ang * i + moveang) * r;
if (prefabs.Count <= i)
{
GameObject go = Instantiate(prefab, transform, false);
go.GetComponent<Image>().sprite = Resources.Load<Sprite>("PlayerIcon/" + UserData.Ins.datas[i].icon);
go.transform.GetChild(0).GetComponent<Text>().text = UserData.Ins.datas[i].nick;
go.transform.GetChild(1).GetComponent<Text>().text = UserData.Ins.datas[i].monster_nick;
go.transform.GetChild(2).GetComponent<Text>().text = UserData.Ins.datas[i].dis;
go.transform.GetChild(3).transform.GetChild(0).GetComponent<Image>().sprite = Resources.Load<Sprite>("Icon/" + UserData.Ins.datas[i].equip[0]);
go.transform.GetChild(4).transform.GetChild(0).GetComponent<Image>().sprite = Resources.Load<Sprite>("Icon/" + UserData.Ins.datas[i].equip[1]);
go.transform.GetChild(5).transform.GetChild(0).GetComponent<Image>().sprite = Resources.Load<Sprite>("Icon/" + UserData.Ins.datas[i].equip[2]);
go.name = i.ToString();
go.transform.GetComponent<Button>().onClick.AddListener(() =>
{
ShowMonster.SetActive(true);
});
prefabs.Add(go);
sorts.Add(prefabs[i].transform);
}
prefabs[i].GetComponent<RectTransform>().anchoredPosition = new Vector2(x, 0);
float p = (y + r) / (2 * r);
float scale = p * (max - min) + min;
prefabs[i].transform.localScale = Vector3.one * scale;
}
sorts.Sort((a,b) =>
{
if (a.localScale.x > b.localScale.x)
{
return 1;
}
else if (a.localScale.x == b.localScale.x)
{
return 0;
}
else
{
return -1;
}
});
for (int i = 0; i < sorts.Count; i++)
{
sorts[i].SetSiblingIndex(i);
}
}
public void Add()
{
float dis = ang * r;
DOTween.To((m) =>
{
distance = m;
Move();
}, distance, dis + distance, 1).OnComplete(() => {
UserData.Ins.MapId = prefabs.IndexOf(sorts[num - 1].gameObject);
}); ;
}
public void Cut()
{
float dis = ang * r;
DOTween.To((m) =>
{
distance = m;
Move();
}, distance, distance - dis, 1).OnComplete(()=> {
UserData.Ins.MapId = prefabs.IndexOf(sorts[num - 1].gameObject);
});
}
}
Add和Cut是两个button按钮绑定的函数方法。实现效果如:
这里我使用的是通过拖拽事件和Dotween来让图片进行缓动旋转的样式
可以不使用Button使其进行移动轮转,可以直接拖动进行轮转。