游戏开发之UGUI工具类

                                           游戏开发之UGUI工具类

在使用UGUI中的Button控件的时候,每次给Button添加绑定一个事件的话,都得调用它的OnClick.AddListener(传方法名),绑定一个方法,但是随着界面越来越复杂,Button也越来越多的时候,如果我们还是这样挨个绑定的话,会增加很多重复的代码,怎么样处理这种情况呢?我们先了解一下Butoon绑定事件的原理,我们知道两个不同的类调用方法的时候,在不new 对象的时候,用委托吧,Button原理就是传一个游戏对象,然后选择这个对象上的某个脚本中的某个方法,这样的好处在于当界面上的Button足够少的时候,拖物体绑定方法方便,不方便的是当Button足够多的时候,会产生很多的垃圾代码。通过看源代码我们知道Button组件继承的是UnityEngine.EventSystem 命名空间下的EventTrigger这个类,这个类有一些Unity本身的回调函数,但都是虚方法,比如OnPointerClickOnPointerDown等,所以呢,我想自己写一个Button组件,绑定事件的原理和Button组件一样,但是为了解决Button组件的不方便问题。具体点就是我本来是想在初始化的时候,遍历Button组件,然后挨个给Button组件绑定方法,但是这样做,只能传一个方法,很不方便,不灵活。怎么办呢?我们可不可以实现在Game视图中当鼠标点击Button控件的时候,回调它绑定的方法呢?

思考,当我们点击Button物体的时候,怎么去回调对应的方法呢?那这个方法该怎么写呢?在写之前把这个类名先确定了UIEventListener

首先想到鼠标点击,那么就得去继承一个类EventTriggerEventTrigger类里面提供了一些回调方法,如下

        public virtual void OnBeginDrag(PointerEventData eventData);

        public virtual void OnCancel(BaseEventData eventData);

        public virtual void OnDeselect(BaseEventData eventData);

        public virtual void OnDrag(PointerEventData eventData);

        public virtual void OnDrop(PointerEventData eventData);

        public virtual void OnEndDrag(PointerEventData eventData);

        public virtual void OnInitializePotentialDrag(PointerEventData eventData);

        public virtual void OnMove(AxisEventData eventData);

        public virtual void OnPointerClick(PointerEventData eventData);

        public virtual void OnPointerDown(PointerEventData eventData);

        public virtual void OnPointerEnter(PointerEventData eventData);

        public virtual void OnPointerExit(PointerEventData eventData);

        public virtual void OnPointerUp(PointerEventData eventData);

        public virtual void OnScroll(PointerEventData eventData);

        public virtual void OnSelect(BaseEventData eventData);

        public virtual void OnSubmit(BaseEventData eventData);

    只需要重写一下 public virtual void OnPointerClick(PointerEventData eventData);

然后给它添加一个回调事件,这个时候就需要用到委托了,委托怎么去定义呢?根据我们要调的方法决定,首先这个委托在OnPointerClick(PointerEventData eventData)方法里回调的,对吧,那么参数必须得有PointerEventData,其次要传一个GameObject对象,那要回调的方法已经可以确定了,

private void MainMenuUI_OnMouseClick(GameObject go,UnityEngine.EventSystems.PointerEventData eventData)

    {

          switch (go.name)

        {

            case UIButtonName.playBtn:

                SceneManager.LoadScene(1);break;

            default:

                break;

        }

    } 

    接下来就可以定义委托和事件了:

public delegate void objEventHandle(GameObject go, PointerEventData eventData);

    //鼠标点击事件

    public event objEventHandle onMouseClick;

    //鼠标按下事件

public event objEventHandle onMouseDownClick;

 

   //重写OnPointerClick方法

    public override void OnPointerClick(PointerEventData eventData)

    {

        //如果委托已经注册事件,那么在回调的时候会回调相应的方法

       if(onMouseClick != null)

        {

            onMouseClick(this.gameObject, eventData);

        }

    }

为了保证每个Button游戏对象身上都有UIEventListener组件,我写了一个根据游戏对象GameObject获取它身上的UIEventListener组件。

   //根据物体对象返回物体对象身上的UIEventListener组件

    public static UIEventListener Get(GameObject obj)

    {

        //从obj获取UIEventListener组件,并返回

        UIEventListener lister = obj.GetComponent<UIEventListener>();

        //如果该物体上没有这个组件,给它添加上这个组件并返回

        if (lister == null) {lister= obj.AddComponent<UIEventListener>(); }

        return lister;

 }

   下面是完善的UIEventListener:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.EventSystems;

 

   //定义委托 是根据要回调的方法决定参数

   public delegate void objEventHandle(GameObject go, PointerEventData eventData);

 

   public class UIEventListener :EventTrigger {

    //鼠标点击事件

    public event objEventHandle onMouseClick;

    //鼠标按下事件

    public event objEventHandle onMouseDownClick;

 

    //根据物体对象返回物体对象身上的UIEventListener组件

    public static UIEventListener Get(GameObject obj)

    {

        //从obj获取UIEventListener组件,并返回

        UIEventListener lister = obj.GetComponent<UIEventListener>();

        //如果该物体上没有这个组件,给它添加上这个组件并返回

        if (lister == null) {lister= obj.AddComponent<UIEventListener>(); }

        return lister;

    }

    //重写OnPointerClick方法

    public override void OnPointerClick(PointerEventData eventData)

    {

        //如果委托已经注册事件,那么在回调的时候会回调相应的方法

       if(onMouseClick != null)

        {

            onMouseClick(this.gameObject, eventData);

        }

    }

    //重写OnPointerDown方法

    public override void OnPointerDown(PointerEventData eventData)

    {

        if(onMouseDownClick!=null)

        { onMouseDownClick(this.gameObject, eventData); }

    }

}

   下面这个类是对UIEventListener的运用:

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.SceneManagement;

using UnityEngine.UI;


public class UIButtonName

{

    public const string playBtn = "PlayBtn";

    public const string headRightBtn = "HeadRightBtn";

    public const string headLeftBtn = "HeadLeftBtn";

    public const string handRightBtn = "HandRightBtn";

    public const string handLeftBtn = "HandLeftBtn";

    public const string upperBodyRightBtn = "UpperBodyRightBtn";

    public const string upperBodyLeftBtn = "UpperBodyLeftBtn";

    public const string lowerBodyRightBtn = "LowerBodyRightBtn";

    public const string lowerBodyLeftBtn = "LowerBodyLeftBtn";

    public const string footRightBtn = "FootRightBtn";

    public const string footLeftBtn = "FootLeftBtn";

    public const string blueBtn = "BlueBtn";

    public const string cyanBtn = "CyanBtn";

    public const string greenBtn = "GreenBtn";

    public const string pureBtn = "PureBtn";

    public const string redBtn = "RedBtn";

}

public class MainMenuUI : MonoBehaviour {

    

    ///这样写的目的 为了保证List<Button>的封装性,

    //不让其他类调用,但是又想在Unity的Inspecter

    //上面板显示,并且可以拖游戏对象,故此用[SerializeField]

    [SerializeField]

    private List<Button> btns=new List<Button>();

 

    private Transform player;

 

private SkinnedMeshRenderer[] meshRenderers;

 

    private void Awake()

    {

        player = GameObject.FindGameObjectWithTag("Player").transform;

        meshRenderers =player.GetComponentsInChildren<SkinnedMeshRenderer>();

        //对于UIEventListener的使用

        foreach (Button btn in btns)

        {

          //给每个Button游戏对象注册回调方法

            UIEventListener.Get(btn.gameObject).onMouseClick += MainMenuUI_OnMouseClick;

        }

 

        AudioManager.Instance.PlayBgMusic(AudioType.BGM);

}

//回调方法,根据游戏对象的名字,调用对应的方法

    private void MainMenuUI_OnMouseClick(GameObject go,UnityEngine.EventSystems.PointerEventData eventData)

    {

        AudioManager.Instance.PlayAudio(AudioType.ButtonClick);

        switch (go.name)

        {

            case UIButtonName.playBtn:

                SceneManager.LoadScene(1);break;

            case UIButtonName.blueBtn:

                ChangeColor(new Color(53f/255f,53f/255,169f/255,1));break;

            case UIButtonName.cyanBtn:

                ChangeColor(new Color(10f / 255, 164f / 255, 164f / 255, 1)); break;

            case UIButtonName.greenBtn:

                ChangeColor(new Color(62f / 255, 152f / 255, 62f / 255, 1)); break;

            case UIButtonName.pureBtn:

                ChangeColor(new Color(130f / 255, 42f / 255, 130f / 255, 1)); break;

            case UIButtonName.redBtn:

                ChangeColor(new Color(183f / 255,43f / 255, 43f / 255, 1)); break;

            case UIButtonName.headLeftBtn:

                ChangeHead(0); break;

            case UIButtonName.headRightBtn:

                ChangeHead(1);break;

            case UIButtonName.handLeftBtn:

                ChangeHand(0);break;

            case UIButtonName.handRightBtn:

                ChangeHand(1);break;

            case UIButtonName.upperBodyLeftBtn:

                ChangeUpperBody(0);break;

            case UIButtonName.upperBodyRightBtn:

                ChangeUpperBody(1);break;

            case UIButtonName.lowerBodyLeftBtn:

                ChangeLowerBody(0);break;

            case UIButtonName.lowerBodyRightBtn:

                ChangeLowerBody(1);break;

            case UIButtonName.footLeftBtn:

                ChangeFoot(0);break;

            case UIButtonName.footRightBtn:

                ChangeFoot(1);break;

            default:

                break;

        }

    }

    [SerializeField]

    private List<Mesh> headMeshs = new List<Mesh>();

    private int headIndex;

    [SerializeField]

    private SkinnedMeshRenderer headMeshRenderer;

 

    [SerializeField]

    private List<Mesh> handMeshs = new List<Mesh>();

    private int handIndex;

    [SerializeField]

    private SkinnedMeshRenderer handMeshRenderer;

 

    [SerializeField]

    private List<Mesh> upperBodyMeshs = new List<Mesh>();

    private int upperBodyIndex;

    [SerializeField]

    private SkinnedMeshRenderer upperBodyMeshRenderer;

 

    [SerializeField]

    private List<Mesh> lowerBodyMeshs = new List<Mesh>();

    private int lowerBodyIndex;

    [SerializeField]

    private SkinnedMeshRenderer lowerBodyMeshRenderer;

 

    [SerializeField]

    private List<Mesh> footMeshs = new List<Mesh>();

    private int footIndex;

    [SerializeField]

    private SkinnedMeshRenderer footMeshRenderer;

    private void ChangeFoot(int leftOrRight)

    {

        //leftButton

        if (leftOrRight == 0)

        {

            footIndex--;

            if (footIndex < 0)

            { footIndex = footMeshs.Count - 1; }

        }

        else

        {

            footIndex++;

            if (footIndex > footMeshs.Count - 1)

            { footIndex = 0; }

        }

        Mesh mesh = footMeshs[footIndex];

        footMeshRenderer.sharedMesh = mesh;

        PlayerTemplate.footMeshRenderer = mesh;

    }

 

    private void ChangeLowerBody(int leftOrRight)

    {

        //leftButton

        if (leftOrRight == 0)

        {

            lowerBodyIndex--;

            if (lowerBodyIndex < 0)

            { lowerBodyIndex = lowerBodyMeshs.Count - 1; }

        }

        else

        {

            lowerBodyIndex++;

            if (lowerBodyIndex > lowerBodyMeshs.Count - 1)

            {lowerBodyIndex = 0; }

        }

        Mesh mesh = lowerBodyMeshs[lowerBodyIndex];

        lowerBodyMeshRenderer.sharedMesh = mesh;

        PlayerTemplate.lowerBodyMeshRenderer = mesh;

    }

 

    private void ChangeUpperBody(int leftOrRight)

    {

        //leftButton

        if (leftOrRight == 0)

        {

            upperBodyIndex--;

            if (upperBodyIndex < 0)

            { upperBodyIndex = upperBodyMeshs.Count - 1; }

        }

        else

        {

            upperBodyIndex++;

            if (upperBodyIndex > upperBodyMeshs.Count - 1)

            { upperBodyIndex = 0; }

        }

        Mesh mesh = upperBodyMeshs[upperBodyIndex];

        upperBodyMeshRenderer.sharedMesh = mesh;

        PlayerTemplate.upperBodyMeshRenderer= mesh;

    }

 

    private void ChangeHand(int leftOrRight)

    {

        //leftButton

        if (leftOrRight == 0)

        {

            handIndex--;

            if (handIndex < 0)

            { handIndex = handMeshs.Count - 1; }

        }

        else

        {

            handIndex++;

            if (handIndex > handMeshs.Count - 1)

            { handIndex = 0; }

        }

        Mesh mesh = handMeshs[handIndex];

        handMeshRenderer.sharedMesh = mesh;

        PlayerTemplate.handMeshRenderer = mesh;

    }

 

    private void ChangeHead(int leftOrRight)

    {

        //leftButton

        if(leftOrRight==0)

        {

            headIndex--;

            if(headIndex<0)

            { headIndex = headMeshs.Count - 1; }

        }

        else

        {

            headIndex++;

            if(headIndex>headMeshs.Count-1)

            { headIndex = 0; }

        }

        Mesh mesh = headMeshs[headIndex];

        headMeshRenderer.sharedMesh = mesh;

        PlayerTemplate.headMeshRenderer = mesh;

    }

 

    private void ChangeColor(Color color)

    {

        PlayerTemplate.selectColor = color;

        foreach (SkinnedMeshRenderer render in meshRenderers)

        {

            render.material.color = color;

        }

    }

 

}


    总结:使用方法

1.把UIEventListener脚本拖到项目中

2.在UI类中写一个List<Button> btns列表

[SerializeField]

 private List<Button> btns=new List<Button>();

3.在初始化的时候遍历btns,挨个添加上UIEventListener组件并绑定方法。

 foreach (Button btn in btns)

 {

    UIEventListener.Get(btn.gameObject).onMouseClick += MainMenuUI_OnMouseClick;

  }

 

 private void MainMenuUI_OnMouseClick(GameObject go,UnityEngine.EventSystems.PointerEventData eventData)

{

        switch (go.name)

        {

            case UIButtonName.playBtn:

                SceneManager.LoadScene(1);break;

            default:

                break;

        }

    }


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值