孙广东  2015.8.15

一、Enemy Aim Ai 
          目的: 这篇文章的主要目的是为了让您了解有关如何使用 Enemy Aim Ai 。你会得到结果:

Enemy aim AI是非常有用的,当你想要敌人一直监视player。适当争取对象在真实世界的场景,需要时间,所以敌人会采取一些之前它锁在目标系统上的时间量。

这种效应可以创建的 Lerping 旋转角度对玩家的敌人。这种情况是在动作游戏,敌人跟随,目的是何地然后射球员的情况下非常有用。对敌人遵循概念是在早些时候发布的博客中已经讨论过。在推行针对在游戏的同时,理解四元数的概念是非常必要的。

四元数存储对象的旋转,还可以计算价值取向。一个可以直接玩欧拉角,但可能会出现 万向锁 的情况。

根据当地的坐标系统,如果你旋转模型X 轴,然后其 Y 和 Z 轴经验万向节锁被"锁定"在一起。

现在回到我们的主题,给出了下面是一个简单的例子来解释 Enemy aim AI

按照下面给出的步骤。

1、创建Cube将作用在player control

  • 应用适当的材料,根据要求向其网格渲染器
  • 将 TargetMovementScript 应用于游戏对象
  • 将Cube 作为对象来将移动上 player'scommands。

TargetMovementScript.cs

public class TargetMovementScript : MonoBehaviour {
public float targetSpeed=9.0f;//Speed At Which the Object Should Move
void Update ()
transform.Translate (Input.GetAxis ("Horizontal")*Time.deltaTime*targetSpeed,Input.GetAxis ("Vertical")*Time.deltaTime*targetSpeed,0);
}
}

2、创建一个Enemy对象,由箭头和Cube组成,

1、应用适当的材料对Cube 。

2、使箭头Sprite作为一个不同的对象

3、其方向由 Cube指出 . 所以在这里,箭头将充当了敌人的枪。

4、此箭头将指向目标对象和它看起来就好像它试图锁定目标

5、我们也可以操纵速度,敌人将能够锁定目标属性 ;作为不同的敌人应该是不同的困难,以及不同的功能。
6、一辆坦克应采取更多的时间锁定一名士兵用枪瞄准。所以在其中之一可以锁定目标的速度应该是不同的。

EnemyAimScript.cs

public class EnemyAimScript : MonoBehaviour {public Transform target; // Target Object
public float enemyAimSpeed=5.0f; // Speed at Which Enenmy locks on the Target
Quaternion newRotation;
float orientTransform;
float orientTarget;
void Update () {
orientTransform = transform.position.x;
orientTarget = target.position.x;
// To Check on which side is the target , i.e. Right or Left of this Object
if (orientTransform > orientTarget) {
// Will Give Rotation angle , so that Arrow Points towards that target
newRotation = Quaternion.LookRotation (transform.position - target.position, -Vector3.up);
}
else {
newRotation = Quaternion.LookRotation (transform.position - target.position,Vector3.up);
}// Here we have to freeze rotation along X and Y Axis, for proper movement of the arrow
newRotation.x = 0.0f;
newRotation.y = 0.0f;// Finally rotate and aim towards the target direction using Code below
transform.rotation = Quaternion.Lerp (transform.rotation,newRotation,Time.deltaTime * enemyAimSpeed);// Another Alternative
// transform.rotation = Quaternion.RotateTowards(transform.rotation,newRotation, Time.deltaTime * enemyAimSpeed);
}
}

7、Hierarchy 和 Scene View 可能会像作为给定下面

备注:-

可以改变敌人目标并设置锁定目标的速度。

可以脚本通过允许X 或 Y 轴旋转,为了解这一概念的 。

可以给敌人添加Follow 脚本,以便敌人Follow 和 瞄准 玩家。

而不是使用 Quaternion.Lerp 你也可以使用 Quaternion.RotateTowards 达到相同的效果。

二、通过有限状态机实现AI

Contents Objective Step -

1: Set up the scene Step -

2: Create and place Game Objects Step -

3: Implement the BoxMovement Script Step -

4: FSM Modelled Script Step -

5: AI Script for the Box -

目的: 这篇文章的主要目的是要给你一个关于如何使用有限状态机模型在 实现 AI 。

FSM 的基础知识:
           在游戏中实施 AI  Finite State Machine Framework是完美的, 产生伟大的结果,而无需复杂的代码。   它是一个模型,由一个或多个状态。可以在一段时间只有一个单一的状态处于活动状态, 所以这台机器必须从一个状态到另一种的转换 为执行不同的操作。

有限状态机框架通常用于管理、 组织和 代表不同的状态、执行流,在游戏中实现人工智能是非常有用的。"brain"是敌人,例如,可以使用有限状态机来实现:   每个状态表示一个动作,例如 巡逻、 Chase、 逃避或拍摄或任何其他种类的行动。

AI FSMs 的工作与Unity的的Animation FSMs,在那里一个动画状态将更改为另一个符合的要求。可以通过使用第三方插件像行为实施 AI FSM 或它可以直接由脚本以及执行。

若要获取有限状态机框架的基本理念,我们将执行一个教程最简单的方法,使用 switch 语句。然后我们将学习如何使用一个框架,使 AI 实现易于管理和扩展。

请按照下面的步骤来执行简单的有限状态机。

在这里我们将会有两个Box,在那里将由玩家控制一个Box和 对方将由 AI 控制Box。此 AI 控制的Box会在chasing追逐状态或patrolling巡逻状态,即Box中将开始追逐Player Box,一旦Player Box进来的接近 AI 控制Box。它将切换回 巡逻状态,如果玩家足够远逃避  未未的定义的愿景。

Step - 1: Set up the scene

以一个平面和两个Box在场景中,如下图所示的设置。

Step - 2: Create and place Game Objects

创建空的游戏对象并将其作为游子点Wanderer Points。放置这些空的游戏对象下,为您选择平面周围。在这里蓝色的Cube是 AI Cube和红一个是玩家控制的Cube。将它们放在距离不够远。

Step - 3: Implement the BoxMovement Script

实现 BoxMovement 脚本来控制玩家的Cube的移动:如下:

public class BoxMovementScript : MonoBehaviour
{public float speed = 0.1f;private Vector3 positionVector3;void Update (){     InitializePosition ();if (Input.GetKey (KeyCode.LeftArrow)) {GoLeft ();}if (Input.GetKey (KeyCode.RightArrow)) {GoRight ();}if (Input.GetKey (KeyCode.UpArrow)) {GoTop ();}if (Input.GetKey (KeyCode.DownArrow)) {GoDown ();}RotateNow ();}private void InitializePosition (){positionVector3 = transform.position;}private void RotateNow (){Quaternion targetRotation = Quaternion.LookRotation (transform.position - positionVector3);transform.rotation = targetRotation;}private void GoLeft (){transform.position = transform.position + new Vector3 (-speed, 0, 0);         }private void GoRight (){transform.position = transform.position + new Vector3 (speed, 0, 0);}private void GoTop (){transform.position = transform.position + new Vector3 (0, 0, speed);}private void GoDown (){transform.position = transform.position + new Vector3 (0, 0, -speed);}
}

Step - 4: FSM Modelled Script

构建FSM模型脚本:

public class FSM : MonoBehaviour
{//Player Transformprotected Transform playerTransform;//Next destination position of the Boxprotected Vector3 destPos;//List of points for patrollingprotected GameObject[] pointList;protected virtual void Initialize (){}protected virtual void FSMUpdate (){}protected virtual void FSMFixedUpdate (){}void Start (){Initialize ();}void Update (){FSMUpdate ();}void FixedUpdate (){FSMFixedUpdate ();}
}

Step - 5: AI Script for the Box

构建 AI 脚本作为Box扩展.

public class BoxFSM : FSM
{public enum FSMState{None,Patrol,Chase,}//Current state that the Box is inpublic FSMState curState;//Speed of the Boxprivate float curSpeed;//Box Rotation Speedprivate float curRotSpeed;//Initialize the Finite state machine for the  AI Driven Boxprotected override void Initialize (){curState = FSMState.Patrol;curSpeed = 5.0f;curRotSpeed = 1.5f;              //Get the list of pointspointList = GameObject.FindGameObjectsWithTag ("WandarPoint");//Set Random destination point for the patrol state firstFindNextPoint ();//Get the target enemy(Player)GameObject objPlayer = GameObject.FindGameObjectWithTag ("Player");playerTransform = objPlayer.transform;if (!playerTransform)print ("Player doesn't exist.. Please add one " + "with Tag named 'Player'");}//Update each frameprotected override void FSMUpdate (){switch (curState) {case FSMState.Patrol:UpdatePatrolState ();break;case FSMState.Chase:UpdateChaseState ();break;}}protected void UpdatePatrolState (){//Find another random patrol point on reaching the current Point //point is reachedif (Vector3.Distance (transform.position, destPos) <= 2.5f) {print ("Reached to the destination point\n" + "calculating the next point");FindNextPoint ();}//Check the distance with player Box//When the distance is near, transition to chase stateelse if (Vector3.Distance (transform.position, playerTransform.position) <= 15.0f) {print ("Switch to Chase State");curState = FSMState.Chase;}//Rotate to the target pointQuaternion targetRotation = Quaternion.LookRotation (destPos - transform.position);transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, Time.deltaTime * curRotSpeed);//Go Forwardtransform.Translate (Vector3.forward * Time.deltaTime * curSpeed);}protected void FindNextPoint (){print ("Finding next point");int rndIndex = Random.Range (0, pointList.Length);float rndRadius = 5.0f;Vector3 rndPosition = Vector3.zero;destPos = pointList [rndIndex].transform.position + rndPosition;//Check Range to Move and decide the random point//as the same as beforeif (IsInCurrentRange (destPos)) {rndPosition = new Vector3 (Random.Range (-rndRadius, rndRadius), 0.0f, Random.Range (-rndRadius, rndRadius));destPos = pointList [rndIndex].transform.position + rndPosition;}}protected bool IsInCurrentRange (Vector3 pos){float xPos = Mathf.Abs (pos.x - transform.position.x);float zPos = Mathf.Abs (pos.z - transform.position.z);if (xPos <= 8 && zPos <= 8)return true;return false;}protected void UpdateChaseState (){//Set the target position as the player positiondestPos = playerTransform.position;//Check the distance with player Box Whenfloat dist = Vector3.Distance (transform.position, playerTransform.position);//Go back to patrol as player is now too farif (dist >= 15.0f) {curState = FSMState.Patrol;FindNextPoint ();}//Rotate to the target pointQuaternion targetRotation = Quaternion.LookRotation (destPos - transform.position);transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, Time.deltaTime * curRotSpeed);//Go Forwardtransform.Translate (Vector3.forward * Time.deltaTime * curSpeed);}
}
此脚本适用于Cube是要跟随玩家,不要忘记把player标记Tag为 Player 和 Tag 为 WandarPoint,现在如 FSMUpdate() 所示的脚本将调用方法,这在子类中重写和它将在每个 update () 上执行。
在这里switch case被实施 将用于执行的当前状态的操作。 因此扩展 AI 是很简单的仅仅通过添加新的state。Initialize() 方法也重写,并将在 start () 方法中调用执行。UpdatePatrolState() 将在每次更新上执行,当当前状态是patrol 周围巡逻,也将会发生在 UpdateChaseState(),当玩家在接近度 AI Box。如果当处于巡逻,玩家进来的 AI Box中,状态将更改为 巡逻,相同 类型的检查仍在  追逐模式检查如果球员已远离其视野范围, 然后切换回巡逻状态, 在每个更新,检查状态更改。
结论:
FSM 的很容易理解和实现,Fsm 可以用于执行复杂的 AI 。他们也可以表示使用图,允许开发人员很容易理解,因此开发人员可以调整、 改变和优化的最终结果。有限状态机使用的函数或方法来代表状态执行是简单、 功能强大、 易于扩展。  可以使用基于堆栈的状态机,确保易于管理和稳定的 执行流,而不会产生消极影响的代码应用甚至更复杂的 AI。 所以让你的敌人更聪明使用有限状态机,让您的游戏的成功。

Unity 内的敌人AI 或者 有限状态机FSM实现AI相关推荐

  1. 游戏 AI 设计之 FSM 有限状态机

    FSM 有限状态机 一.概述 有限状态机(finite-state machine,缩写:FSM)又称有限状态自动机(finite-state automaton,缩写:FSA),简称状态机,是表示有 ...

  2. 9.Unity2D 横版 简单AI 之 敌人跳跃条件优化+自动范围内检测敌人发起攻击(索敌)+对象池优化+主角受伤死亡

    总目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482 1.动画animation和动画 ...

  3. Unity进阶第三章-有限状态机FSM(三种方法实现角色动画操作)

    一.有限状态机FSM概述 二.不用有限状态机实现角色的走路.攻击动作 (1)新建角色.地面.为角色添加动画 (2)为角色添加脚本 using System.Collections; using Sys ...

  4. Cocos Creator 超简洁代码实现有限状态机 FSM,打造丝滑角色动作

    引言:本文作者黄聪是一名在校大学生,设计毕设的过程中,他参考<游戏编程模式>一书,摸索出了一套角色动作控制方案. 作为一名在校学生,前段时间在做毕业设计的过程中,我也遇到了很多同学都会遇到 ...

  5. 有限状态机FSM(finite state machine) 二

    有限状态机FSM(finite state machine) 二 延续上一篇继续有限状态机 上一篇中的状态切换判断是在每一个状态类的 OnExecute 方法中各种 if else 硬编码逻辑 当状态 ...

  6. Unity内置的三套消息发送机制的应用实例

    转自http://blog.sina.com.cn/s/blog_1491e52310102wuf6.html 代码简介 : [1] 实例中包含2个类文件, SendMessage.cs 和 Rece ...

  7. 在Unity内利用混融公式剔除背景颜色导出透明PNG以及半透明遮挡相关问题的研究

    最近听到了一个想法,是将Unity内的一些特效进行截图,导出带透明度的png用于视频制作,于是回顾了一下以前研究过的混融相关的问题,研究了一下如何实现,也学到了一些新的技巧和知识. 混融公式 (图1: ...

  8. Unity 内置着色器下载方法

    Unity 内置着色器下载方法 官方下载 GitHub下载 官方下载 需要科学上网 官方下载链接 https://unity3d.com/get-unity/download/archive GitH ...

  9. Unity内IAP支付二次验证/服务器验证————最白话,手把手教你做系列。

    之前的一篇写了Unity支付的IAP支付接入. 后来就出现了一些问题,数据统计的时候出现大量购买订单.但是实际上账户的钱却没有增加.@¥--&¥--*@¥&@初步判定可能存在部分用户通 ...

最新文章

  1. 让一个 csproj 项目指定多个开发框架
  2. 【Linux】 Kill 批量杀死进程
  3. 鸿蒙之下5怎么跳城池,鸿蒙之空间道尊
  4. WPF 用Popup做下拉菜单
  5. 【MFC系列-第25、26天】绘图软件
  6. protected访问权限_权限修饰符 /重写
  7. 培训机构还能不能信任?
  8. php mysql 字段自增_MySQL自增字段取值的详细介绍(附代码)
  9. Java添零右移_为什么Java中的整数为-1零填充右移1 = 2147483647?
  10. MATLAB Simulink 中的过零检测与代数环
  11. 计算机化分析原理波涛,(波涛)证券期货投资计算机化技术分析原理OCR.pdf
  12. 用PyTorch完成手写数字识别
  13. Linux TTY 串口 struct termios结构体参数
  14. pic由c语言和汇编语言,单片机教程:PIC单片机C语言程序设计(二)
  15. 【拉格朗日差值法】 公式
  16. mysql数据库配置步骤,MySQL数据库安装配置步骤详解
  17. php气泡效果,ps简单制作漂亮的人物气泡效果
  18. oracle将汉字转为全拼或返回拼音首字母sql
  19. #发现你#小说的交互——交互故事性
  20. 葵花宝典——放入word中

热门文章

  1. 我爱软件人*爱软件人
  2. orcad capture cis 原理图库元件封装更新design cache
  3. HTTP Client Post 和 Get 方式(新手使用)
  4. Android BLE低功耗蓝牙开发(下) BLE客户端(中央设备)与GATT服务的通讯
  5. OpenCV学习笔记(16)双目测距与三维重建的OpenCV实现问题集锦(一)图像获取与单目定标
  6. MySQL函数之DATE_SUB,CURDATE等使用记录
  7. 第一次前端培训(HTML基础)
  8. 人工智能+音乐的探索:从洛天依到小冰初窥歌唱合成
  9. html相册翻页效果图,js实现相册翻页,滚动,切换,轮播功能
  10. 如何做一碗完美的葱油拌面?