做网站基本要求,一般通过486,在godaddy做网站贵吗,经营类网站备案文章目录 1 项目介绍2 模块介绍2.1 BaseState2.2 ...State2.2.1 PatrolState2.2.2 ChaseState / AttackState / BackState 2.3 StateMachine2.4 Monster 3 其他功能4 类图 项目借鉴 B 站唐老狮 2023年直播内容。
点击前往唐老狮 B 站主页。 1 项目介绍
本项目使用 Unity 2… 文章目录 1 项目介绍2 模块介绍2.1 BaseState2.2 ...State2.2.1 PatrolState2.2.2 ChaseState / AttackState / BackState 2.3 StateMachine2.4 Monster 3 其他功能4 类图 项目借鉴 B 站唐老狮 2023年直播内容。
点击前往唐老狮 B 站主页。 1 项目介绍
本项目使用 Unity 2022.3.32f1c1实现基本的 AI 框架。其中用 Cube绿色代替怪物模型Cube红色代替玩家即 AI 目标。 项目地址https://github.com/zheliku/StateMachine_AI。
2 模块介绍
2.1 BaseState
在框架介绍的基础上添加了两个方法 DistanceOfXZ(Vector3, Vector3) 用于计算 xz 平面上的距离不考虑 y 轴方向。 DrawGizmos() 用于辅助绘制范围在 Scene 窗口中显示。
using UnityEngine;/// summary
/// 状态基类
/// /summary
public abstract class BaseState
{public virtual EAIState AIState { get; } // 状态类型protected StateMachine _stateMachine; // 附属的状态机public BaseState(StateMachine stateMachine) {_stateMachine stateMachine;}public abstract void OnStateEnter();public abstract void OnStateUpdate();public abstract void OnStateExit();/// summary/// 辅助绘制范围不强制重写/// /summarypublic virtual void DrawGizmos() { }/// summary/// XZ 平面上的距离/// /summaryprotected float DistanceOfXZ(Vector3 pos1, Vector3 pos2) {pos1.y pos2.y 0;return Vector3.Distance(pos1, pos2);}
}2.2 …State
项目实现了 4 种 AI 状态包括
PatrolState巡逻状态ChaseState追逐状态AttackState攻击状态BackState返回状态
2.2.1 PatrolState
PatrolState 实现较为详细其将巡逻方式分为 3 种
public enum EPatrolType
{Stay, // 原地播放某个动作睡觉、放哨等CircleMove, // 圆形范围内随机移动PathMove // 按照路径移动
} 巡逻数据可以直接在 PatrolState 类中声明。本项目选择封装在 PatrolStateData 中。所有 Data 均继承 ScripteObject 类可以在 Project 窗口中右键直接创建并配置对应数据。 PatrolStateData所有巡逻种类的共有数据。 PatrolStateStayData原地巡逻的数据。 PatrolStateMoveData移动巡逻的数据。 PatrolStateCircleMoveData圆形范围移动巡逻的数据。 PatrolStatePathMoveData路径移动巡逻的数据。 Stay 原地播放某个动作因此需要 AI 动作枚举。目前只添加 Sleep 动作。 public enum EAction
{Sleep,
}Move 范围内随机移动分为两种Circle、Path。区别是获取下一次目标位置的方式不同因此提取出如下逻辑 public class PatrolState : BaseState
{private PatrolStateData _data; // 巡逻数据.../// summary/// 移动/// /summaryprivate void OnMoveUpdate(IAIObject aiObject, EPatrolType moveType) {var data (PatrolStateMoveData)_data; // 转化数据..._data.targetPos moveType switch {EPatrolType.CircleMove CalCircleTargetPos((PatrolStateCircleMoveData)data),EPatrolType.PathMove CalPathTargetPos((PatrolStatePathMoveData)data),_ throw new ArgumentOutOfRangeException(nameof(moveType), moveType, null)};...}/// summary/// 更新圆形范围目标位置/// /summaryprivate Vector3 CalCircleTargetPos(PatrolStateCircleMoveData data) { ... }/// summary/// 更新路径范围目标位置/// /summaryprivate Vector3 CalPathTargetPos(PatrolStatePathMoveData data) { ... }...
}2.2.2 ChaseState / AttackState / BackState
该 3 个状态都遵循以下大致框架
using UnityEngine;public class ...State : BaseState
{private ...StateData _data;public override EAIState AIState { get ...; }public AttackState(StateMachine stateMachine) : base(stateMachine) {// 加载数据var data Resources.Load...StateData(StateData/.../...StateData);_data Object.Instantiate(data);}public override void OnStateEnter() { ... }public override void OnStateUpdate() { ... }public override void OnStateExit() { ... }...
}2.3 StateMachine
AddState()、ChangeState() 和 UpdateState() 逻辑如下
/// summary
/// 添加 AI 状态
/// /summary
public void AddState(EAIState state) {switch (state) {case EAIState.Patrol:_stateDic.Add(state, new PatrolState(this));break;case EAIState.Back:_stateDic.Add(state, new BackState(this));break;case EAIState.Chase:_stateDic.Add(state, new ChaseState(this));break;case EAIState.Attack:_stateDic.Add(state, new AttackState(this));break;default: throw new ArgumentOutOfRangeException(nameof(state), state, null);}
}/// summary
/// 切换状态
/// /summary
/// param namestate/param
public void ChangeState(EAIState state) {_nowState?.OnStateExit(); // 退出状态if (_stateDic.TryGetValue(state, out BaseState nowState)) { // 进入状态_nowState nowState;_nowState.OnStateEnter();}
}/// summary
/// 更新当前状态
/// /summary
public void UpdateState() {_nowState?.OnStateUpdate();_nowState?.DrawGizmos(); // 辅助绘图
}
2.4 Monster
怪物类实现了 IAIObject 接口详见 2024-07-12 Unity AI状态机1 —— 框架介绍通过 Unity 导航系统中的 NavMeshAgent 实现基本移动。除了 IAIObject 接口还包含一些自己的数据。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;public class Monster : MonoBehaviour, IAIObject
{public Transform targetTransform; // 目标位置public GameObject bullet; // 子弹public float attackRange 3; // 攻击范围private Quaternion _startRotation; // 记录开始攻击时的角度private Quaternion _targetRotation; // 记录目标角度private float _rotateTime; // 旋转计时private NavMeshAgent _navMeshAgent; // 导航代理private StateMachine _aiMachine; // AI 状态机private void Start() {_navMeshAgent GetComponentNavMeshAgent();BornPos transform.position;_aiMachine new StateMachine();_aiMachine.Init(this);// 为 AI 添加巡逻状态_aiMachine.AddState(EAIState.Patrol);_aiMachine.AddState(EAIState.Chase);_aiMachine.AddState(EAIState.Attack);_aiMachine.AddState(EAIState.Back);// 更改初始状态_aiMachine.ChangeState(EAIState.Patrol);}private void Update() {_aiMachine.UpdateState();}#region IAIObject 接口实现...#endregion
}3 其他功能
为了辅助绘图为 BaseState 添加了 DrawGizmos() 方法virtual子类可以实现该方法在 Scene 窗口中绘制辅助线。同时在 BaseState 中添加 DistanceOfXZ() 方法以便所有状态都可使用。以下是 BaseState 的全部逻辑
using UnityEngine;/// summary
/// 状态基类
/// /summary
public abstract class BaseState
{public virtual EAIState AIState { get; } // 状态类型protected StateMachine _stateMachine; // 附属的状态机public BaseState(StateMachine stateMachine) {_stateMachine stateMachine;}public abstract void OnStateEnter();public abstract void OnStateUpdate();public abstract void OnStateExit();/// summary/// 辅助绘制范围不强制重写/// /summarypublic virtual void DrawGizmos() { }/// summary/// XZ 平面上的距离/// /summaryprotected float DistanceOfXZ(Vector3 pos1, Vector3 pos2) { ... }
} 辅助绘图时使用 Unity Asset Store 中的插件 DrawXXL 实现例如 ChaseState 中的 DrawGizmos 如下
public override void DrawGizmos() {var aiObject _stateMachine.AIObject;// 绘制攻击范围DrawShapes.Circle(aiObject.Transform.position, aiObject.AttackRange, Color.red,Vector3.up, lineWidth: 0.05f);// 绘制脱离范围DrawShapes.Circle(aiObject.Transform.position, _data.chaseDistance, new Color(1, 0.5f, 0),Vector3.up, lineWidth: 0.05f, outlineStyle: DrawBasics.LineStyle.dotted);
}4 类图