Unity 为NGUI增加体感输入方式

背景

NGUI在处理UI和输入方面确实做的不错,但是现在的问题是公司引入体感之后,是通过手的位置来实现按钮的点击操作,前提我不想改变原先设计好的NGUI界面和机制,怎么破?

NGUI的输入底层机制

NGUI对鼠标或者触摸的位置是通过Camera对NGUI层进行射线检测来获得,然后检测按钮事件、触摸屏Press事件来实现UI的操作,从事件机制上而言,NGUI虽然提供了几种事件机制,但底层还是通过Camera的SendMessage来通知被检测到的控件完成某个事件,OK ,看看代码。

NGUI UICamera中进行射线检测的片段 ,利用当前坐标位置转换到世界坐标系射线

static public bool Raycast (Vector3 inPos)
    {
        for (int i = 0; i < list.size; ++i)
        {
            UICamera cam = list.buffer[i];

            // Skip inactive scripts
            if (!cam.enabled || !NGUITools.GetActive(cam.gameObject)) continue;

            // Convert to view space
            currentCamera = cam.cachedCamera;
            Vector3 pos = currentCamera.ScreenToViewportPoint(inPos);
            ..

..

        }
     }

 NGUI UICamera 中ProcessMouse()方法利用射线检测当前响应的按钮,并通过Notify()通知控件。

// No need to perform raycasts every frame
        if (isPressed || posChanged || mNextRaycast < RealTime.time)
        {
            mNextRaycast = RealTime.time + 0.02f;
            if (!Raycast(Input.mousePosition)) hoveredObject = fallThrough;
            if (hoveredObject == null) hoveredObject = genericEventHandler;
            for (int i = 0; i < 3; ++i) mMouse[i].current = hoveredObject;
        }
…
        // The button was released over a different object -- remove the highlight from the previous
        if ((justPressed || !isPressed) && mHover != null && highlightChanged)
        {
            currentScheme = ControlScheme.Mouse;
            if (mTooltip != null) ShowTooltip(false);
            Notify(mHover, "OnHover", false);
            mHover = null;
        }

NGUI UICamera中封装的通知方法,Camera通过逻辑判断发送不同类型,如在点击的时候发送 :Notify(currentTouch.pressed, "OnClick", null);,在按下时候发送:Notify(currentTouch.current, "OnHover", true);

static public void Notify (GameObject go, string funcName, object obj)
    {
        if (mNotifying) return;
        mNotifying = true;

        if (NGUITools.GetActive(go))
        {
            go.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);

            if (genericEventHandler != null && genericEventHandler != go)
            {
                genericEventHandler.SendMessage(funcName, obj, SendMessageOptions.DontRequireReceiver);
            }
        }
        mNotifying = false;
    }

NGUI 中 UIButton中Onclick处理OnClick ()与OnDragOver()事件,是对Notify(currentTouch.pressed, "OnClick", null)的响应,同时通过EventDelegate.Execute(onClick); 来实现委托。

/// <summary>
    /// Call the listener function.
    /// </summary>

    protected virtual void OnClick ()
    {
        if (current == null && isEnabled)
        {
            current = this;
            EventDelegate.Execute(onClick);
            current = null;
        }
    }

OK, 说到底,NGUI底层还是通过SendMessage来实现,那增加一种输入方式怎么破?

解决方案:引入新的射线检测

好的方式是直接修改NGUI底层UICamera代码逻辑,增加一种体感输入,不过涉及到的太多,倒不如再UIROOT或者UICamera增加一个专门用于体感输入方法,把手的位置作为鼠标,增加一个对NGUI层的射线检测机制,对检测到的按钮发送SendMessage消息,当然发送的内容和NGUI中的一样,就可以保证不修改NGUI的UI脚本等等,实现体感输入。代码示例:

/// <summary>
    /// 作者:细雨淅淅,地址:http://www.cnblogs.com/zsb517/
    /// 摄像机射线检测,对检测到的控件重新设置状态,但不影响鼠标状态
    /// </summary>
    private void OnRayCollision()
    {

        if (UICamera == null || CursorGrp == null)
        {
            return;
        }

        Vector3 realPos     = ScreentoWorldPoint();
        Ray     rayCamera   = UICamera.ScreenPointToRay(realPos);
        RaycastHit hit;

        if (Physics.Raycast(rayCamera, out hit, 1000f, LayMaskCollis.value))
        {
            if (hit.collider == null || hit.collider.gameObject == null)
            {
                return ;
            }

            if (curButton == null )
            {
               // Debug.Log(hit.collider.name);
                curButton = hit.collider.gameObject.GetComponent<UIButton>();
                if (curButton != null)
                {
                    curButton.SetState(UIButtonColor.State.Hover,false);
                  //  curButton.SendMessage("OnHover", true, SendMessageOptions.DontRequireReceiver);
                }

                return;
            }
            else if (curButton != null)
            {
                if (curButton != hit.transform.gameObject.GetComponent<UIButton>())
                {
                    //Restore previous button ,and make new button to hover status
                    //curButton.SendMessage("OnPress", false, SendMessageOptions.DontRequireReceiver);
                    curButton.SetState(UIButtonColor.State.Normal, false);
                    curButton = hit.transform.gameObject.GetComponent<UIButton>();
                    if (curButton)
                    {
                        curButton.SetState(UIButtonColor.State.Hover, false);
                        //curButton.SendMessage("OnHover", true, SendMessageOptions.DontRequireReceiver);
                    }

                    return;
                }
                else
                {

                }
            }
        }
        else
        {
            if (curButton != null)
            {
                curButton.SetState(UIButtonColor.State.Hover, false);

                //curButton.SendMessage("OnPress", false, SendMessageOptions.DontRequireReceiver);
                //curButton.SendMessage("OnHover", false, SendMessageOptions.DontRequireReceiver);
                curButton = null;
                return;
            }
        }

        OnReset();
    }

    private Vector3 ScreentoWorldPoint()
    {
        Vector3 wPos = Vector3.zero;
        if (IsMouseOrKinect)
        {
            wPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
        }
        else
        {
            if (NIHandInput.GetInstance() != null)
            {
                Vector2 pos = NIHandInput.GetInstance().ScreenPos;  //体感输入中手的位置
                wPos = new Vector3(pos.x, pos.y, 0);
            }
        }

        Debuger.Log(wPos);
        return wPos;
    }

结论

对于输入问题,Unity Input自身还提供了一种机制,不过没做太多研究,但是想把各种输入柔和在一起,确实是一件很纠结的事情,还要多考虑,不仅仅是代码问题,而是改变了整个游戏的体验。

细雨标记: unity

时间: 2024-11-09 00:58:20

Unity 为NGUI增加体感输入方式的相关文章

多人交互与体感游戏开发相关技术说明

在淘宝开店过程中,经常有客户咨询多点交互与多人体感互动方面的知识,本人是it的门外汉,不是大家说的程序猿,但与相关硬件合作伙伴接触的比较多,对光学识别方面的了解有点时间,所以在果壳网这个地方留个记号,记录自己的一些了解也算分享给大家,希望能给大家的开发带来一些指引或者启发(涉及部分合作客户的利益,技术点过,希望有兴趣的深入研究). 多人互动目前采用的技术: 1.微软kinect,leapmotion为代表的硬件深度场景识别技术,通过官方提供的sdk包或开源驱动进行硬件识别数据的编程.目前利用比较

体感造成思想差异

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 36.0px "PingFang SC" } span.Apple-tab-span { white-space: pre } 4.以体感为主导感觉形成的个人思想 感觉不仅仅是大脑获取信息的基本来源,也是个人幸福或痛苦的决定因素.这一点在体感上表现得尤为明显,任何一种体感在产生的同时总是附带着幸福或痛苦体验.一个人的大部分知识经验都来自于体感,并且他所追求的幸福也是体感体验时,我们将这个人的思想

使用HTML5开发Kinect体感游戏

一.简介 我们要做的是怎样一款游戏? 在前不久成都TGC2016展会上,我们开发了一款<火影忍者手游>的体感游戏,主要模拟手游章节<九尾袭来 >,用户化身四代,与九尾进行对决,吸引了大量玩家参与. 表面上看,这款游戏与其它体感体验无异,实际上,它一直运行于浏览器Chrome下,也就是说,我们只需要掌握前端相应技术,就可以开发基于Kinect的网页体感游戏. 二.实现原理 实现思路是什么? 使用H5开发基于Kinect的体感游戏,其实工作原理很简单,由Kinect采集到玩家及环境数据

制作Kinect体感控制小车教程 &lt;一&gt;

转载请注明出处:http://blog.csdn.net/lxk7280                                        Kinect体感控制小车        Kinect部分:  购买KInect,这第一步就不多说了.因为Kinect二代出了之后,Kinect一代价格立刻降了不少,这对于初学者绝对是一个福音.几个月之前700多的Kinect一代,现在只需要400多了.有的Kinect交流群里面二手的都已经只卖100块钱了. 买回Kinect,之后就开始学习了.

Kinect外包团队(长年承接微软Kinect体感项目外包,有大型Kinect案例)

承接Kinect体感企业项目.游戏项目外包 有丰富案例提供演示,可公对公签正规合同,开发票. 我们是北京的公司.专业团队,成员为专业WPF产品公司一线开发人员,有大型产品开发经验: 提供优质的售后服务,保证产品质量,轻量级产品可以提供规范清晰的源代码,有业务需求可以进行一对一的技术指导. 欢迎联系QQ:372900288,电话:13911652504: 我们提供免费咨询及项目评估,全职WPF程序员,正规办公地点.

Houdini + TouchDesigner + leapmotion 分分钟做出钢铁侠的体感交互效果

接触touchdesigner已经有一段时间了,虽然教程确实非常有限而且很难找到深入的主题,但好在和houdini同根同源很多思路都是可以直接套用的,学习过程目前还没遇到特别难理解的问题. 今天我来讲一讲最近尝试的一个交互实验,目的是想了解touchdesigner到底有多灵活,结果很明显它的能力和Houdini形同手足.如果说Houdini是一个城府很深,每一步都要深思熟虑的老大哥的话,Touchdesigner则有点像一个事事都急于表现,任何精彩的点子都藏不住的小弟.一个是用时间精雕细琢,一

体感差异造成的思想差异

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 36.0px "PingFang SC" } span.Apple-tab-span { white-space: pre } 2.体感差异造成思想差异 在特定的人群之间,体感的差异是非常明显的.比如儿童.中年人.老人,由于身体状况的差异,他们之间的体感差异是明显的.跌倒这一情况对儿童可能会造成巨大痛楚,但无关大碍:中年人跌倒一般不痛不痒:而老年人由于骨质疏松,跌倒轻的伤筋动骨,重的就关乎性命了

[XMove-自主设计的体感解决方案] 系统综述

一 . XMOVE 系统简介       X-MOVE是作者于2010年本科四年级年启动的运动传感模拟,建模和计算的平台,已经发展到第四代.利用优秀算法和自主设计的硬件,充分发挥传感器能力,搭建起全新人机交互和动作传感解决方案,并努力实现产品级成熟度. 目前开发了以下应用: 全身动作捕捉和重现 对使命召唤(COD),街霸,HAWX等主流游戏的体感控制的支持 空中3D鼠标(包含动作识别) 手机屏幕实现电脑触摸板 虚拟现实和远程机械控制 电子指南针 传感器数据采集,分析和重现 其他应用 系统涉及以下

TYVJ P1030 乳草的入侵 Label:靠输入方式坑人的水,跳马问题

背景 USACO OCT09 6TH 描述 Farmer John一直努力让他的草地充满鲜美多汁的而又健康的牧草.可惜天不从人愿,他在植物大战人类中败下阵来.邪恶的乳草已经在他的农场的西北部份佔领了一片立足之地. 草地像往常一样,被分割成一个高度為Y(1 <= y <= 100), 宽度為X(1 <= x <= 100)的直角网格.(1,1)是左下角的格(也就是说坐标排布跟一般的X,Y坐标相同).乳草一开始佔领了格(Mx,My).每个星期,乳草传播到已被乳草佔领的格子四面八方的每一