![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | Sdhy |
I’m using a cube MeshInstance as the RPG-character.
So I have 4 nodes in a 3D scene:
- Cube_KinematicBody
– Cube_MeshInstance - Camera
- Label
The kinematic body gets its own global 3D location (which is the same as the cube’s),
The camera gets this 3D location and turns it into a 2D location on the computer screen.
I set these variables under func _process(delta).
And these variables change and seem to represent the cube’s 3D or 2D-screen location as I move the character around in-game.
But when I try to use the screen-location in the Label node, its value stops changing as I move around.
I thought if I used get_global_transform() to get the cube’s location,
it’d be global.
How can I get RPG dialogue to appear above a 3D character’s head in a 3D game?
Here’s my code:
-------KINEMATIC NODE------
extends KinematicBody
var direction = Vector3(0,0,0)
var myCube3DLoc = Vector3(0,0,0)
func _process(delta): #Use this for things you want to work every frame. e.g. movement.
myCube3DLoc.x = get_global_transform().origin.x
myCube3DLoc.y = get_global_transform().origin.y
myCube3DLoc.z = get_global_transform().origin.z
# print("myCube3DLoc using get_global_transform().origin.x, y, or z returns: ", myCube3DLoc)
-------CAMERA NODE-------
extends Camera
onready var myCube3DLoc = get_node("../Cube_KinematicBody").myCube3DLoc
onready var myCubeScrnLoc = unproject_position(myCube3DLoc)
#unproject_position(Vector3) returns the 2D coordinate in the Viewport rectangle that maps to the given 3D point in worldspace.
func _process(delta):
myCube3DLoc = get_node("../Cube_KinematicBody").myCube3DLoc
print("Camera node says... unproject_position(myCube3DLoc) returns: ", unproject_position(myCube3DLoc))
-------LABEL NODE-------
extends Label
onready var myCubeScrnLoc = get_node("../Camera").myCubeScrnLoc
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
myCubeScrnLoc = get_node("../Camera").myCubeScrnLoc
myCubeScrnLoc = myCubeScrnLoc
#^This doesnt help. The value still doesn't change.
print("LableNode: myCubeScrnLoc equals: ", myCubeScrnLoc)
#^This does't change as I move the cube, even though it's under func _process(delta).
set_position(myCubeScrnLoc)
P.S. I also tried putting the label node underneath the kinematic one. It doesn’t work. Maybe because the Label node isn’t even in the 3D world?
Would signals help?
P.P.S. sorry if this post has weird formatting. I guess I’m not used to Godot Q&A forum posting.
I would think that the value from unproject_position()
would give the correct location of the cube on the Viewport
. Maybe some node has to be set up or initialized in the _ready()
function of the Label
script?
Ertain | 2020-01-16 01:36
What is setting up or initializing a node? I’m not sure what to do here.
2nd Edit: I tried using a Viewport node, but it’s just like the label node.
When the Viewport node tries to get the screen position from the camera node,
it doesn’t change when the cube moves around.
Would signals or global variables help?
Sdhy | 2020-01-16 03:14
It may be easier to write something like this in the Label
node’s script:
# Replace these with paths to the respective nodes in the scene tree.
onready var camera = $path/to/camera_node
onready var cube = $path/to/cube_node
func _process(delta):
var cube_position = camera.unproject_position(cube)
set_position(cube_position)
Ertain | 2020-01-16 07:42