1.將各種屬性應用于戰斗
我們希望將上節課的CharactorState腳本作為一個父類,而玩家和敵人的屬性狀態都是繼承自它的
創建PlayerStats腳本:
public class PlayerStats : CharactorState
{
private Player player;//獲取玩家腳本
? ? protected override void Start()
{
base.Start();//初始化血量
? ? ? ? player = GetComponent<Player>();
}
? ? public override void TakeDamage(int _damage)//直接在傷害函數實現生命的減少以及敵人和玩家被擊中的效果
{
base.TakeDamage(_damage);
? ? ? ? player.DamageEffect();
}
}
創建EnemyStats腳本:
public class EnemyStats : CharactorState//同樣的操作
{
private Enemy enemy;
? ? protected override void Start()
{
base.Start();
? ? ? ? enemy = GetComponent<Enemy>();
}
? ? public override void TakeDamage(int _damage)
{
base.TakeDamage(_damage);
? ? ? ? enemy.DamageEffect();
}
}
CharactorState腳本:
?public State strength;//力量狀態,會改變傷害狀態
? ? public virtual void DoDamage(CharactorState _target)//最終實現傷害的函數,需要接受目標的屬性狀態
{
int totalDamage =damage.GetValue()+strength.GetValue();//傳遞最終的傷害
? ? ? ? _target.TakeDamage(totalDamage);
? ? }
PlayerAnimationTriggers腳本:
? ? private void AttackTrigger()
{
Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(player.attackCheck.position, player.attackCheckRadius);
? ? ? ? foreach(var hit in collider2Ds)
{
if(hit.GetComponent<Enemy>()!=null)
{
EnemyStats EnemyTarget = hit.GetComponent<EnemyStats>();//獲取敵人狀態屬性
? ? ? ? ? ? ? ? player.state.DoDamage(EnemyTarget);
? ? ? ? ? ? ? ??
}
}
}
Enemy_SkeletonAnimationTrigger腳本:
? ? private void AttackTrigger()
{
Collider2D[] collider2Ds = Physics2D.OverlapCircleAll(enemy.attackCheck.position, enemy.attackCheckRadius);
? ? ? ? foreach (var hit in collider2Ds)
{
if (hit.GetComponent<Player>() != null)
{
PlayerStats playerEnemy=hit.GetComponent<PlayerStats>();//同理
? ? ? ? ? ? ? ? enemy.state.DoDamage(playerEnemy);
}
}
}
演示:
2.實現玩家的死亡
準備好玩家的死亡以及參數Die
創建PlayerDeadState腳本并在Player中初始化:
? ? public override void Update()//死亡則設置速度為0
{
base.Update();
? ? ? ? _Player.SetZeroVelocity();
}
Entity腳本:
? ? public virtual void Die()//只是為了便于重寫
{
? ? }
Player腳本:
? ? public override void Die()
{
base.Die();
? ? ? ? stateMachine.ChangeState(deadState);//進入死亡狀態
}
PlayerStats腳本:
? protected override void Die()//調用player的死亡函數
{
base.Die();
? ? ? ? player.Die();
}
3.實現敵人死亡
敵人的死亡與玩家不同,我們希望敵人死亡時會暫停動畫并向上偏移一段距離后落下
因此我們需要獲得敵人死亡前對應的動畫參數名稱
Enemy腳本:
? public string lastAnimBoolName;//記錄當前動畫參數
? ? public void AssignAnimName(string _animBoolName)//分配參數的函數
{
lastAnimBoolName = _animBoolName;
}
創建SkeletonDeadState腳本:
自行在EnemySkeleton中初始化該狀態
public class SkeletonDeadState : EnemyState
{
private EnemySkeleton enemy;
public SkeletonDeadState(EnemyStateMachine _enemyStateMachine, Enemy _enemybase, string _animBoolName, EnemySkeleton enemy) : base(_enemyStateMachine, _enemybase, _animBoolName)
{
this.enemy = enemy;
}
? ? public override void Enter()
{
base.Enter();
? ? ? ? enemy.anim.SetBool(enemy.lastAnimBoolName, true);//進入后接著播放死亡前的動畫
enemy.anim.speed = 0;//暫停動畫
enemy.cd.enabled = false;//設置無碰撞器,這樣敵人會掉落下去
stateTimer = .2f;//上升時間
}
? ? public override void Update()
{
base.Update();
? ? ? ? if (stateTimer > 0)
{
rb.velocity = new Vector2(0, 10);//給予上升速度
}
}
}
EnemySkeleton腳本:
? ? public override void Die()//重寫die函數
{
base.Die();
? ? ? ? enemyStateMachine.ChangeState(deadState);//切換到死亡狀態
}
EnemyState腳本:
? ? public virtual void Exit()
{
enemyBase.anim.SetBool(animBoolName, false);
enemyBase.AssignAnimName(animBoolName);//退出狀態時記錄當前狀態
}
EnemyStats腳本:
? ? protected override void Die()//死亡調用函數
{
base.Die();
? ? ? ? enemy.Die();
}