UnityC# 从0开始完成一个鼠标响应的点击背包/暂停面板系统,利用Horizontal layout group 和 Aspect radio 组件完成UI设计

Editor结构

      

UI顶层是一个Canvas用于渲染下方的Image,button以及TextMeshPro。

下方由:

        包含UI的Button部分的PauseSelectionHightTabPanel

        每个Button的组成

        

                一个ButtonGameObject作为父物件,一个TextMeshPro作为子物件的复合体

        每个Panel是个附带了HorizontalLayoutGroup 的EmptyObject 

                其确保了下方的所有TabImage,Tab,Button 保持一个间距相等的距离,

                并且可以控制子物体的Szie和Scale

        只使一个Tab作为ActiveObject,Tab的ActiveSelf属性会直接影响其他组件

                 代码UImanager通过Tab的Active切换实现。

         

         Aspect radio Fiter组件

               确保了大型Panel与屏幕适配

                可以看看这篇:Aspect Ratio Fitter 重温总结(多图)_Huil的博客-CSDN博客

                             

                        

I的设计只需要一个Class即可实现

如下,UIManager

using UnityEngine;
using UnityEngine.UI;

public class UIManager : SingletonMonoBehaviour<UIManager>
{   
    [SerializeField]
    private bool _isPauseMenuOpen;
    public bool IsPauseMenuOpen
    {
        get{
            return _isPauseMenuOpen;
        }
        set{
            _isPauseMenuOpen=value;
        }
    }

    [SerializeField] private GameObject PauseMenuGOBJ;
    [SerializeField] private GameObject[] menuTabs;
    [SerializeField] private Button[] menuButtons;

    protected override void Awake()
    {
        base.Awake();
        PauseMenuGOBJ.SetActive(false);
        IsPauseMenuOpen=false;
    }

    private void Update() 
    {
        PauseMenu();
    }

    private void PauseMenu() 
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            if(IsPauseMenuOpen)
            {
                DisablePauseMenu();
            }
            else
            {
                EnablePauseMenu();
            }
            //每次点击esc bool取反
            IsPauseMenuOpen=!IsPauseMenuOpen;
        }
    }

    private void DisablePauseMenu()
    {   
        Time.timeScale=1;//使游戏进程继续运行
        PauseMenuGOBJ.SetActive(false);
        // Player.Instance.PlayerInputDisabled=false;//恢复Input
    }

    private void EnablePauseMenu() 
    {   
        Time.timeScale=0;//使游戏进程暂停
        PauseMenuGOBJ.SetActive(true);
        // Player.Instance.PlayerInputDisabled=true;//若其他Script存在输入,应该禁止其他系统需要的Input并使其无效。
        System.GC.Collect();

        HighlightTheSelectedTabButton();
    }

    private void HighlightTheSelectedTabButton()
    {
        for(int i=0;i<menuTabs.Length;i++)
        {
            if(menuTabs[i].activeSelf)
            {
                SetMenuTabActive(menuButtons[i]);//此处更改的对象应该为MenuButton
            }
            else
            {
                SetMenuTabInactive(menuButtons[i]);//此处更改的对象应该为MenuButton
            }
        }
    }

    private void SetMenuTabActive(Button button)
    {
        ColorBlock colors=button.colors;
        colors.normalColor=colors.pressedColor;
        button.colors=colors;
    }

    private void SetMenuTabInactive(Button button)
    {
        ColorBlock colors=button.colors;
        colors.normalColor=colors.disabledColor;
        button.colors=colors;
    }

    //此处提供一个可从外部调用的OnClick函数
    /// <summary>
    /// 
    /// </summary>
    /// <param name="buttonParam">  </param>
    public void SwitchTheSelectedTab(int buttonParam)
    {
        for(int i=0;i<menuTabs.Length;i++)
        {
            if(menuTabs[i].activeSelf)
            {
                menuTabs[i].SetActive(false);
            }
        }
        
        menuTabs[buttonParam].SetActive(true);
        HighlightTheSelectedTabButton();
    }
}

原理

         Unity内部通过TIme.timescale来进行游戏进程的推进

        来自官方api

  1.  timeScale为0时,FixedUpdate完全停止
  2. 当 timeScale 设置为 0 时,如果您的所有函数都是独立于帧率的, 则游戏基本上处于暂停状态。
  3. 当 timeScale 设置为 0 时,不会调用 FixedUpdate 函数。
  4. 如果您减小了 /timeScale/,建议也将 Time.fixedDeltaTime 减小相同的量。
  5. timeScale 影响 Time 类的所有时间和增量时间测量变量(但 realtimeSinceStartup 和 fixedDeltaTime 除外)。

        System.GC.collect()

                    主动使用垃圾处理器,清理游戏进行中出现的Garbage;

        Uimanager使用Tab的ActiveSelf属性达成切换条目(Tab)时同时改变Button和Image

        ColorBlock

               其为Button 各种条件下Color的复合属性,代码中对其直接进行调用更改。

        

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值