Malmo是微软的Minecraft AI框架,包括游戏本身的mod,以及用于发送输入和接收有关世界数据的多平台框架.
Minecraft的瞄准是圆柱形的.它存储在偏航(左和右)和俯仰(上下)中,而不是全开旋转四元数.偏航从最左边的-180度开始,到最右边的180度.俯仰从-90指向直接向上(天顶)到90直接向下(最低点).在我的代码中,我将它们存储为Vector2(重新创建,就像XNA一样),使得X代表Yaw,Y代表Pitch.
我无法创建一个连续瞄准目标算法,以便AI能够将其相机瞄准给定的目标偏航和俯仰.因为在允许连续运动的同时这样做的唯一方法是通过连续瞄准(设定偏航和俯仰速度,而不是值),我需要反复增加偏航和俯仰朝向目标方向.
我通过将目标方向存储在可空属性中来实现此目的.如果属性为null,则表示不更改目标.否则,每次调用更新方法时,减去存储值(目标瞄准)和当前瞄准(通过参数提供)之间的距离.然后它缩放差异,使得偏航或俯仰为1(最大速度),而另一个正确地按比例分配.这个比例的Vector2速度被分成它的偏航和俯仰,然后通过转弯和俯仰命令发送到客户端.一旦在目标方向的10度范围内,目标就设置为空.
在纸面上,似乎这会使相机的目标直接朝向目标方向(不包括偏航环绕).但是,客户端的音高通常会直接超过目标方向,尽管更新方法会发送一个指向相反方向的音高命令.这意味着音调以某种方式被“卡住”在天顶和最低点,但是自我修复并“转过来”并在几秒后卡在相反的极点上.在转身前花费的时间似乎每次都呈指数级增长(或者可能是二次方式).
这是我的目标更新方法的源代码:
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没有正常工作.
设置速度时,它是否保持在您设置的速度,直到设置了另一个速度?或者速度是否相互增加?如果球场超出范围会发生什么?