Unity开发2D类银河恶魔城游戏学习笔记
Unity教程(零)Unity和VS的使用相关内容
Unity教程(一)开始学习状态机
Unity教程(二)角色移动的实现
Unity教程(三)角色跳跃的实现
Unity教程(四)碰撞检测
Unity教程(五)角色冲刺的实现
Unity教程(六)角色滑墙的实现
Unity教程(七)角色蹬墙跳的实现
Unity教程(八)角色攻击的基本实现
Unity教程(九)角色攻击的改进
Unity教程(十)Tile Palette搭建平台关卡
Unity教程(十一)相机
Unity教程(十二)视差背景
Unity教程(十三)敌人状态机
Unity教程(十四)敌人空闲和移动的实现
Unity教程(十五)敌人战斗状态的实现
Unity教程(十六)敌人攻击状态的实现
Unity教程(十七)敌人战斗状态的完善
Unity教程(十八)战斗系统
如果你更习惯用知乎
Unity开发2D类银河恶魔城游戏学习笔记目录
文章目录
- Unity开发2D类银河恶魔城游戏学习笔记
- 前言
- 一、概述
- 二、骷髅退出战斗状态
- 三、玩家在骷髅背后时骷髅进入战斗状态
前言
本文为Udemy课程The Ultimate Guide to Creating an RPG Game in Unity学习笔记,如有错误,欢迎指正。
本节改进敌人的战斗状态。
Udemy课程地址
对应视频:
Finalize Battle State
一、概述
这一节我们将对骷髅的战斗状态做一些完善。
现在骷髅进入战斗状态后将一直保持在战斗状态。这一节我们要做的就是骷髅战斗时间过去或在玩家距离骷髅过远时,让骷髅退出战斗状态恢复空闲状态。
还有玩家在骷髅的背后靠近时,它检测不到玩家,不会进入战斗状态。因此我们要修改转到战斗状态的条件。
状态转换如下图:
二、骷髅退出战斗状态
增加一个变量,战斗状态持续时长battleTime。在此时长内如果骷髅检测到玩家,则进入前几节的处理流程并且重置计时器;如果没有检测到玩家则退出战斗状态转为空闲状态。
我们先改变一下关卡地图,方便验证。
在Enemy基类中添加新的变量battleTime
[Header("Move Info")]public float moveSpeed = 1.5f;public float idleTime = 2.0f;public float battleTime = 7.0f;
在SkeletonBattleState中添加如下代码:
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{if(stateTimer <0)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);
}
这样在战斗时长结束还检测不到玩家时,骷髅就可以恢复空闲状态了。
现在,战斗时长没结束时即使离得很远,骷髅依然处于战斗状态。
游戏中普遍都是距离过远时,怪物脱战。我们在战斗状态中添加这一条件。
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{if(stateTimer <0 || Vector2.Distance(enemy.transform.position,player.transform.position)>10)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);}
当检测不到玩家且距离过远时骷髅马上脱战,效果如下:
三、玩家在骷髅背后时骷髅进入战斗状态
现在玩家靠近骷髅背后时,骷髅不会作出反应。
我们可以在骷髅接地状态转到战斗状态的条件中,加上一条玩家和骷髅之间距离的判定。
在进入接地状态时先获取Player的Transform组件用以计算距离。这个操作会影响性能,在后续教程中会进行改进,但在这里我们先这么用着。
//SkeletonGroundedState:骷髅接地状态
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SkeletonGroundedState : EnemyState
{protected Enemy_Skeleton enemy;protected Transform player;public SkeletonGroundedState(EnemyStateMachine _stateMachine, Enemy _enemyBase, Enemy_Skeleton _enemy, string _animBoolName) : base(_stateMachine, _enemyBase, _animBoolName){enemy=_enemy;}public override void Enter(){base.Enter();//获取Player的Transform组件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.position) < 2)stateMachine.ChangeState(enemy.battleState);}
}
效果如下: