一、演示效果
二、知识点讲解
2.1 布局
public void CreateItems(SlotsData[] slotsData)
{
isInited = false;
slotsPrizeList = new List<SlotsData>();
for (int i = 0; i < slotsData.Length; i++)
{
var item = slotsData[i];
slotsPrizeList.Add(item);
}
float bottomY = -itemPadding * frontItemCount;
slotEdge = new Vector2(bottomY + itemPadding * slotsPrizeList.Count, bottomY);
slotWheelsIds = new int[slotWheels.Length][];
slotsStopIdx = new int[slotWheels.Length];
for (int i = 0; i < slotWheelsIds.Length; i++)
{
slotWheelsIds[i] = new int[slotsPrizeList.Count];
for (int j = 0; j < slotWheelsIds[i].Length; j++)
{
slotWheelsIds[i][j] = slotsPrizeList[j].id;
}
int halfLen = slotsPrizeList.Count / 2;
for (int j = 0; j < halfLen; j++)
{
int randSwapIdx = UnityEngine.Random.Range(0, halfLen + 1);
int swapIdx2 = slotsPrizeList.Count - randSwapIdx - 1;
int tmpPrizeId = slotWheelsIds[i][swapIdx2];
slotWheelsIds[i][swapIdx2] = slotWheelsIds[i][randSwapIdx];
slotWheelsIds[i][randSwapIdx] = tmpPrizeId;
}
}
for (int i = 0; i < slotWheels.Length; i++)
{
var wheel = slotWheels[i];
for (int j = 0; j < slotWheelsIds[i].Length; j++)
{
var prizeId = slotWheelsIds[i][j];
var reward_data = LuckyManager.Instance.GetDataById(rewardDatas, prizeId, out int index);
var item = Instantiate(slot_Item, wheel);
var pos = item.transform.localPosition;
pos.y = slotEdge.y + j * itemPadding;
item.transform.localPosition = pos;
item.transform.localScale = Vector3.one * itemSize;
var reward_img = item.GetComponentInChildren<Image>();
reward_img.sprite = itemImgs[reward_data.type - 1];
reward_img.SetNativeSize();
item.GetComponentInChildren<TextMeshProUGUI>().text = string.Format("{0}", reward_data.amount);
item.SetActive(true);
}
}
isInited = true;
}
2.2、转动逻辑
private void OnClickSpin()
{
if (!isInited || IsRolling)
{
return;
}
GetSelectIndex();
RollSlots(SpinComplete);
}
public void RollSlots(Action<bool, SlotsData> onSpinCompleted)
{
IsRolling = true;
int rewardId = LuckyManager.Instance.CalculateRewardId(rewardDatas);
var reward_data = LuckyManager.Instance.GetDataById(rewardDatas, rewardId, out int slot_index);
bool isMatched = CalculateSlotStopIndex(reward_data, out slotsStopIdx);
int slotWheelsCount = slotWheels.Length;
int roundNum = 5;
for (int i = 0; i < slotWheels.Length; i++)
{
var wheel = slotWheels[i];
var stopIdx = slotsStopIdx[i];
float rollDistance = roundNum * (slotEdge.x - slotEdge.y);
var offsetY = wheel.GetChild(stopIdx).localPosition.y;
rollDistance += offsetY < 0 ? Mathf.Abs(offsetY - slotEdge.y) + slotEdge.x : offsetY;
float preframePosY = 0f;
float curPosY = 0f;
float rollTime = 2.5f;
if (rollStyle2)
{
rollTime = 2.5f + i * 0.5f;
}
else if (rollStyle3)
{
rollTime = 4.5f - i * 0.5f;
}
else if (rollStyle4)
{
rollTime = 2.5f + i * 2.5f;
}
var rollAnim = DOTween.To(() => curPosY, (x) => curPosY = x, rollDistance, rollTime);
rollAnim.SetEase(Ease.OutQuart);
rollAnim.onUpdate = () =>
{
float deltaY = curPosY - preframePosY;
for (int j = 0; j < wheel.childCount; j++)
{
var item = wheel.GetChild(j);
float nextPosY = item.transform.localPosition.y - deltaY;
var localPosition = item.transform.localPosition;
localPosition.y = nextPosY < slotEdge.y ? slotEdge.x - (slotEdge.y - nextPosY) : nextPosY;
item.transform.localPosition = localPosition;
}
preframePosY = curPosY;
};
rollAnim.onComplete = () =>
{
if (--slotWheelsCount <= 0)
{
IsRolling = false;
onSpinCompleted.Invoke(isMatched, reward_data);
}
};
}
}
三、代码完整链接
https://github.com/lixianjun0903/luckydraw-master.git