c# – 持续瞄准马尔默

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没有正常工作.

设置速度时,它是否保持在您设置的速度,直到设置了另一个速度?或者速度是否相互增加?如果球场超出范围会发生什么?

点赞