How can I make the character walk based on the camera angle instead of the world axis? Is there a way to achieve this using the current pre-built scripts?
# Get the input direction and handle the movement/deceleration.
var input_dir := Input.get_vector("left", "right", "forward", "backward")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
1 Like
If your camera is a child of this object then you could try using $Camera3D.global_basis
instead of transform.basis
How are you rotating the character in the script?
2 Likes
gertkeno:
$Camera3D.global_basis
Im using this script for movement, it says there is an error
extends CharacterBody3D
var hp = 125
const SPEED = 5.1
var angular_aceleration = 10
var attacknumb = 1
var canattack = true
var isattack1 = false #animation
var isattack2 = false #animation
var is_dash = false #animation
var candash = true
var is_idle = false #animation
var iswalking = false #animation
var grounded = false
@export var animation_three : AnimationTree
@onready var stepCast = $StepCast
@export var Eloy : CharacterBody3D
@onready var sword: Node3D = $Armature/Skeleton3D/SwordBack/Sword
@onready var PlayerAnimationTree = $AnimationTree.get_path()
@onready var animation_tree = get_node(PlayerAnimationTree)
@onready var playback = animation_tree.get("parameters/playback")
@onready var camera3d = $Camera3D
#So many numbers and boleans for this guy... HELP
func _physics_process(delta: float) -> void: # Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
if Input.is_action_just_pressed("Attack") and canattack: # Dash system, make the player dash.
#canattack = false
if attacknumb == 1 and canattack and !isattack1:
canattack = false
sword.reparent($Armature/Skeleton3D/SwordHand, false)
$Attack1.start()
$Attack1/Attack1CD.start()
$Guardar.start()
isattack1 = true
is_idle= false
iswalking= false
if Input.is_action_just_pressed("Attack") and canattack: # Dash system, make the player dash.
#canattack = false
if attacknumb == 2 and canattack and !isattack2:
canattack = false
sword.reparent($Armature/Skeleton3D/SwordHand, false)
$Attack2.start()
$Attack2/Attack2CD.start()
$Guardar.start()
isattack2 = true
is_idle= false
iswalking= false
if Input.is_action_just_pressed("Dash") and candash: # Dash system, make the player dash.
candash = false
if !is_dash:
#CharacterBody3D.transform.forward + 100 HELP
sword.reparent($Armature/Skeleton3D/SwordHand, false)
$DashTimer.start()
$DashTimer/DashCD.start()
$Guardar.start()
is_dash = true
is_idle= false
iswalking= false
# Get the input direction and handle the movement/deceleration.
var input_dir := Input.get_vector("left", "right", "forward", "backward")
var direction := ($Camera3D.global_basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
if !is_dash and !isattack1 and !isattack2:
$Armature.rotation.y = lerp_angle($Armature.rotation.y, atan2 (direction.x, direction.z), delta * angular_aceleration)
if !is_dash and !isattack1 and !isattack2:
isattack2 = false
is_idle = false
iswalking = true
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
if !is_dash and !isattack1 and !isattack2:
isattack2 = false
is_idle = true
iswalking = false
move(delta);
# Set an animation
animation_tree["parameters/conditions/IsWalking"] = iswalking
animation_tree["parameters/conditions/IsIdle"] = is_idle
animation_tree["parameters/conditions/Dash"] = is_dash
animation_tree["parameters/conditions/IsAttack1"] = isattack1
animation_tree["parameters/conditions/IsAttack2"] = isattack2
func _on_guardar_timeout() -> void: # sword to back
sword.reparent($Armature/Skeleton3D/SwordBack, false)
func _on_dash_cd_timeout() -> void:
candash = true
func _on_dash_timer_timeout() -> void:
is_dash = false
func _on_attack_1_timeout() -> void:
isattack1 = false
attacknumb=2
#canattack = true
func _on_attack_1cd_timeout() -> void:
canattack = true
func _on_attack_2_timeout() -> void:
isattack2 = false
attacknumb=1
#canattack = true
func _on_attack_2cd_timeout() -> void:
canattack = true
func move(delta: float):
stepCast.global_position.x = global_position.x + velocity.x * delta;
stepCast.global_position.z = global_position.z + velocity.z * delta;
if is_grounded():
stepCast.target_position.y = -1;
else:
stepCast.target_position.y = -0.45;
var query = PhysicsShapeQueryParameters3D.new()
query.exclude = [self];
query.shape = stepCast.shape;
query.transform = stepCast.global_transform;
var result = get_world_3d().direct_space_state.intersect_shape(query,1);
if !result:
stepCast.force_shapecast_update();
if stepCast.is_colliding() && velocity.y <= 0.0:
global_position.y = stepCast.get_collision_point(0).y;
velocity.y = 0.0;
grounded = true
else:
grounded = false
move_and_slide();
func is_grounded() -> bool:
return grounded || is_on_floor();
You could add a type to your camera here and use the variable instead of the node path
@onready var camera3d := $Camera3D as Camera3D
1 Like
Camera3D
is a type, your variable is camera3d
with no capital letters. The editor paints types as teal, where most variables are white.
If you are on a version lower than 4.3 try camera3d.global_transform.basis
1 Like
im on godot 4.3 stable version, i tried with no capital letters and this is the result… “Cannot infer the type of “direction” variable because the value doesn’t have a set type.”
soorry
1 Like
Of which I’m betting your camera3d
declaration is untyped. Another way to fix this error is to remove the colon, this will remove auto complete for the direction
variable, or explicitly declare the type.
var direction = etc... # no type (how your camera3d is)
var direction := etc... # infering type (currently erroring)
var direction: Vector3 = etc... # explicit type
1 Like
Your error says it cannot infer the type of “direction” because part of the equation does not have a type. That would be camera3d
, you could make camera3d
an explicit type, as I suggested first, or avoid trying to type direction
by removing the colon (:
) in it’s declaration.
2 Likes
oh… finality it works Thank you. and sorry for bothering you
1 Like