使用Unity制作游戏AI

本文由独立游戏工作室Synnaxium Studio介绍游戏AI的概念和开发方法。本文中所有内容都是他们在开发《Radiant Blade》游戏的原型阶段所积累的经验。

下面是《Radiant Blade》的演示画面。

使用游戏AI的原因

首先,我们要思考为什么要给游戏添加AI?

长期以来,我们都在幻想着为游戏开发令人惊奇的AI,让AI给玩家带来印象深刻的体验。这种AI可以预料到玩家的每一个操作,几乎无法被打败。但说实话,这种AI毫无对抗的乐趣。

值得玩家去玩的游戏应该是玩家可以获得乐趣的游戏。因此,AI必须可以和玩家旗鼓相当。AI可以作为伙伴,让玩家通过特别的方法进行交互。

显然,只有乐趣的游戏不会是一个优秀的游戏。游戏也必须有炫酷的机制,深刻的含义以及精美的外观。但对AI而言,我们希望AI具有娱乐性,因此我们要进一步缩小这个概念的范围。

游戏设计

游戏中的娱乐性是什么?我们的开发团队花了一些时间思考这个问题,结论可以总结为一个词:学习,具备娱乐性的游戏是玩家可以从中学习和利用知识的游戏。

娱乐性源于小小的好奇心,在玩家看到新事物时,好奇心会占据玩家的头脑,并会不断增长,直到玩家完全理解这项新事物。也就是说,具有娱乐性的AI必须是可以被玩家学习的。

这个简单的概念形成了所有游戏中AI的广泛解读,包括:《超级玛丽》、《毁灭战士》、《魔兽世界》和《以撒的结合》。如果分析这些游戏的AI,我们会发现它们都是可以预测的。

由于加入了一些随机元素,这些游戏AI不是完全固定不变的,但仍有预测的可能。这样又出现了另一个问题:如何制作出可预测的游戏AI?

答案很简单:使用状态机

状态机

状态机是包含状态和过渡的数学工具。
 

基本的状态机


在确定性状态机中,我们会处于一个特定状态,在移动时,我们会随着其中一个可用过渡转变到新状态。过渡可能会受到条件限制,例如:只有在拥有特定法术时,AI才可以到达指定状态。

状态机的优点是:它们具有表现力和可预测性。假设状态包括“攻击”、“受击”、“奔跑至目标”和“逃跑”,我们可以使用一些过渡,创建出模拟AI基本行为的状态机。

下面是简单的AI示例。
 


我们制作开发的AI可以用下面三句话描述:

如果AI的生命值在10%以下时,它就会逃跑。

AI可以受到攻击。

玩家处在AI范围内时,AI会向玩家跑去,然后攻击玩家。

这意味着我们的AI很简单。如果无法简单地描述自己设计的AI,那么我们可能需要对自己的AI做进一步思考。

状态机与Unity

我们在Unity使用状态机大致的方法有三种:
 

  • 自己开发。
  • 使用Animator实现。
  • 从Asset Store资源商店获取相应资源。



状态机是游戏中很常见的工具,所以我们不建议开发者自己编写代码开发状态机。除非开发者希望学习如何通过编码实现状态机,否则我们可以获取可直接使用的状态机。

第二种方法是使用Unity的内置Animator功能,它其实是一种可以播放动画的状态机。但在Animator中,我们不一定要使用动画,如果不使用动画的话,它的工作方式和状态机一样。

Animator使用起来快捷而直观。下图是《Radiant Blade》中使用Unity Animator实现的弓箭手AI。
 


第三种方法是从Asset Store资源商店获取相关资源,不少资源有和Animator一样不错的效果。


Animator

或许你使用过Animator在Unity中实现标准动画,但我们会根据需求调整一些方法。

状态

通常,Animator的状态包含动画。我们没有这样使用,而是把状态关联到描述行为的代码。

为了展示这个方法,我们现在查看定义弓箭手的游戏对象。Behaviours对象的子对象是AI行为,它们其实是小型控制器,在对应状态激活时,它们会控制弓箭手。

在Shoot状态激活时,会在弓箭手上使用Shoot Behaviour脚本。
 


这是基于状态的对象。在完成行为后,Shoot Behaviour会通知Animator。Animator内置的蓝色进度条可能会让人迷惑,但它只在外观上起到作用。

变量

我们的AI设计是响应式系统,它会随条件而变化,条件是玩家和环境。

Animator的变量用于描述游戏的状态,以及作出已知决策。下图是弓箭手使用的变量,它们描述了形成AI的所有要素。
 


在以传统方法使用Animator时,大多数状态过渡会随着关联动画结束而结束。对于AI来说,状态就是行为,它会在未定义的时间内保存游戏逻辑。

我们使用了两个变量behaviour_ended和behaviour_error,作用是通知状态的结束。它们是状态的输出结果,表示状态成功结束,或是出现错误。

过渡

过渡定义了AI行为的改变过程。例如,过渡可以表示:当AI完成向目标行走的过程后,它应该要做什么。

下图是示例过渡:如果目标在近战范围内,AI会进行攻击。
 


对Unity的Animator,有些开发者可能不知道的是:过渡是有先后顺序的。特定过渡会被首先评估,仅在它的相关条件为假时,第二个过渡才会进行评估。

如下图所示,选中Neutral状态时,我们可以查看过渡的优先级。
 


这项功能很不错,它允许我们把AI设计为中心大脑,根据优先级来作出合适的选择。

在我们的弓箭手AI中,需要注意AI的顺序和中心部分。Neutral节点是决策中心,它的主要工作过程如下:
 

  • 如果没有玩家的话,AI停止战斗;
  • 如果玩家距离较远,AI向玩家移动,进入射击范围;
  • 如果玩家不在AI的视线方向,AI向玩家移动,从而能够进行射击;
  • 如果处于近战范围,则进行近战攻击;
  • 如果玩家过于接近AI,AI可能会向后退;
  • AI有可能随机改变和玩家的方向;
  • AI会向玩家射击。



该功能的好处是每个单独的过渡都非常简单:过渡会归结为一次测试,或甚至不进行测试。使用后续过渡的前提是之前的过渡条件必须为假。

实现方法

现在,我们开始了解具体操作。你应该会注意到,我们还未提供过任何相关代码。

这意味着我们的框架有足够高的抽象级,不必处理任何技术细节,就可以很好进行解释。在代码部分完成后,设计AI的过程非常直观。

我们需要什么

下面是实现AI的三个任务:

编写AI行为。

将Animator和可用行为关联。

为Animator更新游戏相关变量的列表。

行为

开始处理前,回顾行为的功能:

行为会和游戏的角色控制器配合使用。

行为可以被识别。

行为可以被启用。

行为可以成功完成。

行为也可以出现错误。

行为可以被中断。

现在我们知道了想要的功能,我们要把它编写为API。
 

  1. public abstract class AbstractAIBehaviour : MonoBehaviour {
  2.     // 角色由行为控制
  3.     [SerializeField]
  4.     protected CharController charController;
  5.     // 必须返回对应行为的Animator状态的短哈希值。
  6.     abstract public int GetBehaviourHash();
  7.     // 在行为成功结束时调用的事件。
  8.     public event Action OnBehaviourEnded;
  9.     // 在行为失败时,要调用的事件
  10.     public event Action OnBehaviourError;
  11.     // OnDisable()
  12.     // enable = true/false;
  13. }
复制代码


对于启用和禁用部分,我们会利用Unity的内置方法,这里不必自己编写方法。我们会使用简洁的API。

对于识别符,我们创建了带有特殊名称的方法:GetBehaviourHash。因为Animator状态的识别方式是:使用状态的标识符,也就是其名称的哈希值。

因此对于Shoot状态,对应的标识符是Animator.StringToHash(“Shoot”)。

为了弄清楚对象,避免再次计算相同的哈希值,我们可以把它们保存为静态变量:
 

  1. /**
  2. *该类是预计算哈希值的占位符。
  3. * 目的是创建Animator状态名称和AI行为之间的关联。
  4. * 下面定义的整数应该用于GetBehaviourHash中继承自AbstractAIBehaviour的类。
  5. */
  6. public class BehaviourHashes {
  7.     //该行为会让角色向目标移动。
  8.     static public readonly int OBJ_MOVETO_STATE = Animator.StringToHash("Obj MoveTo");
  9.     // 该行为会让角色什么都不做。
  10.     static public readonly int IDLE_STATE = Animator.StringToHash("Idle");
  11.     // 此时角色会漫无目的地四处移动。
  12.     static public readonly int ROAM_STATE = Animator.StringToHash("Roam");
  13.    
  14.     // ...
  15. }
复制代码


考虑到这点,AbstractAIBehaviour的实现代码如下。
 

  1.   // 必须返回对应行为的Animator状态的短哈希值。
  2.     public override int GetBehaviourHash()
  3.     {
  4.         // State name in the Animator is “Idle”
  5.         // Animator中的状态名称为Idle。
  6.         return BehaviourHashes.IDLE_STATE;
  7.     }
复制代码


我们将每个哈希值存到对应的脚本中,因此ROAM_STATE可以保存在RoamBehaviour类中。

唯一的问题是手游账号购买平台,由于我们暗中把每个行为关联到名称,因此打开每个行为类收集Animator状态的授权名称可能很麻烦。

现在,我们的工作是为真实行为编写实际的代码,我们需要做的是实现AbstractAIBehaviour的子类。

关联行为和Animator

我们的AI的行为可以被识别、监听、启用和禁用,现在我们要利用行为。

我们从控制器开始。由于我们有多个彼此独立的实体,因此我们需要同步它们,从而实现流畅的工作效果。该控制器的目的是确保每次只启用一个行为,并提供修改当前行为的切入点。

一些开发者可能不知道应该何时给游戏添加新控制器的类。好的习惯是把控制器看作用来同步多个较小功能的代码。

  1. /**
  2. * AIBehaviourController应该关联AI的Animator和相应行为。
  3. */
  4. public class AIBehaviourController
  5.     /**
  6.      * 这部分包含可用行为
  7.      *
  8.      * 行为的关键是GetBehaviourHash方法返回的数值
  9.      */
  10.     protected Dictionary<int, AbstractAIBehaviour> behaviours = new Dictionary<int, AbstractAIBehaviour>();
  11.     // AI的Animator
  12.     private Animator stateMachine;
  13.     // 该变量表示正在执行的行为
  14.     private AbstractAIBehaviour currentBehaviour;   
  15.    
  16.     // 下面是必须存在AI  Animator中的触发器
  17.     public static readonly int BEHAVIOUR_ENDED = Animator.StringToHash("behaviour_ended");
  18.     public static readonly int BEHAVIOUR_ERROR = Animator.StringToHash("behaviour_error");
  19.     /**
  20.      * 强制某个行为中断正在执行的行为
  21.      */
  22.     public void SetBehaviour(int behaviorHash)
  23.     {
  24.         // 安全地禁用当前行为
  25.         if (currentBehaviour)
  26.             currentBehaviour.enabled = false;
  27.         try
  28.         {
  29.             // 开始新的行为
  30.             currentBehaviour = behaviours[behaviorHash];
  31.             currentBehaviour.enabled = true;
  32.         }
  33.         catch (KeyNotFoundException)
  34.         {
  35.             currentBehaviour = null;
  36.         }
  37.     }
  38.     void Awake()
  39.     {
  40.         stateMachine = GetComponent<Animator>();
  41.        // 对于每个子对象
  42.         foreach (AbstractAIBehaviour behaviour in GetComponentsInChildren<AbstractAIBehaviour>())
  43.         {
  44.             // 注册行为
  45.             behaviours.Add(behaviour.GetBehaviourHash(), behaviour);
  46.             // 监听行为
  47.             behaviour.OnBehaviourEnded += OnBehaviourEnded;
  48.             behaviour.OnBehaviourError += OnBehaviourError;
  49.         }
  50.     }
  51.     /**
  52.      * 在行为结束时,通知AI的Animator
  53.      */
  54.     private void OnBehaviourEnded()
  55.     {
  56.         stateMachine.SetTrigger(BEHAVIOUR_ENDED);
  57.     }
  58.     /**
  59.      * 在行为失败时,通知AI的Animator
  60.      */
  61.     private void OnBehaviourError()
  62.     {
  63.         stateMachine.SetTrigger(BEHAVIOUR_ERROR);
  64.     }
  65. }
复制代码


这个类比较长,但是代码其实很简单:
 

  • 字典包含我们已知的行为。
  • 方法可以激活特定行为。
  • 两个事件用于在行为结束时通知Animator。



有了切入点,我们可以把它和Animator连接起来。我们会使用一个不常用的功能:StateMachineBehaviour。

如下图所示,选中Animator时,如果在空白处单击左键,我们会聚焦Animator本身,并显示Animator的隐藏检视窗口。
 


StateMachineBehaviour允许我们向Animator插入自定义代码。我们会在Animator的状态变化时,调用我们的AIBehaviourController。
 

  1. /**
  2. * 该类会插入AI的Animator。
  3. *
  4. * 它的唯一作用是监视Animator中的状态转换。
  5. */
  6. public class AIStateController : StateMachineBehaviour {
  7.    
  8.     /**
  9.      * 在Animator进入新状态时,通知AI控制器。
  10.      */
  11.     override public void OnStateEnter(Animator animator, AnimatorStateInfo info, int layerIndex)
  12.     {
  13.         if (!animator.GetComponent<AIBehaviourController>().SetBehaviour(animatorStateInfo.shortNameHash))
  14.         {
  15.             // 如果状态不存在,那么把它设为决策中心。
  16.             // 强制Animator直接评估该状态。
  17.             animator.Update(0f);
  18.         }
  19.     }
  20. }
复制代码


这些代码非常直观,它会处理Unity的一个特别之处:Animator无法在每帧处理多个状态,因此在我们遍历决策中心时,会造成短暂的延迟。

幸运的是,解决方法很简单,我们可以强行执行Update方法,强制Animator处理状态。

通过使用我们的新类,我们可以把功能结合起来,只要把该脚本添加到AI的Animator即可。现在进入新状态时,我们的AI Animator会调用AIBehaviourController。
 


最后,我们在框架中包含三个类,子类以及一个角色控制器,它们包含着实际的游戏逻辑。

下图是一个组合成AI框架的小型类图示。
 


处理游戏逻辑

总而言之,技术解决方案可以总结为三个类,每个类都非常简洁。

我们还需要什么呢?当然是游戏本身了。但这个部分必须由开发者自己制作,实现自己的AI需要的内容如下:

一个角色控制器,负责角色和其渲染的实际逻辑。

变量以及让变量与Animator保持同步的代码。

自定义行为,例如:攻击,移动。



此时我们要处理的都是常见的Unity标准代码。
 


小结

如何在Unity中制作游戏AI的方法为大家介绍到这里,行动起来,在你的游戏中,实现自定义行为的AI吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/60698.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Novel AI】使用绘画AI构建unity游戏资源

请勿在商业用途中使用下面的示例图中的任何资源&#xff01; 1. 设想&#xff1a; 首先根据自己的设想&#xff0c;创造一些角色原型&#xff0c;角色特点等等 这里我根据网络上找的一些参考&#xff0c;我大概想要的是比较特别的一个警察的猫人形的动物角色&#xff1b; 2…

2023-04-27 Android APP 不同机型跳转应用权限设置页面,我这里在小米(android12)和三星(android8)上测试

一、代码 package com.xxx.bluetooth_ble.permission;import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.…

【ROM定制】Android 12 制作『MIUI官改』那点事④修改

作者&#xff1a;小谢 内容&#xff1a;「MIUI官改」的修改 时间&#xff1a;2022.10.14 机型&#xff1a;小米10 安卓&#xff1a;Android 12 版本&#xff1a;V13.0.7.0稳定版 制作『MIUI官改』③工具&#xff1a;查看链接 ————————ROM修改———————— →◆解压…

雅思小作文 / IELTS Task1

The collection of IELTS Test resources. Based on Cambridge English 9-14 Last edited by Tang at 2019.06.11 17.01 Writing Task 1&#xff08;1 or 2 days&#xff09; 为什么我认为在准备writing时&#xff0c;task1更加重要&#xff1f; 因为task1侧重描写&#…

插画培训班学费一般是多少钱

插画培训班学费一般是多少钱&#xff1f;我们看待任何问题都要全面的思考&#xff0c;所以今天将会从三个方面来解析&#xff0c;分别是如何辨别插画培训机构是否靠谱、插画网课平台有哪些、插画培训班如何避坑&#xff0c;赶紧进入精彩内容吧&#xff01; 一&#xff1a;插画培…

首席新媒体运营黎想教程:线上活动推广策划及方案解析

对运营人员来说&#xff0c;活动运营是非常重要的一部分工作内容。那么细化到在线学习平台&#xff0c;组织运营一场活动有哪些要点呢&#xff1f;活动设计上又要注意什么呢&#xff1f;本文将告诉我们答案。 现在我介绍一下&#xff0c;我是青岛艺形艺意文化传媒有限公司创始…

新媒体运营教程:策划一场成功漂亮的活动策划

作为一个运营人&#xff0c;活动推广&#xff08;活动运营&#xff09;是我们运营人在工作当中运用最多的一个推广手段&#xff0c;也是通过活动策划&#xff0c;创意策划、活动互惠、互动反馈&#xff0c;对于引流、交互等行之有效的方式。 所以&#xff0c;在营销推广中的活动…

游戏推广怎么做比较好?做游戏推广时如何选取靠谱的宣传机构

本文由鲨鱼网媒小编为你分享&#xff01; 一、游戏推广的方法 1、多平台游戏推广 游戏推广可以透过多平台进行&#xff0c;比如通过社交媒体、论坛、网站、网络广告、视频、游戏联盟等渠道进行推广。可以通过利用这些渠道进行游戏宣传&#xff0c;可以更有效地提高游戏的知名…

APP社交类项目(类微信)运营之一线上推广

项目二于上月已完成原型设计&#xff0c;内部测试&#xff0c;目前处于推广阶段。下面聊一下我们团队目前想到并正在使用的推广方式&#xff1a; 推广方式主要聚焦于线上&#xff0c; 一、上线各大android平台&#xff0c;现在各大安卓市场都有活动&#xff0c;而且都是免费的&…

新媒体渠道运营推广技巧

渠道运营主要在于帮助产品在不同流量渠道获取到更多的目标用户&#xff0c;进而使得产品在整个生命周期内实现良性循环发展。通过一切可以利用的资源和流量为你的产品带来新增的的手段;其中包括免费、付费、换量、人脉积攒、产品的吸引力、圈内人的推荐、策划活动、内容营销、用…

3an推客推广有效果吗?

3an推客推广有效果。首先&#xff0c;我们都知道&#xff0c;3an推客可以帮助广大商家和小伙伴进行推广和营销。门槛很低&#xff0c;即使你的店铺零销售或者无销售&#xff0c;也可以进入3an推客进行推广。 而且3an推客的推广模式和淘宝客是一样的&#xff0c;也就是我们熟知的…

网络推广具体做什么

很多人都知道网络推广是每家公司必备的营销方法&#xff0c;但许多人就有疑问了&#xff0c;那到底什么是网络推广&#xff0c;网络推广具体做什么呢?今天一米软件就来告诉大家。 网络推广按照渠道来分析&#xff0c;大致可以分为以下几种&#xff1a; 1、搜索引擎营销&#x…

如何选择靠谱的插画培训课程

如何选择靠谱的插画培训课程&#xff0c;今天教你3个维度选择一个靠谱的插画培训班&#xff01; 插画培训机构课程&#xff1a; 1.选择插画培训班时&#xff0c;要先考察课程&#xff0c;看看课程内容是否符合自己的需求&#xff0c;是否有助于提高插画技术。课程设置应该灵活…

如何做好新媒体运营推广工作,黎想首谈一位优秀新媒体运营策划人员的思维模型

学而不思则罔&#xff0c;思而不学则殆。 首先能够打开这篇文章的朋友一定是非常优秀的&#xff0c;懂新媒体运营的&#xff0c;想学习的。那么就请大家花上三五分钟看完这篇对你未来事业具有重要影响意义的文章&#xff01; 在正式介绍前&#xff0c;我想请大家先和我一起做个…

重磅:上海将举办首届人工智能生成内容国际会议AIGC2023

2023首届人工智能生成内容国际会议&#xff08;The 1st International Conference on AI-generated Content&#xff0c;简称AIGC2023&#xff09;将于8月25日至26日在中国上海举行。本次会议得到了复旦大学、中国科技大学、同济大学、上海交通大学、上海人工智能实验室和香港中…

使用谷歌语音识别打造语音管家HiVoice

写在前面的话&#xff1a; 博客园是分享原创精品博文的地方&#xff0c;感觉自己的这篇博客至少是原创&#xff0c;也花了一些心思&#xff0c;自我感觉良好&#xff0c;呵呵&#xff0c;所以还是发布上来了&#xff0c;期望和大家一起交流。这个HiVoice是个人根据时下流行的语…

GBA模拟器 My Boy!的远程连接-wifi连接联机教程

因为有些平板没有蓝牙&#xff0c;所以写了这个教程 有些人不会用&#xff0c;所以。。。 例如两台手机&#xff0c; A手机和B手机 在A手机里打开“系统设置”-“无线和网络”-“绑定和便携式热点”&#xff0c;然后用户名和密码随便设置{不设置也行}&#xff0c;打开便携式…

远程控制teamviewer|远程桌面teamviewer|远程桌面连接软件teamviewer|teamviewer无人值守

如果你只管理10台电脑够你忙1天&#xff0c;那么1000台电脑的时候&#xff0c;你可能需要能够帮助你提供工作效率的利器。TeamViewer就可以帮助我进行统一的用户和设备配置管理&#xff0c;自动大规模部署。TeamViewer产品优异的表现和稳定性是实现这些的关键因素&#xff0c;我…

超好用的windows远程桌面管理工具Remote Desktop Connection Manager

Remote Desktop Connection Manager Remote Desktop Connection Manager (RDCMan) 是微软Windows Live体验团队的主要开发者 Julian Burger开发的一个远程桌面管理工具。简称为RDCMan。RDCMan 可以集中管理我们常用的远程桌面&#xff0c;并可在多个同时打开的远程面桌面间快速…

向日葵远程控制软件。

向日葵远程控制是一款提供远程控制免费的服务的软件。 向日葵远程控制支持主流操作系统Windows、Linux、Mac、Android、iOS跨平台协同操作&#xff0c;在任何可连入互联网的地点&#xff0c;都可以轻松访问和控制安装了向日葵远程控制客户端的设备。整个远控过程&#xff0c;可…