我编写了这段代码,用于在角色前面创建一个平面,然后使用 检查敌人的位置并知道他们是否在飞机内。
该代码是Java语言,并在我们的服务器上运行,并且我们在使用Unity的游戏中使用它。
在下面的代码中AreaWidth是我们要检查的平面的宽度,Area length是它的长度。 信息中包含有关我们玩家的数据,例如位置和四元数。 bwNode正在保存有关我们正在检查的当前目标的数据。
float AreaWidth = message.getWidth();
float AreaLength = message.getLength();
double Fi, cs, sn;
Fi = message.quaternion.toEulerAngles().getY();
cs = Math.cos(Fi);
sn = Math.sin(Fi);
int ptx, pty;
ptx = (int)(bwNode.getLoc().getX() - message.loc.getX());
pty = (int)(bwNode.getLoc().getZ() - message.loc.getZ());
double perplen, alonglen;
perplen = Math.abs(ptx * sn - pty * cs);
alonglen = ptx * cs + pty * sn;
if (perplen <= AreaWidth / 2)
{
if (alonglen >= 0 && alonglen <= AreaLength)
{
//the target is inside the area
}
}
因此,当在游戏中调试或实际使用此代码时,它仅处理1个问题,飞机始终面向我们玩家的右侧或左侧,而不是始终面向前方/面向玩家的方向。
这是在玩家Y旋转时代表0度,90度,180度和270度的图像。 (在此图像中,白色立方体是游戏者,三角形显示了游戏者面对的位置,球体是敌人,红色透明框显示了我们的飞机应该在的位置,彩色线形成了实际创建的飞机。)
我需要帮助弄清楚是什么导致了我的代码。
答案 0 :(得分:1)
据我了解,这不是关于Unity的问题,因为它仅与您的后端有关。
无论如何,您实际上是在混淆目标位置和玩家位置的术语,请注意,无论玩家在哪里,飞机在屏幕上始终会面对目标。
我要这样做的方法是在玩家的坐标系中表达目标,像这样:
float AreaWidth = message.getWidth();
float AreaLength = message.getLength();
Fi = message.quaternion.toEulerAngles().getY();
cs = Math.cos(Fi);
sn = Math.sin(Fi);
// First, move the target from word axis origin to player axis origin
float tx = (bwNode.getLoc().getX() - message.loc.getX());
float tz = (bwNode.getLoc().getZ() - message.loc.getZ());
// Now rotate the target around it new word origin to apply player rotation
float ptx = cs * tx - sn * tz;
float ptz = sn * tx + cs * tz;
// Now ptx and ptz are in new word coordinates, simply test them agains area
if (-AreaWidth / 2 <= ptx && ptx <= AreaWidth / 2 && AreaLength => 0 && AreaLength <= l) {
// It is inside
} else {
// It is outside
}
P.S:将玩家完整的变换矩阵传递到服务器而不是分别处理变换和旋转组件,可能会更容易(并且肯定更有效)。