赞
踩
轮转图也叫做轮播图
在UI上,我们只要掌握好近大远小以及角标层级的分配,就能模拟出3D的轮转效果了。
不管是横向、纵向、斜向都能有不错的表现。
这里以纵向代码举例:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
-
- public class Circle2D : MonoBehaviour,IDragHandler,IEndDragHandler
- {
- public InputField inputf;
- public int num = 14;//Item数量
- public float offest = 10;//间距
- public Image prefab;//Item预制体
- public float max = 1;//Item最大比例
- public float min = 0.5f;//Item最小比例
- public float dec = 10;//减速度
- float c;//周长
- float r;//半径
- float ang;//每个角弧度
- float allang;//移动的总弧度
- public List<GameObject> list = new List<GameObject>();
- public List<Transform> sort = new List<Transform>();
- DT dt;
- DT dt0;
- void Start()
- {
- c = num * (prefab.rectTransform.sizeDelta.y+offest);
- r = c / (360 * Mathf.Deg2Rad);
- ang = 360 * Mathf.Deg2Rad / num;
- Move();
- }
- public void Move()
- {
- for(int i = 0; i < num; i++)
- {
- if (list.Count <= i)
- {
- list.Add(Instantiate(prefab.gameObject, transform));
- sort.Add(list[i].transform);
- list[i].transform.GetComponentInChildren<Text>().text = i.ToString();
- }
- float y = Mathf.Sin(i * ang+allang) * r;
- float z = Mathf.Cos(i * ang+allang) * r;
- float p = (z + r) / (r + r);
- float scale = max * (1 - p) + min * p;
- list[i].transform.localPosition = new Vector3(0, y, 0);
- list[i].transform.localScale = Vector3.one * scale;
- }
- //排序设置角标
- Sort();
- }
- public void OnDrag(PointerEventData eventData)
- {
- if (dt != null)
- {
- Destroy(dt.gameObject);
- }
- if (dt0 != null)
- {
- Destroy(dt0.gameObject);
- }
- allang-=eventData.delta.y/r;
- Move();
- }
-
- public void OnEndDrag(PointerEventData eventData)
- {
- float dis = eventData.delta.y;
- float time = Mathf.Abs(dis / dec);
- dt=DT.To((a) =>
- {
- allang -= a / r;
- Move();
- }, dis, 0, time).OnComlate(() =>
- {
- float moveang = Mathf.Asin(sort[num - 1].localPosition.y / r);
- float movetime = Mathf.Abs(moveang * r / dec);
- dt0=DT.To((b) =>
- {
- allang = b;
- Move();
- }, allang, allang + moveang, movetime).OnComlate(() =>
- {
-
- });
- });
- }
- public void Sort()
- {
- sort.Sort((a, b) =>
- {
- if (a.localScale.z < b.localScale.z)
- {
- return -1;
- }
- else if (a.localScale.z == b.localScale.z)
- {
- return 0;
- }
- else
- {
- return 1;
- }
- });
- for (int i = 0; i < sort.Count; i++)
- {
- sort[i].SetSiblingIndex(i);
- }
- }
- public void OnButton()
- {
-
- int next = int.Parse(inputf.text);
- Sort();
- //当前位置
- int id = list.IndexOf(sort[^1].gameObject);
- int n0 = id - next;
- int n1 = num - Mathf.Abs(n0);
- int n2 = n0 > 0 ? -n1 : n1;
- int n3 = Mathf.Abs(n0) < Mathf.Abs(n2) ? n0 : n2;
- //预计位置
- float moveang = Mathf.Asin(sort[num - 1].localPosition.y / r) + n3 * ang;
- float movetime = Mathf.Abs(moveang * r / dec);
- dt0 = DT.To((b) =>
- {
- allang = b;
- Move();
- }, allang, allang + moveang, movetime).OnComlate(() =>
- {
-
- });
-
- }
- void Update()
- {
-
- }
- }
这里用了一个简单的脚本代替DoTween:
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class DT : MonoBehaviour
- {
- float starttime, nowtime, alltime;
- float now;
- Action<float> action;
- Action comlate;
- bool isplay = true;
- void Start()
- {
-
- }
- public static DT To(Action<float>action,float starttime,float nowtime,float alltime)
- {
- GameObject obj = new GameObject("Dt");
- DT self = obj.AddComponent<DT>();
- self.starttime = starttime;
- self.nowtime = nowtime;
- self.alltime = alltime;
- self.now = Time.time;
- self.action = action;
- return self;
- }
- public DT OnComlate(Action comlate)
- {
- this.comlate = comlate;
- return this.GetComponent<DT>();
- }
- void Update()
- {
- if (Time.time - now < alltime)
- {
- float p = (Time.time - now) / alltime;
- float c = (1 - p) * starttime + nowtime * p;
- if (action != null)
- {
- action(c);
- }
- }
- else if(isplay)
- {
- isplay = false;
- if (action != null)
- {
- action(nowtime);
- }
- if (comlate != null)
- {
- comlate();
- }
- Destroy(gameObject);
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。