整理武器配置和重构

This commit is contained in:
2026-09-15 10:13:58 +08:00
parent 17ee268416
commit 421f8bf619
115 changed files with 1431 additions and 1905 deletions
@@ -1,25 +0,0 @@
namespace SepCore.Entity
{
public partial class WeaponHandgun
{
private class AttackState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Attack;
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponHandgun;
public override void OnEnter()
{
_weapon.ResetAttackCooldown(_weapon._weaponData.Cooldown);
_weapon.Attack();
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.TransitionTo(WeaponStateType.Check_InRange);
}
public override void OnLeave() { }
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 4e72df067466464fa3be92bfd049dd0d
timeCreated: 1771579220
@@ -1,45 +0,0 @@
namespace SepCore.Entity
{
public partial class WeaponHandgun
{
private class CheckInRangeState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Check_InRange;
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponHandgun;
public override void OnEnter()
{
if (_weapon._canAttack)
{
_weapon.TransitionTo(WeaponStateType.Attack);
}
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.Check();
_weapon.RotateToTarget(elapseSeconds);
if (_weapon._target == null || !_weapon._target.Available)
{
_weapon.TransitionTo(WeaponStateType.Idle);
return;
}
if (!_weapon.IsInRange(_weapon._target, _weapon._sqrRange))
{
_weapon.TransitionTo(WeaponStateType.Check_OutRange);
return;
}
if (_weapon._canAttack)
{
_weapon.TransitionTo(WeaponStateType.Attack);
}
}
public override void OnLeave() { }
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: bfd76c0fb7284ceaa28f78c702f595da
timeCreated: 1771579231
@@ -1,32 +0,0 @@
namespace SepCore.Entity
{
public partial class WeaponHandgun
{
private class CheckOutRangeState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Check_OutRange;
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponHandgun;
public override void OnEnter() { }
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.Check();
_weapon.RotateToTarget(elapseSeconds);
if (_weapon._target == null || !_weapon._target.Available)
{
_weapon.TransitionTo(WeaponStateType.Idle);
return;
}
if (_weapon.IsInRange(_weapon._target, _weapon._sqrRange))
{
_weapon.TransitionTo(WeaponStateType.Check_InRange);
}
}
public override void OnLeave() { }
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 3a9f936d3c8643f7bf632734548f800c
timeCreated: 1771579241
@@ -1,26 +0,0 @@
namespace SepCore.Entity
{
public partial class WeaponHandgun
{
private class IdleState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Idle;
public override void OnInit(WeaponBase weapon) => _weapon = weapon as WeaponHandgun;
public override void OnEnter() { }
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.Check();
_weapon.RotateToOrigin(elapseSeconds);
if (_weapon._target != null && _weapon._target.Available)
{
_weapon.TransitionTo(WeaponStateType.Check_OutRange);
}
}
public override void OnLeave() { }
}
}
}
@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 9c5341944d1a467b8553d31bc3d81d5b
timeCreated: 1771579252
@@ -1,20 +1,12 @@
using SepCore.Definition;
using SepCore.CustomUtility;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace SepCore.Entity
{
public partial class WeaponHandgun : WeaponBase
public class WeaponHandgun : WeaponBase
{
#region Property
private WeaponHandgunData _weaponData;
private Quaternion _cachedRotation;
[SerializeField] private float _rotateSpeed = 6f;
[SerializeField] private LayerMask _hitMask = ~0;
[SerializeField] private Vector3 _fireOriginOffset = Vector3.zero;
[SerializeField] private float _hitMarkerSize = 0.2f;
@@ -26,21 +18,15 @@ namespace SepCore.Entity
#endregion
public override ImpactData GetImpactData()
{
return new ImpactData(_weaponData.OwnerCamp, _weaponData.Attack, AttackStat);
}
protected override void BuildStates()
{
RegisterState(new IdleState());
RegisterState(new CheckOutRangeState());
RegisterState(new CheckInRangeState());
RegisterState(new AttackState());
RegisterState(new WeaponHandgunIdleState());
RegisterState(new WeaponHandgunSeekState());
RegisterState(new WeaponHandgunAimState());
RegisterState(new WeaponHandgunAttackState());
}
protected override void Attack()
public override void Attack()
{
FaceTargetImmediately();
@@ -49,43 +35,12 @@ namespace SepCore.Entity
return;
}
_attackEffect?.Play(this, hitPosition, targetable, 0f);
_attackEffect.Play(this, hitPosition, targetable, 0f);
_isAttacking = true;
AIUtility.PerformCollision(targetable, this);
_isAttacking = false;
}
protected override void Check()
{
_target = SelectTarget(_sqrRange);
}
private void RotateToTarget(float elapseSeconds)
{
if (_target == null || !_target.Available) return;
Vector3 directionToTarget = (_target.CachedTransform.position - CachedTransform.position).normalized;
Quaternion targetRotation = Quaternion.LookRotation(directionToTarget, Vector3.up);
CachedTransform.rotation = Quaternion.Slerp(CachedTransform.rotation, targetRotation,
_rotateSpeed * elapseSeconds);
}
private void RotateToOrigin(float elapseSeconds)
{
CachedTransform.rotation = Quaternion.Slerp(CachedTransform.rotation, _cachedRotation,
_rotateSpeed * elapseSeconds);
}
private void FaceTargetImmediately()
{
if (_target == null || !_target.Available) return;
Vector3 directionToTarget = _target.CachedTransform.position - CachedTransform.position;
if (directionToTarget.sqrMagnitude <= Mathf.Epsilon) return;
CachedTransform.rotation = Quaternion.LookRotation(directionToTarget.normalized, Vector3.up);
}
private bool TryResolveAttackTarget(out TargetableObject targetable, out Vector3 hitPosition)
{
targetable = _target as TargetableObject;
@@ -95,17 +50,12 @@ namespace SepCore.Entity
return false;
}
Transform targetTransform = targetable.CachedTransform;
if (targetTransform == null)
{
return false;
}
hitPosition = targetTransform.position;
Vector3 targetPosition = targetable.CachedTransform.position;
hitPosition = targetPosition;
Vector3 fireOrigin = CachedTransform.TransformPoint(_fireOriginOffset);
Vector3 directionToTarget = targetTransform.position - fireOrigin;
float maxDistance = Mathf.Max(0.1f, _weaponData.AttackRange);
Vector3 directionToTarget = targetPosition - fireOrigin;
float maxDistance = WeaponData.AttackRange;
if (directionToTarget.sqrMagnitude > Mathf.Epsilon &&
Physics.Raycast(fireOrigin, directionToTarget.normalized, out RaycastHit hit, maxDistance, _hitMask,
QueryTriggerInteraction.Collide))
@@ -124,46 +74,16 @@ namespace SepCore.Entity
protected override bool OnWeaponShow(object userData)
{
_weaponData = RequireWeaponData<WeaponHandgunData>(userData);
if (_weaponData == null) return false;
WeaponData = _weaponData;
StartAttackCooldown(_weaponData.Cooldown);
_sqrRange = _weaponData.AttackRange * _weaponData.AttackRange;
_cachedRotation = CachedTransform.rotation;
_attackEffect = new HandgunHitMarkerAttackEffect(_hitMarkerSize, _hitMarkerYOffset, _hitMarkerDuration,
_hitMarkerColor);
if (_weaponData.OwnerCamp == CampType.Player)
{
gameObject.layer = LayerMask.NameToLayer("PlayerWeapon");
_hitMask = LayerMask.GetMask("Enemy");
}
else if (_weaponData.OwnerCamp == CampType.Enemy)
{
gameObject.layer = LayerMask.NameToLayer("EnemyWeapon");
_hitMask = LayerMask.GetMask("Player");
}
return true;
}
protected override void OnWeaponHide(object userData)
{
CancelAttackCooldown();
_attackEffect = null;
}
protected override void OnWeaponAttach(EntityLogic parentEntity, Transform parentTransform, object userData)
{
BindAttackStatFromOwner(parentEntity);
}
protected override void OnWeaponDetach(EntityLogic parentEntity, object userData)
{
ReleaseAttackStatSubscription();
}
#endregion
}
}
@@ -0,0 +1,51 @@
using SepCore.Definition;
namespace SepCore.Entity
{
/// <summary>
/// 手枪的瞄准状态。
/// </summary>
public sealed class WeaponHandgunAimState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Aim;
public override void OnInit(WeaponBase weapon) => _weapon = (WeaponHandgun)weapon;
public override void OnEnter()
{
if (_weapon.CanAttack)
{
_weapon.TransitionTo(WeaponStateType.Attack);
}
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.Check();
_weapon.RotateToTarget(elapseSeconds);
if (_weapon.Target == null || !_weapon.Target.Available)
{
_weapon.TransitionTo(WeaponStateType.Idle);
return;
}
if (!_weapon.IsInRange(_weapon.Target, _weapon.SqrRange))
{
_weapon.TransitionTo(WeaponStateType.Seek);
return;
}
if (_weapon.CanAttack)
{
_weapon.TransitionTo(WeaponStateType.Attack);
}
}
public override void OnLeave()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 71e311baa75a23448a593f2abb05999c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,34 @@
using SepCore.Definition;
namespace SepCore.Entity
{
/// <summary>
/// 手枪的攻击状态。
/// </summary>
public sealed class WeaponHandgunAttackState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Attack;
public override void OnInit(WeaponBase weapon) => _weapon = (WeaponHandgun)weapon;
public override void OnEnter()
{
_weapon.ResetAttackCooldown(_weapon.AttackCooldown);
_weapon.Attack();
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (!_weapon.IsAttacking)
{
_weapon.TransitionTo(WeaponStateType.Aim);
}
}
public override void OnLeave()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f0513d1d0592c344b93c8df22f892ea0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,35 @@
using SepCore.Definition;
namespace SepCore.Entity
{
/// <summary>
/// 手枪的待机状态。
/// </summary>
public sealed class WeaponHandgunIdleState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Idle;
public override void OnInit(WeaponBase weapon) => _weapon = (WeaponHandgun)weapon;
public override void OnEnter()
{
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.Check();
_weapon.RotateToOrigin(elapseSeconds);
if (_weapon.Target != null && _weapon.Target.Available)
{
_weapon.TransitionTo(WeaponStateType.Seek);
}
}
public override void OnLeave()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd6af23da5725ce4385e23b49b0d4811
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,41 @@
using SepCore.Definition;
namespace SepCore.Entity
{
/// <summary>
/// 手枪的搜寻状态。
/// </summary>
public sealed class WeaponHandgunSeekState : WeaponStateBase
{
private WeaponHandgun _weapon;
public override WeaponStateType State => WeaponStateType.Seek;
public override void OnInit(WeaponBase weapon) => _weapon = (WeaponHandgun)weapon;
public override void OnEnter()
{
}
public override void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_weapon.Check();
_weapon.RotateToTarget(elapseSeconds);
if (_weapon.Target == null || !_weapon.Target.Available)
{
_weapon.TransitionTo(WeaponStateType.Idle);
return;
}
if (_weapon.IsInRange(_weapon.Target, _weapon.SqrRange))
{
_weapon.TransitionTo(WeaponStateType.Aim);
}
}
public override void OnLeave()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3e7a9fee7c4ec5f498756d6e17b1259e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: