一 、效果展示
二、知識點
2.1 布局需要實現功能
1、轉動的根目錄為itemSpinRoot
2、創建對應的item
3、每個item轉動的角度
2.2 代碼
public class WheelDialog : UIBase{[SerializeField] Button btnClick;[SerializeField] Button btnClose;[SerializeField] Sprite[] itemImgs;[SerializeField] Transform itemParent;Transform itemSpinRoot;[Header("物體數量")][SerializeField] int ItemCount = 8;private float item_rangle;private RewardData[] rewardDatas;protected internal override void OnInit(UIView view){base.OnInit(view);item_rangle = 360f / ItemCount;//轉動的根目錄為itemSpinRootitemSpinRoot = itemParent.parent;btnClick.onClick.RemoveAllListeners();btnClick.onClick.AddListener(OnClickSpin);btnClose.onClick.RemoveAllListeners();btnClose.onClick.AddListener(OnCloseEvent);rewardDatas = LuckyManager.Instance.GetDefaultWheelData(ItemCount);//創建對應的itemCreateItems(rewardDatas);}protected internal override void OnOpen(object userData){base.OnOpen(userData);ResetWheels();}private void ResetWheels(){}private void CreateItems(RewardData[] wheel_tb){Vector3 init_pos = itemParent.GetChild(0).transform.localPosition;if (wheel_tb.Length != ItemCount){Debug.LogError("wheel_tb.Count != wheel_count !!!");}for (int i = 0; i < wheel_tb.Length; i++){var reward_data = wheel_tb[i];var next_rot = Quaternion.Euler(0, 0, i * item_rangle);var next_pos = next_rot * init_pos;GameObject item;if (i + 1 <= itemParent.childCount){item = itemParent.GetChild(i).gameObject;}else{item = Instantiate(itemParent.GetChild(0).gameObject, itemParent);}//每個item轉動的角度item.transform.localPosition = next_pos;item.transform.localRotation = next_rot;var reward_text = item.GetComponentInChildren<TextMeshProUGUI>();var reward_img = item.GetComponentInChildren<Image>();reward_img.sprite = itemImgs[reward_data.type - 1];reward_img.SetNativeSize();reward_text.text = string.Format("{0}", reward_data.amount);item.GetComponentInChildren<ParticleSystem>().GetComponent<Renderer>().sortingOrder = m_Canvas.sortingOrder + 1;}}private void OnClickSpin(){if (IsRolling){return;}StartSpin(SpinComplete);}}
三、轉動核心邏輯
3.1 知識點
1、DOTween實現轉動角度方法實現
public static TweenerCore<float, float, FloatOptions> To(
DOGetter<float> getter,
DOSetter<float> setter,
float endValue,
float duration)
{
return DOTween.ApplyTo<float, float, FloatOptions>(getter, setter, endValue, duration);
}2、設置轉動模式
roll_act.SetEase(GetEase());
3.2 代碼
private void StartSpin(Action<RewardData> onSpinCompleted){IsRolling = true;int rewardId = LuckyManager.Instance.CalculateRewardId(rewardDatas);var reward_data = LuckyManager.Instance.GetDataById(rewardDatas, rewardId, out int wheel_index);//初始角度float cur_angle = itemSpinRoot.localRotation.eulerAngles.z;int round_count = UnityEngine.Random.Range(4, 5);//最后要轉動的角度float final_angle = -item_rangle * wheel_index + 360 * round_count;float duration = 2.5f;// DOTween實現轉動角度方法實現1var roll_act = DOTween.To(() => cur_angle, (x) => cur_angle = x, final_angle, duration);//轉動模式設置roll_act.SetEase(GetEase());roll_act.onUpdate = () =>{// DOTween實現轉動角度方法實現2itemSpinRoot.localRotation = Quaternion.Euler(0, 0, cur_angle);};roll_act.OnComplete(() =>{IsRolling = false;onSpinCompleted.Invoke(reward_data);});}
四、完整代碼
using UnityEngine; using DG.Tweening; using System; using UnityEngine.UI; using TMPro;namespace Pillow.Lucky {public class WheelDialog : UIBase{[SerializeField] Button btnClick;[SerializeField] Button btnClose;[SerializeField] Sprite[] itemImgs;[SerializeField] Transform itemParent;Transform itemSpinRoot;[Header("物體數量")][SerializeField] int ItemCount = 8;private float item_rangle;private RewardData[] rewardDatas;protected internal override void OnInit(UIView view){base.OnInit(view);item_rangle = 360f / ItemCount;//轉動的根目錄為itemSpinRootitemSpinRoot = itemParent.parent;btnClick.onClick.RemoveAllListeners();btnClick.onClick.AddListener(OnClickSpin);btnClose.onClick.RemoveAllListeners();btnClose.onClick.AddListener(OnCloseEvent);rewardDatas = LuckyManager.Instance.GetDefaultWheelData(ItemCount);//創建對應的itemCreateItems(rewardDatas);}protected internal override void OnOpen(object userData){base.OnOpen(userData);ResetWheels();}private void ResetWheels(){}private void CreateItems(RewardData[] wheel_tb){Vector3 init_pos = itemParent.GetChild(0).transform.localPosition;if (wheel_tb.Length != ItemCount){Debug.LogError("wheel_tb.Count != wheel_count !!!");}for (int i = 0; i < wheel_tb.Length; i++){var reward_data = wheel_tb[i];var next_rot = Quaternion.Euler(0, 0, i * item_rangle);var next_pos = next_rot * init_pos;GameObject item;if (i + 1 <= itemParent.childCount){item = itemParent.GetChild(i).gameObject;}else{item = Instantiate(itemParent.GetChild(0).gameObject, itemParent);}//每個item轉動的角度item.transform.localPosition = next_pos;item.transform.localRotation = next_rot;var reward_text = item.GetComponentInChildren<TextMeshProUGUI>();var reward_img = item.GetComponentInChildren<Image>();reward_img.sprite = itemImgs[reward_data.type - 1];reward_img.SetNativeSize();reward_text.text = string.Format("{0}", reward_data.amount);item.GetComponentInChildren<ParticleSystem>().GetComponent<Renderer>().sortingOrder = m_Canvas.sortingOrder + 1;}}private void OnClickSpin(){if (IsRolling){return;}StartSpin(SpinComplete);}private void StartSpin(Action<RewardData> onSpinCompleted){IsRolling = true;int rewardId = LuckyManager.Instance.CalculateRewardId(rewardDatas);var reward_data = LuckyManager.Instance.GetDataById(rewardDatas, rewardId, out int wheel_index);//初始角度float cur_angle = itemSpinRoot.localRotation.eulerAngles.z;int round_count = UnityEngine.Random.Range(4, 5);//最后要轉動的角度float final_angle = -item_rangle * wheel_index + 360 * round_count;float duration = 2.5f;// DOTween實現轉動角度方法實現1var roll_act = DOTween.To(() => cur_angle, (x) => cur_angle = x, final_angle, duration);//轉動模式設置roll_act.SetEase(GetEase());roll_act.onUpdate = () =>{// DOTween實現轉動角度方法實現2itemSpinRoot.localRotation = Quaternion.Euler(0, 0, cur_angle);};roll_act.OnComplete(() =>{IsRolling = false;onSpinCompleted.Invoke(reward_data);});}void SpinComplete(RewardData rewardData){UIManager.Instance.ShowRewardDialog(rewardData, itemImgs);}private Ease GetEase(){int index = GetSelectLayoutIndex();switch (index){case 2:return Ease.OutBack;case 3:return Ease.OutQuad;case 4:return Ease.OutQuart;case 5:return Ease.OutCubic;case 6:return Ease.OutCirc;case 1:default:return Ease.Linear;}}}}
五、代碼鏈接
https://github.com/lixianjun0903/luckydraw-master.git