美文网首页Unity技术VR/AR分享Unity教程合集
01VR房地产中射线作用及代码了解

01VR房地产中射线作用及代码了解

作者: _谭小坤 | 来源:发表于2017-05-13 17:31 被阅读43次

    一、房地产中关于射线的用处##

    1.用来瞬移(曲线)。
    2.直线用来与物体进行交互。

    二、直线射线的代码解析(与物体在场景中交互处理)##

    using UnityEngine;
    using System.Collections;
    
    //通过这个代码可以控制手柄发射一条射线。
    public class LaserPointer : MonoBehaviour
    {
        //public bool active = true;
        public Color color;
        public float thickness = 0.002f;
        private GameObject pointer;
    
        public Transform launchTarget;
        private GameObject aim;
    
        private GameObject holder;
    
        private Material colorMaterial;
        private Material overlayColorMaterial;
        void Awake()
        {
            holder = new GameObject("Laser");
            //holder.transform.parent = this.transform;
             pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
            pointer.transform.parent = holder.transform;
            pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
            pointer.transform.localPosition = new Vector3( 0f, 0f, 50f);
            Object.Destroy(pointer.transform.GetComponent<Collider>());
            aim = GameObject.CreatePrimitive(PrimitiveType.Sphere);
            Object.Destroy(aim.transform.GetComponent<Collider>());
            aim.transform.parent = holder.transform;
            aim.transform.localScale = new Vector3(thickness*5, thickness*5, thickness*5);
            aim.transform.localPosition = Vector3.zero;
    
            if (colorMaterial == null)
            {
                colorMaterial = new Material(Shader.Find("MyShader/Color"));
            }
            colorMaterial.SetColor("_Color", color);
            pointer.GetComponent<MeshRenderer>().material = colorMaterial;
            aim.GetComponent<MeshRenderer>().material = colorMaterial;
            if (overlayColorMaterial == null)
            {
                overlayColorMaterial = new Material(Shader.Find("MyShader/ColorOverlay"));
            }
            overlayColorMaterial.SetColor("_Color", color);
            if (launchTarget==null)
            {
                launchTarget = this.transform;
            }
        }
    
        public bool isWorking
        {
            get
            {
                if(holder)
                {
                    return holder.activeSelf;
                }
                return false;
            }
            set
            {
                if (holder)
                {
                    holder.SetActive(value);
                }
            }
        }
    
        private bool _isOver = false;
       
        public void setValue(Vector3 position,Vector3 forward, float distance,bool isOver=false)
        {
            //isOver = true;
            if (holder != null)
            {
                
                pointer.transform.localScale = new Vector3(thickness, thickness, distance);
                pointer.transform.localPosition = new Vector3(0f, 0f, distance / 2f);
                holder.transform.position = position;
                holder.transform.forward = forward;
                aim.transform.position = position + forward.normalized * distance;
    
                if (isOver != _isOver)
                {
                    _isOver = isOver;
                    if (isOver)
                    {
                        pointer.GetComponent<MeshRenderer>().material = overlayColorMaterial;
                        aim.GetComponent<MeshRenderer>().material = overlayColorMaterial;
                    }
                    else
                    {
                        pointer.GetComponent<MeshRenderer>().material = colorMaterial;
                        aim.GetComponent<MeshRenderer>().material = colorMaterial;
                    }
    
                }
    
    
            }
        }
    
        public void setValue(Vector3 startPos,Vector3 endPos, bool isOver = false)
        {
            Vector3 forward = endPos - startPos;
            setValue(startPos, forward, Vector3.Distance(endPos,startPos),isOver);
        }
    
    
       
    }
    

    二、特定要求检测射线的发出(比如:按下Trigger才发射射线出来)射线的长度(只显示从手柄到我们进行交互物体的距离)—————————————————————这里用监听进行按键的检测。

                          公司有一套架构,做了一套架构用来检测手柄交互(按键信息的检测)
    

    三、架构信息简单理解。

    using System;
    using Mvc.Base;
    
    namespace Mvc
    {
       
        public class MvcTool
        {
            /// <summary>
            /// 事件消息的发送
            /// </summary>
            /// <param name="noticeType"></param>
            /// <param name="data"></param>
            /// <param name="manageName"></param>
            public static void sendNotice(string noticeType, object data = null, string manageName = NoticeTypes.ManageName)
            {
                Manage.getInstance(manageName).sendNotice(noticeType, data);
            }
    
            /// <summary>
            /// 消息监听注册
            /// </summary>
            /// <param name="noticeType"></param>
            /// <param name="listener">Listener(string noticeType,object data=null)</param>
            /// <param name="data"></param>
    
          //Listener是一个委托*******************************************************
    
            public static void addNoticeListener(string noticeType, Listener listener,string manageName = NoticeTypes.ManageName)
            {
                Manage.getInstance(manageName).addNoticeListener(noticeType, listener);
            }
    
            /// <summary>
            /// 消息监听去除
            /// </summary>
            /// <param name="noticeType"></param>
            /// <param name="listener"></param>
            /// <param name="manageName"></param>
            public static void removeNoticeListener(string noticeType, Listener listener,string manageName = NoticeTypes.ManageName)
            {
                Manage.getInstance(manageName).removeNoticeListener(noticeType, listener);
            }
            /// <summary>
            /// 查找消息接收者对象
            ///tagName标记名,若标记名不为空以标记名进行管理,若标记名为空则以类名进行管理
            /// </summary>
            /// <param name="?"></param>
            /// <returns></returns>
            public static INotice retrieveReceiver(string tagName, string manageName = NoticeTypes.ManageName)
            {
                return Manage.getInstance(manageName).retrieveReceiver(tagName);
            }
    
            /// <summary>
            /// 获取消息接收者对象注册名,若没有返回空
            /// </summary>
            /// <param name="receiver"></param>
            /// <param name="manageName"></param>
            /// <returns></returns>
            public static string getReceiveTagName(INotice receiver,string manageName = NoticeTypes.ManageName)
            {
                return Manage.getInstance(manageName).getReceiveTagName(receiver);
            }
    
    
        }
    }
    
    
    

    理解委托信息

    
    using System;
    using System.Collections.Generic;
    using UnityEngine;
    
    namespace Mvc.Base
    {
        /// <summary>
        /// 监听功能函数
        /// </summary>
        /// <param name="noticeType"></param>
        /// <param name="data"></param>
        public delegate void Listener(string noticeType, object data = null);
    
        internal struct TempReceiver
        {
            internal INotice receiver;
            internal string tagName;
    
            internal bool isAdd;
        }
    
        internal struct TempListener
        {
            internal string noticeType;
            internal Listener listener;
            internal bool isAdd;
        }
    
        internal struct TempNotice
        {
            internal string noticeType;
            internal object data;
        }
        public class Manage
        {
            private static Dictionary<string, Manage> _manages = new Dictionary<string, Manage>();
            private Dictionary<string, List<INotice>> _receiverDic;
            private Dictionary<string, INotice> _receiverClassDic;
            private Dictionary<INotice, string> _receiverTagDic;
    
            private Dictionary<string, List<Listener>> _listeners;
    
            private List<TempReceiver> _tempReceiverWorkList;
            private List<TempListener> _tempListenerWorkList;
            private List<TempNotice> _tempNoticeList;
    
            private int _index = 0;
    
            public Manage()
            {
                _receiverDic = new Dictionary<string, List<INotice>>();
                _receiverClassDic = new Dictionary<string, INotice>();
                _receiverTagDic = new Dictionary<INotice, string>();
    
                _listeners = new Dictionary<string, List<Listener>>();
    
                _tempReceiverWorkList = new List<TempReceiver>();
                _tempListenerWorkList = new List<TempListener>();
                _tempNoticeList = new List<TempNotice>();
            }
    
            public static Manage getInstance(string name)
            {
                if (!_manages.ContainsKey(name))
                {
                    _manages[name] = new Manage();
                }
                return _manages[name];
            }
    
            /// <summary>
            /// 某标记对象是否存在
            ///tagName标记名,若标记名不为空以标记名进行管理,若标记名为空则以类名进行管理
            /// </summary>
            /// <param name="tagName"></param>
            /// <returns></returns>
            public bool hasReceiver(string tagName)
            {
                return _receiverClassDic.ContainsKey(tagName);
            }
    
            /// <summary>
            /// 获得监听者注册标记名
            /// </summary>
            /// <param name="receiver"></param>
            /// <returns></returns>
            public string getReceiveTagName(INotice receiver)
            {
                if (_receiverTagDic.ContainsKey(receiver))
                {
                    return _receiverTagDic[receiver];
                }
                return null;
            }
            /// <summary>
            /// 获得新添加监听者标记名
            /// </summary>
            /// <param name="receiver"></param>
            /// <returns></returns>
            private string getAddReceiveDefaultTagName(INotice receiver)
            {
                if (_receiverTagDic.ContainsKey(receiver))
                {
                    return _receiverTagDic[receiver];
                }
                Type type = receiver.GetType();
                _index++;
                string tagName = type.Name + _index.ToString();
                return tagName;
            }
            /// <summary>
            /// 消息是否在发送状态中
            /// 消息发送过程中不能对队列进行操作
            /// </summary>
            private bool _isWorking = false;
            /// <summary>
            /// 添加消息接收者
            ///tagName标记名,若标记名不为空以标记名进行管理,若标记名为空则以类名进行管理
            /// </summary>
            /// <param name="receiver"></param>
            /// <param name="tagName"></param>
            public void addNoticeReceiver(INotice receiver, string tagName = null)
            {
    
                if (_isWorking)
                {//在消息发送过程中,注册延后 
                    TempReceiver temp = new TempReceiver();
                    temp.receiver = receiver;
                    temp.tagName = tagName;
                    temp.isAdd = true;
                    _tempReceiverWorkList.Add(temp);
                    return;
                }
                if (tagName == null)
                {
                    tagName = getAddReceiveDefaultTagName(receiver);
                }
                if (!_receiverTagDic.ContainsKey(receiver))
                {
    
                    if (!hasReceiver(tagName))
                    {
                        string[] arr = receiver.listNoticeTypes();
                        foreach (string noticeType in arr)
                        {
                            if (!_receiverDic.ContainsKey(noticeType))
                            {
                                _receiverDic[noticeType] = new List<INotice>();
                            }
                            List<INotice> list = _receiverDic[noticeType];
    
                            if (!list.Contains(receiver))
                            {
                                int priority = receiver.getPriority();
                                if (receiver.getPriority() < 0)
                                {
                                    list.Add(receiver);
                                }
                                else
                                {
                                    int count = list.Count;
                                    bool isIn = false;
                                    for (int j = 0; j < count; j++)
                                    {
                                        if (priority > list[j].getPriority())
                                        {
                                            list.Insert(j, receiver);
                                            isIn = true;
                                            break;
                                        }
                                    }
                                    if (isIn)
                                    {
                                        list.Add(receiver);
                                    }
                                }
                            }
                        }
                        _receiverClassDic[tagName] = receiver;
                        _receiverTagDic[receiver] = tagName;
                    }
                    else
                    {
                        Debug.LogError("该标记名已经存在" + tagName);
                        throw new Exception("该标记名已经存在" + tagName);
                    }
    
                }
                else
                {
                    Debug.LogError("该消息接收者已经存在" + tagName);
                    throw new Exception("该消息接收者已经存在" + tagName);
                }
            }
    
            /// <summary>
            /// 去除消息接收者
            ///tagName标记名,若标记名不为空以标记名进行管理,若标记名为空则以类名进行管理
            ///tagName标记名,在添加时用标记名进行管理,则去除时需提供标记名
            /// </summary>
            /// <param name="?"></param>
            /// <returns></returns>
            public void removeNoticeReceiver(INotice receiver, string tagName = null)
            {
                if (_isWorking)
                {//在消息发送过程中,注册延后 
                    TempReceiver temp = new TempReceiver();
                    temp.receiver = receiver;
                    temp.tagName = tagName;
                    temp.isAdd = false;
                    _tempReceiverWorkList.Add(temp);
                    return;
                }
                if (tagName == null)
                {
                    tagName = getAddReceiveDefaultTagName(receiver);
                }
                if (hasReceiver(tagName))
                {
                    foreach (KeyValuePair<string, List<INotice>> kv in _receiverDic)
                    {
                        List<INotice> list = kv.Value;
                        if (list.Contains(receiver))
                        {
                            list.Remove(receiver);
                        }
                    }
                    _receiverClassDic.Remove(tagName);
                    _receiverTagDic.Remove(receiver);
                }
            }
    
            /// <summary>
            /// 发送消息
            /// </summary>
            /// <param name="?"></param>
            /// <returns></returns>
            public void sendNotice(string noticeType, object data = null)
            {
                if (_isWorking)
                {
                    TempNotice tempNotice = new TempNotice();
                    tempNotice.noticeType = noticeType;
                    tempNotice.data = data;
                    _tempNoticeList.Add(tempNotice);
                    return;
                }
                _isWorking = true;
    
                if (_receiverDic.ContainsKey(noticeType))
                {
                    List<INotice> list = _receiverDic[noticeType];
                    foreach (INotice receiver in list)
                    {
    
    
    #if !UNITY_EDITOR
                        try
                        {
    #endif
                        receiver.handlerNotice(noticeType, data);
    #if !UNITY_EDITOR
                        }
                        catch (Exception e)
                        {
                            Type type = receiver.GetType();
                            Debug.LogError("INotice Error>>> noticeType:[" + noticeType + "] receiver:[" + type.Name + "]");
                        }
    #endif
                    }
                }
    
                if (_listeners.ContainsKey(noticeType))
                {
                    List<Listener> list = _listeners[noticeType];
                    foreach (Listener listener in list)
                    {
    #if !UNITY_EDITOR
                        try
                        {
    #endif
                        listener(noticeType, data);
    #if !UNITY_EDITOR
                        }
                        catch (Exception e)
                        {
                            Debug.LogError("Listener Error");
                        }
    #endif
                    }
                }
    
                _isWorking = false;
                if (_tempReceiverWorkList.Count > 0)
                {
                    foreach (TempReceiver temp in _tempReceiverWorkList)
                    {
                        if (temp.isAdd)
                        {
                            addNoticeReceiver(temp.receiver, temp.tagName);
                        }
                        else
                        {
                            removeNoticeReceiver(temp.receiver, temp.tagName);
                        }
                    }
                    _tempReceiverWorkList.Clear();
                }
                if (_tempListenerWorkList.Count > 0)
                {
                    foreach (TempListener temp in _tempListenerWorkList)
                    {
                        if (temp.isAdd)
                        {
                            addNoticeListener(temp.noticeType, temp.listener);
    
                        }
                        else
                        {
                            removeNoticeListener(temp.noticeType, temp.listener);
                        }
                    }
                    _tempListenerWorkList.Clear();
                }
    
                if (_tempNoticeList.Count > 0)
                {
                    TempNotice tempNotice = _tempNoticeList[0];
                    _tempNoticeList.RemoveAt(0);
                    sendNotice(tempNotice.noticeType, tempNotice.data);
                }
            }
    
    
    
            /// <summary>
            /// 查找消息接收者对象
            ///tagName标记名,若标记名不为空以标记名进行管理,若标记名为空则以类名进行管理
            /// </summary>
            /// <param name="?"></param>
            /// <returns></returns>
            public INotice retrieveReceiver(string tagName)
            {
                if (hasReceiver(tagName))
                {
                    return _receiverClassDic[tagName] as INotice;
                }
                return null;
            }
    
            /// <summary>
            /// 功能监听添加
            /// </summary>
            /// <param name="noticeType"></param>
            /// <param name="listener"></param>
            /// <param name="data"></param>
            public void addNoticeListener(string noticeType, Listener listener)
            {
                if (_isWorking)
                {//在消息发送过程中,注册延后 
                    TempListener temp = new TempListener();
                    temp.noticeType = noticeType;
                    temp.listener = listener;
                    temp.isAdd = true;
                    _tempListenerWorkList.Add(temp);
                    return;
                }
                if (!_listeners.ContainsKey(noticeType))
                {
                    _listeners[noticeType] = new List<Listener>();
                }
                List<Listener> list = _listeners[noticeType];
                if (!list.Contains(listener))
                {
                    list.Add(listener);
                }
            }
            /// <summary>
            /// 功能监听删除
            /// </summary>
            /// <param name="noticeType"></param>
            /// <param name="listener"></param>
            public void removeNoticeListener(string noticeType, Listener listener)
            {
                if (_isWorking)
                {//在消息发送过程中,注册延后 
                    TempListener temp = new TempListener();
                    temp.noticeType = noticeType;
                    temp.listener = listener;
                    temp.isAdd = false;
                    _tempListenerWorkList.Add(temp);
                    return;
                }
                if (_listeners.ContainsKey(noticeType))
                {
                    List<Listener> list = _listeners[noticeType];
                    if (list.Contains(listener))
                    {
                        list.Remove(listener);
                    }
                }
            }
        }
    }
    
    
    using System.Collections;
    using System.Collections.Generic;
    using Mvc;
    
    
    public class VrNotice:MvcTool
    {
       
        /// <summary>
        /// ui 显示
        /// </summary>
        public const string UI_SHOW = "ui show";
        /// <summary>
        /// 3Dui 显示
        /// </summary>
        public const string UI_3D_SHOW="ui 3d show";
        /// <summary>
        /// ui 关闭
        /// </summary>
        public const string UI_CLOSE = "ui close";
        /// <summary>
        /// 3Dui关闭
        /// </summary>
        public const string UI_3D_CLOSE = "ui 3d close";
        /// <summary>
        /// 添加UI条目
        /// </summary>
        public const string ADD_UI_ITEM = "add ui item";
    
        public const string ADD_RAY_ITEM = "add ray item";
    
        public const string REMOVE_RAY_ITEM = "remove ray item";
        /// <summary>
        /// 删除UI条目
        /// </summary>
        public const string REMOVE_UI_ITEM = "remove ui item";
        /// <summary>
        /// 添加model条目
        /// </summary>
        public const string ADD_MODEL_ITEM = "add model item";
        /// <summary>
        /// 删除model条目
        /// </summary>
        public const string REMOVE_MODEL_ITEM = "remove model item";
        /// <summary>
        /// 场景切换
        /// </summary>
        public const string SCENE_CHANGE = "scene change";
        /// <summary>
        /// 没有item被选中
        /// </summary>
        public const string NO_ITEM_SELECTED = "no item selected";
        /// <summary>
        /// 射线
        /// </summary>
        public const string LASER_TO = "laser to";
        /// <summary>
        /// VR按键操作
        /// </summary>
        public const string VR_KEY_OPER = "vr key oper";
        /// <summary>
        /// 标记传送
        /// </summary>
        public const string SIGN_TELEPORT = "sign teleport";
        /// <summary>
        /// 标记传送功能
        /// </summary>
        public const string SIGN_TELEPORT_FUN = "sign teleport fun";
        /// <summary>
        /// 关闭传送功能标记
        /// </summary>
        public const string CANCEL_TELEPORT_FUN = "cancel teleport fun";
        /// <summary>
        /// 取消传送
        /// </summary>
        public const string CANCEL_TELEPORT = "cancel teleport";
        /// <summary>
        /// 传送
        /// </summary>
        public const string TELEPORT = "teleport";
        public const string TELEPORT_OVER = "teleport over";
        /// <summary>
        /// 挤压传送
        /// </summary>
        public const string GRIPPED_TELEPORT = "gripped teleport";
        public const string GRIPPED_TELEPORT_OVER = "gripped teleport over";
        /// <summary>
        /// 移动vr定位区域
        /// </summary>
        public const string MOVE_PLAYAREA = "move play area";
        /// <summary>
        /// 传送功能
        /// </summary>
        public const string TELEPORT_FUN = "teleport fun";
    
        /// <summary>
        /// 圆盘顺时针滑动消息
        /// </summary>
        public const string PADGESTURE_SHUN = "pad gesture shun";
    
        /// <summary>
        /// 圆盘逆时针滑动消息
        /// </summary>
        public const string PADGESTURE_NI = "pad gesture ni";
    
        /// <summary>
        /// 圆盘左滑动
        /// </summary>
        public const string PADGESTURE_LEFT = "pad gesture left";
        /// <summary>
        /// 圆盘右滑动
        /// </summary>
        public const string PADGESTURE_RIGHT = "pad gesture right";
        /// <summary>
        /// 圆盘上滑动
        /// </summary>
        public const string PADGESTURE_UP = "pad gesture up";
        /// <summary>
        /// 圆盘下滑动
        /// </summary>
        public const string PADGESTURE_DOWN = "pad gesture down";
    
        /// <summary>
        /// 画布提示
        /// </summary>
        public const string PROMPT = "prompt";
    
        /// <summary>
        /// 播放声音
        /// </summary>
        public const string PLAYAUDIO = "play audio";
    
        /// <summary>
        /// 停止播放声音
        /// </summary>
        public const string STOPAUDIO = "stop audio";
    
        /// <summary>
        /// 暂停播放声音
        /// </summary>
        public const string PAUSEAUDIO = "pause audio";
        /// <summary>
        /// 场景切换
        /// </summary>
        public const string CHANGE_SCENE = "change scene";
        /// <summary>
        /// 更新菜单
        /// </summary>
        public const string UP_MENU = "up menu";
    
        public static void socketSend(Hashtable data)
        {
            sendNotice(SocketClient.SOCKET_SEND, data);
        }
    
        ///// <summary>
        ///// 切换场景
        ///// </summary>
        ///// <param name="sceneName">场景名</param>
        ///// <param name="isLoadSence">是否加载场景界面</param>
        //public static void changeScene(string sceneName,bool isLoadSence=false)
        //{
        //    ChangeSceneSync.getInstance().toScene(sceneName, isLoadSence);
        //}
    }
    

    3.按键操作已经用委托处理了,后面就是调用了。

    一开始进行监听 监听后的处理操作 监听的移除

    三、总结##

    上面就是对手柄按键的交互进行了一种更好检测。不用再每帧都去对手柄按键进行检测监听。

    相关文章

      网友评论

        本文标题:01VR房地产中射线作用及代码了解

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