mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
feat(architecture): 集成Arch ECS框架并升级目标框架
- 在ArchitectureContext中添加ECS世界和系统调度器支持 - 添加IEcsWorld和IEcsSystem接口定义 - 实现EcsWorld、EcsSystemBase和EcsSystemRunner核心类 - 添加Position和Velocity示例组件及MovementSystem示例 - 创建ECS使用示例代码 - 将多个项目的TargetFramework从netstandard2.0升级到netstandard2.1 - 添加Arch和Arch.System包依赖到核心项目 - 在测试项目中添加ECS相关接口的模拟实现
This commit is contained in:
parent
d653994ded
commit
daff1fa12b
@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
<Using Include="GFramework.Core.Abstractions"/>
|
<Using Include="GFramework.Core.Abstractions"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.9">
|
<PackageReference Update="Meziantou.Analyzer" Version="3.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@ -25,6 +25,7 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
<PackageReference Include="Arch" Version="2.1.0"/>
|
||||||
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
<PackageReference Include="Mediator.Abstractions" Version="3.0.1"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
using GFramework.Core.Abstractions.environment;
|
using GFramework.Core.Abstractions.environment;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.model;
|
using GFramework.Core.Abstractions.model;
|
||||||
@ -205,4 +206,18 @@ public interface IArchitectureContext
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>环境对象实例</returns>
|
/// <returns>环境对象实例</returns>
|
||||||
IEnvironment GetEnvironment();
|
IEnvironment GetEnvironment();
|
||||||
|
|
||||||
|
// === ECS 支持 ===
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取ECS世界实例
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ECS世界实例</returns>
|
||||||
|
IEcsWorld GetEcsWorld();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册ECS系统
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">ECS系统类型</typeparam>
|
||||||
|
void RegisterEcsSystem<T>() where T : class, IEcsSystem;
|
||||||
}
|
}
|
||||||
20
GFramework.Core.Abstractions/ecs/IEcsSystem.cs
Normal file
20
GFramework.Core.Abstractions/ecs/IEcsSystem.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using GFramework.Core.Abstractions.system;
|
||||||
|
|
||||||
|
namespace GFramework.Core.Abstractions.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS系统接口,继承自ISystem以集成到现有架构
|
||||||
|
/// </summary>
|
||||||
|
public interface IEcsSystem : ISystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 系统优先级,数值越小越先执行
|
||||||
|
/// </summary>
|
||||||
|
int Priority { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 每帧更新
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">帧间隔时间(秒)</param>
|
||||||
|
void Update(float deltaTime);
|
||||||
|
}
|
||||||
44
GFramework.Core.Abstractions/ecs/IEcsWorld.cs
Normal file
44
GFramework.Core.Abstractions/ecs/IEcsWorld.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
|
||||||
|
namespace GFramework.Core.Abstractions.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS世界接口,封装Arch的World实例
|
||||||
|
/// </summary>
|
||||||
|
public interface IEcsWorld : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前实体数量
|
||||||
|
/// </summary>
|
||||||
|
int EntityCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取内部的Arch World实例(用于高级操作)
|
||||||
|
/// </summary>
|
||||||
|
World InternalWorld { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建一个新实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="types">组件类型数组</param>
|
||||||
|
/// <returns>创建的实体</returns>
|
||||||
|
Entity CreateEntity(params ComponentType[] types);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁指定实体
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">要销毁的实体</param>
|
||||||
|
void DestroyEntity(Entity entity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查实体是否存活
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">要检查的实体</param>
|
||||||
|
/// <returns>实体是否存活</returns>
|
||||||
|
bool IsAlive(Entity entity);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有实体
|
||||||
|
/// </summary>
|
||||||
|
void Clear();
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.architecture;
|
using GFramework.Core.Abstractions.architecture;
|
||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
using GFramework.Core.Abstractions.environment;
|
using GFramework.Core.Abstractions.environment;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.ioc;
|
using GFramework.Core.Abstractions.ioc;
|
||||||
@ -356,6 +357,16 @@ public class TestArchitectureContextV3 : IArchitectureContext
|
|||||||
{
|
{
|
||||||
return _environment;
|
return _environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEcsWorld GetEcsWorld()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("ECS not implemented in test context");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterEcsSystem<T>() where T : class, IEcsSystem
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("ECS not implemented in test context");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.architecture;
|
using GFramework.Core.Abstractions.architecture;
|
||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
using GFramework.Core.Abstractions.environment;
|
using GFramework.Core.Abstractions.environment;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.ioc;
|
using GFramework.Core.Abstractions.ioc;
|
||||||
@ -451,4 +452,14 @@ public class TestArchitectureContext : IArchitectureContext
|
|||||||
{
|
{
|
||||||
return Environment;
|
return Environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEcsWorld GetEcsWorld()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("ECS not implemented in test context");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterEcsSystem<T>() where T : class, IEcsSystem
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("ECS not implemented in test context");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -14,5 +14,7 @@
|
|||||||
<PackageReference Include="LanguageExt.Core" Version="4.4.9"/>
|
<PackageReference Include="LanguageExt.Core" Version="4.4.9"/>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3"/>
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3"/>
|
||||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0"/>
|
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0"/>
|
||||||
|
<PackageReference Include="Arch" Version="2.1.0"/>
|
||||||
|
<PackageReference Include="Arch.System" Version="1.1.0"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using GFramework.Core.Abstractions.architecture;
|
using GFramework.Core.Abstractions.architecture;
|
||||||
using GFramework.Core.Abstractions.command;
|
using GFramework.Core.Abstractions.command;
|
||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
using GFramework.Core.Abstractions.environment;
|
using GFramework.Core.Abstractions.environment;
|
||||||
using GFramework.Core.Abstractions.events;
|
using GFramework.Core.Abstractions.events;
|
||||||
using GFramework.Core.Abstractions.ioc;
|
using GFramework.Core.Abstractions.ioc;
|
||||||
@ -7,6 +8,7 @@ using GFramework.Core.Abstractions.model;
|
|||||||
using GFramework.Core.Abstractions.query;
|
using GFramework.Core.Abstractions.query;
|
||||||
using GFramework.Core.Abstractions.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
using GFramework.Core.Abstractions.utility;
|
using GFramework.Core.Abstractions.utility;
|
||||||
|
using GFramework.Core.ecs;
|
||||||
using Mediator;
|
using Mediator;
|
||||||
using ICommand = GFramework.Core.Abstractions.command.ICommand;
|
using ICommand = GFramework.Core.Abstractions.command.ICommand;
|
||||||
|
|
||||||
@ -19,6 +21,8 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
|
|||||||
{
|
{
|
||||||
private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container));
|
private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container));
|
||||||
private readonly Dictionary<Type, object> _serviceCache = new();
|
private readonly Dictionary<Type, object> _serviceCache = new();
|
||||||
|
private EcsSystemRunner? _ecsRunner;
|
||||||
|
private EcsWorld? _ecsWorld;
|
||||||
|
|
||||||
#region Mediator Integration (新实现)
|
#region Mediator Integration (新实现)
|
||||||
|
|
||||||
@ -412,4 +416,59 @@ public class ArchitectureContext(IIocContainer container) : IArchitectureContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ECS Support
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取ECS世界实例
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>ECS世界实例</returns>
|
||||||
|
public IEcsWorld GetEcsWorld()
|
||||||
|
{
|
||||||
|
return _ecsWorld ??
|
||||||
|
throw new InvalidOperationException("ECS World not initialized. Call InitializeEcs() first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册ECS系统
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">ECS系统类型</typeparam>
|
||||||
|
public void RegisterEcsSystem<T>() where T : class, IEcsSystem
|
||||||
|
{
|
||||||
|
// 使用RegisterPlurality注册到所有接口
|
||||||
|
_container.RegisterPlurality<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化ECS(在架构初始化时调用)
|
||||||
|
/// </summary>
|
||||||
|
public void InitializeEcs()
|
||||||
|
{
|
||||||
|
if (_ecsWorld != null) return;
|
||||||
|
|
||||||
|
// 创建ECS世界
|
||||||
|
_ecsWorld = new EcsWorld();
|
||||||
|
_container.Register(_ecsWorld);
|
||||||
|
|
||||||
|
// 注册系统调度器
|
||||||
|
_container.RegisterPlurality<EcsSystemRunner>();
|
||||||
|
_ecsRunner = _container.Get<EcsSystemRunner>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取ECS系统调度器
|
||||||
|
/// </summary>
|
||||||
|
internal EcsSystemRunner? GetEcsRunner() => _ecsRunner;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁ECS资源
|
||||||
|
/// </summary>
|
||||||
|
private void DisposeEcs()
|
||||||
|
{
|
||||||
|
_ecsWorld?.Dispose();
|
||||||
|
_ecsWorld = null;
|
||||||
|
_ecsRunner = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
62
GFramework.Core/ecs/EcsSystemBase.cs
Normal file
62
GFramework.Core/ecs/EcsSystemBase.cs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
|
using GFramework.Core.system;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS系统基类,继承自AbstractSystem以集成到现有架构
|
||||||
|
/// </summary>
|
||||||
|
public abstract class EcsSystemBase : AbstractSystem, IEcsSystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ECS世界实例
|
||||||
|
/// </summary>
|
||||||
|
protected EcsWorld EcsWorld { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 快捷访问内部World
|
||||||
|
/// </summary>
|
||||||
|
protected World World => EcsWorld.InternalWorld;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统优先级,默认为0
|
||||||
|
/// </summary>
|
||||||
|
public virtual int Priority => 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 每帧更新(子类实现)
|
||||||
|
/// </summary>
|
||||||
|
public abstract void Update(float deltaTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统初始化
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
EcsWorld = Context.GetService<EcsWorld>() ?? throw new InvalidOperationException(
|
||||||
|
"EcsWorld not found in context. Make sure ECS is properly initialized.");
|
||||||
|
|
||||||
|
OnEcsInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统销毁
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnDestroy()
|
||||||
|
{
|
||||||
|
OnEcsDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS系统初始化(子类实现)
|
||||||
|
/// </summary>
|
||||||
|
protected abstract void OnEcsInit();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS系统销毁(子类可选实现)
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnEcsDestroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
66
GFramework.Core/ecs/EcsSystemRunner.cs
Normal file
66
GFramework.Core/ecs/EcsSystemRunner.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
|
using GFramework.Core.system;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS系统调度器,负责管理和更新所有ECS系统
|
||||||
|
/// </summary>
|
||||||
|
public sealed class EcsSystemRunner : AbstractSystem
|
||||||
|
{
|
||||||
|
private readonly List<IEcsSystem> _systems = new();
|
||||||
|
private bool _isRunning;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化调度器,从DI容器获取所有ECS系统
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnInit()
|
||||||
|
{
|
||||||
|
// 从容器获取所有已注册的ECS系统
|
||||||
|
var systemsList = Context.GetService<IReadOnlyList<IEcsSystem>>();
|
||||||
|
if (systemsList != null && systemsList.Count > 0)
|
||||||
|
{
|
||||||
|
// 按优先级排序
|
||||||
|
_systems.AddRange(systemsList.OrderBy(s => s.Priority));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新所有ECS系统
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">帧间隔时间</param>
|
||||||
|
public void Update(float deltaTime)
|
||||||
|
{
|
||||||
|
if (!_isRunning) return;
|
||||||
|
|
||||||
|
foreach (var system in _systems)
|
||||||
|
{
|
||||||
|
system.Update(deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动调度器
|
||||||
|
/// </summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_isRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止调度器
|
||||||
|
/// </summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁调度器
|
||||||
|
/// </summary>
|
||||||
|
protected override void OnDestroy()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
_systems.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
66
GFramework.Core/ecs/EcsWorld.cs
Normal file
66
GFramework.Core/ecs/EcsWorld.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
using GFramework.Core.Abstractions.ecs;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS世界实现,封装Arch的World实例
|
||||||
|
/// </summary>
|
||||||
|
public sealed class EcsWorld : IEcsWorld
|
||||||
|
{
|
||||||
|
private readonly World _world = World.Create();
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取内部的Arch World实例
|
||||||
|
/// </summary>
|
||||||
|
public World InternalWorld => _world;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前实体数量
|
||||||
|
/// </summary>
|
||||||
|
public int EntityCount => _world.Size;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建一个新实体
|
||||||
|
/// </summary>
|
||||||
|
public Entity CreateEntity(params ComponentType[] types)
|
||||||
|
{
|
||||||
|
return _world.Create(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁指定实体
|
||||||
|
/// </summary>
|
||||||
|
public void DestroyEntity(Entity entity)
|
||||||
|
{
|
||||||
|
_world.Destroy(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查实体是否存活
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAlive(Entity entity)
|
||||||
|
{
|
||||||
|
return _world.IsAlive(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清空所有实体
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_world.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放资源
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
|
||||||
|
World.Destroy(_world);
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
GFramework.Core/ecs/components/Position.cs
Normal file
16
GFramework.Core/ecs/components/Position.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace GFramework.Core.ecs.components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 位置组件
|
||||||
|
/// </summary>
|
||||||
|
public struct Position
|
||||||
|
{
|
||||||
|
public float X;
|
||||||
|
public float Y;
|
||||||
|
|
||||||
|
public Position(float x, float y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
GFramework.Core/ecs/components/Velocity.cs
Normal file
16
GFramework.Core/ecs/components/Velocity.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace GFramework.Core.ecs.components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 速度组件
|
||||||
|
/// </summary>
|
||||||
|
public struct Velocity
|
||||||
|
{
|
||||||
|
public float X;
|
||||||
|
public float Y;
|
||||||
|
|
||||||
|
public Velocity(float x, float y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
67
GFramework.Core/ecs/examples/EcsUsageExample.cs
Normal file
67
GFramework.Core/ecs/examples/EcsUsageExample.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
using GFramework.Core.Abstractions.architecture;
|
||||||
|
using GFramework.Core.ecs.components;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs.examples;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ECS使用示例 - 演示如何创建和管理实体
|
||||||
|
/// </summary>
|
||||||
|
public static class EcsUsageExample
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 示例1: 创建移动的敌人实体
|
||||||
|
/// </summary>
|
||||||
|
public static void CreateMovingEnemies(IArchitectureContext context, int count)
|
||||||
|
{
|
||||||
|
var ecsWorld = context.GetEcsWorld();
|
||||||
|
var world = ecsWorld.InternalWorld;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
// 创建实体
|
||||||
|
var entity = ecsWorld.CreateEntity(
|
||||||
|
new ComponentType[]
|
||||||
|
{
|
||||||
|
typeof(Position),
|
||||||
|
typeof(Velocity)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 设置初始位置和速度
|
||||||
|
world.Set(entity, new Position(i * 10, 0));
|
||||||
|
|
||||||
|
var random = new Random();
|
||||||
|
world.Set(entity, new Velocity(
|
||||||
|
(float)(random.NextDouble() * 100 - 50),
|
||||||
|
(float)(random.NextDouble() * 100 - 50)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例2: 批量清理实体
|
||||||
|
/// </summary>
|
||||||
|
public static void ClearAllEntities(IArchitectureContext context)
|
||||||
|
{
|
||||||
|
var ecsWorld = context.GetEcsWorld();
|
||||||
|
ecsWorld.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 示例3: 查询特定实体
|
||||||
|
/// </summary>
|
||||||
|
public static int CountMovingEntities(IArchitectureContext context)
|
||||||
|
{
|
||||||
|
var ecsWorld = context.GetEcsWorld();
|
||||||
|
var world = ecsWorld.InternalWorld;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
var query = new QueryDescription()
|
||||||
|
.WithAll<Position, Velocity>();
|
||||||
|
|
||||||
|
world.Query(in query, (Entity entity) => { count++; });
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
GFramework.Core/ecs/systems/MovementSystem.cs
Normal file
31
GFramework.Core/ecs/systems/MovementSystem.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Arch.Core;
|
||||||
|
using GFramework.Core.ecs.components;
|
||||||
|
|
||||||
|
namespace GFramework.Core.ecs.systems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动系统示例 - 根据速度更新位置
|
||||||
|
/// </summary>
|
||||||
|
public class MovementSystem : EcsSystemBase
|
||||||
|
{
|
||||||
|
private QueryDescription _query;
|
||||||
|
|
||||||
|
public override int Priority => 0;
|
||||||
|
|
||||||
|
protected override void OnEcsInit()
|
||||||
|
{
|
||||||
|
// 创建查询:查找所有同时拥有Position和Velocity组件的实体
|
||||||
|
_query = new QueryDescription()
|
||||||
|
.WithAll<Position, Velocity>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float deltaTime)
|
||||||
|
{
|
||||||
|
// 查询并更新所有符合条件的实体
|
||||||
|
World.Query(in _query, (ref Position pos, ref Velocity vel) =>
|
||||||
|
{
|
||||||
|
pos.X += vel.X * deltaTime;
|
||||||
|
pos.Y += vel.Y * deltaTime;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
<Using Include="GFramework.Game.Abstractions"/>
|
<Using Include="GFramework.Game.Abstractions"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.9">
|
<PackageReference Update="Meziantou.Analyzer" Version="3.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// This type is required to support init-only setters and record types
|
// This type is required to support init-only setters and record types
|
||||||
// when targeting netstandard2.0 or older frameworks.
|
// when targeting netstandard2.0 or older frameworks.
|
||||||
|
|
||||||
#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2_0
|
#if NETSTANDARD2_1 || NETFRAMEWORK || NETCOREAPP2_1
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace System.Runtime.CompilerServices;
|
namespace System.Runtime.CompilerServices;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
<Folder Include="logging\"/>
|
<Folder Include="logging\"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.9">
|
<PackageReference Update="Meziantou.Analyzer" Version="3.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
|
|
||||||
<!-- 这是 Analyzer,不是运行时库 -->
|
<!-- 这是 Analyzer,不是运行时库 -->
|
||||||
<IsRoslynAnalyzer>true</IsRoslynAnalyzer>
|
<IsRoslynAnalyzer>true</IsRoslynAnalyzer>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj" PrivateAssets="all"/>
|
<ProjectReference Include="..\GFramework.Core.Abstractions\GFramework.Core.Abstractions.csproj" PrivateAssets="all"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.9">
|
<PackageReference Update="Meziantou.Analyzer" Version="3.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
<!-- import parent: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" PrivateAssets="all"/>
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" PrivateAssets="all"/>
|
||||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.9">
|
<PackageReference Update="Meziantou.Analyzer" Version="3.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
<PackageId>GeWuYou.$(AssemblyName)</PackageId>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
|
|
||||||
<!-- 这是 Analyzer,不是运行时库 -->
|
<!-- 这是 Analyzer,不是运行时库 -->
|
||||||
<IsRoslynAnalyzer>true</IsRoslynAnalyzer>
|
<IsRoslynAnalyzer>true</IsRoslynAnalyzer>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user