diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 74714b9..92b23f9 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -22,22 +22,22 @@ /// /// 当前物体显示的精灵图像, 节点名称必须叫 "AnimatedSprite2D", 类型为 AnimatedSprite2D /// - public AnimatedSprite2D AnimatedSprite { get; } + public AnimatedSprite2D AnimatedSprite { get; private set; } /// /// 当前物体显示的阴影图像, 节点名称必须叫 "ShadowSprite", 类型为 Sprite2D /// - public Sprite2D ShadowSprite { get; } + public Sprite2D ShadowSprite { get; private set; } /// /// 当前物体碰撞器节点, 节点名称必须叫 "Collision", 类型为 CollisionShape2D /// - public CollisionShape2D Collision { get; } + public CollisionShape2D Collision { get; private set; } /// /// 动画播放器 /// - public AnimationPlayer AnimationPlayer { get; } + public AnimationPlayer AnimationPlayer { get; private set; } /// /// 是否调用过 Destroy() 函数 @@ -57,7 +57,7 @@ /// /// 移动控制器 /// - public MoveController MoveController { get; } + public MoveController MoveController { get; private set; } /// /// 物体移动基础速率 @@ -97,8 +97,8 @@ private ActivityObjectTemplate _templateInstance; private static long _instanceIndex = 0; - - public ActivityObject(string scenePath) + + private void _InitNode(string scenePath) { Name = GetType().Name + (_instanceIndex++); //加载预制体 @@ -1058,12 +1058,4 @@ _coroutineList.Clear(); } } - - /// - /// 通过 ItemId 实例化 ActivityObject 对象 - /// - public static T Create(string itemId) where T : ActivityObject - { - return null; - } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs new file mode 100644 index 0000000..111bea6 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs @@ -0,0 +1,79 @@ + +using System; +using System.Collections.Generic; +using System.Reflection; + +public partial class ActivityObject +{ + private static bool _initState = false; + + private class RegisterActivityData + { + public RegisterActivityData(RegisterActivity registerActivity, Func callBack) + { + RegisterActivity = registerActivity; + CallBack = callBack; + } + + public RegisterActivity RegisterActivity; + public Func CallBack; + } + + private static readonly Dictionary _activityRegisterMap = new(); + + public static void Init() + { + if (_initState) + { + return; + } + + _initState = true; + + ScannerFromAssembly(typeof(ActivityObject).Assembly); + } + + public static void ScannerFromAssembly(Assembly assembly) + { + var types = assembly.GetTypes(); + foreach (var type in types) + { + //注册类 + var attribute = Attribute.GetCustomAttributes(type, typeof(RegisterActivity), false); + if (attribute.Length > 0) + { + if (!typeof(ActivityObject).IsAssignableFrom(type)) + { + throw new Exception($"The registered object '{type.FullName}' does not inherit the class ActivityObject."); + } + else if (type.IsAbstract) + { + throw new Exception($"'RegisterActivity' cannot be used on abstract class '{type.FullName}'."); + } + var attrs = (RegisterActivity[])attribute; + foreach (var att in attrs) + { + if (_activityRegisterMap.ContainsKey(att.Id)) + { + throw new Exception($"Object ID: '{att.Id}' is already registered"); + } + var registerCallback = att.RegisterInstantiationCallback(type); + _activityRegisterMap.Add(att.Id, new RegisterActivityData(att, registerCallback)); + } + } + } + } + + /// + /// 通过 ItemId 实例化 ActivityObject 对象 + /// + public static T Create(string itemId) where T : ActivityObject + { + if (_activityRegisterMap.TryGetValue(itemId, out var item)) + { + var instance = item.CallBack(); + instance._InitNode(item.RegisterActivity.PrefabPath); + } + return null; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs b/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs new file mode 100644 index 0000000..9b05eb8 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs @@ -0,0 +1,29 @@ + +using System; +using System.Diagnostics.CodeAnalysis; + +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class RegisterActivity : Attribute +{ + /// + /// 注册物体唯一ID, 该ID不能有重复 + /// + public string Id { get; } + + /// + /// 模板Prefab的路径 + /// + public string PrefabPath { get; protected set; } + + public RegisterActivity(string id, string prefabPath) + { + Id = id; + PrefabPath = prefabPath; + } + + + public virtual Func RegisterInstantiationCallback(Type type) + { + return () => { return (ActivityObject)Activator.CreateInstance(type); }; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs b/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs index 8bdf623..ddb58e8 100644 --- a/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs @@ -1,6 +1,9 @@ using Godot; +/// +/// 房间连接门的站位导航数据 +/// public class DoorNavigationInfo { public DoorNavigationInfo(NavigationRegion2D navigationNode, NavigationPolygonData navigationData) @@ -9,7 +12,13 @@ NavigationData = navigationData; } + /// + /// 导航区域节点 + /// public NavigationRegion2D NavigationNode; + /// + /// 导航形状数据 + /// public NavigationPolygonData NavigationData; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs b/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs index 66cfb70..8e8ec50 100644 --- a/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs @@ -42,7 +42,7 @@ public Vector2 Cross; /// - /// 导航网格 + /// 占位导航网格 /// public DoorNavigationInfo Navigation; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeapon.cs b/DungeonShooting_Godot/src/game/item/weapon/RegisterWeapon.cs deleted file mode 100644 index 3cbcd57..0000000 --- a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeapon.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -/// -/// 用作 Weapon 子类上, 用于注册武器, 允许同时存在多个 RegisterWeapon 特性 -/// -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public class RegisterWeapon : Attribute -{ - - public string Id { get; private set; } - public Type AttributeType { get; private set; } - - public RegisterWeapon(string id) - { - Id = id; - } - - public RegisterWeapon(string id, Type attributeType) - { - Id = id; - AttributeType = attributeType; - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponOld.cs b/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponOld.cs new file mode 100644 index 0000000..026bc53 --- /dev/null +++ b/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponOld.cs @@ -0,0 +1,22 @@ +using System; + +/// +/// 用作 Weapon 子类上, 用于注册武器, 允许同时存在多个 RegisterWeapon 特性 +/// +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class RegisterWeaponOld : Attribute +{ + public string Id { get; private set; } + public Type AttributeType { get; private set; } + + public RegisterWeaponOld(string id) + { + Id = id; + } + + public RegisterWeaponOld(string id, Type attributeType) + { + Id = id; + AttributeType = attributeType; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs b/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs index d5e8bf1..b084ddb 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs @@ -20,14 +20,14 @@ foreach (var type in types) { //注册类 - Attribute[] attribute = Attribute.GetCustomAttributes(type, typeof(RegisterWeapon), false); + Attribute[] attribute = Attribute.GetCustomAttributes(type, typeof(RegisterWeaponOld), false); if (attribute != null && attribute.Length > 0) { if (!typeof(Weapon).IsAssignableFrom(type)) { throw new Exception($"注册武器类'{type.FullName}'没有继承类'Weapon'!"); } - var atts = (RegisterWeapon[])attribute; + var atts = (RegisterWeaponOld[])attribute; foreach (var att in atts) { //注册类 diff --git a/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs b/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs new file mode 100644 index 0000000..181584e --- /dev/null +++ b/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs @@ -0,0 +1,13 @@ + +using System; + +public class RegisterWeapon : RegisterActivity +{ + public WeaponAttribute WeaponAttribute { get; } + + public RegisterWeapon(string id, Type attribute) : base(id, null) + { + WeaponAttribute = (WeaponAttribute)Activator.CreateInstance(attribute); + if (WeaponAttribute != null) PrefabPath = WeaponAttribute.WeaponPrefab; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs index 2416ce3..a003ae9 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs @@ -3,8 +3,9 @@ /// /// 普通的枪 /// -[RegisterWeapon("1001", typeof(Gun.RifleAttribute))] -[RegisterWeapon("1003", typeof(Gun.PistolAttribute))] +[RegisterWeaponOld("1001", typeof(Gun.RifleAttribute))] +[RegisterWeaponOld("1003", typeof(Gun.PistolAttribute))] +[RegisterWeapon("1003", typeof(PistolAttribute))] public partial class Gun : Weapon { //步枪属性数据 diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs index 8402af5..24ac9b8 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs @@ -1,6 +1,6 @@ using Godot; -[RegisterWeapon("1002", typeof(Shotgun.ShotgunAttribute))] +[RegisterWeaponOld("1002", typeof(Shotgun.ShotgunAttribute))] public partial class Shotgun : Weapon { diff --git a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs index 817ce68..1225928 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs @@ -1,7 +1,7 @@ using Godot; -[RegisterWeapon("1004", typeof(KnifeAttribute))] +[RegisterWeaponOld("1004", typeof(KnifeAttribute))] public partial class Knife : Weapon { private class KnifeAttribute : WeaponAttribute diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs index 4881aa4..3422540 100644 --- a/DungeonShooting_Godot/src/game/role/Role.cs +++ b/DungeonShooting_Godot/src/game/role/Role.cs @@ -44,7 +44,7 @@ /// /// 角色携带的枪套 /// - public Holster Holster { get; } + public Holster Holster { get; private set; } /// /// 武器挂载点 @@ -213,15 +213,11 @@ public Role() : this(ResourcePath.prefab_role_Role_tscn) { } - - public Role(string scenePath) : base(scenePath) - { - Holster = new Holster(this); - } - + public override void _Ready() { base._Ready(); + Holster = new Holster(this); _startScale = Scale; MountPoint = GetNode("MountPoint"); MountPoint.Master = this; diff --git a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs index a377c86..f0eb813 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs @@ -17,9 +17,9 @@ /// /// 基础敌人 /// +[RegisterActivity("1001", ResourcePath.prefab_role_Enemy_tscn)] public partial class Enemy : Role { - /// /// 公共属性, 是否找到目标, 如果找到目标, 则所有敌人都会知道玩家的位置 ///