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)
blank

相关推荐

  • ps测量精灵图[通俗易懂]

    ps测量精灵图[通俗易懂]1.调出图片信息2.测量图片大小、3.把鼠标放在需要用到的小图片的左上角  精灵图的测量:B站中有详细的教程    第43集  京东项目精灵图的使用:B站精灵图的使用第24集   李江南讲解精灵图第44集  定位口诀:子绝父相(孩子是绝对定位,父亲是相对定位;)…

  • matlab 时频分析(短时傅里叶变换、STFT)「建议收藏」

    matlab 时频分析(短时傅里叶变换、STFT)「建议收藏」短时傅里叶变换,short-timefouriertransformation,有时也叫加窗傅里叶变换,时间窗口使得信号只在某一小区间内有效,这就避免了传统的傅里叶变换在时频局部表达能力上的不足,

  • CSS颜色代码对照表

    CSS颜色代码对照表CSS颜色代码大全CSS颜色对照表  FFFFFF#DDDDDD#AAAAAA#888888#666666#444444#000000#FFB7DD#FF88C2#FF44AA #FF0088 #C10066 #A20055 #8C0044 #FFCCCC#FF8888#FF3333 #FF0000 #CC0000 #AA0000 #880000 #FFC8B4#FFA488#FF7744…

  • 传统电视or互联网电视,智能电视领域谁才是虎狼之师

    传统电视or互联网电视,智能电视领域谁才是虎狼之师

  • 我的世界服务器必备指令手机版_我的世界服务器传送点指令

    我的世界服务器必备指令手机版_我的世界服务器传送点指令6、技能插件:【箭术】-Archery箭非常的酷。大约五分钟,这项技能会不断增加它的伤害随着级别的升高,最后你能射晕对手,对PVP有好处。还有,箭术等级越高,你就越容易从尸体上拿回箭。【制药学】-Herbalism这很受那些喜欢收获的人欢迎,捡起那些药草,比如:花啊,蘑菇啊。或者收割庄稼,都会让你提升技能。他的好处包括农业上两倍的掉率,增加面包和汤的效果。【剑术】Swords这项技能会给…

  • TCP/IP协议详解

    TCP/IP协议详解认识HTTP协议它是互联网协议(InternetProtocolSuite),一个网络通信模型,是互联网的一个基本的构架。HTTP协议是HyperTextTransferProtocol(超文本传输协议)的缩写,是用于从万维网(WWW:WorldWideWeb)服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML文件,图片文件…

发表回复

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

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