一、演示效果
二、知识点讲解
2.1 布局
void CreateItems()
{
reward_data_list = reward_data_list ?? new List<RewardData>();
reward_data_list.Clear();
for (int i = 0; i < ItemCount; i++)
{
GameObject item;
if (i + 1 <= itemParent.childCount)
{
item = itemParent.GetChild(i).gameObject;
}
else
{
item = Instantiate(itemParent.GetChild(0).gameObject, itemParent);
}
item.transform.localPosition = initPosArr[i];
item.transform.localScale = Vector3.one;
var cardGraphics = item.transform.Find("Graphics").GetComponent<RectTransform>();
RefreshCardData(cardGraphics, false, rewardDatas[i]);
SetCardOpen(false, item.GetComponent<Button>(), true, rewardDatas[i]);
}
StartAnim(rewardDatas);
}
/// <summary>
/// 明牌,洗牌动画
/// </summary>
private void StartAnim(RewardData[] rewardsArr)
{
CardSelectable = false;
if (rewardsArr.Length != itemParent.childCount)
{
Debug.LogErrorFormat("rewards length is not equals cards count:{0}", itemParent.childCount);
return;
}
isSwapCard = true;
var seqAnim = DOTween.Sequence();
seqAnim.AppendInterval(2f);
seqAnim.AppendCallback(() =>
{
int overCount = itemParent.childCount;
for (int i = 0; i < itemParent.childCount; i++)
{
SetCardOpen(false, itemParent.GetChild(i).GetComponent<Button>(), false, null, 0.2f, () =>
{
//所有卡片翻回去之后开始洗牌
if (--overCount <= 0)
{
List<int> cardsList = new List<int>();
for (int childIndex = 0; childIndex < itemParent.childCount; childIndex++)
{
cardsList.Add(childIndex);
}
SwapCards(cardsList, 10, () =>
{
RefreshCardADState(false);
CardSelectable = true;
});
}
});
}
});
}
2.2 转动逻辑
private void SwapCards(List<int> cardsList, int swapCount, Action onComplete)
{
if (swapCount <= 0)
{
onComplete?.Invoke();
return;
}
SwapCardAnim(cardsList, () =>
{
ListRandom(cardsList);
SwapCards(cardsList, --swapCount, onComplete);
});
}
public static void ListRandom<T>(List<T> sources)
{
int index;
T temp;
for (int i = 0; i < sources.Count; i++)
{
index = UnityEngine.Random.Range(0, sources.Count);
if (index != i)
{
temp = sources[i];
sources[i] = sources[index];
sources[index] = temp;
}
}
}
/// <summary>
/// 洗牌动画
/// </summary>
/// <param name="onSwapOver"></param>
private void SwapCardAnim(List<int> cardsindexList, Action onSwapOver)
{
if (itemParent.childCount % 2 != 0)
{
Debug.LogError("cardsRoot 卡片个数不能为奇数");
return;
}
int moveMission = itemParent.childCount;
TweenCallback onMoveOver = () =>
{
if (--moveMission <= 0)
{
onSwapOver?.Invoke();
}
};
for (int i = 0; i < cardsindexList.Count; i += 2)
{
var indexA = cardsindexList[i];
var indexB = cardsindexList[i + 1];
var cardA = itemParent.GetChild(indexA);
var cardB = itemParent.GetChild(indexB);
float moveDuration = Vector2.Distance(initPosArr[indexA], initPosArr[indexB]) / 1500;
moveDuration = Mathf.Clamp(moveDuration, 0, 0.18f);
cardA.DOLocalMove(initPosArr[indexB], moveDuration).onComplete = onMoveOver;
cardB.DOLocalMove(initPosArr[indexA], moveDuration).onComplete = onMoveOver;
}
}
private void SetCardOpen(bool isUser, Button cardBt, bool isOpen, RewardData reward = null, float duration = 0.2f, Action onCardAnimOver = null)
{
if (isOpen && reward == null)
{
Debug.LogError("翻卡传入奖励数据为null");
return;
}
if (isUser && !CardSelectable)
{
return;
}
CardSelectable = false;
int texIndex = 0;
int colorIndex = 0;
string tmStr = string.Empty;
Vector3 halfRotate = new Vector3(0, 90, 0);
if (isOpen)
{
texIndex = reward.type;
colorIndex = reward.type - 1;
tmStr = reward.amount.ToString();
halfRotate.y = 270;
}
cardBt.interactable = !isOpen;
var card = cardBt.transform;
var cardGraphics = card.Find("Graphics").GetComponent<RectTransform>();
var seqAnim = DOTween.Sequence();
seqAnim.Append(cardGraphics.DOLocalRotate(halfRotate, duration).SetEase(Ease.Linear));
seqAnim.AppendCallback(() =>
{
RefreshCardData(cardGraphics, isOpen, reward);
});
seqAnim.Append(cardGraphics.DOLocalRotate(halfRotate + Vector3.up * 90, duration).SetEase(Ease.Linear));
seqAnim.onComplete = () =>
{
if (!isUser)
{
//CardSelectable = true;
onCardAnimOver?.Invoke();
}
};
if (isUser)
{
card.SetSiblingIndex(itemParent.childCount);
//float moveDuration = Vector2.Distance(card.transform.localPosition, Vector3.zero) / 400;
//moveDuration = Mathf.Clamp(moveDuration, 0, 0.4f);
//card.DOMove(Vector3.zero, moveDuration);
//card.DOScale(1.4f, moveDuration).onComplete = () =>
//{
// var moveSeq = DOTween.Sequence();
// moveSeq.AppendInterval(1.0f);
// moveSeq.AppendCallback(() =>
// {
// var smallCard = smallCardsRoot.GetChild(CurClaimIndex);
// moveDuration = Mathf.Clamp(Vector2.Distance(card.position, smallCard.position) / 10, 0, 0.4f);
// card.DOScale(smallCard.GetComponent<RectTransform>().sizeDelta.x / card.GetComponent<RectTransform>().sizeDelta.x, moveDuration);
// card.DOMove(smallCard.position, moveDuration).onComplete = () =>
// {
// CardSelectable = true;
// GF.Sound.PlaySound("poker_end.wav", false);
// //加奖励
// GF.UserData.ClaimReward(UserDataType.LuckpokerRedpacket, reward, GF.UserData.GameUIForm.gameMainView.levelSocreTxt.transform);
// onCardAnimOver?.Invoke();
// };
// });
//};
CardSelectable = true;
onCardAnimOver?.Invoke();
}
}
三 、完整代码逻辑
https://github.com/lixianjun0903/luckydraw-master.git