Unity 自定义事件
来源:互联网 发布:arm-linux-gcc是什么 编辑:程序博客网 时间:2024/05/17 20:24
Unity 自定义事件
EventId.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Assets.Scripts.Event{ //事件ID public enum EventId { event1, event2, Count,//必须写在最后 用于表示所有Event的个数以及存储时间数组长度 }}
EventEatResponse.cs
using UnityEngine;using System.Collections;namespace Assets.Scripts.Event{ public enum EventEatResponse { /// 继续向下一个已经注册该事件的游戏体传递当前事件 NotEaten, /// 停止向下一个已经注册该事件的游戏体传递当前事件 Eaten, }}
EventObservers.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Assets.Scripts.DataStructures;using Assets.Scripts.Core;namespace Assets.Scripts.Event{ /// <summary> /// 事件监听列表 /// </summary> public class EventObservers { public PriorityList<IEventObserver> List { get; private set; } public MutableIterator Iter { get; private set; } public EventObservers() { List = new PriorityList<IEventObserver>(); Iter = new MutableIterator(); } }}
EventPriority.cs
using UnityEngine;using System.Collections;namespace Assets.Scripts.Event{ /// <summary> /// 事件优先级 /// </summar> public enum EventPriority { AfterDefault, Default, BeforeDefault, Notification, }}
IEventObserver.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Assets.Scripts.Event{ /// <summary> /// 事件接口 所有要注册事件的类都要实现 /// </summary> /// public interface IEventObserver { // 接到事件后会调用该接口 EventEatResponse OnEvent(EventId id, object cookie); }}
EventManager.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Assets.Scripts.Core;using Assets.Scripts.DataStructures;namespace Assets.Scripts.Event{ /// <summary> /// 事件管理类 /// </summary> public class EventManager { //已经注册事件的游戏体列表 根据事件优先级分组 private EventObservers[] eventIdToObservers; public EventManager() { Service.Set<EventManager>(this); int count = (int)EventId.Count; eventIdToObservers = new EventObservers[count]; // Fill with nulls until someone decides to listen for a given event. // .Net does this for us. Just being explicit. for (int i = 0; i < count; i++) { eventIdToObservers[i] = null; } } // 注册默认优先级别的事件 public void RegisterObserver(IEventObserver observer, EventId id) { RegisterObserver(observer, id, EventPriority.Default); } // 根据优先级来注册事件 public void RegisterObserver(IEventObserver observer, EventId id, EventPriority priority) { if (observer == null) { return; } int index = (int)id; EventObservers observers = eventIdToObservers[index]; if (observers == null) { observers = new EventObservers(); eventIdToObservers[index] = observers; } PriorityList<IEventObserver> list = observers.List; if (list.IndexOf(observer) < 0) { list.Add(observer, (int)priority); } } // 根据id接触已经注册的事件 public void UnregisterObserver(IEventObserver observer, EventId id) { int index = (int)id; EventObservers observers = eventIdToObservers[index]; if (observers != null) { PriorityList<IEventObserver> list = observers.List; MutableIterator miter = observers.Iter; int i = list.IndexOf(observer); if (i >= 0) { list.RemoveAt(i); miter.OnRemove(i); if (list.Count == 0) { eventIdToObservers[index] = null; } } } } // 根据ID发送事件 public void SendEvent(EventId id, object cookie) { int index = (int)id; EventObservers observers = eventIdToObservers[index]; if (observers != null) { PriorityList<IEventObserver> list = observers.List; MutableIterator miter = observers.Iter; for (miter.Init(list.Count); miter.Active(); miter.Next()) { IEventObserver observer = list.GetElement(miter.Index); if (observer.OnEvent(id, cookie) == EventEatResponse.Eaten) { break; } } miter.Reset(); } } }}ElementPriorityPair.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Assets.Scripts.Event{ public class ElementPriorityPair<T> { public T Element { get; set; } public int Priority { get; set; } public ElementPriorityPair(T element, int priority) { Element = element; Priority = priority; } }}
MutableIterator.cs
using System;using System.Collections.Generic;using System.Collections;using System.Linq;using System.Text;namespace Assets.Scripts.Event{ public class MutableIterator { int index; int count; public MutableIterator() { Reset(); } public void Reset() { index = 0; count = 0; } public void Init(int count) { index = 0; this.count = count; } public void Init(ICollection list) { index = 0; this.count = list.Count; } public bool Active() { return index < count; } public void Next() { index++; } public int Index { get { return index; } set { // Only allow manual index setting if we haven't yet started iterating. if (index == 0) { index = value; } } } public int Count { get { return count; } } public void OnRemove(int i) { if (count > 0) { count--; if (i <= index) { index--; } } } }}
PriorityList.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Assets.Scripts.Event{ public class PriorityList<T> { private List<ElementPriorityPair<T>> list; public PriorityList() { list = new List<ElementPriorityPair<T>>(); } // Just like List<T>.Count. public int Count { get { return list.Count; } } // Similar to List<T>.Add() but inserts based on priority. // Returns the index where the element was inserted. // Returns -1 on failure. public virtual int Add(T element, int priority) { // Prevent null from being added. It's just one of the features of this class. if (element == null) { return -1; } for (int i = 0, count = list.Count; i < count; i++) { ElementPriorityPair<T> pair = list[i]; if (object.ReferenceEquals(pair.Element, element)) { // Already added. return -1; } // Keep the list sorted, higher priority first. // For equal priorities, we'll add ourselves to the end of that range. if (priority > pair.Priority) { // Found insertion point. list.Insert(i, new ElementPriorityPair<T>(element, priority)); return i; } } // Didn't find an insertion point. Add new currently-lowest-priority element. list.Add(new ElementPriorityPair<T>(element, priority)); return list.Count - 1; } public ElementPriorityPair<T> Get(int i) { return list[i]; } // Similar to List<T>[i]. public T GetElement(int i) { return list[i].Element; } // Get the associated prioriity of the i'th element. public int GetPriority(int i) { return list[i].Priority; } // Alternative for when you want both the element and its associated prioiryt. public void GetElementPriority(int i, out T element, out int priority) { ElementPriorityPair<T> pair = list[i]; element = pair.Element; priority = pair.Priority; } // Just like List<T>.IndexOf(element). public int IndexOf(T element) { for (int i = 0, count = list.Count; i < count; i++) { if (object.ReferenceEquals(list[i].Element, element)) { return i; } } return -1; } // No Remove(T t), to discourage misuse. Callers must know the index to remove. // Remove(T t) can always be implemented is "if ((i = IndexOf(t)) >= 0) RemoveAt(i);". public void RemoveAt(int i) { list.RemoveAt(i); } }}
Service.cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Assets.Scripts.Event{ public static class Service {#if SERVER [ThreadStatic]#endif private static List<IServiceWrapper> serviceWrapperList; public static void Set<T>(T instance) { if (ServiceWrapper<T>.instance != null) { throw new Exception("An instance of this service class has already been set!"); } ServiceWrapper<T>.instance = instance; if (serviceWrapperList == null) { serviceWrapperList = new List<IServiceWrapper>(); } serviceWrapperList.Add(new ServiceWrapper<T>()); } public static T Get<T>() { return ServiceWrapper<T>.instance; } public static bool IsSet<T>() { return ServiceWrapper<T>.instance != null; } // Resets references to all services back to null so that they can go out of scope and // be subjected to garbage collection. // * Services that reference each other will be garbage collected. // * AssetBundles should be manually unloaded by an asset manager. // * GameObjects will be destroyed by the next level load done by the caller. // * Any application statics should be reset by the caller as well. // * If there are any unmanaged objects, those need to be released by the caller, too. public static void ResetAll() { if (serviceWrapperList == null) { return; } // Unset in the reverse order in which services were set. Probably doesn't matter. for (int i = serviceWrapperList.Count - 1; i >= 0; i--) { serviceWrapperList[i].Unset(); } serviceWrapperList = null; } } internal class ServiceWrapper<T> : IServiceWrapper {#if SERVER [ThreadStatic]#endif public static T instance = default(T); public void Unset() { ServiceWrapper<T>.instance = default(T); } } internal interface IServiceWrapper { void Unset(); }}
具体使用:
void Start () { Debug.Log("MyCube Start"); //注册事件 Service.Get<EventManager>().RegisterObserver(this, EventId.event1, EventPriority.Default); Service.Get<EventManager>().RegisterObserver(this, EventId.event2, EventPriority.Default);}
发送事件:
Service.Get<EventManager>().SendEvent(EventId.event1, null);
发送事件后会根据优先级调用注册当前EventId的那个游戏体, 继而执行 相应的OnEvent()
例如给myCube分别注册事件1 和 事件2 mySphere只注册事件1
(如果在OnEvent当中返回的是Eaten)则不会继续向下一个注册改事件的游戏体传递这个事件)
0 0
- Unity 自定义事件
- Unity自定义事件相应区域
- Unity中使用自定义事件在View之间传递消息
- Unity中为UGUI精灵自定义事件响应区域
- unity事件
- 【Unity】Unity自定义热键代码
- unity游戏开发之服务器与客户端或页面流转之自定义交互事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- 自定义事件
- T解套
- MySQL执行计划解读
- CAN总线简介
- 【IOS类扩展之日期操作】NSDate+Helpers
- leetcode 263 Ugly Number
- Unity 自定义事件
- javascript中window.document的属性、方法和事件的总结
- 对象数组或list排序及Collections排序原理
- Dalvik VM (DVM) 与Java VM (JVM)之间有哪些区别
- C++ 中4中类型转换关键字及其特点
- IntelliJ IDEA使用教程六 常用配置
- VC6工程升级VS2013遇到的问题
- Leetcode: Longest Valid Parentheses
- 页面防止重复提交,在服务端使用struts令牌机制,前台分为jsp和extJs(其他js框架同理)