第一批重构,主要是物理迁移脚本和部分命名空间的调整
- 结构上迁移文件,将脚本分成 Base/Runtime/Presentation/Procedure/Editor 五大文件夹 - 调整 DataTable 和 Definition 下脚本的命名空间 - 依据 UI-5层架构设计规范 拆分原先的 UI 到 Runtime 和 Presentation 下
This commit is contained in:
+135
@@ -0,0 +1,135 @@
|
||||
using CustomEvent;
|
||||
using Entity;
|
||||
using Entity.EntityData;
|
||||
using Entity.Weapon;
|
||||
using GameFramework.Event;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Simulation
|
||||
{
|
||||
public sealed partial class SimulationWorld
|
||||
{
|
||||
[Header("投射物命中表现")]
|
||||
[Tooltip("是否监听投射物命中表现事件。")]
|
||||
[SerializeField]
|
||||
private bool _projectileHitPresentationEnabled = true;
|
||||
|
||||
[Tooltip("是否播放投射物命中标记。")]
|
||||
[SerializeField]
|
||||
private bool _projectileHitMarkerEnabled = true;
|
||||
|
||||
[Tooltip("命中标记尺寸。")][SerializeField] private float _projectileHitMarkerSize = 0.2f;
|
||||
|
||||
[Tooltip("命中标记在目标上的高度偏移。")]
|
||||
[SerializeField]
|
||||
private float _projectileHitMarkerYOffset = 1.2f;
|
||||
|
||||
[Tooltip("命中标记持续时间。")]
|
||||
[SerializeField]
|
||||
private float _projectileHitMarkerDuration = 0.15f;
|
||||
|
||||
[Tooltip("命中标记颜色。")][SerializeField] private Color _projectileHitMarkerColor = new(1f, 0f, 0f, 0.95f);
|
||||
|
||||
[Tooltip("是否播放投射物命中特效实体。")]
|
||||
[SerializeField]
|
||||
private bool _projectileHitEffectEnabled;
|
||||
|
||||
[Tooltip("投射物命中特效实体类型 Id(<=0 表示不启用)。")]
|
||||
[SerializeField]
|
||||
private int _projectileHitEffectTypeId;
|
||||
|
||||
private sealed class HitPresentation
|
||||
{
|
||||
private readonly SimulationWorld _world;
|
||||
private HandgunHitMarkerAttackEffect _projectileHitMarkerEffect;
|
||||
private bool _isProjectileHitEventSubscribed;
|
||||
|
||||
public HitPresentation(SimulationWorld world)
|
||||
{
|
||||
_world = world;
|
||||
}
|
||||
|
||||
public void OnStart()
|
||||
{
|
||||
if (_world == null || !_world._projectileHitPresentationEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var eventComponent = GameEntry.Event;
|
||||
if (eventComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
eventComponent.Subscribe(ProjectileHitPresentationEventArgs.EventId, OnProjectileHitPresentationEvent);
|
||||
_isProjectileHitEventSubscribed = true;
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
if (!_isProjectileHitEventSubscribed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var eventComponent = GameEntry.Event;
|
||||
if (eventComponent != null)
|
||||
{
|
||||
eventComponent.Unsubscribe(ProjectileHitPresentationEventArgs.EventId,
|
||||
OnProjectileHitPresentationEvent);
|
||||
}
|
||||
|
||||
_isProjectileHitEventSubscribed = false;
|
||||
}
|
||||
|
||||
private void OnProjectileHitPresentationEvent(object sender, GameEventArgs e)
|
||||
{
|
||||
if (!_isProjectileHitEventSubscribed || _world == null ||
|
||||
e is not ProjectileHitPresentationEventArgs args)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.ShowHitMarker && _world._projectileHitMarkerEnabled)
|
||||
{
|
||||
PlayHitMarker(args);
|
||||
}
|
||||
|
||||
if (args.ShowHitEffect && _world._projectileHitEffectEnabled)
|
||||
{
|
||||
PlayHitEffect(args);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayHitMarker(ProjectileHitPresentationEventArgs args)
|
||||
{
|
||||
// Projectile hit markers were reusing the handgun marker effect and were
|
||||
// visually indistinguishable from handgun lock/hit feedback.
|
||||
}
|
||||
|
||||
private void PlayHitEffect(ProjectileHitPresentationEventArgs args)
|
||||
{
|
||||
int effectTypeId = args.EffectEntityTypeId > 0
|
||||
? args.EffectEntityTypeId
|
||||
: _world._projectileHitEffectTypeId;
|
||||
if (effectTypeId <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var entityComponent = GameEntry.Entity;
|
||||
if (entityComponent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EffectData effectData = new EffectData(entityComponent.GenerateSerialId(), effectTypeId)
|
||||
{
|
||||
Position = args.HitPosition
|
||||
};
|
||||
entityComponent.ShowEffect(effectData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99cec505913140a2b4bdf1498b28c044
|
||||
timeCreated: 1771911517
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Simulation
|
||||
{
|
||||
public sealed partial class SimulationWorld
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed4e018208ef0d042b99372c1f9ae778
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
using Entity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Simulation
|
||||
{
|
||||
public sealed partial class SimulationWorld
|
||||
{
|
||||
private sealed class TransformSync
|
||||
{
|
||||
private readonly SimulationWorld _world;
|
||||
|
||||
public TransformSync(SimulationWorld world)
|
||||
{
|
||||
_world = world;
|
||||
}
|
||||
|
||||
public void OnLateUpdate()
|
||||
{
|
||||
if (_world == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var enemyManager = GameEntry.EnemyManager;
|
||||
if (enemyManager != null && enemyManager.Enemies != null)
|
||||
{
|
||||
var enemies = enemyManager.Enemies;
|
||||
foreach (var enemy in enemies)
|
||||
{
|
||||
if (enemy is not EnemyBase enemyEntity || !enemyEntity.Available)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_world.TryGetEnemyData(enemyEntity.Id, out EnemySimData enemyData))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ApplyEnemyPresentation(enemyEntity, enemyData);
|
||||
}
|
||||
}
|
||||
|
||||
var projectiles = _world._projectiles;
|
||||
for (int i = 0; i < projectiles.Count; i++)
|
||||
{
|
||||
ProjectileSimData projectileData = projectiles[i];
|
||||
if (!projectileData.Active || projectileData.State != ProjectileStateActive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityBase projectileEntity = TryGetEntityById(projectileData.EntityId);
|
||||
if (projectileEntity == null || !projectileEntity.Available)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ApplyProjectilePresentation(projectileEntity, projectileData);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyEnemyPresentation(EnemyBase enemyEntity, in EnemySimData enemyData)
|
||||
{
|
||||
Transform enemyTransform = enemyEntity.CachedTransform;
|
||||
enemyTransform.position = enemyData.Position;
|
||||
|
||||
Quaternion rotation = enemyData.Rotation;
|
||||
float rotationMagnitude = Mathf.Abs(rotation.x) + Mathf.Abs(rotation.y) + Mathf.Abs(rotation.z) +
|
||||
Mathf.Abs(rotation.w);
|
||||
if (rotationMagnitude > float.Epsilon)
|
||||
{
|
||||
enemyTransform.rotation = rotation;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 forward = enemyData.Forward;
|
||||
forward.y = 0f;
|
||||
if (forward.sqrMagnitude > float.Epsilon)
|
||||
{
|
||||
enemyTransform.forward = forward.normalized;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyProjectilePresentation(EntityBase projectileEntity,
|
||||
in ProjectileSimData projectileData)
|
||||
{
|
||||
Transform projectileTransform = projectileEntity.CachedTransform;
|
||||
if (projectileTransform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
projectileTransform.position = projectileData.Position;
|
||||
Vector3 forward = projectileData.Forward;
|
||||
if (forward.sqrMagnitude <= float.Epsilon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
projectileTransform.rotation = Quaternion.LookRotation(forward.normalized, Vector3.up);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21da1bcb02d247358738e9b562af5512
|
||||
timeCreated: 1771911431
|
||||
Reference in New Issue
Block a user