Unity自定义ButtonGroup类

18 篇文章 0 订阅

本文只作为参考,个人水平有限,望见谅!
最近接触HTC Vive的项目中,使用的UI交互要不就是World下的UGUI,要不就是使用立体的Sprite来实现。而最经常出现的就是多个选择按钮,高亮选择,点击执行操作。所以在这里总结出两种情况下的ButtonGroup类,提供给有需要的人。PC是可以使用的,在Vive中需要导入Vive Input Utility这个插件,由于时间关系我还没试过。

ButtonGroup.cs

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


public delegate void ButtonEventArg(BaseEventData data);

[System.Serializable]
public abstract class ButtonGroup
{
    public bool canRepeatClick;
    public List<ButtonEventArg> OnMouseEnter;
    public List<ButtonEventArg> OnMouseExit;
    public List<ButtonEventArg> OnMouseClick;

    private int currentClickIndex;
    private int currentEnterIndex;

    public void Init(int heilightIndex)
    {
        OnMouseEnter = new List<ButtonEventArg>();
        OnMouseExit = new List<ButtonEventArg>();
        OnMouseClick = new List<ButtonEventArg>();
        currentClickIndex = heilightIndex;
        SetButtonSprite(currentClickIndex, true);
    }

    public void OnEnter(BaseEventData data)
    {
        int index = GetIndexFromData(data);
        if (index == -1) return;
        if (currentClickIndex!=index)
            SetButtonSprite(currentClickIndex, false);
        SetButtonSprite(index, true);

        if (index < OnMouseEnter.Count && OnMouseEnter[index] != null)
            OnMouseEnter[index](data);
        currentEnterIndex = index;
    }

    public void OnExit(BaseEventData data)
    {
        int index = currentEnterIndex;
        if (index == -1) return;
        SetButtonSprite(index, false);

        if (index<OnMouseExit.Count&&OnMouseExit[index] != null)
            OnMouseExit[index](data);
        currentEnterIndex = -1;
    }

    public void OnClick(BaseEventData data)
    {
        int index = GetIndexFromData(data);
        if (index == -1) return;
        SetButtonSprite(index, true);

        if (index!=currentClickIndex)
            SetButtonSprite(currentClickIndex, false);
        if (index < OnMouseClick.Count && OnMouseClick[index] != null)
        {
            if(canRepeatClick||(!canRepeatClick&&index!=currentClickIndex))
                OnMouseClick[index](data);
        }
        currentClickIndex = index;     
    }

    protected abstract int GetIndexFromData(BaseEventData data);

    protected abstract void SetButtonSprite(int index, bool heilight);
}


[System.Serializable]
public class UGUIButton
{
    public Image image;
    public Sprite normal;
    public Sprite heilight;
}

[System.Serializable]
public class SpriteButton
{
    public SpriteRenderer image;
    public Sprite normal;
    public Sprite heilight;
}



[System.Serializable]
public class UGUIButtonGroup:ButtonGroup
{

    public List<UGUIButton> buttonList;

    protected override int GetIndexFromData(BaseEventData data)
    {
        PointerEventData pData = (PointerEventData)data;
        GameObject go = pData.pointerCurrentRaycast.gameObject;
        if (!go) return -1;
        Button bt = go.GetComponent<Button>();
        if (!bt) return -1;
        for(int i=0;i<buttonList.Count;i++)
        {
            if (buttonList[i].image.Equals(bt.image))
                return i;
        }
        return -1;
    }

    protected override void SetButtonSprite(int index, bool heilight)
    {
        if (index != -1 && index < buttonList.Count && buttonList[index] != null)
            buttonList[index].image.sprite = heilight ?
                buttonList[index].heilight :buttonList[index].normal;
    }
}


[System.Serializable]
public class SpriteButtonGroup : ButtonGroup
{

    public List<SpriteButton> buttonList;

    protected override int GetIndexFromData(BaseEventData data)
    {
        PointerEventData pData = (PointerEventData)data;
        GameObject go = pData.pointerCurrentRaycast.gameObject;
        if (!go) return -1;
        SpriteRenderer sp = go.GetComponent<SpriteRenderer>();
        if (!sp) return -1;
        for (int i = 0; i < buttonList.Count; i++)
        {
            if (buttonList[i].image.Equals(sp))
                return i;
        }
        return -1;
    }

    protected override void SetButtonSprite(int index, bool heilight)
    {
        if (index != -1 && index < buttonList.Count && buttonList[index] != null)
            buttonList[index].image.sprite = heilight ?
                buttonList[index].heilight : buttonList[index].normal;
    }
}

test.cs

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class test : MonoBehaviour {

    public UGUIButtonGroup btGroup;

    void Start () {

        // 参数为按钮序号,-1表示不需要初始高亮按钮
        btGroup.Init(0); 

        // 添加按钮事件

        btGroup.OnMouseClick.Add(ClickBt1);

        // 如果中间有一个按钮不需要事件则
        // btGroup.OnMouseClick.Add((BaseEventData data) => { });
        btGroup.OnMouseClick.Add(ClickBt2);

        btGroup.OnMouseClick.Add(ClickBt3);
    }

    public void Click(BaseEventData data)
    {
        btGroup.OnClick(data);
    }

    void ClickBt1(BaseEventData data)
    {
        Debug.Log("Button 1 Clicked!");
    }
    void ClickBt2(BaseEventData data)
    {
        Debug.Log("Button 2 Clicked!");
    }
    void ClickBt3(BaseEventData data)
    {
        Debug.Log("Button 3 Clicked!");
    }

    //以下为鼠标进入Button就高亮的代码

    //public void Enter(BaseEventData data)
    //{
    //    btGroup.OnEnter(data);
    //}
    //public void Exit(BaseEventData data)
    //{
    //    btGroup.OnExit(data);
    //}

}

使用方法

1.UGUIButtonGroup
将所有Button引用和[正常态、高亮态图片]的引用拖入带有test脚本的物体中,将每个Button的Translation改为none并添加【EventTrigger】组件。最后根据需要为每个Button添加[PointClick]和[PointEnter+PointExit]事件,事件方法指定到test的物体上的[Click]和[Enter+Exit]就可以了。
2.SpriteButtonGroup
同上,只是还需要为每个Sprite添加【Box Collider】组件以及为摄像机添加 【Physics Racaster】组件即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值