Skip to main content

操作变换

移动(转换位置)

在变换之间转换位置

在许多情况下,你可能需要将某个位置转换为变换前或者变换后的位置。

// World space vector 100 units below the player.
GD.Print(Transform * new Vector2(0, 100));

如果你事先知道变换位于 (0, 0) 处,则可以改用“basis_xform”或“basis_xform_inv”方法,这将跳过处理平移的过程。

相对于对象本身移动对象

一种常见的操作,尤其是在 3D 游戏中,是相对于自身移动对象。例如,在第一人称射击游戏中,当你按下 W 键时,你希望角色向前移动(-Z 轴)

Transform2D t = Transform;
t.Origin += t.X * 100;
Transform = t;

要在 3D 中移动,需要将“x”替换为“basis.x”。

将变换应用于变换

要手动计算子变换的世界空间变换, 我们将使用以下代码:

// Set up transforms like in the image, except make positions be 100 times bigger.
Transform2D parent = new Transform2D(2, 0, 0, 1, 100, 200);
Transform2D child = new Transform2D(0.5f, 0, 0, 0.5f, 100, 100);

// Calculate the child's world space transform
// origin = (2, 0) * 100 + (0, 1) * 100 + (100, 200)
Vector2 origin = parent.X * child.Origin.X + parent.Y * child.Origin.Y + parent.Origin;
// basisX = (2, 0) * 0.5 + (0, 1) * 0 = (0.5, 0)
Vector2 basisX = parent.X * child.X.X + parent.Y * child.X.Y;
// basisY = (2, 0) * 0 + (0, 1) * 0.5 = (0.5, 0)
Vector2 basisY = parent.X * child.Y.X + parent.Y * child.Y.Y;

// Change the node's transform to what we calculated.
Transform = new Transform2D(basisX, basisY, origin);

在实际项目中,我们可以通过以下方式找到子对象的世界变换 使用*

// Set up transforms like in the image, except make positions be 100 times bigger.
Transform2D parent = new Transform2D(2, 0, 0, 1, 100, 200);
Transform2D child = new Transform2D(0.5f, 0, 0, 0.5f, 100, 100);

// Change the node's transform to what would be the child's world transform.
Transform = parent * child;

当矩阵相乘时, 顺序很重要!别把它们弄混了.

获取信息

现在你可能在想: "好吧, 但是我怎么从变换中获得角度?" 。 答案又一次是: 没有必要。你必须尽最大努力停止用角度思考。

物体方向

想象一下, 你需要朝你的游戏角色面对的方向射击子弹. 只需使用向前的轴(通常为 Z 或 -Z )。

bullet.Transform = transform;
bullet.LinearVelocity = transform.Basis.Z * BulletSpeed;

位置判定

敌人在看着游戏角色吗? 为此判断你可以使用点积

// Get the direction vector from player to enemy
Vector3 direction = enemy.Transform.Origin - player.Transform.Origin;
if (direction.Dot(enemy.Transform.Basis.Z) > 0)
{
enemy.ImWatchingYou(player);
}
### 移动

向左平移

// Remember that +X is right
if (Input.IsActionPressed("strafe_left"))
{
TranslateObjectLocal(-Transform.Basis.X);
}

跳跃

// Keep in mind Y is up-axis
if (Input.IsActionJustPressed("jump"))
velocity.Y = JumpSpeed;

MoveAndSlide();

所有常见的行为和逻辑都可以用向量来完成。