Files
2026-09-15 11:07:01 +08:00

125 lines
3.6 KiB
C#

using Cysharp.Threading.Tasks;
using SepCore.AsyncTask;
using SepCore.Components;
using SepCore.Definition;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace SepCore.Entity
{
public abstract class EnemyBase : TargetableObject
{
protected Transform _target;
public EnemyData EnemyData { get; private set; }
public MovementComponent Movement { get; private set; }
protected override TargetableObjectData _targetableObjectData => EnemyData;
public virtual float AttackRange => EnemyData.AttackRange;
public float AttackCooldown => EnemyData.AttackCooldown;
public int AttackDamage => EnemyData.AttackDamage;
public override ImpactData GetImpactData()
{
return new ImpactData(EnemyData.Camp, EnemyData.AttackDamage);
}
public virtual void SetTarget(Transform target) => _target = target;
#region Lifecycle
protected override void OnInit(object userData)
{
base.OnInit(userData);
Movement = GetComponent<MovementComponent>();
_healthComponent = GetComponent<HealthComponent>();
}
protected override void OnShow(object userData)
{
base.OnShow(userData);
if (userData is EnemyData enemyData)
{
EnemyData = enemyData;
_healthComponent.OnInit(enemyData.MaxHealthBase);
Movement.OnInit(enemyData.SpeedBase, CachedTransform, null, true);
Movement.SetMove(true);
StartAttackCooldown(enemyData.AttackCooldown);
CachedTransform.position = enemyData.Position;
ApplyVisualParams(enemyData);
}
else
{
Log.Error("Invalid enemy data type: {0}", userData?.GetType());
}
}
protected override void OnHide(bool isShutdown, object userData)
{
Movement.OnReset();
_healthComponent.OnReset();
CancelAttackCooldown();
_target = null;
base.OnHide(isShutdown, userData);
}
protected override void OnDead(EntityBase attacker)
{
if (Random.value < EnemyData.DropPercent)
{
var data = new CoinData(EnemyData.DropCoin, GameEntry.Entity.NextId())
{
Position = CachedTransform.position
};
GameEntry.Entity.ShowCoinAsync(data).Forget();
}
if (Random.value < EnemyData.DropPercent)
{
var data = new ExpData(EnemyData.DropExp, GameEntry.Entity.NextId())
{
Position = CachedTransform.position
};
GameEntry.Entity.ShowExpAsync(data).Forget();
}
base.OnDead(attacker);
}
#endregion
protected Vector3 GetTargetDirection()
{
if (_target == null)
{
return Vector3.zero;
}
return new Vector3(
_target.position.x - CachedTransform.position.x,
0f,
_target.position.z - CachedTransform.position.z
).normalized;
}
private void ApplyVisualParams(EnemyData data)
{
CachedTransform.localScale = Vector3.one * data.Scale;
var renderer = GetComponentInChildren<Renderer>();
var block = new MaterialPropertyBlock();
block.SetColor("_BaseColor", data.Color);
renderer.SetPropertyBlock(block);
}
}
}