Unity3d游戏物体、UGUI、NGUI、模型等等的点击、指向、移开事件(包括HTC手柄、Pico 手柄、鼠标等)

目的是将检测和响应分离开,降低耦合性,提高易用性;

主要功能:鼠标(手柄)指向、移开、点击物体(这里的物体可以是游戏物体、模型、UGUI、NGUI等等,可以说几乎任何需要交互的对象都适用),响应这三个操作;

基本原理:通过射线(Ray)来检测目标对象

主要脚本:1、ButtonSetFather(定义一个父类主要包含三个响应方法,无需挂载)

                   2、OnTagetButton(挂在目标物体上,注册三个响应事件)

                   3、NormalButtonSet(挂在目标物体上重写父类方法,实现各自需求的功能)

                   4、InteroperatToRay(用来发射射线来检测碰触到的物体,随便挂载一个物体上)

                   5、还有一点不要忘记,目标物体上一定要有BoxCollider,大小自己调整

public abstract class ButtonSetFather : MonoBehaviour
{
    public abstract void OnFocusRespons();       //鼠标指向响应
    public abstract void OnLoseFocusRespons();   //鼠标离开响应
    public abstract void OnClickRespons();       //鼠标点击响应
}
public class OnTagetButton: MonoBehaviour
{
    //定义三个事件,这里需要引用命名空间“using UnityEngine.Events;”
    public UnityEvent OnClick, OnFocus, OnLoseFocus;

    private void Awake()
    {
        //这里可以设置每个物体的层级方便控制点击层级
        this.transform.gameObject.layer = 8;               
        ButtonSetFather Bsf = this.GetComponent<ButtonSetFather>();  //实例化父类
        OnClick.AddListener(Bsf.OnClickRespons);               //监听点击事件
        OnFocus.AddListener(Bsf.OnFocusRespons);               //鉴听指向事件
        OnLoseFocus.AddListener(Bsf.OnLoseFocusRespons);       //监听移开事件
    }

    public void GetFocus()
    {
        OnFocus.Invoke();      //响应指向
    }
    public void LoseFocus()
    {
        OnLoseFocus.Invoke();  //响应移开

    }
    public void GetClicked()
    {
        OnClick.Invoke();       //响应点击
    }
}
public class NormalButtonSet : ButtonSetFather
{
    //在这里可以根据自己需求改写这三个方法,我这里写的是指向变大,移开缩小
    Vector3 startScale;
    private void Start()
    {
        startScale = new Vector3(1f,1f,1f);
    }
    public override void OnClickRespons()
    {

    }

    public override void OnFocusRespons()
    {
        Debug.Log("射线指向于此");
        this.transform.localScale = startScale * 1.4f;  //指向物体(UI)变大
    }

    public override void OnLoseFocusRespons()
    {
        Debug.Log("Loset");
        this.transform.localScale = startScale;         //移开物体(UI)变小
    }
}
public class InteroperatToRay : MonoBehaviour
{

    private OnTagetButton _currentButton;  //定义一个先接触到的对象
    public OnTagetButton CurrentButton
    {
        get
        {
            return _currentButton;
        }
    }
    private OnTagetButton_lastButton;      //定义一个在_currentButton之前接触到的对象
    private Ray ray = new Ray();           //使用射线来检测碰触到的物体
    private RaycastHit hitInfo;         
    private OnTagetButton hitButton;       //用来临时存储碰触到的对象
    private void Update()
    {
        //射线从相机为远点发出指向鼠标位置
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        
        if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, 1 << 8))
        {
            try
            {
                //使用try catch试着得到射线接触到的物体
                hitButton = hitInfo.transform.GetComponent<OnTagetButton>();
            }
            catch
            {
                Debug.LogError("标记为button的物体,没有mybutton script  " + hitInfo.transform.name);
            }
            //如果得到了碰触到的物体
            if (hitButton != null)
            {
                //使用_currentButton来存储碰触到的物体
                _currentButton = hitButton;
                if (_lastButton != _currentButton)//若这次和上次碰触到的不是一个对象
                {
                    //次目标响应指向事件,这里可以根据自己需求写点击移开指向事件
                    _currentButton.GetFocus(); 
                    if (_lastButton != null)//若上次的目标不为空,那么上次目标响应移开事件
                        _lastButton.LoseFocus();
                    _lastButton = CurrentButton;//这次目标付给_lastButton
                }
            }
            else
            {
                _currentButton = null;
                if (_lastButton != null)
                {
                    _lastButton.LoseFocus();
                    _lastButton = null;
                }
            }

        }
        else
        {
            _currentButton = null;
            if (_lastButton != null)
            {
                _lastButton.LoseFocus();
                _lastButton = null;
            }
        }
    }

}

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值