Checkpoint 1:
- 新增三类 SimData:
- EnemySimData
- ProjectileSimData
- PickupSimData
- 新增 Tick 上下文:SimulationTickContext
- 新增双向索引绑定:EntityBinding
- 新增纯数据容器世界:SimulationWorld
This commit is contained in:
parent
ed3b37d0f7
commit
3b8e0731f0
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7f519a6e4d7b4cb4ab5eabf95fb55e1b
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
public struct EnemySimData
|
||||||
|
{
|
||||||
|
public int EntityId;
|
||||||
|
public Vector3 Position;
|
||||||
|
public Vector3 Forward;
|
||||||
|
public float Speed;
|
||||||
|
public float AttackRange;
|
||||||
|
public int TargetType;
|
||||||
|
public int State;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ef2eea85685544189eef2d9f2cece080
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
public sealed class EntityBinding
|
||||||
|
{
|
||||||
|
private readonly Dictionary<int, int> _entityIdToSimulationIndex = new Dictionary<int, int>();
|
||||||
|
private readonly Dictionary<int, int> _simulationIndexToEntityId = new Dictionary<int, int>();
|
||||||
|
|
||||||
|
public int Count => _entityIdToSimulationIndex.Count;
|
||||||
|
|
||||||
|
public void Bind(int entityId, int simulationIndex)
|
||||||
|
{
|
||||||
|
if (_entityIdToSimulationIndex.TryGetValue(entityId, out int oldSimulationIndex))
|
||||||
|
{
|
||||||
|
_simulationIndexToEntityId.Remove(oldSimulationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_simulationIndexToEntityId.TryGetValue(simulationIndex, out int oldEntityId))
|
||||||
|
{
|
||||||
|
_entityIdToSimulationIndex.Remove(oldEntityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_entityIdToSimulationIndex[entityId] = simulationIndex;
|
||||||
|
_simulationIndexToEntityId[simulationIndex] = entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemapIndex(int entityId, int newSimulationIndex)
|
||||||
|
{
|
||||||
|
if (!_entityIdToSimulationIndex.TryGetValue(entityId, out int oldSimulationIndex))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_simulationIndexToEntityId.Remove(oldSimulationIndex);
|
||||||
|
_entityIdToSimulationIndex[entityId] = newSimulationIndex;
|
||||||
|
_simulationIndexToEntityId[newSimulationIndex] = entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetSimulationIndex(int entityId, out int simulationIndex)
|
||||||
|
{
|
||||||
|
return _entityIdToSimulationIndex.TryGetValue(entityId, out simulationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetEntityId(int simulationIndex, out int entityId)
|
||||||
|
{
|
||||||
|
return _simulationIndexToEntityId.TryGetValue(simulationIndex, out entityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UnbindByEntityId(int entityId)
|
||||||
|
{
|
||||||
|
if (!_entityIdToSimulationIndex.TryGetValue(entityId, out int simulationIndex))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_entityIdToSimulationIndex.Remove(entityId);
|
||||||
|
_simulationIndexToEntityId.Remove(simulationIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UnbindBySimulationIndex(int simulationIndex)
|
||||||
|
{
|
||||||
|
if (!_simulationIndexToEntityId.TryGetValue(simulationIndex, out int entityId))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_simulationIndexToEntityId.Remove(simulationIndex);
|
||||||
|
_entityIdToSimulationIndex.Remove(entityId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_entityIdToSimulationIndex.Clear();
|
||||||
|
_simulationIndexToEntityId.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c4f6d93561db4b9092ab61182f2983d7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
public struct PickupSimData
|
||||||
|
{
|
||||||
|
public int EntityId;
|
||||||
|
public Vector3 Position;
|
||||||
|
public float PickupRadius;
|
||||||
|
public int State;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ff6e8b75e4af4c3ca9e3b732b1383f95
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
public struct ProjectileSimData
|
||||||
|
{
|
||||||
|
public int EntityId;
|
||||||
|
public int OwnerEntityId;
|
||||||
|
public Vector3 Position;
|
||||||
|
public Vector3 Forward;
|
||||||
|
public float Speed;
|
||||||
|
public float RemainingLifetime;
|
||||||
|
public int State;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2eec1f4389004d69bdce8c4dd95d255e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
public readonly struct SimulationTickContext
|
||||||
|
{
|
||||||
|
public SimulationTickContext(float deltaTime, float realDeltaTime, Vector3 playerPosition)
|
||||||
|
{
|
||||||
|
DeltaTime = deltaTime;
|
||||||
|
RealDeltaTime = realDeltaTime;
|
||||||
|
PlayerPosition = playerPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float DeltaTime { get; }
|
||||||
|
public float RealDeltaTime { get; }
|
||||||
|
public Vector3 PlayerPosition { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c4c57fcf285f488b821c9141a6d0ad09
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Simulation
|
||||||
|
{
|
||||||
|
public sealed class SimulationWorld
|
||||||
|
{
|
||||||
|
private readonly List<EnemySimData> _enemies = new List<EnemySimData>();
|
||||||
|
private readonly List<ProjectileSimData> _projectiles = new List<ProjectileSimData>();
|
||||||
|
private readonly List<PickupSimData> _pickups = new List<PickupSimData>();
|
||||||
|
|
||||||
|
public EntityBinding EnemyBinding { get; } = new EntityBinding();
|
||||||
|
public EntityBinding ProjectileBinding { get; } = new EntityBinding();
|
||||||
|
public EntityBinding PickupBinding { get; } = new EntityBinding();
|
||||||
|
|
||||||
|
public IReadOnlyList<EnemySimData> Enemies => _enemies;
|
||||||
|
public IReadOnlyList<ProjectileSimData> Projectiles => _projectiles;
|
||||||
|
public IReadOnlyList<PickupSimData> Pickups => _pickups;
|
||||||
|
|
||||||
|
public int AddEnemy(in EnemySimData simData)
|
||||||
|
{
|
||||||
|
int simulationIndex = _enemies.Count;
|
||||||
|
_enemies.Add(simData);
|
||||||
|
EnemyBinding.Bind(simData.EntityId, simulationIndex);
|
||||||
|
return simulationIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveEnemyByEntityId(int entityId)
|
||||||
|
{
|
||||||
|
if (!EnemyBinding.TryGetSimulationIndex(entityId, out int simulationIndex))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastIndex = _enemies.Count - 1;
|
||||||
|
if (simulationIndex != lastIndex)
|
||||||
|
{
|
||||||
|
EnemySimData movedData = _enemies[lastIndex];
|
||||||
|
_enemies[simulationIndex] = movedData;
|
||||||
|
EnemyBinding.RemapIndex(movedData.EntityId, simulationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
_enemies.RemoveAt(lastIndex);
|
||||||
|
EnemyBinding.UnbindByEntityId(entityId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AddProjectile(in ProjectileSimData simData)
|
||||||
|
{
|
||||||
|
int simulationIndex = _projectiles.Count;
|
||||||
|
_projectiles.Add(simData);
|
||||||
|
ProjectileBinding.Bind(simData.EntityId, simulationIndex);
|
||||||
|
return simulationIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveProjectileByEntityId(int entityId)
|
||||||
|
{
|
||||||
|
if (!ProjectileBinding.TryGetSimulationIndex(entityId, out int simulationIndex))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastIndex = _projectiles.Count - 1;
|
||||||
|
if (simulationIndex != lastIndex)
|
||||||
|
{
|
||||||
|
ProjectileSimData movedData = _projectiles[lastIndex];
|
||||||
|
_projectiles[simulationIndex] = movedData;
|
||||||
|
ProjectileBinding.RemapIndex(movedData.EntityId, simulationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
_projectiles.RemoveAt(lastIndex);
|
||||||
|
ProjectileBinding.UnbindByEntityId(entityId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AddPickup(in PickupSimData simData)
|
||||||
|
{
|
||||||
|
int simulationIndex = _pickups.Count;
|
||||||
|
_pickups.Add(simData);
|
||||||
|
PickupBinding.Bind(simData.EntityId, simulationIndex);
|
||||||
|
return simulationIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemovePickupByEntityId(int entityId)
|
||||||
|
{
|
||||||
|
if (!PickupBinding.TryGetSimulationIndex(entityId, out int simulationIndex))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastIndex = _pickups.Count - 1;
|
||||||
|
if (simulationIndex != lastIndex)
|
||||||
|
{
|
||||||
|
PickupSimData movedData = _pickups[lastIndex];
|
||||||
|
_pickups[simulationIndex] = movedData;
|
||||||
|
PickupBinding.RemapIndex(movedData.EntityId, simulationIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pickups.RemoveAt(lastIndex);
|
||||||
|
PickupBinding.UnbindByEntityId(entityId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick(in SimulationTickContext context)
|
||||||
|
{
|
||||||
|
_ = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_enemies.Clear();
|
||||||
|
_projectiles.Clear();
|
||||||
|
_pickups.Clear();
|
||||||
|
|
||||||
|
EnemyBinding.Clear();
|
||||||
|
ProjectileBinding.Clear();
|
||||||
|
PickupBinding.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8a558ebbc9cb4d94946ac9f4f27914d8
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
- 以上问题修正后,核心流程可稳定连续跑 10 分钟无异常日志。
|
- 以上问题修正后,核心流程可稳定连续跑 10 分钟无异常日志。
|
||||||
|
|
||||||
## 2. P1 Simulation 分层(为 Job/Burst 做结构准备)
|
## 2. P1 Simulation 分层(为 Job/Burst 做结构准备)
|
||||||
- [ ] Checkpoint 1:搭建 Simulation 基础骨架(仅新增,不改行为)
|
- [x] Checkpoint 1:搭建 Simulation 基础骨架(仅新增,不改行为)
|
||||||
- 新建目录:`Assets/GameMain/Scripts/Simulation`。
|
- 新建目录:`Assets/GameMain/Scripts/Simulation`。
|
||||||
- 新建 `SimulationWorld`,统一持有 `EnemySimData / ProjectileSimData / PickupSimData` 容器。
|
- 新建 `SimulationWorld`,统一持有 `EnemySimData / ProjectileSimData / PickupSimData` 容器。
|
||||||
- 新建 `EntityBinding`,维护 `EntityId <-> SimulationIndex` 双向映射。
|
- 新建 `EntityBinding`,维护 `EntityId <-> SimulationIndex` 双向映射。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue