在保持玩家全局方向的同时改变场景,3d

change scene while preserving the player's global direction,3d

当玩家触碰场景A的起始传送门盒子时,会从场景A切换到场景B,并降落在场景B的登陆传送门盒子上。 我希望玩家在着陆时面向同一个方向,就像他开始进入门户时一样。 我不知道如何处理它的 vector3 变换。 感谢您提前提供帮助。

自动加载(单例)在场景更改后仍然存在。因此,您可以使用它们来存储必须在场景更改后保留下来的信息。

要创建自动加载,请转到“项目”菜单,然后select“项目设置”选项打开“项目设置”对话框,然后转到“AutoLoad”选项卡。

创建或使用现有的自动加载脚本,该脚本将保存您需要跟踪场景变化的任何变量。 例如,您可以将玩家得分、生命数和类似变量放在那里。

在这种情况下,您需要玩家头像的方向。


由于我们讨论的是 3D,因此我假设玩家头像是一个 Spatial(或派生的)节点。另外我假设我们只想保持旋转。不缩放或任何其他转换。严格来说只是旋转。


仅旋转

你可以得到一个 Quat 代表这样的方向:

$Avatar.Transform.basis.get_rotation_quat()

并在更改场景之前将其存储在您的 atuoload 中:

AutoloadName.orientation = $Avatar.Transform.basis.get_rotation_quat()

然后,在新场景准备就绪后,就可以取回并设置了,需要重新制作Transform


我们可以将我们存储的旋转与我们在目的地上的 Basis 结合起来,如下所示:

var quat = AutoloadName.orientation
var basis = $Avatar.Transform.basis
var new_basis:Basis = Basis(quat.xfrom(basis.x), quat.xfrom(basis.y), quat.xfrom(basis.z))
$Avatar.Transform = Transform(new_basis, $Avatar.Transform.origin)

明确地说,我在该代码中所做的是创建一个新的 Transform,它将保留其 origin(以及其翻译),基础为 旋转 存储的 Quat。所以它实际上会结合旋转。


或者,我们可以从 Quat 创建一个新的基础:

var quat = AutoloadName.orientation
$Avatar.Transform = Transform(Basis(quat), $Avatar.Transform.origin)

这也意味着目标的任何缩放都将丢失。


嗯,我们可以读取目的地的缩放,再缩放一下:

var scale = $Avatar.Transform.basis.get_scale()
var quat = AutoloadName.orientation
$Avatar.Transform = Transform(Basis(quat).scaled(scale), $Avatar.Transform.origin)

这样,它将根据您存储的旋转角度对目的地进行缩放。 请注意,基础可以表示缩放和旋转以外的变换(例如倾斜)。


旋转和缩放

如果可以保留缩放等,但不能保留平移,您可以简单地存储 basis:

AutoloadName.basis = $Avatar.Transform.basis

并设置它:

$Avatar.Transform = Transform(AutoloadName.basis, $Avatar.Transform.origin)

完全变换

当然,如果您也想保留翻译,您只需存储 Transform:

AutoloadName.transform = $Avatar.Transform

并设置它:

$Avatar.Transform = AutoloadName.transform