- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
Malmo 是 Microsoft 的 Minecraft AI 框架,由游戏本身的模组和用于发送输入和接收有关世界的数据的多平台框架组成。
Minecraft 的瞄准是圆柱形的。它存储在偏航(左和右)和俯仰(上下)而不是完整的旋转四元数中。偏航从最左边的 -180 度到最右边的 180 度。音高从 -90 直接向上(天顶)到 90 直接向下(天底)。在我的代码中,我将它们存储为 Vector2
(重新创建以像 XNA 一样工作),这样 X 代表 Yaw,Y 代表 Pitch。
我在创建连续瞄准目标算法时遇到问题,以便 AI 能够将其相机对准给定的目标偏航和俯仰。因为这样做同时仍然允许连续移动的唯一方法是通过连续瞄准(设置偏航和俯仰速度,而不是值),我需要向目标方向重复增加偏航和俯仰。
我通过将目标方向存储在可为空的属性中来实现这一点。如果该属性为空,则表示不改变目标。否则,每次调用更新方法时,减去存储值(目标目标)和当前目标(通过参数提供)之间的距离。然后它会缩放差异,使偏航或俯仰为 1(最大速度),而另一个则与之正确成比例。这个成比例的 Vector2
速度被分成偏航和俯仰,然后通过 turn
和 pitch
命令发送到客户端。一旦在目标方向的 10 度范围内,目标将被设置为空。
在纸面上,这似乎会使相机的瞄准直接朝向目标方向(不包括偏航环绕)。然而,客户端的俯仰通常直接越过目标方向,尽管更新方法发送了一个 pitch
命令,表明要朝相反的方向前进。这意味着球场不知何故“卡在”了天顶和最低点,但在几秒钟后自行修复并“掉头”并卡在了相反的极点。每次转身前停留的时间似乎都呈指数级(或可能呈二次方级)增长。
这是我的目标更新方法的源代码:
public void UpdateAim(Observations obs)
{
// AimTarget is a Vector2? property
if (AimTarget == null || obs == null)
{
return;
}
if (AimTarget.Value.Distance(obs.Aim) < AIM_CLOSE_ENOUGH) // < 10
{
Logger.LogInfo("Reached {0}", AimTarget.Value);
Look(Vector2.Zero);
AimTarget = null;
return;
}
double deltaYaw = AimTarget.Value.X - obs.Aim.X;
double deltaPitch = AimTarget.Value.Y - obs.Aim.Y;
// These two are stored as private Vector2 fields
deltaAim = new Vector2(deltaYaw, deltaPitch);
scaledAim = deltaAim / Math.Max(Math.Abs(deltaAim.X), Math.Abs(deltaAim.Y));
Look(scaledAim); // sets continuous aim velocity
}
Look(Vector2)
的(简化)源代码:
public void Look(Vector2 direction)
{
// Agent is an AgentHost property
Agent.sendCommand("turn " + velocity);
Agent.sendCommand("pitch " + velocity);
}
UpdateAim()
在主游戏循环中每秒被调用 20 次(尽管我尝试过高达每秒 50 次和低至 5 次)。
在我最后一次运行 AI(卡在最低点)结束时,我的瞄准调试数据如下所示:
// Format: (yaw, pitch)
Target Aim: (134.75, 27.90)
Actual In-Game Aim: (-6.50, 90.00) // Lines up with MC's debug screen
Delta Aim : (145.17, -62.10) // Total degrees needed to go in yaw and pitch
Scaled Aim Velocity: (1.00, -0.43)
缩放的目标速度是提供给 Look()
的。如您所见,投球速度本来应该是负的,但游戏中的实际目标仍然是 90,并且由于某种原因没有得到纠正。我算对了吗?
最佳答案
据我所见,数学很优雅,可以检验。如果俯仰速度在最低点处为负并且没有向下移动,对我来说它看起来像 Agent.sendCommand 没有正常工作。
在设置速度时,它是否保持在您设置的速度,直到设置另一个速度?还是速度会相互叠加?如果球场出界怎么办?
关于c# - 持续瞄准马尔默,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38407584/
我是一名优秀的程序员,十分优秀!