Unity 基于eventTriggers的3D场景交互系统「建议收藏」

Unity 基于eventTriggers的3D场景交互系统「建议收藏」Unity基于eventTriggers的3D场景交互系统  Unity里的3D项目有时候需要大量的交互,而且是无UI的交互。这时候可以像UI系统里,使用eventTrigger去制作交互系统。但是这个缺少自定义功能,所以我写了个自定义交互系统。这个交互系统可以做到什么呢?直接上图(仅为演示DEMO)。点击触发事件移动并且事件复杂的交互  该系统采用的工厂设计模式,将你需要的功能写入EventTriggersDemo,将你的功能码

大家好,又见面了,我是你们的朋友全栈君。


Unity 基于eventTriggers的3D场景交互系统

  Unity里的3D项目有时候需要大量的交互,而且是无UI的交互。

这时候可以像UI系统里,使用eventTrigger去制作交互系统。但是这个缺少自定义功能,所以我写了个自定义交互系统。这个交互系统可以做到什么呢?直接上图(仅为演示DEMO)。

  1. 点击触发事件
    在这里插入图片描述

  2. 移动并且事件
    在这里插入图片描述

  3. 复杂的交互
    在这里插入图片描述

  该系统采用的工厂设计模式,将你需要的功能写入EventTriggersDemo,将你的功能码和相关设置写入(需继承TriggerHelper抽象类)你的类。
使用时将根据设置触发事件。以下代码仅为框架,无具体实现代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game
{ 
   
    [Flags]
    public enum THcode:int   //添加TH时可以使用&一次添加多个
    { 
   
        _null=0,
        one=1,
        two=2,
        three=4,
        _virtual=8
    }
}
using System.Collections.Generic;
using UnityEngine;

namespace Game
{ 
   
    public abstract class TriggerHelper
    { 
   
        public THcode Code;
        public GameObject cardObject;
        public abstract void DefaultHelp();
        public abstract void CloseHelp();
    }
} 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;

namespace Game
{ 
   
    public class VirtualTH : TriggerHelper
    { 
   
        public VirtualTH()
        { 
   
            Code = THcode._virtual;
        }
        public VirtualTH(GameObject gameObject):this()
        { 
   
            cardObject = gameObject;
        }
        public override void CloseHelp()
        { 
   
            CardEventTriggers.RemoveEventTriggersListener(cardObject, EventTriggerType.PointerDown,
                cardObject.GetComponent<CardEventTriggers>().Click);
        }

        public override void DefaultHelp()
        { 
   
            CardEventTriggers.AddEventTriggersListener(cardObject, EventTriggerType.PointerDown,
                cardObject.GetComponent<CardEventTriggers>().Click);
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System;

namespace Game
{ 
   
    public class EventTriggersDemo : MonoBehaviour
    { 
   
        public  Dictionary<int, TriggerHelper> THdic = new Dictionary<int, TriggerHelper>();
        private THcode Oncode;
        private THcode Offcode;
        [HideInInspector]
        public THcode showCode;
        
       
        protected void Start()
        { 
   
            showCode = THcode._null;
            
            InitDic();

        }

        #region Check
        public bool Check(THcode hcode)
        { 
   
            if ((showCode & hcode) == hcode)
                return true;
            else return false;
        }
        [ContextMenu("ShowCode")]
        private void ShowCode()
        { 
   
            Debug.Log(showCode);
        }

        #endregion
        #region Set or Delete
        public void SetOncode(THcode hcode)
        { 
   
            Oncode = hcode;
            UpdateHelp();
        }
        public void DelTrigger(THcode hcode)
        { 
   
            Offcode = hcode;
            RemoveHelp();
        }

        #endregion
        
        /// <summary>
        /// 必须调用,注意更新
        /// </summary>
        private void InitDic()
        { 
   
            VirtualTH virtualTH = new VirtualTH(this.gameObject);

            THdic.Add((int)THcode._virtual, virtualTH);
        }
        
        /// <summary>
        /// 更新卡牌挂载 (算法可优化,请自行优化)
        /// </summary>
        public void UpdateHelp()
        { 
   
            foreach (KeyValuePair<int, TriggerHelper> kvp in THdic)
            { 
   
                DefaultMultiHelp(kvp, Oncode);
            }
        }
        public void RemoveHelp()
        { 
   
            foreach (KeyValuePair<int, TriggerHelper> kvp in THdic)
            { 
   
                CloseMultiHelp(kvp, Offcode);
            }
        }
        private void DefaultHelp(KeyValuePair<int, TriggerHelper> kvp , THcode oncode,THcode target)
        { 
   
            if(((THcode)kvp.Key & oncode)== target)
            { 
   
                showCode = showCode | target;
                kvp.Value.DefaultHelp();
            }
        }
        private void DefaultMultiHelp(KeyValuePair<int, TriggerHelper> kvp, THcode oncode)
        { 
   
            Array enum_array = Enum.GetValues(typeof(THcode));
            foreach (THcode _enum in enum_array)
            { 
   
                if (_enum != THcode._null)
                    DefaultHelp(kvp, oncode, _enum);
            }
        }
        private void CloseHelp(KeyValuePair<int, TriggerHelper> kvp, THcode offcode, THcode target)
        { 
   
            if(((THcode)kvp.Key & offcode)== target)
            { 
   
                showCode = showCode & (~target);
                kvp.Value.CloseHelp();
            }
        }
        private void CloseMultiHelp(KeyValuePair<int, TriggerHelper> kvp, THcode offcode)
        { 
   
            Array enum_array= Enum.GetValues(typeof(THcode));
            foreach(THcode _enum in enum_array)
            { 
   
                if(_enum != THcode._null)
                   CloseHelp(kvp,offcode,_enum);
            }
        }


        #region EventData :书写我需要的EventTrigger功能
        //以下为虚方法形式的功能自定义,也可直接自定义(不开源,请自行研究)
        //除了鼠标交互系统,按键交互也可以制作。
        #region Virtual 
        public void Click(BaseEventData baseEventData)
        { 
   
            Click();
        }
        public virtual void Click()
        { 
   
            Debug.LogWarning("Don't Override!Or it wasn't invoked!");
        }
        #endregion
        
        #endregion


        /// <summary>
        /// 添加事件(不能识别是否重复添加事件,重复添加,触发时将多次运行自定义功能。这是我要的功能,不想要重复添加,需要修改)
        /// </summary>
        /// <param name="object"></param>
        /// <param name="type">事件类型</param>
        /// <param name="action">事件方法</param>
        public static void AddEventTriggersListener(GameObject @object, EventTriggerType type, UnityAction<BaseEventData> action)
        { 
   
            EventTrigger.Entry entry=null;
            EventTrigger eventTrigger = @object.GetComponent<EventTrigger>();
            if (eventTrigger == null)
            { 
   
                @object.AddComponent<EventTrigger>();
                eventTrigger = @object.GetComponent<EventTrigger>();
            }
            foreach (EventTrigger.Entry existingEntry in eventTrigger.triggers)
            { 
   
                if (existingEntry.eventID == type)
                { 
   
                    entry = existingEntry;
                }
            }
            if (NeedNew(entry))
            { 
   
                entry = new EventTrigger.Entry();
                entry.eventID = type;
                entry.callback.AddListener(action);
                eventTrigger.triggers.Add(entry);
                return;
            }
                Debug.Log(@object.transform.name + String.Format(" Add {0} ETListener!",type.ToString()));
                entry.callback.AddListener(action);
        }
        /// <summary>
        /// 删除事件(不是删除一个,而是相同的全删)
        /// </summary>
        /// <param name="object"></param>
        /// <param name="type">事件类型</param>
        /// <param name="action">事件方法</param>
        public static void RemoveEventTriggersListener(GameObject @object, EventTriggerType type,UnityAction<BaseEventData> action)
        { 
   
            if (@object.GetComponent<EventTrigger>())
            { 
   
                EventTrigger eventTrigger = @object.GetComponent<EventTrigger>();
                foreach (EventTrigger.Entry _entry in eventTrigger.triggers)
                { 
   
                   // Debug.Log(_entry.eventID.ToString());
                    if (_entry.eventID == type)
                    { 
   
                            Debug.Log(@object.transform.name + String.Format(" Remove {0} ETListener!", type.ToString()));
                            _entry.callback.RemoveListener(action);
                    }
                }
            }
        }
        private static bool NeedNew(EventTrigger.Entry entry)
        { 
   
            if (entry == null)
                return true;
            else return false;
        }

    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137569.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • django笔记_django 异步

    django笔记_django 异步前言Django是一个开放源代码的Web应用框架,由Python写成,最初用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站,即CMS(内容管理系统)软件,于2005年7月在BSD许可证下发布,这

    2022年7月29日
    6
  • uml的14种图_uml有几种图

    uml的14种图_uml有几种图目录什么是UML?为什么要用UML?UML图有哪些?UML图概览什么是类图?泛化(Generalization)实现(Realization)关联(Association)聚合(Aggregation)组合(Composition)依赖(Dependency)什么是组件图?什么是部署图?什么是对象图?什么是包图?什么是组合结构图?什么是轮廓图?什么是用例图?什么是活动图?什么是状态机图?什么是序列图?什么是通讯图?什

    2025年8月8日
    3
  • 堆积柱形图_excel堆叠图分层怎么做

    堆积柱形图_excel堆叠图分层怎么做今天我们用reportservice开发堆积图,先上个图,见上方。1.新建rdlc文件,工具箱图片,新建一个图标类型(三维堆积圆柱图),然后把三维效果去掉就0了。2.绑定数据源(事先最好新建一个x

    2022年8月2日
    4
  • uWSGI简介_uwsgi启动

    uWSGI简介_uwsgi启动WSGI协议WebServerGatewayInterfaceWebServer和WebApplication通信规范uWSGI概述实现了WSGI协议Web服务器接收客户端请求,通过协议传达给Django应用安装pipinstalluwsgi基本配置chdir:WSGI应用目录module:WSGI应用的模块名字processes:uWSGI进程数(http-)socket:套接字路径、地址max-requests:最大并发请求数vacuum:退

    2025年10月28日
    1
  • 算法学习笔记之一阶低通滤波算法

    算法学习笔记之一阶低通滤波算法1.一阶滤波算法的原理一阶滤波,又叫一阶惯性滤波,或一阶低通滤波。是使用软件编程实现普通硬件RC低通滤波器的功能。一阶低通滤波的算法公式为:Y(n)=αX(n)(1-α)Y(n-1)式中:α=滤波系数;X(n)=本次采样值;Y(n-1)=上次滤波输出值;Y(n)=本次滤波输出值。一阶低通滤波法采用本次采样值与

    2022年6月11日
    200
  • python人机交互式编程_python运行的两种方式交互式

    python人机交互式编程_python运行的两种方式交互式在PyCharm下使用ipython交互式编程的方法目的:方便调试,查看中间结果,因为觉得设断点调试相对麻烦。【运行环境:macOS10.13.3,PyCharm2017.2.4】老手:选中代码行,Alt+Shift+E。或选中,鼠标右键-ExecuteLineinConsole。新手:1、安装ipython之后,查看PyCharm设置,确保Console的通用设置Us…

    2022年8月27日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号