Godot4第一人称控制器滑动结束后镜头复位问题求助
问题:滑动结束后镜头自动复位到正面,希望保持当前视角状态
我跟着YouTube博主lukky的第一人称控制器系列教程,在Godot 4中制作了一款第一人称控制器。目前遇到的问题是:每次滑动动作结束后,镜头会突然复位到正面。我希望滑动结束后能保持当前的视角状态,无需重新移动鼠标即可继续操作。
以下是我的实现代码:
extends CharacterBody3D # Player nodes @onready var neck = $Neck @onready var head = $Neck/Head @onready var eyes = $Neck/Head/Eyes @onready var standing_collision_shape = $StandingCollisionShape @onready var crouching_collisiong_shape = $CrouchingCollisiongShape @onready var up_ray_cast = $UpRayCast @onready var camera_3d = $Neck/Head/Eyes/Camera3D @onready var animation_player = $Neck/Head/Eyes/AnimationPlayer # Speed vars var current_speed = 5.0 const walking_speed = 5.0 const sprinting_speed = 8.0 const crouching_speed = 3.0 # States var walking = false var sprinting = false var crouching = false var free_looking = false var sliding = false # Slide vars var slide_timer = 0.0 var slide_timer_max = 1.0 var slide_vector = Vector2.ZERO var slide_speed = 13.0 # Head bobbing vars const head_bobbing_sprinting_speed = 22.0 const head_bobbing_walking_speed = 14.0 const head_bobbing_crouching_speed = 10.0 const head_bobbing_sprinting_intensity = 0.2 const head_bobbing_walking_intensity = 0.1 const head_bobbing_crouching_intensity = 0.05 var head_bobbing_vector = Vector2.ZERO var head_bobbing_index = 0.0 var head_bobbing_current_intensity = 0.0 # Movement vars const jump_velocity = 5.5 var crouching_depth = -0.5 var lerp_speed = 10.0 var air_lerp_speed = 3.0 var free_look_tilt_amount = 8 var last_velocity = Vector3.ZERO # Input vars var direction = Vector3.ZERO const mouse_sens = 0.1 # Get the gravity from the project settings to be synced with RigidBody nodes. var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") func _ready(): Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) func _input(event): # Mouse looking logic if event is InputEventMouseMotion: if free_looking: neck.rotate_y(deg_to_rad(-event.relative.x * mouse_sens)) neck.rotation.y = clamp(neck.rotation.y, deg_to_rad(-120), deg_to_rad(120)) else: rotate_y(deg_to_rad(-event.relative.x * mouse_sens)) head.rotate_x(deg_to_rad(-event.relative.y * mouse_sens)) head.rotation.x = clamp(head.rotation.x, deg_to_rad(-89), deg_to_rad(89)) func _physics_process(delta): # Getting movement input var input_dir = Input.get_vector("left", "right", "forward", "backward") # Handle movement state # Crouching if Input.is_action_pressed("crouch") || sliding: current_speed = lerp(current_speed, crouching_speed, delta * lerp_speed) head.position.y = lerp(head.position.y, crouching_depth, delta * lerp_speed) crouching_collisiong_shape.disabled = false standing_collision_shape.disabled = true # Slide begin logic if sprinting && input_dir != Vector2.ZERO: sliding = true slide_timer = slide_timer_max slide_vector = input_dir free_looking = true walking = false sprinting = false crouching = true elif not up_ray_cast.is_colliding(): # Standing standing_collision_shape.disabled = false crouching_collisiong_shape.disabled = true head.position.y = lerp(head.position.y, 0.0, delta * lerp_speed) if Input.is_action_pressed("sprint"): # Sprinting current_speed = lerp(current_speed, sprinting_speed, delta * lerp_speed) walking = false sprinting = true crouching = false else: # Walking current_speed = lerp(current_speed, walking_speed, delta * lerp_speed) walking = true sprinting = false crouching = false # Handle free looking if Input.is_action_pressed("free_look") || sliding: free_looking = true if sliding: eyes.rotation.z = lerp(eyes.rotation.z, -deg_to_rad(7.0), delta * lerp_speed) else: eyes.rotation.z = -deg_to_rad(neck.rotation.y * free_look_tilt_amount) else: free_looking = false neck.rotation.y = lerp(neck.rotation.y, 0.0, delta * lerp_speed) eyes.rotation.z = lerp(eyes.rotation.z, 0.0, delta * lerp_speed) # Hanle sliding if sliding: slide_timer -= delta if slide_timer <= 0: sliding = false free_looking = false # Handle headbob if sprinting: head_bobbing_current_intensity = head_bobbing_sprinting_intensity head_bobbing_index += head_bobbing_sprinting_speed * delta elif walking: head_bobbing_current_intensity = head_bobbing_walking_intensity head_bobbing_index += head_bobbing_walking_speed * delta elif crouching: head_bobbing_current_intensity = head_bobbing_crouching_intensity head_bobbing_index += head_bobbing_crouching_speed * delta if is_on_floor() && !sliding && input_dir != Vector2.ZERO: head_bobbing_vector.y = sin(head_bobbing_index) head_bobbing_vector.x = sin(head_bobbing_index / 2) + 0.5 eyes.position.y = lerp(eyes.position.y, head_bobbing_vector.y * (head_bobbing_current_intensity / 2.0), delta * lerp_speed) # can tweak 2.0 eyes.position.x = lerp(eyes.position.x, head_bobbing_vector.x * head_bobbing_current_intensity, delta * lerp_speed) else: eyes.position.y = lerp(eyes.position.y, 0.0, delta * lerp_speed) eyes.position.x = lerp(eyes.position.x, 0.0, delta * lerp_speed) # ------------MOVEMENT CODE------------ # # Add the gravity. if not is_on_floor(): velocity.y -= gravity * delta # Handle Jump. if Input.is_action_just_pressed("jump") and is_on_floor(): velocity.y = jump_velocity sliding = false # MAYBE LATER MAKE "C" SLIDE CANCEL INSTEAD OF SPACE (But still keep slide jumping) animation_player.play("jump") # Handle landing if is_on_floor(): if last_velocity.y < -10.0: animation_player.play("roll") elif last_velocity.y < -4.0: animation_player.play("landing") # Get the input direction and handle the movement/deceleration. # As good practice, you should replace UI actions with custom gameplay actions. if is_on_floor(): direction = lerp(direction, transform.basis * Vector3(input_dir.x, 0, input_dir.y).normalized(), delta * lerp_speed) else: if input_dir != Vector2.ZERO: direction = lerp(direction, transform.basis * Vector3(input_dir.x, 0, input_dir.y).normalized(), delta * air_lerp_speed) if sliding: direction = (transform.basis * Vector3(slide_vector.x, 0, slide_vector.y)).normalized() current_speed = (slide_timer + 0.1) * slide_speed if direction: velocity.x = direction.x * current_speed velocity.z = direction.z * current_speed else: velocity.x = move_toward(velocity.x, 0, current_speed) velocity.z = move_toward(velocity.z, 0, current_speed) last_velocity = velocity # RESPAWN if position.y < -10.0: position = Vector3(0, 0, 0) last_velocity = Vector3.ZERO move_and_slide()
节点结构截图:
内容的提问来源于stack exchange,提问作者Coding_Guy
相关产品推荐
相关产品推荐

