Unity类银河恶魔城学习记录3-6 Finalize BattleState源代码 P52

本文详细介绍了Unity教程中的敌方类Enemy的实现,包括状态机、移动、攻击逻辑以及与玩家交互的部分。主要涉及敌机检测玩家、状态转换和攻击冷却机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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


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

public class Enemy : Entity
{
    [SerializeField] protected LayerMask whatIsPlayer;
    [Header("Move Info")]
    public float moveSpeed;
    public float idleTime;
    public float battleTime;//多久能从battle状态中退出来
    [Header("Attack Info")]
    public float attackDistance;
    public float attackCooldown;//攻击冷却
    [HideInInspector]public float lastTimeAttacked;//最后一次攻击的时间
    #region 类
    public EnemyStateMachine stateMachine;
    
    #endregion

    protected override void Awake()
    {
        base.Awake();
        stateMachine = new EnemyStateMachine();
        
    }
    protected override void Start()
    {
        base.Start();
       
    }


    protected override void Update()
    {
        base.Update();

        stateMachine.currentState.Update();
        
        //Debug.Log(IsPlayerDetected().collider.gameObject.name + "I see");//这串代码会报错,可能使版本的物体,因为在没有找到Player的时候物体是空的,NULL,你想让他在控制台上显示就报错了
    }

    
    public virtual void AnimationFinishTrigger() => stateMachine.currentState.AnimationFinishTrigger();//动画完成时调用的函数,与Player相同
    public virtual RaycastHit2D IsPlayerDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, 7, whatIsPlayer);//用于从射线投射获取信息的结构。
    //该函数的返回值可以变,可以只返回bool,也可以是碰到的结构

    protected override void OnDrawGizmos()
    {
        base.OnDrawGizmos();

        Gizmos.color = Color.yellow;
        Gizmos.DrawLine(transform.position, new Vector3(transform.position.x + attackDistance * facingDir, transform.position.y));
    }


}
SkeletonGroundState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SkeletonGroundState : EnemyState
{
    protected Enemy_Skeleton enemy;
    protected Transform player;
    public SkeletonGroundState(Enemy _enemyBase, EnemyStateMachine _stateMachine, string _animBoolName,Enemy_Skeleton _enemy) : base(_enemyBase, _stateMachine, _animBoolName)
    {
        enemy = _enemy;
    }

    public override void Enter()
    {
        base.Enter();
        player = GameObject.Find("Player").transform;
    }

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

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

        if(enemy.IsPlayerDetected()||Vector2.Distance(enemy.transform.position,player.transform.position)<2)
        {
            stateMachine.ChangeState(enemy.battleState);
        }
    }
}
SkeletonBattleState.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
//从ground进来的
public class SkeletonBattleState : EnemyState
{
    private Transform player;//用于给Player定位,好判断怎么跟上他
    private Enemy_Skeleton enemy;
    private int moveDir;
    public SkeletonBattleState(Enemy _enemyBase, EnemyStateMachine _stateMachine, string _animBoolName,Enemy_Skeleton _enemy ) : base(_enemyBase, _stateMachine, _animBoolName)
    {
        enemy = _enemy;
    }

    public override void Enter()
    {
        base.Enter();
        
        player = GameObject.Find("Player").transform;//全局找Player位置
    }

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

    public override void Update()
    {
        base.Update();
        //退出此状态的方式
        if(enemy.IsPlayerDetected())
        {
            stateTimer = enemy.battleTime;
            if (enemy.IsPlayerDetected().distance < enemy.attackDistance)//当距离小于攻击距离,变为攻击状态
            {
                if (CanAttack())
                    stateMachine.ChangeState(enemy.attackState);
            }
        }
        else//当没有看见player后,才会根据没有看到的时间来使其退出battle状态
        {
            if(stateTimer < 0||Vector2.Distance(player.transform.position,enemy.transform.position)>7)//根据距离来判断是否结束battle状态
            {
                stateMachine.ChangeState(enemy.idleState);
            }
        }
        

        //下面为移动方向设置
        if(player.position.x > enemy.transform.position.x)//在右,向右移动
        {
            moveDir = 1;
        }
        else if(player.position.x<enemy.transform.position.x)//在左,向左移动
        {
            moveDir = -1;
        }

        enemy.SetVelocity(enemy.moveSpeed * moveDir, rb.velocity.y);
    }

    private bool CanAttack()
    {
        if(Time.time > enemy.lastTimeAttacked + enemy.attackCooldown)
        {
            enemy.lastTimeAttacked = Time.time;
            return true;
        }
        Debug.Log("Attack is on cooldown");
        return false;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值