following this tutorial https://youtu.be/V4a_J38XdHk?t=1367 at roughly that chapter, he does the thing to like synchronize the input direction, but i don’t know how to replicate it in my project since im doing 3d and i have different movement (for example I don’t have only 1 variable “direction”, but I also have “input_dir” etc)
This is my current character script (equivalent to his multiplayer_controller script basically):
extends CharacterBody3D
@onready var camera = $Camera3D
@onready var skeleton_3d = $metarig/Skeleton3D
const SPEED = 10
const JUMP_VELOCITY = 10
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
var MouseSensivity = 0.002
var camerarotation = Vector2(0,0)
@export var player_id := 1:
set(id):
player_id = id
func _apply_animations(delta):
if velocity.x == 0 and velocity.z == 0:
$AnimationPlayer.play("Idle")
else:
$AnimationPlayer.play("walk")
func _apply_movement_from_input(delta):
if not is_on_floor():
velocity.y -= gravity * delta
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
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)
move_and_slide()
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
if event.is_action_pressed("ui_cancel"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if event.is_action_pressed("leftclick"):
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
if event is InputEventMouseMotion:
var MouseEvent = event.relative *MouseSensivity
CameraLook(MouseEvent)
func CameraLook(Movement: Vector2):
camerarotation += Movement
camerarotation.y = clamp(camerarotation.y, -1.5,1.2)
transform.basis = Basis()
camera.transform.basis = Basis()
rotate_object_local(Vector3(0,1,0), -camerarotation.x)
func _physics_process(delta):
if multiplayer.is_server():
_apply_movement_from_input(delta)
if not multiplayer.is_server() || MultiplayerManager.host_mode_enabled:
_apply_animations(delta)
Any help would be appreciated, let me know if more information are needed.
It would be very similar, the only difference I can see is using Input.get_vector for 3D instead of Input.get_axis for the x axis. You can follow along seamlessly.
This method of multiplayer will cause tremendous input lag and potentially desynchronize players, usually it’s better to synchronize positions directly and check if movements are valid on the server if you want to catch cheaters.
Who is allowed to edit what. It is used by the RPC configs and synchronizers. By default the server is authority of everything, individual players and components must be changed with set_multiplayer_authority(id)
Btw MultiplayerManager.host_mode_enabled is giving me errors, any suggestion? I have no idea of what this is and its invalid apparently (and if i remove it the client just cant move)
I am not sure why that’s in the code, host_mode_enabled is used once and the same as multiplayer.is_server(). Where it’s used creates a strange is_server or not is_server condition that should always be true.
and for some reason i can control both players from server and from client i can control only server. is this supposed to happen right now and i just have to continue the tutorial or am i missing something
You will have to continue the tutorial, they talk about disabling the physics_process and process functions for non-authority characters. Something along these lines to look out for
func _ready() -> void:
if not is_multiplayer_authority():
set_process(false)
set_physics_process(false)