简体   繁体   中英

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

when the player touches the start portal box of scene A, it changes the scene from scene A to scene B. And it lands on the landing portal box of scene B. I want the player to face in the same direction when it lands similar to when he started going to the portal. I don't know how to tract its vector3 transform. thanks for helping in advance.

Autoloads (singletons) survive scene changes. Thus, you can use them to store information that must survive an scene change.

To create an autoload go to the "Project" menu, then select the "Project Settings" options which opens the "Project settings" dialog, and there go to the "AutoLoad" tab.

Create - or use an existing - autoload with an script that will hold any variables that you need to keep track of across scene changes. For example, you could put player score, number of lives, and similar variables there.

In this case you want the orientation of the player avatar.


Since we are talking 3D, I'll assume the player avatar is an Spatial (or derived) node. Also I will assume we only want to preserve rotation. Not scaling, or any other transformation. Strictly just rotation.


Rotation Only

You can get a Quat that represents the orientation like this:

$Avatar.Transform.basis.get_rotation_quat()

And Store that in your atuoload before changing scenes:

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

Then, on ready on the new scene, you can retrieve it and set it, which requires making a new Transform .


We can combine the rotation we stored with the Basis we have on the destination like this:

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)

To be clear, what I'm doing in that code is creating a new Transform , that will preserve its origin (and thus its translation), with a basis rotated by the stored Quat . So it would actually combine the rotations.


Alternatively, we could create a new basis from the Quat instead:

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

Which also means any scaling of the destination would be lost.


Well, we can read the scaling of the destination, and scale again:

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

That way it will have the scaling of the destination, with the rotation you stored. Be aware that a basis can represent transformation other than scaling and rotation (eg skewing).


Rotation And Scaling

If it is ok to preserve scaling and so on, but not translation, you can simply store basis :

AutoloadName.basis = $Avatar.Transform.basis

And to set it:

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

Full transform

Of course, if you would to preserve translation too, you would just store the Transform :

AutoloadName.transform = $Avatar.Transform

And to set it:

$Avatar.Transform = AutoloadName.transform

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM