当前位置:   article > 正文

Unity DOTS纯ECS写一个类似UGUI的EventSystem(实现IPointerDownHandler/IPointerUpHandler/IBeginDragHandler等)_unity ipointerdownhandler

unity ipointerdownhandler

这篇文章主要展示下在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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/704260
推荐阅读
相关标签
  

闽ICP备14008679号