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

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

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

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

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

点击触发事件

移动并且事件

复杂的交互

该系统采用的工厂设计模式,将你需要的功能写入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().Click);
}

public override void DefaultHelp()
{

CardEventTriggers.AddEventTriggersListener(cardObject, EventTriggerType.PointerDown,
cardObject.GetComponent().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 THdic = new Dictionary();
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

///
/// 必须调用,注意更新
///

private void InitDic()
{

VirtualTH virtualTH = new VirtualTH(this.gameObject);

THdic.Add((int)THcode._virtual, virtualTH);
}

///
/// 更新卡牌挂载 (算法可优化,请自行优化)
///

public void UpdateHelp()
{

foreach (KeyValuePair kvp in THdic)
{

DefaultMultiHelp(kvp, Oncode);
}
}
public void RemoveHelp()
{

foreach (KeyValuePair kvp in THdic)
{

CloseMultiHelp(kvp, Offcode);
}
}
private void DefaultHelp(KeyValuePair kvp , THcode oncode,THcode target)
{

if(((THcode)kvp.Key & oncode)== target)
{

showCode = showCode | target;
kvp.Value.DefaultHelp();
}
}
private void DefaultMultiHelp(KeyValuePair 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 kvp, THcode offcode, THcode target)
{

if(((THcode)kvp.Key & offcode)== target)
{

showCode = showCode & (~target);
kvp.Value.CloseHelp();
}
}
private void CloseMultiHelp(KeyValuePair 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


///
/// 添加事件(不能识别是否重复添加事件,重复添加,触发时将多次运行自定义功能。这是我要的功能,不想要重复添加,需要修改)
///

///
/// 事件类型
/// 事件方法
public static void AddEventTriggersListener(GameObject @object, EventTriggerType type, UnityAction action)
{

EventTrigger.Entry entry=null;
EventTrigger eventTrigger = @object.GetComponent();
if (eventTrigger == null)
{

@object.AddComponent();
eventTrigger = @object.GetComponent();
}
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);
}
///
/// 删除事件(不是删除一个,而是相同的全删)
///

///
/// 事件类型
/// 事件方法
public static void RemoveEventTriggersListener(GameObject @object, EventTriggerType type,UnityAction action)
{

if (@object.GetComponent())
{

EventTrigger eventTrigger = @object.GetComponent();
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;
}

}
}
编程小号
上一篇 2025-03-26 23:27
下一篇 2025-04-11 18:51

相关推荐

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