大家好,又见面了,我是你们的朋友全栈君。
Unity 基于eventTriggers的3D场景交互系统
Unity里的3D项目有时候需要大量的交互,而且是无UI的交互。 这时候可以像UI系统里,使用eventTrigger去制作交互系统。但是这个缺少自定义功能,所以我写了个自定义交互系统。这个交互系统可以做到什么呢?直接上图(仅为演示DEMO)。
- 点击触发事件
- 移动并且事件
- 复杂的交互
该系统采用的工厂设计模式,将你需要的功能写入EventTriggersDemo,将你的功能码和相关设置写入(需继承TriggerHelper抽象类)你的类。 使用时将根据设置触发事件。以下代码仅为框架,无具体实现代码。
代码语言:javascript复制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
}
}
代码语言:javascript复制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();
}
}
代码语言:javascript复制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);
}
}
}
代码语言:javascript复制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.cn/137569.html原文链接:https://javaforall.cn