unity基于反射的事件系统

该文章介绍了一种基于反射的Unity游戏事件系统EventSystem的实现,该系统允许自动订阅和管理事件,但不支持取消订阅。示例中展示了如何创建和处理KillPlayer事件,通过XEvent泛型类和IEvent接口进行事件分发。EventSystem类负责事件的管理和分发,使用反射机制查找标记了特定属性的事件处理类。
摘要由CSDN通过智能技术生成

游戏开发-基于反射的事件系统EventSystem

好处

  1. 不用手动添加订阅
  2. 代码跟容易管理

缺点

  1. 不能取消订阅

使用

using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        EventSystem.Instance.Push(new KillPlayer() { 
        Player1="坤坤",
        Player2= "I坤的真爱粉"
        });
        
    }
}
public struct KillPlayer
{
    public string Player1;
    public string Player2;
}
[Event]
public class KillPlayer_UpdateUI : XEvent<KillPlayer>
{
    protected override void Run(KillPlayer t)
    {
        Debug.Log($"KillPlayer_UpdateUI:{t.Player1}击杀了{t.Player2}");
    }
}
[Event]
public class KillPlayer_LogInfo : XEvent<KillPlayer>
{
    protected override void Run(KillPlayer t)
    {
        Debug.Log($"KillPlayer_LogInfo:{t.Player1}击杀了{t.Player2}");
    }
}

调试结果

源码

using QFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Unity.VisualScripting;
using UnityEngine;
public interface IEvent
{
    Type Type { get; }

}
public abstract class XEvent<T>:IEvent where T:struct
{
    public Type Type
    {
        get
        {
            return typeof(T);
        }
    }
    protected abstract void Run( T t);

    public  void Handle(T t)
    {
        try
        {
            Run(t);
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }
    }
}
[AttributeUsage(AttributeTargets.Class)]
public class BaseAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class)]
public class EventAttribute : BaseAttribute
{ 
}
public class EventSystem
{
    private static EventSystem instance;
    public static EventSystem Instance { get {
            if(instance==null)
                instance = new EventSystem();
            return instance;
        } }
    private EventSystem()
    {
        OnSingletonInit();
    }

    Dictionary<Type, List<IEvent>> EventPool = new Dictionary<Type, List<IEvent>>();
    public void OnSingletonInit()
    {
       
        UnOrderMultiMapSet<Type, Type> types = new UnOrderMultiMapSet<Type, Type>();
        Dictionary<string, Type> types1 = AssemblyHelper.GetAssemblyTypes(Assembly.GetAssembly(typeof(EventSystem)));
        foreach ((string fullName, Type type) in types1)
        {
            if (type.IsAbstract)
            {
                continue;
            }
            // 记录所有的有BaseAttribute标记的的类型
            object[] objects = type.GetCustomAttributes(typeof(BaseAttribute), true);
            foreach (object o in objects)
            {
                types.Add(o.GetType(), type);
            }
        }
        HashSet<Type> hs=types[typeof(EventAttribute)];
        foreach (var v in hs)
        {
           
            EventAttribute attr = v.GetCustomAttributes(typeof(EventAttribute), false)[0] as EventAttribute;
            var interfaces = v.GetInterfaces();
            if (interfaces.Contains(typeof(IEvent)))
            {
                var value = Activator.CreateInstance(v) as IEvent;
                var key = value.Type;
                if (!EventPool.ContainsKey(key))
                {
                    EventPool.Add(key, new List<IEvent>());
                }
                EventPool[key].Add(value);
            }
        }
    }
    public void Push<T>(T t) where T : struct
    { 
        Type type= typeof(T);
        if (EventPool.ContainsKey(type))
        {
            foreach (var v in EventPool[type])
            {
                XEvent<T> xEvent =v  as XEvent<T>;
                xEvent.Handle(t);
            }
           
        }
    }
}
public static class AssemblyHelper
{
    public static Dictionary<string, Type> GetAssemblyTypes(params Assembly[] args)
    {
        Dictionary<string, Type> types = new Dictionary<string, Type>();

        foreach (Assembly ass in args)
        {
            foreach (Type type in ass.GetTypes())
            {
                types[type.FullName] = type;
            }
        }

        return types;
    }
}
public class UnOrderMultiMapSet<T, K> : Dictionary<T, HashSet<K>>
{
    // 重用HashSet
    public new HashSet<K> this[T t]
    {
        get
        {
            HashSet<K> set;
            if (!this.TryGetValue(t, out set))
            {
                set = new HashSet<K>();
            }
            return set;
        }
    }

    public Dictionary<T, HashSet<K>> GetDictionary()
    {
        return this;
    }

    public void Add(T t, K k)
    {
        HashSet<K> set;
        this.TryGetValue(t, out set);
        if (set == null)
        {
            set = new HashSet<K>();
            base[t] = set;
        }
        set.Add(k);
    }

    public bool Remove(T t, K k)
    {
        HashSet<K> set;
        this.TryGetValue(t, out set);
        if (set == null)
        {
            return false;
        }
        if (!set.Remove(k))
        {
            return false;
        }
        if (set.Count == 0)
        {
            this.Remove(t);
        }
        return true;
    }

    public bool Contains(T t, K k)
    {
        HashSet<K> set;
        this.TryGetValue(t, out set);
        if (set == null)
        {
            return false;
        }
        return set.Contains(k);
    }

    public new int Count
    {
        get
        {
            int count = 0;
            foreach (KeyValuePair<T, HashSet<K>> kv in this)
            {
                count += kv.Value.Count;
            }
            return count;
        }
    }
}

https://github.com/egametang/ET

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当然!以下是一个基于Unity开发的三维设计件的简单案例: 案例名称:3D模型编辑器 功能: 1. 导入和导出模型文件,支持常见的格式如OBJ、FBX等。 2. 创建、编辑和删除三维模型,包括移动、旋转和缩放等操作。 3. 材质编辑:添加纹理、调整颜色、透明度等。 4. 光照设置:调整场景光照、阴影和反射效果。 5. 物理模拟:模拟物理效果,如重力、碰撞等。 6. 动画编辑:创建和编辑模型的动画序列。 7. 场景编辑:创建和编辑场景,包括地形、天空盒、摄像机等。 8. 用户界面:设计直观的用户界面,包括工具栏、菜单和操作面板等。 实现方法: 1. 利用Unity提供的建模工具或者导入第三方建模软件创建模型,并通过编写脚本实现模型的编辑功能。 2. 利用Unity的材质系统和着色器来实现材质编辑功能。 3. 利用Unity的光照系统来调整光照效果。 4. 利用Unity的物理引擎来实现物理模拟功能。 5. 利用Unity的动画系统来创建和编辑动画序列。 6. 利用Unity的场景编辑器来创建和编辑场景。 7. 利用Unity的UI系统来设计用户界面,并通过编写脚本实现交互功能。 以上仅为一个简单的案例示例,实际开发过程中可能涉及更多功能和复杂性的设计。使用Unity作为开发工具,你可以通过脚本编程、图形界面设计、资源管理等功能,实现一个强大的三维设计软件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值