引入属性、伤害管线

This commit is contained in:
2026-09-18 21:43:22 +08:00
parent 92e1ea0d55
commit ba25ec1926
108 changed files with 2920 additions and 720 deletions
@@ -1,5 +1,3 @@
using System;
using SepCore.Definition;
using SepCore.Entity;
using UnityEngine;
@@ -7,85 +5,32 @@ namespace SepCore.Components
{
public class AbsorbComponent : MonoBehaviour
{
[SerializeField] private int _maxDetectCount = 64;
private Player _player;
private Transform _target;
private StatComponent _statComponent;
private Collider[] _buffer;
private StatProperty _absorbRangeStat;
private Action<modifier, bool> _absorbRangeStatCallback;
private float AbsorbRangeBase => GameEntry.Luban.Global.DefaultAbsorbRange / 1000f;
private float AbsorbSpeed => GameEntry.Luban.Global.AbsorbSpeed / 1000f;
private float CollectDistance => GameEntry.Luban.Global.CollectDistance / 1000f;
private float AbsorbRange => Mathf.Max(0f, (AbsorbRangeBase + _absorbRangeStat.Value) * _absorbRangeStat.Percent);
private float AbsorbRange => AbsorbRangeBase;
public void OnInit(Player player, StatComponent statComponent)
{
_player = player;
_target = player.CachedTransform;
_statComponent = statComponent;
_buffer = new Collider[Mathf.Max(1, _maxDetectCount)];
_absorbRangeStat = _statComponent.GetStat(StatType.AbsorbRange);
_absorbRangeStatCallback = (modifier, isApply) =>
_statComponent.UpdateStat(_absorbRangeStat, modifier, isApply);
_statComponent.Subscribe(StatType.AbsorbRange, _absorbRangeStatCallback);
}
public void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (!_player.Available) return;
int hitCount = Physics.OverlapSphereNonAlloc(
_target.position,
AbsorbRange,
_buffer,
Constant.Layer.DropLayerMask
);
for (int i = 0; i < hitCount; i++)
{
Collider hit = _buffer[i];
if (hit == null) continue;
CoinEntity coin = hit.GetComponent<CoinEntity>();
if (coin != null && coin.Available)
{
AbsorbDrop(coin.CachedTransform, elapseSeconds);
coin.TryCollect(_player, CollectDistance);
continue;
}
ExpEntity exp = hit.GetComponent<ExpEntity>();
if (exp != null && exp.Available)
{
AbsorbDrop(exp.CachedTransform, elapseSeconds);
exp.TryCollect(_player, CollectDistance);
}
}
GameEntry.SimulationWorld.SyncPlayerAbsorbSettings(AbsorbRange, AbsorbSpeed, CollectDistance);
}
public void OnReset()
{
if (_statComponent != null)
{
_statComponent.Unsubscribe(StatType.AbsorbRange, _absorbRangeStatCallback);
_absorbRangeStatCallback = null;
}
_statComponent = null;
_target = null;
_player = null;
_buffer = null;
}
private void AbsorbDrop(Transform drop, float deltaTime)
{
drop.position = Vector3.MoveTowards(drop.position, _target.position, AbsorbSpeed * deltaTime);
}
}
}