Unity类银河恶魔城学习记录4-4 4-5 P57-58 On Hit Impactp- Attack‘direction fix源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

Entity.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Entity : MonoBehaviour
{
    [Header("Knockback info")]
    [SerializeField] protected Vector2 knockbackDirection;//被击打后的速度信息
    [SerializeField] protected float knockbackDuration;//被击打的时间
    protected bool isKnocked;//此值通过卡住SetVelocity函数的方式用来阻止当一个角色被攻击时,会乱动的情况

    [Header("Collision Info")]
    public Transform attackCheck;//transform类,代表的时物体的位置,用来控制攻击检测的位置
    public float attackCheckRadius;//检测半径
    [SerializeField] protected Transform groundCheck;//transform类,代表的时物体的位置,后面会来定位子组件的位置    
    [SerializeField] protected float groundCheckDistance;
    [SerializeField] protected Transform wallCheck;//transform类,代表的时物体的位置,后面会来定位子组件的位置    
    [SerializeField] protected float wallCheckDistance;
    [SerializeField] protected LayerMask whatIsGround;//LayerMask类,与Raycast配合,https://docs.unity3d.com/cn/current/ScriptReference/Physics.Raycast.html

    #region 定义Unity组件
    public Animator anim { get; private set; }//这样才能配合着拿到自己身上的animator的控制权
    public Rigidbody2D rb { get; private set; }//配合拿到身上的Rigidbody2D组件控制权
    public EntityFX fx { get; private set; }//拿到EntityFX
    #endregion
    public int facingDir { get; private set; } = 1;
    protected bool facingRight = true;//判断是否朝右

    protected virtual void Awake()
    {
        fx = GetComponent();拿到的组件上的EntityFX控制权
        anim = GetComponentInChildren();//拿到自己子组件身上的animator的控制权
        rb = GetComponent();
    }
    protected virtual void Start()
    {

    }
    protected virtual void Update()
    {

    }
    public virtual void Damage()
    {

        fx.StartCoroutine("FlashFX");//IEnumertor本质就是将一个函数分块执行,只有满足某些条件才能执行下一段代码,此函数有StartCoroutine调用
                                     //https://www.zhihu.com/tardis/bd/art/504607545?source_id=1001
        StartCoroutine("HitKnockback");//调用被击打后产生后退效果的函数
        Debug.Log(gameObject.name+"was damaged");
    }
    
    protected virtual IEnumerator HitKnockback()
    {
        isKnocked = true;//此值通过卡住SetVelocity函数的方式用来阻止当一个角色被攻击时,会乱动的情况
        rb.velocity = new Vector2(knockbackDirection.x * -facingDir, knockbackDirection.y);
        yield return new WaitForSeconds(knockbackDuration);
        isKnocked = false;
    }
    //被击打后产生后退效果的函数
    #region 速度函数Velocity
    public virtual void SetZeroVelocity()
    {
        if(isKnocked)
        {
            return;
        }
        rb.velocity = new Vector2(0, 0);
    }//设置速度为0函数

    public virtual void SetVelocity(float _xVelocity, float _yVelocity)
    {
        if(isKnocked)
            return;此值通过卡住SetVelocity函数的方式用来阻止当一个角色被攻击时,会乱动的情况

        rb.velocity = new Vector2(_xVelocity, _yVelocity);//将rb的velocity属性设置为对应的想要的二维向量。因为2D游戏的速度就是二维向量
        FlipController(_xVelocity);//在其他设置速度的时候调用翻转控制器
    }//控制速度的函数,此函数在其他State中可能会使用,但仅能通过player.SeVelocity调用
    #endregion
    #region 翻转函数Flip
    public virtual void Flip()
    {
        facingDir = facingDir * -1;
        facingRight = !facingRight;
        transform.Rotate(0, 180, 0);//旋转函数,transform不需要额外定义,因为他是自带的
    }//翻转函数

    public virtual void FlipController(float _x)//目前设置x,目的时能在空中时也能转身
    {
        if (_x > 0 && !facingRight)//当速度大于0且没有朝右时,翻转
        {
            Flip();
        }
        else if (_x < 0 && facingRight)
        {
            Flip();
        }
    }
    #endregion
    #region 碰撞函数Collision
    public virtual bool IsGroundDetected()
    {
        return Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);
    }//通过RayCast检测是否挨着地面,https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.Raycast.html
    //xxxxxxxx()   => xxxxxxxx  == xxxxxxxxxx() return xxxxxxxxx;
    public virtual bool IsWallDetected()
    {
        return Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround);
    }//通过RayCast检测是否挨着地面,https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.Raycast.html
    //xxxxxxxx()   => xxxxxxxx  == xxxxxxxxxx() return xxxxxxxxx;
    protected virtual void OnDrawGizmos()
    {
        Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));//绘制一条从 from(前面的) 开始到 to(后面的) 的线。
        Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance, wallCheck.position.y));//绘制一条从 from(前面的) 开始到 to(后面的) 的线。
        Gizmos.DrawWireSphere(attackCheck.position, attackCheckRadius);//https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Gizmos.DrawWireSphere.html
        //绘制具有中心和半径的线框球体。
    }//画图函数
    #endregion
}
PlayerPrimaryAttack.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerPrimaryAttackState : PlayerState
{
    //p38 2.从ground进入

    private int comboCounter;

    private float lastTimeAttacked;//距离上一次攻击的时间
    private float comboWindow = 2;//可以间隔的时间
    public PlayerPrimaryAttackState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {
    }

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

        xInput = 0;//修复攻击乱转的问题

        if(comboCounter >2||Time.time>comboWindow+lastTimeAttacked)//当计数器超过2和间隔时间大于window时,进入第一个攻击动作
        {
            comboCounter = 0;
        }
        Debug.Log(comboCounter);

        player.anim.SetInteger("ComboCounter", comboCounter);//设置animtor里的comboCounter

        #region 选择攻击方向
        float attackDir = player.facingDir;

        if(xInput != 0)
        {
            attackDir = xInput;
        }
        #endregion
                                                                   //使其能改变攻击方向
        player.SetVelocity(player.attackMovement[comboCounter].x * attackDir, player.attackMovement[comboCounter].y);//给角色初速度,让角色在攻击触发时移动一点

        stateTimer = .1f;
    }

    public override void Exit()
    {
        base.Exit();
        player.StartCoroutine("BusyFor", .15f);
        comboCounter++;
        lastTimeAttacked = Time.time;
    }

    public override void Update()
    {
        base.Update();
        if(stateTimer<0)
        {
            player.SetZeroVelocity();
        }//1.修改移动时攻击时后可以移动的BUG
        //2.但给了点时间模拟惯性可以动一点
        if (triggerCalled)
        {
            stateMachine.ChangeState(player.idleState);
        }
    }
}

你可能感兴趣的:(学习,游戏引擎,C#,Unity,unity)