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;
        }

    }
}

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • C语言pow函数(编程pow函数)

    ❶用C语言编程实现pow函数的功能。#includevoidmain(){inta;//底数intb;//指数inti,j;printf(“输入底数:”);scanf(“%d”,&a);printf(“输入指数:”);scanf(“%d”,&b);j=1;for(i=0;ij*=a;printf(“结果为%d\n”,j);}❷C语言中怎样用POW函数和POW1…

  • bi报表开发工具_三大报表的勾稽关系图

    bi报表开发工具_三大报表的勾稽关系图为什么需要电子表格国内目前的同类产品中都有报表工具,这些工具大部分都有一个类似Excel的操作界面:单元格、快捷键、工具栏等典型设计工具要求。这些工具要么需要有专业的背景,或者专业的工程师提供支持,要么学习成本高,调整报表样式十分麻烦。作为报表开发人员而言,花费大量时间去学习一个新工具是一件非常苦恼的事情,我们能否直接把exce作为报表设计的工具呢?基于这个思路,诞生了我们的Spreadsheet…

    2022年10月19日
  • MyBatis工作原理步骤

    MyBatis的工作原理第一步:读取MyBatis配置文件,即mybatis-config.xml第二步:加载映射文件,如ManMapper1.xml,…Mapper2.xml等。第三步:构造会话工厂,即SqlSessionFactory。第一种方法:SqlSessionFactoryfactory=sqlSessionFactoryBuilder.build(reader,p…

  • Putty(菩提)远程连接服务器教程听语音

    Putty(菩提)远程连接服务器教程听语音

  • allow_url_fopen与安全以及PHP libcurl

    allow_url_fopen与安全以及PHP libcurl  allow_url_fopen=ON常常会给服务器和管理员带来麻烦,但是经常性(至少我这样认为)的我们需要远程读取某个东西,如果设置allow_url_fopen=OFF将其关闭,我们就没有办法远程读取。  幸好我们有一个很好的PHP模块–curl。下面我就以一个例子说说我用curl远程读取的方法:  第一,allow_url_fopen=ON的情况下:

  • Pytest(16)随机执行测试用例pytest-random-order[通俗易懂]

    Pytest(16)随机执行测试用例pytest-random-order[通俗易懂]前言通常我们认为每个测试用例都是相互独立的,因此需要保证测试结果不依赖于测试顺序,以不同的顺序运行测试用例,可以得到相同的结果。pytest默认运行用例的顺序是按模块和用例命名的ASCII编码

发表回复

您的电子邮箱地址不会被公开。

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