我对正确的 vector 对齐有疑问。我想得到一个指向与玩家相同方向的 vector ,但 Y 值为 0。关键是,无论玩家的垂直和水平旋转, vector 的 Y 值为 0。 vector 始终应该指向水平(值为 0),但保持玩家旋转的方向。
这张图是侧面的情况。红线代表玩家的观看方向(上 - 下)的示例,绿线代表我想要实现的效果。无论玩家朝哪个方向看,向上或向下,绿线都保持不变:
这里,反过来,我已经从顶部展示了这种情况。红线是玩家的观看方向(左-右),绿线是我想要达到的效果。如您所见,玩家在此轴上的旋转设置我的 vector 完全相同。
我能够编写一段代码,但它的行为不正确:随着玩家向上或向下转动,Y 轴变得越来越高。我不知道为什么:
Vector playerDirection = player.getLocation().getDirection();
Vector vector = new Vector(playerDirection.getX(), 0, playerDirection.getZ()).normalize().multiply(3);
如何正确操作?
最佳答案
tl;博士:
Vector vector = new Vector(-1 * Math.sin(Math.toRadians(player.getLocation().getYaw())), 0, Math.cos(Math.toRadians(player.getLocation().getYaw())));
您缺少基于玩家注视位置创建新 Vector
的基本原则。我不太了解它的数学,但我可以和那些在几何方面比我好的人的数学混在一起。
因此,让我们尝试减少您定义的 Vector
变量的数量。快速浏览一下 Location
的来源,我们实际上可以直接创建您的 Vector
以避免定义多个。
public Vector getDirection() {
Vector vector = new Vector();
double rotX = this.getYaw();
double rotY = this.getPitch();
vector.setY(-Math.sin(Math.toRadians(rotY)));
double xz = Math.cos(Math.toRadians(rotY));
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
return vector;
}
如您所见,玩家的俯仰和偏航不是 1:1 的关系。不知道为什么,但让我们重新调整他们的逻辑。
下面是我们将如何做到这一点:
public Vector getVectorForAdixe(Location playerLoc) {
Vector vector = new Vector();
double rotX = playerLoc.getYaw();
double rotY = 0; // this is the important change from above
// Original Code:
// vector.setY(-Math.sin(Math.toRadians(rotY)));
// Always resolves to 0, so just do that
vector.setY(0);
// Original Code:
// double xz = Math.cos(Math.toRadians(rotY));
// Always resolves to 1, so just do that
double xz = 1;
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
return vector;
不错!现在,稍微清理一下以删除那些注释和不必要的变量:
public Vector getVectorForAdixe(Location playerLoc) {
Vector vector = new Vector();
double rotX = playerLoc.getYaw();
vector.setY(0);
vector.setX(-1 * Math.sin(Math.toRadians(rotX)));
vector.setZ(Math.cos(Math.toRadians(rotX)));
return vector;
为什么这个数学会这样?不知道!但这几乎肯定对你有用。如果你真的想保持它原来的样子,甚至可以内联它:
Vector vector = new Vector(-1 * Math.sin(Math.toRadians(player.getLocation().getYaw())), 0, Math.cos(Math.toRadians(player.getLocation().getYaw())));
结束语,如果你想从 vector 中获得俯仰/偏航,代码在这里:https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/Location.java#310
关于Java Spigot 设置 vector 相对于玩家位置的方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74185528/