更改总则
设置停顿状态,此状态会被击飞和红白闪烁
更改
Enemy
[Header("Stunned info")]
public float stunDuration;
public Vector2 stunDirction;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : Entity
{
[SerializeField] protected LayerMask whatIsPlayer;
[Header("Stunned info")]
public float stunDuration;
public Vector2 stunDirction;
[Header("Move info")]
public float moveSpeed;
public float idleTime;
public float battleTime;
[Header("Attack info")]
public float attackDistance;
public float attackCooldown;
[HideInInspector] public float lastTimeAttacked;
public EnemyStateMachine stateMachine { get; private set; }//定义敌人状态机类
//唤醒控制器
protected override void Awake()
{
base.Awake();
stateMachine = new EnemyStateMachine();
}
protected override void Update()
{
base.Update();
stateMachine.currentState.Update();
}
public virtual void AnimationFinishTrigger() => stateMachine.currentState.AnimationFinishTrigger();
public virtual RaycastHit2D IsPlayerDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, 10, whatIsPlayer);
protected override void OnDrawGizmos()
{
base.OnDrawGizmos();
Gizmos.color = Color.yellow;
Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + attackDistance * facingDir, transform.position.y));
}
}
Enemy_Skeleton
public SkeletonStunnedState stunnedState { get; private set; }
protected override void Awake()
{
base.Awake();
idleState = new SkeletonIdleState(stateMachine, this, "Idle", this);
moveState = new SkeletonMoveState(stateMachine, this, "Move", this);
battleState = new SkeletonBattleState(stateMachine, this, "Move", this);
attackState = new SkeletonAttackState(stateMachine, this, "Attack", this);
stunnedState = new SkeletonStunnedState(stateMachine, this, "Stunned", this);
}
protected override void Update()
{
base.Update();
if(Input.GetKeyDown(KeyCode.U))
stateMachine.ChangeState(stunnedState);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy_Skeleton : Enemy
{
#region State
public SkeletonIdleState idleState { get; private set; }
public SkeletonMoveState moveState { get; private set; }
public SkeletonBattleState battleState { get; private set; }
public SkeletonAttackState attackState { get; private set; }
public SkeletonStunnedState stunnedState { get; private set; }
#endregion
protected override void Awake()
{
base.Awake();
idleState = new SkeletonIdleState(stateMachine, this, "Idle", this);
moveState = new SkeletonMoveState(stateMachine, this, "Move", this);
battleState = new SkeletonBattleState(stateMachine, this, "Move", this);
attackState = new SkeletonAttackState(stateMachine, this, "Attack", this);
stunnedState = new SkeletonStunnedState(stateMachine, this, "Stunned", this);
}
protected override void Start()
{
base.Start();
stateMachine.Initialize(idleState);
}
protected override void Update()
{
base.Update();
if(Input.GetKeyDown(KeyCode.U))
stateMachine.ChangeState(stunnedState);
}
}
EntityFX
private void RedColorBlink()
{
if (sr.color != Color.white)
sr.color = Color.white;
else
sr.color = Color.red;
}
private void CancleRedBlink()
{
CancelInvoke();
sr.color = Color.white;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityFX : MonoBehaviour
{
private SpriteRenderer sr;
[Header("Flash Fx")]
[SerializeField] private float flashDuration;
[SerializeField] private Material hitMat;
private Material originalMat;
private void Start()
{
sr = GetComponentInChildren<SpriteRenderer>();//获取子组件 SpriteRender,为之后的对Render的操作做铺垫
originalMat = sr.material;//获取sr中的material,材料。先保存起来以便以后换回去
}
private IEnumerator FlashFX()//用IEnumerator,目的在于将材料变为白色后经过一段时间能够变回去,时间由flashDuration控制
{
sr.material = hitMat;
yield return new WaitForSeconds(flashDuration);//WaitForSeconds()函数,应该是等待一段时间后变为0,与yield配合。
sr.material = originalMat;
}
private void RedColorBlink()
{
if (sr.color != Color.white)
sr.color = Color.white;
else
sr.color = Color.red;
}
private void CancleRedBlink()
{
CancelInvoke();
sr.color = Color.white;
}
}
新添加代码
SkeletonStunnedState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SkeletonStunnedState : EnemyState
{
private Enemy_Skeleton enemy;
public SkeletonStunnedState(EnemyStateMachine _stateMachine, Enemy _enemyBase, string _animBoolName, Enemy_Skeleton _enemy) : base(_stateMachine, _enemyBase, _animBoolName)
{
this.enemy = _enemy;
}
public override void Enter()
{
base.Enter();
enemy.fx.InvokeRepeating("RedColorBlink", 0, .1f);
stateTimer = enemy.stunDuration;
rb.velocity = new Vector2(-enemy.facingDir * enemy.stunDirction.x,enemy.stunDirction.y);
}
public override void Exit()
{
base.Exit();
enemy.fx.Invoke("CancleRedBlink", 0);
}
public override void Update()
{
base.Update();
if (stateTimer < 0)
stateMachine.ChangeState(enemy.idleState);
}
}
注意
本节新增加Invoke类型函数,大意是重复调用某函数。具体的查文档,我不过多讲了