赞
踩
这篇文章主要展示下在Unity的ProjectTiny环境中用纯ECS代码实现UGUI里的EventSystem,包括常用的IPointerDownHandler、IPointerUpHandler、IBeginDragHandler、IDragHandler、IEndDragHandler、IPointerEnterHandler、IPointerExitHandler、IPointerClickHandler等功能。
虽然ProjectTiny里有自带的Button等UI,但是它的点击事件并不是通用的,无法随便给想要的2D entity加上点击事件。不过ProjectTiny提供了最基本的InputSystem,可以获得输入数据。根据这些数据,再处理下,就可以实现UGUI里的那几个Handler了,然后就可以让任意的2D entity(带RectTransform的entity)响应按下抬起点击滑动等事件,还有游戏中常用的鼠标滑动到物品icon上就弹出一个tip,滑出icon后tip消失(也就是IPointerEnter/IPointerExit的功能)。
需要注意一点,由于IComponentData中不能存放NativeList这种Container,所以用的是IBufferElementData,跟数组用法差不多,可以动态增长,但是增删比较麻烦。也可以直接在System里用一个NativeList来存放数据,但是这样不够ECS,而且数据不多,遍历几遍数组对性能影响不会太大。
看代码。代码只是展示一下实现方法,可以继续优化。
using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using Unity.Transforms; using Unity.Tiny.UI; using Unity.Tiny; using Unity.Tiny.Input; using Unity.Tiny.Rendering; using Unity.Collections; namespace wangtal.EventSystem { public interface IPointerDownHandler { } public interface IPointerUpHandler { } public interface IPointerClickHandler { } public interface IPointerEnterHandler { } public interface IPointerExitHandler { } public interface IBeginDragHandler { } public interface IDragHandler { } public interface IEndDragHandler { } public interface ICancelHandler { } internal struct PointerEventData : IBufferElementData { internal enum TriggerState : byte { None = 0 << 0, PointerDown = 1 << 0, PointerUp = 1 << 1, PointerClick = 1 << 2, BeginDrag = 1 << 3, Drag = 1 << 4, EndDrag = 1 << 5, PointerEnter = 1 << 6, PointerExit = 1 << 7 } public TriggerState State; public int PointerId; public Entity Target; // 当前位置 public float2 Position; // 滑动间隔 public float2 Delta; // 按下时的位置 public float2 PressPosition; } public class InputSystemGroup : ComponentSystemGroup { const int MaxTriggerEvent = 10; protected override void OnCreate() { base.OnCreate(); var entity = EntityManager.CreateEntity(); var buffer = EntityManager.AddBuffer<PointerEventData>(entity); for (int i = 0; i < MaxTriggerEvent; i++) { PointerEventData data = new PointerEventData { State = PointerEventData.TriggerState.None, PointerId = -1, Target = Entity.Null, Position = float2.zero, Delta = float2.zero, PressPosition = float2.zero }; buffer.Add(data); } } } [UpdateInGroup(typeof(InputSystemGroup))] unsafe public class EventSystem : SystemBase { private ScreenToWorld screenToWorld; private InputSystem inputSystem; protected override void OnCreate() { base.OnCreate(); screenToWorld = World.GetExistingSystem<ScreenToWorld>(); inputSystem = World.GetExistingSystem<InputSystem>(); } protected override void OnUpdate() { var input = inputSystem; Entities.ForEach((Entity entity, ref DynamicBuffer<PointerEventData> eventDatas) => { PointerEventData* p = (PointerEventData*)eventDatas.GetUnsafePtr(); for (int i = 0; i < eventDatas.Length; i++, p++) { ref var eventData = ref UnsafeUtility.AsRef<PointerEventData>(p);//eventDatas[i]; if (eventData.State == PointerEventData.TriggerState.PointerDown || eventData.State == PointerEventData.TriggerState.PointerUp || eventData.State == PointerEventData.TriggerState.BeginDrag || eventData.State == PointerEventData.TriggerState
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。