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(); _healthComponent = GetComponent(); } 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(); var block = new MaterialPropertyBlock(); block.SetColor("_BaseColor", data.Color); renderer.SetPropertyBlock(block); } } }