Align 3D Model's rotation to where the camera is pointing
Asked Answered
N

15

0

Let me clarify what really is the issue here. Basically i'm making a First-Person game, and i already have the camera coded and the movement and yadada, but now, i need to make the model of my player rotate to where my camera is also pointing at. Obviously he will only rotate in the X axis and not Y, but i really can't find anywhere a good way to make it work in first person. I know i could just hide the model or not show it at all in the camera, but for me, that's the approach i want to make.

Below is the code of my camera:
var gravity = 25
@onready var neck := $Neck
@onready var camera := $Neck/Camera3D

func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event: InputEvent):
if event is InputEventMouseButton:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
elif event.is_action_pressed("ui_cancel"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
if event is InputEventMouseMotion:
neck.rotate_y(deg_to_rad(-event.relative.x * mous_sens))
camera.rotate_x(deg_to_rad(-event.relative.y * mous_sens))
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(60))

If more code is needed, it will be provided, although i do think that's not necessary. In any way, thanks to anyone that could help me with this, i really can't find it anywhere

Nafis answered 14/11, 2023 at 23:37 Comment(0)
M
0

Nafis Post the complete movement script and format your code block properly by enclosing it in ~~~ tags. Post the scene hierarchy as well.

Millwater answered 14/11, 2023 at 23:43 Comment(0)
N
0

Millwater Of course! here's the movement code script:

func _physics_process(delta):
if Input.is_action_pressed("CROUCH"):
CURRENT_SPEED = crouch_spd
else:
CURRENT_SPEED = walking_spd

# Add the gravity.
if not is_on_floor():
	velocity.y -= gravity * delta

# Handle Jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
	velocity.y = JUMP_VELOCITY

# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir = Input.get_vector("LEFT", "RIGHT", "UP", "DOWN")
var direction = (neck.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
	velocity.x = direction.x * CURRENT_SPEED
	velocity.z = direction.z * CURRENT_SPEED
	if Input.is_action_pressed("RUN"):
		velocity.x *= sprint_spd
		velocity.z *= sprint_spd
else:
	velocity.x = move_toward(velocity.x, 0, CURRENT_SPEED)
	velocity.z = move_toward(velocity.z, 0, CURRENT_SPEED)

move_and_slide()

and here's the scene hierarchy as well (above is the ground and below is the player)

Nafis answered 14/11, 2023 at 23:54 Comment(0)
M
0

Nafis To format a code snippet properly put it between lines containing only ~~~

~~~

paste code here

~~~

Edit both of your posts so the code is displayed properly.

Didn't you say you solved this in your previous thread by zeroing node transforms?

Millwater answered 15/11, 2023 at 0:1 Comment(0)
N
0

Millwater i used the ~~~ but it acted strange, when i tried to pin the print of my scene hierarchy it didn't quite work so well, like it just came the link of the image, not the image itself.

Oh, and no, now the problem is related to something else entirely. I want to rotate the 3D model to align with the X rotation of the camera, and i can't find a way to do that in first person, everything is zeroed out already.

Nafis answered 15/11, 2023 at 0:9 Comment(0)
M
0

Nafis i used the ~~~ but it acted strange

Try again. It should work.

Nafis I want to rotate the 3D model to align with the X rotation of the camera

Why? Isn't it already following the character body? Anyway you can parent it to the camera and it will follow camera's rotation.

Millwater answered 15/11, 2023 at 0:15 Comment(0)
N
0

Millwater parent the characterbody to the camera? already tried that, even tried parenting to the neck, it always gives an error, like the following: "Attempt to call function 'rotate_y' in base 'null instance' on a null instance."

It always says the error is directly coming from this line: "neck.rotate_y(deg_to_rad(-event.relative.x * mous_sens))" in the camera part of the code of the player script.

I can't really put my finger why it isn't following the camera and how i could do that without errors, it's really bugging me out

Nafis answered 15/11, 2023 at 1:6 Comment(0)
M
0

Nafis Can you give an example from an existing game/video of what type of control you actually want to achieve?

Millwater answered 15/11, 2023 at 1:23 Comment(0)
N
0

Millwater I don't really remember now any reference, but picture that: As you are walking, not only can you see your surroundings but you can also see through your vision part of the character that you are controlling, so if you actually look down you can see the rest of his body, and furthermore when i add walking animation, you can see your character actually moving its arms while walking and whatnot...i hope you could get it

Nafis answered 15/11, 2023 at 1:55 Comment(0)
M
0

Nafis Then the character's mesh shouldn't rotate around x (sideways) axis, only around y (up) axis. Isn't that what you already have?

But anyway, It's hard to give a specific advice if you can't clearly and precisely formulate what type of movement/behavior you want to have.

The generalized answer to your questions is: if you want to align orientation of one node with some other node, simply align their global bases. That's all there is to it.

Millwater answered 15/11, 2023 at 2:5 Comment(0)
N
0

Millwater why should it rotate around y axis? i am actually fair new to 3d games but, i think the character model rotating up and down is not the desired result, at least that's what i think. It should simply rotate to where the camera is pointing at, if it's pointing to a rock or tree for example, the character model will too point directly to where the camera is looking at, and be limited only to the X axis, so it doesn't rotate in a way that could awkwardly make it position in Y axis.

What i'm trying to say is, i only want for the 3D model to look directly to where the camera is pointing at. It really don't need to go further than that, everything beyond is just details. I guess it shouldn't be hard, i just don't really know how to do this. I already tried to parent the characterbody (that uses the 3D model i'm working with here) to the camera or the neck and it does nothing but give the error that i already mentioned...

Nafis answered 15/11, 2023 at 2:16 Comment(0)
M
0

Nafis I don't see any meshes parented to character body in your setup.
The simplest setup should be something like this:

  • CharacterBody
    • Camera
    • Mesh
    • Collider

Now orient the camera using the mouse and wasd the character body along camera's basis x and z axes projected onto horizontal plane in global space.

Millwater answered 15/11, 2023 at 2:19 Comment(0)
N
0

Millwater Well, if it doesn't bother, how exactly i would do that? couldn't really wrap my head around it, sorry 🙁 ....if you could provide with an example it would be much appreciated

Nafis answered 15/11, 2023 at 2:48 Comment(0)
M
1

Nafis

extends CharacterBody3D

func _input(event):
	if event is InputEventMouse:
		$camera.rotation.y -= event.relative.x * .01
		$camera.rotation.x -= event.relative.y * .01
		$mesh.rotation.y = $camera.rotation.y
		
func _physics_process(delta):
	var input = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var forward = $camera.global_transform.basis.z
	var right = $camera.global_transform.basis.x
	forward.y = 0.0
	right.y = 0.0
	velocity = (right.normalized() * input.x + forward.normalized() * input.y ) * 5.0
	move_and_slide()
Millwater answered 15/11, 2023 at 2:55 Comment(0)
N
0

Millwater Thanks, with your help and this simple line of code "$mesh.rotation.y = $camera.rotation.y" i could finally wrap my head around a logic, that was so simple, but i tried and definitely did it wrong.

Only thing i needed to do is do this "mesh.rotate_y(deg_to_rad(-event.relative.x * mous_sens))", defining the mesh as the 3Dmodel of my character, rotating a little so it matches the camera, zeroing out it's rotation and voilá, problem solved. It's not perfect, sure, but it's of my taste.

I really appreciate you for helping me on 2 different occasions, and if that's not a problem to you, i will probably require some of your help in the future, as you definitely are my main guide in problem solving lol...Thanks for everything

Nafis answered 15/11, 2023 at 17:35 Comment(0)
M
1

Nafis You should probably get rid of the neck node as well and use the simpler setup I suggested. It'll make things easier to manage.

Millwater answered 15/11, 2023 at 18:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.