125 lines
3.6 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
|