unity泛型委托制作排行榜

泛型能解决一些重复性的问题,比如分数从大到小排,死亡数从大到小排等等

这里先封装玩家数据

如名字,击杀数,死亡数等


using UnityEngine;
[System.Serializable]
public class PlayerStatus 
{
    public string playerName;
    public int killNmber, deatNmber, flagNmber;
    public Sprite profileSprite, playerSprite;

    [HideInInspector] public string title;
    [HideInInspector] public string dateTime;

    public static bool CompareKill(PlayerStatus playerStatusA, PlayerStatus playerStatusB) => playerStatusA.killNmber>playerStatusB.killNmber;
}

再创建一个游戏数据处理类,单列模式,来计算玩家的数据的排序

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
///     委托条件 参数要一致至  返回值也有一致
///     Action 可以带参数 没有返回值
///     Func 可以带参数 有返回值
/// </summary>

public class GameDataManager : MonoBehaviour
{

    public static GameDataManager Instance;
    public PlayerStatus[] playstatus;
   [HideInInspector] public string topSkllName, topDeathName, topFlagName;//[HideInInspector] Inspector隐藏 不能在unity中看到和编辑

    private void Awake()
    {
        if(Instance!=null) 
        {
            Destroy(Instance);
        }
        else
        {
            Instance= this;
        }
        DontDestroyOnLoad(Instance);
    }

    private void Start()
    {
        topSkllName=GetTopNum((player) => player.killNmber);
        topDeathName=GetTopNum((player) => player.deatNmber);
        topFlagName=GetTopNum((player) => player.flagNmber);

        UIManager.Instance.UpdatePlayerTitle(topSkllName, "杀人王", (player) => player.playerName);
        UIManager.Instance.UpdatePlayerTitle(topDeathName, "死亡者", Logger.Log);
        UIManager.Instance.UpdatePlayerTitle(topFlagName, "夺标晓", Logger.Log);


        Debug.Log("kill "+GetTopNum((player) => player.killNmber));//lambda 会做类型推断 等同与上方的 //public int GetPlayerKillNum(PlayerStatus player)
        Debug.Log("death"+GetTopNum((player) => player.deatNmber));
        Debug.Log("flag"+GetTopNum((player) => player.flagNmber));


        UIManager.Instance.UpdataLeftUI();
        UIManager.Instance.UpdataRightUI();
        UIManager.Instance.UpdateSoltAlpha();

    }

    //委托 找到最大值
    public string GetTopNum(Func<PlayerStatus,int> func)//PlayerStatus 是参数  int 返回值
    {
        string topName = "";
        int bestRecrod = 0;
        foreach(PlayerStatus player in playstatus)
        {
            int tempNum = func(player);
            if(tempNum>bestRecrod)
            {
                bestRecrod = tempNum;
                topName=player.playerName;
            }
        }
        return topName;
    }

    //委托 冒泡排序法 泛型
    public void BubbleSort<T>(T[] playerStatuses ,Func<T, T, bool> func)
    {
        bool isSwapped=false;
        do
        {
            isSwapped=false;
            for (int i = 0; i <playerStatuses.Length-1; i++)
            {
                if (func(playerStatuses[i], playerStatuses[i+1]))
                {
                    T temp = playerStatuses[i];
                    playerStatuses[i]= playerStatuses[i+1];
                    playerStatuses[i+1]= temp;
                    isSwapped=true;
                }
            }
        }while( isSwapped);
        UIManager.Instance.UpdataLeftUI();
    }

}

在创建一个UI管理类负责UI的显示

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public static UIManager Instance;
    int currentIndex;
    [Header("left UI")]
    public GameObject[] solts;
    [Header("right UI")]
    public Text statauText;
    public Image playerImage;
    public Text playerName;
    public Text titleText;//ToDo 称号

    [Header("按钮")]
    public Button leftButton, rightButton, skllButton, deatButton, flagButton;

    bool isAscendSkll=true;//判断是否倒序 从底层 从小到大
    bool isAscendDeath=true;//判断是否倒序
    bool isAscendFlag=true;//判断是否倒序
    bool isPressButton = true;

    private void Awake()
    {
        if (Instance!=null)
        {
            Destroy(Instance);
        }
        else
        {
            Instance= this;
        }
        DontDestroyOnLoad(Instance);
    }
    private void Start()
    {
        leftButton.onClick.AddListener(BackButton);
        rightButton.onClick.AddListener(NextButton);
        skllButton.onClick.AddListener(KillSortButton);
        deatButton.onClick.AddListener(DeathSortButton);
        flagButton.onClick.AddListener(FlagSortButton);

       // skllButton.onClick.AddListener(() => SortMetond(GameDataManager.Instance.playstatus, (playerStatusA, playerStatusB) => playerStatusA.killNmber>playerStatusB.killNmber));
    }
    private void Update()
    {
        Debug.Log(isPressButton);
    }
    //更新左边UI
    public void UpdataLeftUI()
    {
        for (int i = 0; i < solts.Length; i++)
        {
            solts[i].transform.GetChild(0).GetComponent<Image>().sprite=GameDataManager.Instance.playstatus[i].profileSprite;
            solts[i].GetComponentInChildren<Text>().text=string.Format("{0}/{1}/{2}",   GameDataManager.Instance.playstatus[i].killNmber,
                                                                                        GameDataManager.Instance.playstatus[i].deatNmber,
                                                                                        GameDataManager.Instance.playstatus[i].flagNmber);
           solts[i].transform.GetChild(2).GetComponent<Text>().text=GameDataManager.Instance.playstatus[i].dateTime;
            Debug.Log(i+"号"+GameDataManager.Instance.playstatus[i].dateTime);

        }
    }
    //图层透明度控制
   public   void UpdateSoltAlpha()
    {
        for (int i = 0; i < solts.Length; i++)
        {
            if(i==currentIndex)
            {
                solts[i].GetComponent<CanvasGroup>().alpha=1f;
                solts[i].transform.GetChild(0).GetComponentInChildren<ParticleSystem>().Play();//获得子物体的粒子
            }
            else
            {
                // solts[i].GetComponent<CanvasGroup>().alpha=0.25f;
                UITweener.instance.AlphaChange(solts[i].GetComponent<CanvasGroup>(), 0.25f);
                solts[i].transform.GetChild(0).GetComponentInChildren<ParticleSystem>().Stop();//获得子物体的粒子

            }
        }
    }

    //更新右边UI
   public void UpdataRightUI()
    {
        PlayerStatus playerStatus = GameDataManager.Instance.playstatus[currentIndex];
        playerImage.sprite=playerStatus.playerSprite;
        statauText.text=string.Format("{0}/{1}/{2}", playerStatus.killNmber, playerStatus.deatNmber, playerStatus.flagNmber);
        playerName.text=playerStatus.playerName;
        titleText.text=playerStatus.title;
    }

    //更新玩家称号
    public void UpdatePlayerTitle(string topName,string title,Func<PlayerStatus,string> func)
    {
        for (int i = 0; i < GameDataManager.Instance.playstatus.Length; i++)//遍历数据
        {
            if (GameDataManager.Instance.playstatus[i].playerName==topName)
            {
                GameDataManager.Instance.playstatus[i].title=title;
                GameDataManager.Instance.playstatus[i].dateTime=func(GameDataManager.Instance.playstatus[i]);

            }
        }
    }
    //总排列方法 <T> 泛型标志
    public void SortMetond<T>(T[] playerStatuses, Func<T, T, bool> func,bool isAscend)
    {
        if (isAscend)//是否升序
        {
            GameDataManager.Instance.BubbleSort(playerStatuses, func);
        }
        else
        {
            ReverseArray();
        }
        UpdataLeftUI();
        UpdataRightUI();
        UpdateSoltAlpha();
    }

    //右按钮
    public void NextButton()
    {
        if(isPressButton)
        {
            currentIndex++;
            if (currentIndex >= solts.Length)
            {
                currentIndex=0;
            }
            UpdataRightUI();
            UpdateSoltAlpha();
            UIAimitor();
        }
         StopCoroutine(nameof(PressButtonCorotinue));
         StartCoroutine(nameof(PressButtonCorotinue));
    }
    //左按钮
    public void BackButton()
    {
        if (isPressButton)
        {
            currentIndex--;
            if (currentIndex<0)
            {
                currentIndex=solts.Length-1;
            }
            UpdataRightUI();
            UpdateSoltAlpha();
            UIAimitor();
        }
        StopCoroutine(nameof(PressButtonCorotinue));
        StartCoroutine(nameof(PressButtonCorotinue));
    }

    //击杀数排列

    public void KillSortButton()
    {
        SortMetond(GameDataManager.Instance.playstatus,(playerStatusA, playerStatusB) => playerStatusA.killNmber>playerStatusB.killNmber,isAscendSkll);
        isAscendSkll=!isAscendSkll;
        isAscendDeath=true;
        isAscendFlag=true;
    }
    //死亡数排列
    public void DeathSortButton()
    {
        SortMetond(GameDataManager.Instance.playstatus, (playerStatusA, playerStatusB) => playerStatusA.deatNmber>playerStatusB.deatNmber,isAscendDeath);
        isAscendDeath=!isAscendDeath;
        isAscendFlag=true;
        isAscendSkll=true;
    }
    //旗帜排列
    public void FlagSortButton()
    {
        SortMetond(GameDataManager.Instance.playstatus, (playerStatusA, playerStatusB) => playerStatusA.flagNmber>playerStatusB.flagNmber,isAscendFlag);
        isAscendFlag=!isAscendFlag;
        isAscendDeath=true;
        isAscendSkll=true;
    }

    //将数组倒序
    public void ReverseArray()=>Array.Reverse(GameDataManager.Instance.playstatus);
    //各种ui动画效果
    public void UIAimitor()
    {
        UITweener.instance.DoTweenPlayerImage();
    }

   IEnumerator PressButtonCorotinue()//IEnumerator 开始协程
    {
        isPressButton=false;
        yield return new WaitForSeconds(0.5f);
        isPressButton=true;
    }
    
}

显示获得称呼的时间


using UnityEngine;
using System;

public class Logger 
{
    public static string Log(PlayerStatus player)
    {
        DateTime currentTime= DateTime.UtcNow;//通用时间 UtcNow不带时区
        Debug.Log(string.Format("{0}{1}{2}", player.playerName, player.title, player.dateTime));
        return currentTime.ToString();
    }

}

后面可以用Dotween来丰富UI的交互

using UnityEngine;
using DG.Tweening;
using UnityEngine.EventSystems;

public class UITweener : MonoBehaviour
{
    public static UITweener instance;
    public RectTransform statusRT, playerImageRT, playerTextRT, titleTextRT;
    public RectTransform nextButton, backButton;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            if (instance != null)
            {
                Destroy(gameObject);
            }
        }
        DontDestroyOnLoad(gameObject);
    }

    //鼠标进入【上下页按钮】触发,按钮变大
    public void ScaleIn(RectTransform _trans)
    {
        _trans.DOScale(new Vector3(2f, 2f, 2f), 0.2f).SetEase(Ease.InSine);
    }

    //鼠标离开【上下页按钮】触发,按钮恢复
    public void ScaleOut(RectTransform _trans)
    {
        _trans.DOScale(new Vector3(1f, 1f, 1f), 0.2f).SetEase(Ease.OutSine);
    }

    //鼠标点击【上下页按钮】触发,右侧人物“扭动”动画
    public void ShakeScale(RectTransform _trans)
    {
        _trans.DOShakeScale(0.5f, 0.25f, 10, 15);
    }

    //鼠标点击【上下页按钮】触发,右侧人物信息“颤抖”动画
    public void ShakeRotation(RectTransform _trans)
    {
        _trans.DOShakeRotation(0.5f, 25, 5, 25);
    }
    //改变透明度
    public void AlphaChange(CanvasGroup _canvasGroup, float _amount)
    {
        _canvasGroup.DOFade(_amount, 0.5f);//DOFade 透明度 所需时间
    }

    public void DoTweenPlayerImage()
    {
        ShakeScale(playerImageRT);
        ShakeRotation(statusRT);
        ShakeScale(playerTextRT);
        ShakeRotation(titleTextRT);
    }


}

详细的可以学习

【UI游戏界面】上下页切换,委托类型作为方法的参数和LAMBDA表达式的实际使用(附:计算所有数据最高的方法,GetChild方法优缺点等)_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值