Unity 之 月签到累计签到代码实现(ScriptableObject应用 | DoTween入场动画)

Posted 陈言必行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 之 月签到累计签到代码实现(ScriptableObject应用 | DoTween入场动画)相关的知识,希望对你有一定的参考价值。

Unity 之 实现月签到累计签到

一,签到效果

实现效果:


二,实现步骤

2.1 场景搭建

  1. 创建Image设计为大背景,作为一级父物体,命名为:SignPanel
  2. 再SignPanel下再创建一个Image,命名为Context。作为所有签到内容的父物体,并在其上添加’Grid Layout Group’,根据签到内容大小调整其数值即可:
  3. 再创建一个Image,作为签到内容的背景板,在其下一次创建:Image,Text,Button,Image;分别作为每个签到内容的奖励图片,奖励数量,可领取按钮,已领取图片。此物体将作为签到内容的克隆体。

最终搭建场景如下:


2.2 创建配置

通过ScriptableObject做一个配置文件,里面存储每日签到的奖励类型和数量。创建代码命名为MonthSignAwardData,继承修改为ScriptableObject,并给其添加CreateAssetMenu编辑器拓展。

完整代码如下:

using System;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "MonthSignAwardData", menuName = "GameData/MonthSignAwardData", order = 1)]
public class MonthSignAwardData : ScriptableObject

    public List<AwardItem>  awardDataList = new List<AwardItem>();


[Serializable]
public class AwardItem

    /// <summary>
    /// 奖励类型 0:金币,1:钻石
    /// </summary>
    public CurrencyType awardType;
    
    // 奖励数量
    public int awardCount;

创建完成此代码就可以在文件中右键 --> Create --> GameData --> MonthSignAwardData。创建出一个MonthSignAwardData配置文件,然后手动编辑一下奖励内容就可以了。

PS:我这里为了方便演示后面加载,将配置文件直接存储到Resources文件夹下了。


2.3 编写代码

逻辑也比较简单,通过PlayerPrefs存储一个上次签到日期,存储一个上传签到索引。然后通过上次签到日期和本地日期比较判断今日是否已签到。

完整逻辑如下:

using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class MonthSignIn : MonoBehaviour

    [Header("奖励图")]
    [SerializeField] private Sprite[] Spr_AwardSprites;
    
    [Header("模版")]
    [SerializeField] private GameObject Obj_Item;

    [Header("内容父物体")]
    [SerializeField] private Transform Tran_Context;
    
    [Header("关闭按钮")]
    [SerializeField] private Button Btn_Close;

    [Header("内容列表")]
    [SerializeField] private List<SignItem> signList;

    // 配置文件
    private MonthSignAwardData _signAwardData;
    
    // 上次签到索引
    private int LastSignIndex
    
        get  return PlayerPrefs.GetInt("CzhenyaGameDataLastSignIndex", 0); 
        set  PlayerPrefs.SetInt("CzhenyaGameDataLastSignIndex", value); 
    
    // 上次签到日期
    private string LastSignDate
    
        get  return PlayerPrefs.GetString("CzhenyaGameDataLastSignDate", "yy-MM-dd"); 
        set  PlayerPrefs.SetString("CzhenyaGameDataLastSignDate", value); 
    

    void Start()
    
        Obj_Item.gameObject.SetActive(false);
        _signAwardData = Resources.Load<MonthSignAwardData>("MonthSignAwardData");
        
        signList = new List<SignItem>();
        for (int i = 0; i < _signAwardData.awardDataList.Count; i++)
        
            Transform itemTrans = Instantiate(Obj_Item, Tran_Context).transform;
            itemTrans.gameObject.SetActive(true);
            SignItem signItem = new SignItem();
            signItem.Img_Context = itemTrans.GetChild(0).GetComponent<Image>();
            signItem.Text_ContextNum = itemTrans.GetChild(1).GetComponent<Text>();
            signItem.Btn_Receive = itemTrans.GetChild(2).GetComponent<Button>();
            signItem.Obj_Mask = itemTrans.GetChild(3).gameObject;
            
            signItem.Btn_Receive.onClick.AddListener(OnClickReceive);
            int awardCount = _signAwardData.awardDataList[i].awardCount;
            int spriteIndex = (int)_signAwardData.awardDataList[i].awardType;
            signItem.Img_Context.sprite = Spr_AwardSprites[spriteIndex];
            //signItem.Img_Context.SetNativeSize();
            signItem.Text_ContextNum.text = "x" + awardCount;
            
            signList.Add(signItem);
        

        Btn_Close.onClick.AddListener(OnClickClose);
        UpdateSignStatus();
    

    /// <summary>
    /// 更新签到状态
    /// </summary>
    void UpdateSignStatus()
    
        for (int i = 0; i < signList.Count; i++)
        
            signList[i].Btn_Receive.gameObject.SetActive(false);
            signList[i].Obj_Mask.SetActive(i < LastSignIndex);
        
        // 今天没签
        if (!LastSignDate.Contains(DateTime.Today.ToString("MM/dd/yyyy")))
        
            signList[LastSignIndex].Btn_Receive.gameObject.SetActive(true);
        
    

    /// <summary>
    /// 点击签到 -- 领取签到奖励
    /// </summary>
    void OnClickReceive()
    
        int curIndex = LastSignIndex;
        // todo... 恭喜获得
        Debug.Log("当前领取id:" + curIndex);

        if (LastSignIndex >= 27)
        
            LastSignIndex = 0;
        
        else
        
            LastSignIndex++;
        

        LastSignDate = DateTime.Today.ToString("MM/dd/yyyy");
        UpdateSignStatus();
    

    /// <summary>
    /// 关闭面板
    /// </summary>
    void OnClickClose()
    
        gameObject.SetActive(false);
    
    


// 签到内容
public class SignItem

    public Image Img_Context;
    public Text Text_ContextNum;
    public Button Btn_Receive;
    public GameObject Obj_Mask;


public enum CurrencyType

    /// <summary>
    /// 金币
    /// </summary>
    Gold,

    /// <summary>
    /// 钻石
    /// </summary>
    Gam,

将上面代码挂载到SignPanel,然后将公开变量挨个赋值:


三,拓展:入场动画

将下面代码添加到MonthSignIn类中,即可实现开篇看到的入场动画效果:

private void OnEnable()

    PlayDoAni();

// 播放进入动画
public void PlayDoAni()

    StartCoroutine(DoAni());


// 入场动画
IEnumerator DoAni()

    for (int i = 1; i < Tran_Context.childCount; i++)
    
        Tran_Context.GetChild(i).gameObject.SetActive(false);
    
    for (int i = 1; i < Tran_Context.childCount; i++)
    
        Tran_Context.GetChild(i).gameObject.SetActive(true);
        Tran_Context.GetChild(i).transform.localScale = Vector3.zero;
        Tran_Context.GetChild(i).DOScale(Vector3.one, 0.2f).SetEase(Ease.OutBack);
        if (i % 3 == 0)
        
            yield return new WaitForSeconds(0.06f);
        
    

Demo下载地址:https://download.csdn.net/download/Czhenya/87021883

以上是关于Unity 之 月签到累计签到代码实现(ScriptableObject应用 | DoTween入场动画)的主要内容,如果未能解决你的问题,请参考以下文章

实现每日签到日历的脚本

Redis实战之附近商户用户签到UV 统计

Redis实战之附近商户用户签到UV 统计

python3之51cto自动定时签到

java如何实现二维码签到功能(二维码可以动态设置时效)

微信公众平台二维码签到的原理是啥?有代码可以熟悉一下吗