美文网首页Unity技术应用
unity 手指旋转角色的功能

unity 手指旋转角色的功能

作者: 丛小胖有个锤子 | 来源:发表于2020-05-04 10:01 被阅读0次

    unity 手指旋转角色的功能

    1. 需求说明

    1.1 可以用手指进行旋转。
    1.2 点击角色时可以触发事件

    2. Unity 鼠标点击3D物体的方法

    2.1 第一种 OnMouse

    在需要检测的物体上 首先物体要有Collider 添加脚本 使用OnMouse系列方法(脚本的enable不影响OnMouse的调用)

        //当鼠标悬停在网格上时,
        void OnMouseEnter()
        {
           
        } 
     
        // ...当鼠标悬浮在物体上
        void OnMouseOver()
        {
        
        } 
     
        // ...当鼠标移开时
        void OnMouseExit()
        {
           
        }
        // ...当鼠标点击
        void OnMouseDown()
        {
           
        }
        // ...当鼠标抬起
        void OnMouseUp()
        {
           
        }
    

    2.2 第二种方法 射线检测(首先物体要有Collider 然后挂载脚本)

    using UnityEngine;
    using System.Collections;
     
    public class RayCastHitControl : MonoBehaviour 
    {
        Ray ray;
        RaycastHit hit;
        GameObject obj;
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Debug.Log("点击鼠标左键");
                ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out hit))
                {
                    Debug.Log(hit.collider.gameObject.name);
                    obj = hit.collider.gameObject;
                    //通过名字
                    if (obj.name.Equals("BeiJiuChuan"))
                    {
                        Debug.Log("点中"+obj.name);
                    }
                    //通过标签
                    if (obj.tag == "move")
                    {
                        Debug.Log("点中" + obj.name);
                    }
                }
            }
        }
    }
    

    2.3 第三种方法 游戏物体 EventTrigger 物体动态事件监听

    先说一下 有哪些封装好的公共方法

    OnBeginDrag         //在拖动开始之前调用。
    OnCancel            //发生Cancel事件时由EventSystem调用。
    OnDeselect          //在选择新对象时由EventSystem调用。
    ondragDown          //每次在拖动期间移动指针时由EventSystem调用。
    OnDrop              //当对象接受丢弃时由EventSystem调用。
    OnEndDrag           //拖动结束后由EventSystem调用。
    OnInitializePotentialDrag   //在找到拖动时,但在有效开始拖动之前由EventSystem调用。
    OnMove              //发生Move事件时由EventSystem调用。
    OnPointerClick      //发生Click事件时由EventSystem调用。
    OnPointerDown       //发生PointerDown事件时由EventSystem调用。
    OnPointerEnter      //当指针进入与此EventTrigger关联的对象时由EventSystem调用。
    OnPointerExit       //当指针退出与此EventTrigger关联的对象时,由EventSystem调用。
    OnPointerUp         //发生PointerUp事件时由EventSystem调用。
    OnScroll            //当Scroll事件发生时由EventSystem调用。
    ONSELECT            //当Select事件发生时由EventSystem调用。
    OnUpdateSelected    //更新与此EventTrigger关联的对象时由EventSystem调用。
    

    然后说一下使用方法

    1.通过编辑器中添加

    在Inspector中添加EventTrigger的componnent组件,然后点击Add New Event Type按钮添加一个基本的事件

    image.pngimage.png

    当我们选择一个事件的时候,就相当于将要于此事件绑定了,例如当我们选择Pointer Click的时候,绑定了这个组件的物体将接受Pointer Click 事件的消息,当我们在物体上按下鼠标的时候,(当然空间中的物体我们是无法通过鼠标点击的,但是当我们可以通过射线碰撞的方法,来实现Pointer Enter,Pointer Exit等事件的触发)这里我们用来绑定这个EventTrigger 的是一个UI Panel 这样便可以让它接受我们自定义的单击事件了


    image.pngimage.png
    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    using System.Collections.Generic;
    using UnityEngine.Events;
     
    public class OnClickMouseDown : MonoBehaviour
    {
      
        void Start()
        {
            //获取或添加EventTrigger组件
            EventTrigger trigger = transform.GetComponent<EventTrigger>();
            if (trigger == null)
            {
                trigger = transform.gameObject.AddComponent<EventTrigger>();
            }
            //初始化EventTrigger.Entry的数组
            trigger.triggers = new List<EventTrigger.Entry>();
            //创建各种 EventTrigger.Entry的类型
            EventTrigger.Entry entry = new EventTrigger.Entry();
            entry.eventID = EventTriggerType.PointerEnter;//设置Entry的eventID类型 即EventTriggerType的各种枚举(比如鼠标点击,滑动,拖动等)
            UnityAction<BaseEventData> callback =new UnityAction<BaseEventData>(OnEventTrigger);  //注册代理
            entry.callback.AddListener(callback);//添加代理事件到EventTrigger.Entry
            EventTrigger.Entry entry2 = new EventTrigger.Entry();
            entry2.eventID = EventTriggerType.PointerDown;
            UnityAction<BaseEventData> callback1 =new UnityAction<BaseEventData>(OnMouseDown);
            entry2.callback.AddListener(callback1);
     
            //在EventTrigger.Entry的数组添加EventTrigger.Entry
            trigger.triggers.Add(entry);
            trigger.triggers.Add(entry2);
        }
     
        private void OnMouseDown(BaseEventData arg0)
        {
            Debug.Log("OnMouseDown");
        }
     
        private void OnEventTrigger(BaseEventData arg0)
        {
            Debug.Log("OnEventTrigger");
        }
    }
    

    最后 别忘了 在摄像机下添加一个Physics Raycaster的组件,用来检测鼠标射线


    image.pngimage.png

    3. 具体实现

    考虑到以后的扩展,我们使用第三种方式来实现具体的功能。

    using System;
    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
    
    namespace Tuyoo
    {
        public class MoveTarget : EventTrigger
        {
            //对外提供的点击回调
            public Action clickAct = null;
    
            public bool isClick = false;
    
            void Start()
            {
                EventTriggerListener.GetListener(gameObject).onDrag += onDrag;
                EventTriggerListener.GetListener(gameObject).onBeginDrag += onBeginDrag;
                EventTriggerListener.GetListener(gameObject).onPointerClick += onPointerClick;
                EventTriggerListener.GetListener(gameObject).onPointerUp += onPointerUp;
            }
    
            private float beginfloat = 0;
            public void onBeginDrag(GameObject go, PointerEventData eventData)
            {
                beginfloat = eventData.position.x;
            }
    
            public void onDrag(GameObject go, PointerEventData eventData)
            {
                isClick = false;
                transform.localRotation = Quaternion.Euler(transform.localRotation.eulerAngles.x, transform.localRotation.eulerAngles.y - (eventData.position.x - beginfloat), transform.localRotation.eulerAngles.z);
                beginfloat = eventData.position.x;
            }
            
            public void onPointerUp(GameObject go, PointerEventData eventData)
            {
                // 点击容错处理,只有在0.1秒内,松开手指并且没有移动事件触发,才算点击。
                StartCoroutine(delayTime(0.1f));
            }
    
            private IEnumerator delayTime(float numtimes)
            {
                yield return WaitForTimeMgr.Instance.GetWaitForSeconds(numtimes);
                isClick = true;
            }
    
            public void onPointerClick(GameObject go, PointerEventData eventData)
            {
                if (clickAct != null && isClick)
                {
                    clickAct();
                }
            }
        }
    }
    
    using UnityEngine;
    using System.Collections;
    using UnityEngine.EventSystems;
     
    public class EventTriggerListener : EventTrigger
    {
        #region 变量
        //带参数是为了方便取得绑定了UI事件的对象  
        public delegate void PointerEventDelegate(GameObject go, PointerEventData eventData);
        public delegate void BaseEventDelegate(GameObject go, BaseEventData eventData);
        public delegate void AxisEventDelegate(GameObject go, AxisEventData eventData);
     
        public event PointerEventDelegate onPointerEnter;
        public event PointerEventDelegate onPointerExit;
        public event PointerEventDelegate onPointerDown;
        public event PointerEventDelegate onPointerUp;
        public event PointerEventDelegate onPointerClick;
        public event PointerEventDelegate onInitializePotentialDrag;
        public event PointerEventDelegate onBeginDrag;
        public event PointerEventDelegate onDrag;
        public event PointerEventDelegate onEndDrag;
        public event PointerEventDelegate onDrop;
        public event PointerEventDelegate onScroll;
        public event BaseEventDelegate onUpdateSelected;
        public event BaseEventDelegate onSelect;
        public event BaseEventDelegate onDeselect;
        public event AxisEventDelegate onMove;
        public event BaseEventDelegate onSubmit;
        public event BaseEventDelegate onCancel;
        #endregion
     
        public static EventTriggerListener GetListener(GameObject go)
        {
            EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
            if (listener == null) listener = go.AddComponent<EventTriggerListener>();
            return listener;
        }
     
        #region 方法
        public override void OnPointerEnter(PointerEventData eventData)
        {
            if (onPointerEnter != null) onPointerEnter(gameObject, eventData);
        }
        public override void OnPointerExit(PointerEventData eventData)
        {
            if (onPointerExit != null) onPointerExit(gameObject, eventData);
        }
        public override void OnPointerDown(PointerEventData eventData)
        {
            if (onPointerDown != null) onPointerDown(gameObject, eventData);
        }
        public override void OnPointerUp(PointerEventData eventData)
        {
            if (onPointerUp != null) onPointerUp(gameObject, eventData);
        }
        public override void OnPointerClick(PointerEventData eventData)
        {
            if (onPointerClick != null) onPointerClick(gameObject, eventData);
        }
        public override void OnInitializePotentialDrag(PointerEventData eventData)
        {
            if (onInitializePotentialDrag != null) onInitializePotentialDrag(gameObject, eventData);
        }
        public override void OnBeginDrag(PointerEventData eventData)
        {
            if (onBeginDrag != null) onBeginDrag(gameObject, eventData);
        }
        public override void OnDrag(PointerEventData eventData)
        {
            if (onDrag != null) onDrag(gameObject, eventData);
        }
        public override void OnEndDrag(PointerEventData eventData)
        {
            if (onEndDrag != null) onEndDrag(gameObject, eventData);
        }
        public override void OnDrop(PointerEventData eventData)
        {
            if (onDrop != null) onDrop(gameObject, eventData);
        }
        public override void OnScroll(PointerEventData eventData)
        {
            if (onScroll != null) onScroll(gameObject, eventData);
        }
        public override void OnUpdateSelected(BaseEventData eventData)
        {
            if (onUpdateSelected != null) onUpdateSelected(gameObject, eventData);
        }
        public override void OnSelect(BaseEventData eventData)
        {
            if (onSelect != null) onSelect(gameObject, eventData);
        }
        public override void OnDeselect(BaseEventData eventData)
        {
            if (onDeselect != null) onDeselect(gameObject, eventData);
        }
        public override void OnMove(AxisEventData eventData)
        {
            if (onMove != null) onMove(gameObject, eventData);
        }
        public override void OnSubmit(BaseEventData eventData)
        {
            if (onSubmit != null) onSubmit(gameObject, eventData);
        }
        public override void OnCancel(BaseEventData eventData)
        {
            if (onCancel != null) onCancel(gameObject, eventData);
        }
        #endregion
    }
    

    将脚本挂到要旋转的物体上就可以进行旋转了。


    image.pngimage.png

    效果如下图:


    Jietu20200504-095321-HD.gifJietu20200504-095321-HD.gif

    相关文章

      网友评论

        本文标题:unity 手指旋转角色的功能

        本文链接:https://www.haomeiwen.com/subject/ffreghtx.html