Failed Rotation in 3D - SOLVED

Godot Version

Godot 4.5

Question

EDIT: OKAY so SORRY TO ANYONE ALREADY readin this oops. But i DID figure out a WAY simpler way to do it: use an offset variable for the hit box, and add or subtract it from the x to get it to move with the rotation of the player.

the offset var was defined up top, and equals 2 in my case. gonna refine testing but now i know

ex:

	if moving:
		anim_tree.set("parameters/conditions/moving", true)
		anim_tree.set("parameters/conditions/not_moving", false)
		#rotate if we are not going the right way
		if velocity.x > 0.1:
			#move to right. 
			melee_attack_zone.global_rotation.y = 0.0
			melee_attack_zone.position.x = hitbox_offset
			model.rotation.y = 0.0
		elif velocity.x < -0.1:
			melee_attack_zone.global_rotation.y = PI
			model.rotation.y = PI #we should ALSO rotate the rest of our character i imagine!!!!
			melee_attack_zone.position.x = -hitbox_offset

I’m trying to create a platformer in 3D, which is probably not my best idea but its what I’m doing right now. I’ve got some code down that let the character move, and had a bunch of trouble when I tried to actually limit the characters rotation (as opposed to setting it directly).

When I set it directly it looked very jittery, and would go back and forth between left and right very fast. This also messed up the camera, so I had to do some code to decouple the camera from the player. I hope that’s not what the problem is, but I’ll share camera code too, just in case.

the part I THINK the bug is in is in this specific part,

func set_animations(delta):
	#rotation
	if moving:
		anim_tree.set("parameters/conditions/moving", true)
		anim_tree.set("parameters/conditions/not_moving", false)
		#rotate if we are not going the right way
		if velocity.x > 0.1:
			#move to right. 
			#melee_attack_zone.rotation.y = 0.0
			if self.global_rotation.y > 0:
				#magic number alert
				self.global_rotation.y -= 5 * delta
			#tryin some thing new: we are goin to rotate quickly instead of just one flip
			#if self.rotation.y != 0:
				#current_y_rotation += -.1
			#model.rotation.y = 0.0
		elif velocity.x < -0.1:
			if self.global_rotation.y < PI:
				self.global_rotation.y += 5 * delta 
			#self.rotation = Vector3(0, PI, 0)#THIS doens't work, though the above one does :O
			#weird
			#if self.rotation.y != PI:
				#current_y_rotation += .1
		#	melee_attack_zone.rotation.y = PI
		#	model.rotation.y = PI #we should ALSO rotate the rest of our character i imagine!!!!
		self.rotation.y = clampf(global_rotation.y, 0, PI)

But the whole script is :

extends "res://scripts/combatant.gd"
#vars
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
@export var accel = 4.0 #not in use yet
@export var jump = 7.0
# we sh ould probably make a combatant script.... should think of what that'd look like
@export var claws_damage = 15.0
@export var magic_damage = 25.0
var jumping = false
var moving = false
var not_moving = true #im stupid fix this later
var grounded = true #maybe set later better. with a grounded c heck in physics process
var falling = false
var claws_attack = false
var magic_basic = false
#onreadies
@onready var model = $Armature
@onready var anim_tree = $AnimationTree
@onready var anim_state = $AnimationTree.get("parameters/playback")
@onready var melee_attack_zone = $MeleeAttackZone

func _ready():
	melee_attack_zone.monitoring = false

#for some reason grouned is reading as true when we are still mid air = after our jump
func _physics_process(delta):
	do_movement(delta)
	var current_x_pos = self.global_position.x  #this works for gettin current positoin for x. 
	var current_y_pos = self.global_position.y #ditto but y
	pass_move_args(current_x_pos, current_y_pos, delta)
	set_animations(delta)
	if Input.is_action_just_pressed("basic_attack"):
		do_melee_basic()

func do_melee_basic():
	current_damage_type = damage_types.PHYSICAL
	anim_tree.set("parameters/conditions/claws_attack", true)
	#turn on melee attack zone????
	melee_attack_zone.monitoring = true
	#or do in animatoins? good quesiton
	#await the time of animation
	await get_tree().create_timer(.59).timeout
	anim_tree.set("parameters/conditions/claws_attack", false)
	melee_attack_zone.monitoring = false

func do_movement(delta):
	velocity.y += -gravity * delta
	var input = Input.get_vector("left", "right", "back", "front") #followin 3d tutorials o im doing this st upid : 
	#set left right fine, then just pass in 0 for forward back
	var movement_dir = transform.basis * Vector3(input.x, 0, 0)
	if is_on_floor():
		falling = false
		grounded = true
		jumping = false
	if input:
		moving = true
		not_moving = false
	velocity.x = movement_dir.x * speed
	if velocity.x == 0:
		not_moving = true
		moving= false
	move_and_slide()
	if is_on_floor() and Input.is_action_just_pressed("jump"):
		velocity.y = jump
		jumping = true
		grounded = false
		falling = false
	if !is_on_floor():
		grounded = false
		falling = true
		jumping = false

func set_animations(delta):
	#rotation
	if moving:
		anim_tree.set("parameters/conditions/moving", true)
		anim_tree.set("parameters/conditions/not_moving", false)
		#rotate if we are not going the right way
		if velocity.x > 0.1:
			#move to right. 
			#melee_attack_zone.rotation.y = 0.0
			if self.global_rotation.y > 0:
				#magic number alert
				self.global_rotation.y -= 5 * delta
			#tryin some thing new: we are goin to rotate quickly instead of just one flip
			#if self.rotation.y != 0:
				#current_y_rotation += -.1
			#model.rotation.y = 0.0
		elif velocity.x < -0.1:
			if self.global_rotation.y < PI:
				self.global_rotation.y += 5 * delta 
			#self.rotation = Vector3(0, PI, 0)#THIS doens't work, though the above one does :O
			#weird
			#if self.rotation.y != PI:
				#current_y_rotation += .1
		#	melee_attack_zone.rotation.y = PI
		#	model.rotation.y = PI #we should ALSO rotate the rest of our character i imagine!!!!
		self.rotation.y = clampf(global_rotation.y, 0, PI)
	if not_moving:
		#anim_state.travel("Idle") #this line is what was kicking my ass. weird. 
		#keeping it  here to show DO NOT USE THAT with the rest of way state machine
		#is set up
		anim_tree.set("parameters/conditions/moving", false)
		anim_tree.set("parameters/conditions/not_moving", true)
	if jumping: 
		anim_tree.set("parameters/conditions/grounded", false)
		anim_tree.set("parameters/conditions/jumping", true)
		anim_tree.set("parameters/conditions/falling", false)
	if falling: 
		anim_tree.set("parameters/conditions/falling", true)
		anim_tree.set("parameters/conditions/grounded", false)
		anim_tree.set("parameters/conditions/jumping", false)
	if grounded: 
		anim_tree.set("parameters/conditions/falling", false)
		anim_tree.set("parameters/conditions/grounded", true)
		anim_tree.set("parameters/conditions/jumping", false)


func _on_melee_attack_zone_body_entered(body: Node3D) -> void:
	if body.current_team == teams.ENEMY:
		body.take_damage(damage_types.PHYSICAL, claws_damage) 
		#take into account other, non basic attacks later
	#we need to make whoever entered this take damage, if they are an enemy

The camera script is :

extends Camera3D
class_name CustomCamera

#@export var zoom = 1.5
#var min_zoom = .5
#var max_zoom = 3.0
#var zoom_speed = 0.1
@export var TargetNode : Node3D = null


func _ready():
	pass
	
func _process(_delta) -> void:
	set_position(TargetNode.get_position())
	position.z = 8.0

but i’m mostly using it atm to set the z position farther away from teh character.

this all started because I was just rotating the model originally, but couldn’t rotate my box that detects enemies (hit box? Forget the word, sorry. Its so the script knows if an enemy si in that box and can apply damage to the enemy )

I feelliek I’m VASTLY overcomplicating this , what i really want is to rotate taht box and the model can also rotate if it wants. But i’ve way overcomplicated the problem so I’m not sure what I’m doing wrong atm

thanks to anyone who took the time to read this and anyone who can help