当前位置:   article > 正文

【2D轮转图】简单详细的2D轮转,并自动对齐最终人物,生成角色_unity轮转图自动对齐

unity轮转图自动对齐

1,制作显示形象的预制体,两层image,美观一些

2,制作一个image,就是效果里面的半透明灰色背景,在这里挂脚本

 

 代码如下:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.EventSystems;
  6. using DG.Tweening;
  7. public class RotationChart2D : MonoBehaviour,IDragHandler, IEndDragHandler
  8. {
  9. public Image prefab; //预制体
  10. public float max=1; //缩放最大值
  11. public float min=0.5f; //缩放最小值
  12. public int n; //个数
  13. public float spacing = 100;//UI间距单位是像素 比较大
  14. public float cut = 100; //减速度
  15. float c;
  16. float r;
  17. float ang;
  18. List<Image> list = new List<Image>();
  19. List<Transform> sortList = new List<Transform>();
  20. //拖动弧度
  21. float moveAng = 0;
  22. //角色
  23. private GameObject player;
  24. //雷达显示部分
  25. public GameObject show;
  26. void Start()
  27. {
  28. //周长=(宽+间距)*个数
  29. c = (prefab.rectTransform.rect.width + spacing) * n;
  30. //半径=周长/2π
  31. r = c / (2 * Mathf.PI);
  32. ang = 2 * Mathf.PI / n;
  33. //转动方法
  34. Move();
  35. //获取数据
  36. show.GetComponent<RadarMap3>().GetArr();
  37. }
  38. public void Move()
  39. {
  40. for (int i = 0; i < n; i++)
  41. {
  42. //判断集合中有就不创建,没有再创建
  43. if(list.Count<=i)
  44. {
  45. list.Add(Instantiate(prefab, transform));//添加图片
  46. list[i].transform.GetChild(0).GetComponent<Image>().sprite = Resources.Load<Sprite>("Image/image" + i);
  47. sortList.Add(list[i].transform);
  48. }
  49. float x = Mathf.Sin(i * ang+moveAng) * r;
  50. float z = Mathf.Cos(i * ang+moveAng) * r;
  51. //通过z 计算 近大远小
  52. //计算z 0-1的比值 和雷达图计算uv坐标相同
  53. float p = (z + r) / (2 * r);
  54. float scale = (max - min) * p + min; //这是一个比值
  55. //float scale = min * (1 - p) + max * p;
  56. list[i].rectTransform.anchoredPosition = new Vector2(x, 0);
  57. list[i].transform.localScale = Vector3.one * scale;
  58. }
  59. //排序
  60. sortList.Sort((a, b) =>
  61. {
  62. if (a.localScale.x < b.localScale.x)
  63. {
  64. return -1;
  65. }
  66. else if (a.localScale.x == b.localScale.x)
  67. {
  68. return 0;
  69. }
  70. else
  71. {
  72. return 1;
  73. }
  74. });
  75. for (int i = 0; i < sortList.Count; i++)
  76. {
  77. sortList[i].SetSiblingIndex(i);
  78. }
  79. }
  80. // Update is called once per frame
  81. void Update()
  82. {
  83. }
  84. public void OnDrag(PointerEventData eventData)
  85. {
  86. //每帧拖动的距离
  87. float dis = eventData.delta.x;
  88. //通过距离计算弧度
  89. float dragAng = dis / r;
  90. moveAng += dragAng;
  91. //鼠标只要移动就会移动
  92. Move();
  93. }
  94. public void OnEndDrag(PointerEventData eventData)
  95. {
  96. float speed = eventData.delta.x;
  97. float time = Mathf.Abs(speed) / cut;
  98. DOTween.To((a)=>
  99. {
  100. //通过距离计算弧度
  101. float dragAng = a / r;
  102. moveAng += dragAng;
  103. //结束拖拽也会移动
  104. Move();
  105. },speed,0,time).OnComplete(()=>
  106. {
  107. //下标 获取图片的id
  108. Align(list.IndexOf(sortList[n - 1].GetComponent<Image>()));
  109. });
  110. }
  111. //对齐
  112. public void Align(int id)
  113. {
  114. //当前下标
  115. int index = list.IndexOf(sortList[n - 1].GetComponent<Image>());
  116. //指定下标与当前下标的间隔
  117. int sp = id - index;
  118. //计算另一个旋转方向需要的间隔
  119. int sp0 = n - Mathf.Abs(sp);
  120. //一个为顺时针 另一个必为逆时针 所以正负要注意
  121. sp0 = sp > 0?-sp0:sp0;
  122. //选择两个方向中 间隔较小的一方 去旋转
  123. int end = Mathf.Abs(sp) < Mathf.Abs(sp0) ? sp : sp0;
  124. //通过间隔计算弧度
  125. float spAng = end * ang;
  126. //弧度=asin(对边x/斜边r)
  127. //需要旋转的弧度=与中间偏差的弧度+间隔弧度
  128. float AlignAng = Mathf.Asin(sortList[n - 1].GetComponent<RectTransform>().anchoredPosition.x / r)+spAng;
  129. //距离=弧度*半径
  130. float AlugnDis = AlignAng * r;
  131. //时间
  132. float time = Mathf.Abs(AlugnDis)/cut;
  133. //自动对齐
  134. DOTween.To((a)=>
  135. {
  136. moveAng = a;
  137. Move();
  138. },moveAng,moveAng-AlignAng,time).OnComplete(()=> //生成角色
  139. {
  140. if (player != null)
  141. {
  142. Destroy(player);
  143. }
  144. player = Instantiate(Resources.Load<GameObject>("Player/" + id));
  145. player.transform.position = new Vector3(0.45f, -2, 0);
  146. player.transform.eulerAngles = new Vector3(0, 180, 0);
  147. show.GetComponent<RadarMap3>().Change(id);
  148. });
  149. }
  150. }

参考参数:

这里的Show是雷达图,可以显示每个人的数据,我们下期再讲雷达图。

 

补充:SetSiblingIndex 设置创建的物体在你想要的位置

 3. 若是点击button 转到初始第一位

注意 这的“0” 就是传入参数 0  代表第一位初始角色

4:转动结束后,实例化对应角色

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/90223
推荐阅读
相关标签
  

闽ICP备14008679号