UI抽奖转盘
(转盘的item转动指针不动 如需指针转动自行修改原理类似)
圆形布局code CircularLayoutGroup : LayoutGroup
public override void CalculateLayoutInputVertical()
{
if (rectTransform.childCount > 0)
Calculate();
}
public int StartAngle = 0;
public int Radius = 360;
public bool IsAutoRotateSelfToCenter = false;
public void Calculate()
{
float perAngle = 360f / rectTransform.childCount;
for (int i = 0; i < rectTransform.childCount; i++)
{
float angle = (i * perAngle + StartAngle) * Mathf.Deg2Rad;
//半径 * 旋转角度的 sin cos的值 相对于圆心的 x,y
float x = Radius * Mathf.Sin(angle);
float y = Radius * Mathf.Cos(angle);
var pos = new Vector2(x, y);
pos.x += padding.left;
pos.x -= padding.right;
pos.y += padding.top;
pos.y -= padding.bottom;
rectTransform.GetChild(i).localPosition = pos;
if (IsAutoRotateSelfToCenter)
{
Vector2 dir1 = -pos;
Vector2 dir2 = Vector2.down; //
float signedAngle = Vector2.SignedAngle(dir1, dir2);
rectTransform.GetChild(i).localRotation = Quaternion.Euler(0, 0, -signedAngle);
}
else
{
rectTransform.GetChild(i).localRotation = Quaternion.identity;
}
}
}
逻辑code 用到了Dotween商店自行下载
using DG.Tweening;
public Transform _dial;//转盘
private int _cyclesNum = 3;//旋转的整圈数
private float _duration = 3;//旋转的持续时间
List<Transform> items = new List<Transform>();
public InputField _resultId;
public Button _startButton;
public bool _isAntidicDirection;//逆时针旋转
private void Start()
{
for (int i = 0; i < _dial.childCount; i++)
{
items.Add(_dial.GetChild(i));
}
_startButton.onClick.AddListener(() => startDial());
}
public void startDial()
{
_startButton.interactable = false;
_resultId.text = string.Empty;
//伪随机
int rotNum = Random.Range(1, items.Count);
int angle = _cyclesNum * (_isAntidicDirection ? 360 : -360) + (rotNum - 1) * 360 / items.Count;
//本次旋转的度数
_dial.DORotate(new Vector3(0, 0, angle), _duration, RotateMode.FastBeyond360).OnUpdate(() =>
{
foreach (var item in items)
//矫正子物体旋转防止父物体带动子物体旋转
item.localEulerAngles = (-_dial.transform.eulerAngles);
}).OnComplete(() =>
{
_resultId.text = rotNum.ToString();
_startButton.interactable = true;
}).SetEase(Ease.InOutCubic);
}