Reputation: 13
I have character code:
extends CharacterBody3D
@onready var camera_mount = $camera_mount
@onready var animation_player = $visuals/mixamo_base/AnimationPlayer
@onready var visuals = $visuals
@onready var camera_3d = $camera_mount/Camera3D
@export var is_current:bool = true
@export var is_main = true
@export var SPEED = 5.0
@export var JUMP_VELOCITY = 4.5
@export var SENSIVITY = 0.05
var walk_speed = 3.0
var run_speed = 5.0
var is_running = false
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready() -> void:
if is_main:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
if is_main:
if event is InputEventMouseMotion:
rotate_y(deg_to_rad(-event.relative.x*SENSIVITY))
visuals.rotate_y(deg_to_rad(event.relative.x*SENSIVITY))
camera_mount.rotate_x(deg_to_rad(-event.relative.y*SENSIVITY))
func _physics_process(delta):
if is_main:
camera_3d.current = is_current
if not is_on_floor():
velocity.y -= gravity * delta
if Input.is_action_pressed("run"):
SPEED = run_speed
is_running = true
else:
is_running = false
SPEED = walk_speed
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
if Input.is_action_just_pressed("ui_cancel"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
if animation_player.current_animation != "walking" && is_running == false:
animation_player.play("walking")
if animation_player.current_animation != "running" && is_running:
animation_player.play("running")
visuals.look_at(position+direction)
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
else:
if animation_player.current_animation != "idle":
animation_player.play("idle")
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
camera_mount.rotation.x = clamp(camera_mount.rotation.x,
deg_to_rad(-90),
deg_to_rad(70)
)
move_and_slide()
And the script responsible for changing the character in the game using a button:
extends Node3D
@onready var player_1 = $"../Player1"
@onready var player_2 = $"../Player2"
func _physics_process(_delta):
if Input.is_action_just_pressed("switch_player"):
if player_1.is_main:
player_1.is_main = false
player_2.is_main = true
player_2.is_current = true
player_1.animation_player.play("idle")
else:
player_1.is_main = true
player_2.is_main = false
player_1.is_current = true
player_2.animation_player.play("idle")
The problem is that if you change the player while the one you were playing for before is in the air, then he freezes in this position. How can I make it so that as soon as I change a player, the one I played for before falls to the ground, i.e. began to succumb to the laws of physics?
Upvotes: 1
Views: 56
Reputation: 653
I've made something similar in concept so I might have an idea on what went wrong. You need to transfer property values from the old player to the new one. That way it'll seem like player_2
picks up exactly where player_1
left off.
Something like this:
extends Node3D
@onready var player_1 = $"../Player1"
@onready var player_2 = $"../Player2"
const TRANSFER_PROPERTIES = ["velocity", "is_running", "walk_speed"] # add whatever variable names you need
func transfer_values(from, to):
to.set_physics_process(false) # avoid running the _physics_process while variables are being transfered
from.set_physics_process(false)
for prop in TRANSFER_PROPERTIES:
to[prop] = from[prop]
to.set_physics_process(true)
from.set_physics_process(true)
func _physics_process(_delta):
if Input.is_action_just_pressed("switch_player"):
if player_1.is_main:
transfer_values(player_1, player_2)
player_1.is_main = false
player_2.is_main = true
player_2.is_current = true
player_1.animation_player.play("idle")
else:
transfer_values(player_2, player_1)
player_1.is_main = true
player_2.is_main = false
player_1.is_current = true
player_2.animation_player.play("idle")
Some references that might help you out in the future if things get more complex:
get_script()
get_script_property_list()
Upvotes: 0