unity 手指旋转角色的功能

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.png
image.png

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


image.png
image.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.png
image.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.png
image.png

效果如下图:


Jietu20200504-095321-HD.gif
Jietu20200504-095321-HD.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343