136 lines
4.4 KiB
C#
136 lines
4.4 KiB
C#
using SepCore.Event;
|
|
using SepCore.Entity;
|
|
using SepCore.AsyncTask;
|
|
using Cysharp.Threading.Tasks;
|
|
using GameFramework.Event;
|
|
using UnityEngine;
|
|
|
|
namespace SepCore.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.NextId(), effectTypeId)
|
|
{
|
|
Position = args.HitPosition
|
|
};
|
|
entityComponent.ShowEffectAsync(effectData).Forget();
|
|
}
|
|
}
|
|
}
|
|
}
|