寻找避免游戏障碍的方法是所有游戏开发人员都必须面对的经典任务。 有许多效率不同程度的众所周知的算法。 所有这些人都在某种程度上分析了障碍物和玩家的相对位置,并根据结果对移动做出了一个或另一个决定。 我试图使用训练有素的神经网络来解决避障问题。 我想在这篇简短的文章中分享我在Unity3D中实现这种方法的经验。
概念图
基于标准地形的地形被用作游戏空间。 本文不考虑与表面的碰撞。 每个模型都配备了一组对撞机,它们尽可能准确地描述了障碍物的几何形状。 必须绕过障碍物的模型有四个
碰撞传感器(在屏幕截图中,传感器的位置和距离由绿松石线指示)。 本质上,传感器是雷卡斯特,在分析算法中,每个传感器都会将距离传递到碰撞对象。 距离从0(物体尽可能靠近)到1(无碰撞,该方向没有障碍物)变化。
通常,避障算法的工作如下:
- 来自碰撞传感器的四个值被馈送到经过训练的神经网络的四个输入
- 计算神经网络的状态。 在输出中,我们得到三个值:
一个 模型的逆时针旋转功率(取值从0到1)
b。 模型的顺时针旋转功率(取值从0到1)
c。 制动加速度(取值从0到1) - 努力以适当的系数应用于模型。
实作
老实说,我不知道这次冒险是否会带来任何收益。 首先,我在Unity中实现了NeuroNet类。 我不会讲解类代码,因为它是经典的多层感知器。 在此过程中,立即出现了网络层数的问题。 为了提供所需的容量,另一方面需要可接受的计算速度,需要多少个? 经过一系列实验,我确定了十二层(四个输入的三个基本条件)。
接下来,有必要实施训练神经网络的过程。 为此,我必须创建一个使用相同NeuroNet类的单独应用程序。 现在,用于训练的数据问题已经达到了最高点。 最初,我想使用直接从游戏应用程序获取的值。 为此,我组织了传感器的数据记录,以便将来针对四个传感器的每组值向训练计划指示正确的输出值。 但是,看着结果,我感到沮丧。 事实是,对于四个传感器值的每组,仅指示一个适当的值是不够的;这些值需要保持一致。 这对于成功训练神经网络非常重要。 此外,不能保证所得样本代表所有可能的情况。
另一种解决方案是手动编译基本值传感器和输出值的表格。 基本选项采用以下值:0.01-障碍物接近,0.5-障碍物位于中途,1-方向是自由。 这减小了训练样本的大小。
传感器1 | 传感器2 | 传感器3 | 传感器4 | 顺时针旋转 | 逆时针旋转 | 煞车 |
---|
0.01 | 0.01 | 0.01 | 0.01 | 0.01 | 0.01 | 0.01 |
0.01 | 0.01 | 0.01 | 0.5 | 0.01 | 0.01 | 0.01 |
0.01 | 0.01 | 0.01 | 0,999 | 0.01 | 0.01 | 0.01 |
0.01 | 0.01 | 0.5 | 0.01 | 0,999 | 0.01 | 0.01 |
0.01 | 0.01 | 0.5 | 0.5 | 0,999 | 0.01 | 0.01 |
0.01 | 0.01 | 0.5 | 0,999 | 0,999 | 0.01 | 0.5 |
0.01 | 0.01 | 0,999 | 0.01 | 0,999 | 0.01 | 0.5 |
0.01 | 0.01 | 0,999 | 0.5 | 0,999 | 0.01 | 0,999 |
0.01 | 0.01 | 0,999 | 0,999 | 0,999 | 0.01 | 0,999 |
该表显示了训练样本的一小部分(表81-行中的总计)。 培训计划的最终结果是一个权重表,该表保存在单独的文件中。
结果
出于对搓手的期待,我将赔率的加载安排到了演示游戏中,并开始了这一过程。 但是,事实证明,我显然还不够。 从一开始,经过测试的模型就旋转成一排,遇到所有障碍,就像一只盲目的小猫。 总的来说,结果很一般。 我不得不深入研究这个问题。 很快就发现了无助行为的根源。 由于神经网络对传感器读数的响应通常是正确的,因此传输的控制动作被证明太强了。
解决了这个问题后,我遇到了一个新的难题-传感器reykast距离。 由于检测到干扰的距离很长,该模型执行了过早的操作,从而导致路线发生严重变形(甚至在看似已经通过的障碍物中发生了不可预见的碰撞)。 一小段距离就会导致一件事-模型无奈地“陷入”了所有障碍,显然没有足够的响应时间。
我越是喜欢演示游戏模型,试图教它避免障碍,对我来说我不是在编程,而是在教孩子走路。 这是一种不寻常的感觉! 看到我的努力取得了切实的成果,这使我更加高兴。 最后,不幸的是,悬停在水面上方的悬停船开始自信地绕过该路线上出现的建筑物。 当我有意识地尝试将模型推向死胡同时,就开始对该算法进行真正的测试。 在这里,需要改变制动加速的工作逻辑,以对训练样本进行一些校正。 让我们看一下实际发生的情况的例子。
1.简单绕过一个障碍
如您所见,旁路并没有造成任何困难。
2.两个障碍(选项1)
该模型很容易在两座建筑物之间找到一条通道。 简单的任务。
3.两个障碍(选项2)
建筑物距离更近,但是模型找到了通道。
4.两个障碍(选项3)
该选项更为复杂,但仍然可以解决。
5.三个障碍
这个问题很快就解决了。
6.死胡同
这里的模型有问题。 视频的前30秒显示,该模型在简单的建筑配置中无助地挣扎。 这里的问题很可能不是神经网络模型,而是沿路线移动的主要算法中的问题-尽管他不顾一切地避免碰撞,但他仍坚持不懈地努力使船舶重回正轨。
在使用不同参数对这种情况进行了几次不成功的运行之后,我设法获得了积极的结果。 从视频的第30秒开始,您可以观察到如何从死角中选择传感器距离增加且制动力更大的模型。 为此,她需要将近五分钟的时间(我消除了痛苦,只留下了视频的最后30秒)。 在真实的游戏中这不太可能被认为是一个很好的结果,因此显然有改进该算法的空间。
结论
总的来说,问题就解决了。 该解决方案的有效性如何是一个悬而未决的问题,需要进行更多的研究。 例如,尚不知道当动态障碍物(其他移动物体)出现时模型将如何表现。 另一个问题是缺少向后指向的碰撞传感器,这导致避免复杂障碍物的困难。
在训练的介绍中可以看到神经网络避障算法思想的明显进一步发展。 为此,应引入对决策结果的评估,并在随后进行更正而对象位置没有明显变化的情况下,评估应恶化。 在达到某个值时,模型应进入训练模式,例如,随机更改所做出的决策以寻找出路。
在我看来,该模型的另一个功能似乎是初始训练的可变性。 例如,这使针对不同模型的多种行为成为可能,而无需分别对每个行为进行编程。 换句话说,如果我们拥有重型战车和轻型侦察机,它们避开障碍物的方式可能会有很大不同。 为了达到这种效果,我们使用相同的感知器,但是对不同的样本进行了训练。