类银河恶魔城学习记录-3-7和3-8反击提示与反击-P59,60,61

更改总则

在敌人攻击是给予提示
更改
Enemy

 [Header("Stunned info")]
 public float stunDuration;
 public Vector2 stunDirction;
 protected bool canBeStunned;
 [SerializeField] protected GameObject counterImage;

 public virtual void OpenCounterAttackWindow()
 {
     canBeStunned = true;
     counterImage.SetActive(true);
 }
 public virtual void CloseCounterAttackWindow()
 {
     canBeStunned = false;
     counterImage.SetActive(false);
 }
 public virtual bool CanBeStunned()
 {
     if(canBeStunned)
     {
         CloseCounterAttackWindow();
         return true;
     }
     return false;
 }    

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;
    protected bool canBeStunned;
    [SerializeField] protected GameObject counterImage;

    [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();
    }
    #region 是否反击
    public virtual void OpenCounterAttackWindow()
    {
        canBeStunned = true;
        counterImage.SetActive(true);
    }
    //此函数通过animator调用
    public virtual void CloseCounterAttackWindow()
    {
        canBeStunned = false;
        counterImage.SetActive(false);
    }
    //此函数通过animator调用
    public virtual bool CanBeStunned()
    {
        if(canBeStunned)
        {
            CloseCounterAttackWindow();
            return true;
        }
        return false;
    }
    //表示是否能被攻击的函数,
    #endregion
    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 override bool CanBeStunned()
 {
     if(base.CanBeStunned())
     {
         stateMachine.ChangeState(stunnedState);

         return true;
     }
     return false;
 }

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();
    }
    public override bool CanBeStunned()
    {
        if(base.CanBeStunned())
        {
            stateMachine.ChangeState(stunnedState);

            return true;
        }
        return false;
    }
}
Enemy_SkeletonAnimationTriggers

private void OpenCounterAttackWindow() => enemy.OpenCounterAttackWindow();
private void CloseCounterAttackWindow() => enemy.CloseCounterAttackWindow();

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy_SkeletonAnimationTriggers : MonoBehaviour
{
    private Enemy_Skeleton enemy => GetComponentInParent();
    private void AnimationTrigger()
    {
        enemy.AnimationFinishTrigger();
    }
    private void AttackTrigger()
    {
        Collider2D[] colliders = Physics2D.OverlapCircleAll(enemy.attackCheck.position, enemy.attackCheckRadius);

        foreach (var hit in colliders)
        {
            if (hit.GetComponent() != null)
            {
                hit.GetComponent().Damage();
            }
        }
    }
    private void OpenCounterAttackWindow() => enemy.OpenCounterAttackWindow();
    private void CloseCounterAttackWindow() => enemy.CloseCounterAttackWindow();
}
根据提示进行反击
更改
Player

[Header("Attack details")]
public Vector2 [] attackMovement;
public float counterAttackDuration = .2f;

 public PlayerCounterAttackState counterAttack { get; private set; }

counterAttack = new PlayerCounterAttackState(this, stateMachine, "CounterAttack");

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Player : Entity
{
    [Header("Attack details")]
    public Vector2 [] attackMovement;
    public float counterAttackDuration = .2f;
    public bool isBusy { get; private set; }
    [Header("Move Info")]
    [SerializeField] public float moveSpeed = 12;
    [SerializeField] public float jumpForce = 12;

    [Header("Dash Info")]
    [SerializeField] private float dashColdown;
    [SerializeField] private float dashUsageTimer;
    [SerializeField] public float dashSpeed;
    [SerializeField] public float dashDuration;
    [SerializeField] public float dashDir { get; private set; }

    

 

    #region States
    public PlayerStateMachine stateMachine { get; private set; }
    public PlayerIdleState idleState { get; private set; }
    public PlayerMoveState moveState { get; private set; }
    public PlayerJumpState jumpState { get; private set; }
    public PlayerAirState airState { get; private set; }

    public PlayerDashState dashState { get; private set; }
    public PlayerWallSlideState wallSlide { get; private set; }
    public PlayerWallJumpState wallJump { get; private set; }
    public PlayerPrimaryAttackState primaryAttack { get; private set; }
    public PlayerCounterAttackState counterAttack { get; private set; }

    #endregion
    protected override void Awake()
    {
        base.Awake();
        stateMachine = new PlayerStateMachine();

        idleState = new PlayerIdleState(this,stateMachine,"Idle");
        moveState = new PlayerMoveState(this, stateMachine, "Move");
        jumpState = new PlayerJumpState(this, stateMachine, "Jump");
        airState = new PlayerAirState(this, stateMachine, "Jump");
        dashState = new PlayerDashState(this, stateMachine, "Dash");
        wallSlide = new PlayerWallSlideState(this, stateMachine, "WallSlide");
        wallJump = new PlayerWallJumpState(this, stateMachine, "WallJump");
        primaryAttack = new PlayerPrimaryAttackState(this, stateMachine, "Attack");
        counterAttack = new PlayerCounterAttackState(this, stateMachine, "CounterAttack");
        //this 就是 player
    }
    protected override void Start()
    {

        base.Start();
        stateMachine.Initialize(idleState);

        
    }

    public float timer;
    public float cooldown = 5;
    protected override void Update()//在mano种update会自动刷新但其他没有mano的不会故需要在这个updata中调用函数以实现
                         //stateMachine中的update
    {
        base.Update();
        CheckForDashInput();
        stateMachine.currentState.Update();

        timer -= Time.deltaTime;
        if (timer < 0 && Input.GetKeyDown(KeyCode.R))
        {
            timer = cooldown;
        }
    }
    public IEnumerator BusyFor(float _seconds)
    {
        isBusy = true;
        yield return new WaitForSeconds(_seconds);
        isBusy = false;

    }
    public void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();
    private void CheckForDashInput()
    {
        if (IsWallDetected())
            return;

        dashUsageTimer -= Time.deltaTime;
        if (Input.GetKeyDown(KeyCode.LeftShift)&& dashUsageTimer<0)
        {
            dashUsageTimer = dashColdown;
            dashDir = Input.GetAxisRaw("Horizontal");
            if(dashDir == 0)
            {
                dashDir = facingDir;
            }
            
        }
    }
    
    
   
}
PlayerGroundState 

 public override void Update()
 {
     base.Update();
     if (Input.GetKey(KeyCode.Q))//摁Q进行反击
         stateMachine.ChangeState(player.counterAttack);

     if (Input.GetKeyDown(KeyCode.Mouse0))
         stateMachine.ChangeState(player.primaryAttack);
     if(!player.IsGroundDetected())
         stateMachine.ChangeState(player.airState);

     if (Input.GetKeyDown(KeyCode.Space) && player.IsGroundDetected())
         stateMachine.ChangeState(player.jumpState);
 }

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class PlayerGroundState : PlayerState
{
    public PlayerGroundState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {
    }

    public override void Enter()
    {
        base.Enter();
    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update()
    {
        base.Update();
        if (Input.GetKey(KeyCode.Q))
            stateMachine.ChangeState(player.counterAttack);
        if (Input.GetKeyDown(KeyCode.Mouse0))
            stateMachine.ChangeState(player.primaryAttack);
        if(!player.IsGroundDetected())
            stateMachine.ChangeState(player.airState);

        if (Input.GetKeyDown(KeyCode.Space) && player.IsGroundDetected())
            stateMachine.ChangeState(player.jumpState);
    }
}
新添
PlayerCounterAttackState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCounterAttackState : PlayerState
{
    //此脚本通过PlayerGroundState调用,及当按下Q时,进入本脚本
    public PlayerCounterAttackState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {
    }

    public override void Enter()
    {
        base.Enter();
        stateTimer = player.counterAttackDuration;
        player.anim.SetBool("SuccessfulCounterAttack", false);
    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update()
    {
        base.Update();
        player.SetZeroVelocity();
        Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position, player.attackCheckRadius);
        //将距离内的所以碰撞器打包进自己建立的碰撞器包中,通过调用Physics2D中的OverlapCircleAll函数来实现该目的
        foreach (var hit in colliders)
        {
            if (hit.GetComponent() != null)
            {
                if(hit.GetComponent().CanBeStunned())//当Enemy中的CanBeStunned()的返回值为True时,将SuccessfulCounterAttack设为true,及调用成功反击动画
                {
                    stateTimer = 10;
                    player.anim.SetBool("SuccessfulCounterAttack", true);
                }
            }
            if (stateTimer < 0 || triggerCalled)
            {
                stateMachine.ChangeState(player.idleState);
            }
                //通过或||来调用改回默认状态,当triggerCalled为true时,及动画已经完成。
                //设置triggerCalled为true,也是是通过animator控制的
                //当stateTimer为0返回默认状态,是因为当反击并没有成功时,时不会调用SuccessfulCounterAttack动画的,也就没法用triggerCalled为true来返回默认状态  
        }
    }
}

你可能感兴趣的:(学习,java,开发语言)