I know I did a similar post a day ago but I just ran into another problem. I have been making a 2 player multiplayer game in Godot. When I tried to sync animations with the host and the client, nothing is happening even though I am sending all the right info through to the client. I send the animation state to the client and then the client should play the animation state.
I don't know really anything I can do to troubleshoot this problem.
Player.gd:
extends KinematicBody2D
const ACCELERAION = 512
const MAX_SPEED = 64
const FRICTION = 0.25
const GRAVIY = 200
const JUMP_FORCE = 128
var motion = Vector2.ZERO
var animationState = ""
onready var sprite = $Sprite
onready var animationPlayer = $AnimationPlayer
remote func _set_positon_and_animation_state(pos, hFlip, animState):
global_transform.origin = pos
sprite.flip_h = hFlip
animationState = animState
func _physics_process(delta):
var xInput = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
print(xInput)
if xInput != 0:
animationState = "Running"
motion.x += xInput * ACCELERAION * delta
motion.x = clamp(motion.x, -MAX_SPEED, MAX_SPEED)
if is_network_master():
sprite.flip_h = xInput < 0
else:
animationState = "Standing"
motion.y += GRAVIY * delta
if is_on_floor():
if xInput == 0:
motion.x = lerp(motion.x, 0, FRICTION)
if Input.is_action_just_pressed("ui_up"):
motion.y = -JUMP_FORCE
else:
animationState = "Jumping"
if Input.is_action_just_released("ui_up") and motion.y < -JUMP_FORCE / 2:
motion.y = -JUMP_FORCE / 2
if xInput == 0:
motion.x = lerp(motion.x, 0, 0.2)
if is_network_master():
motion = move_and_slide(motion, Vector2.UP)
rpc_unreliable("_set_positon_and_animation_state", global_transform.origin, sprite.flip_h, animationState)
animationPlayer.play(animationState)
World.gd
extends Node2D
onready var playerSpawn = $SpawnPoint
onready var playerSpawn2 = $SpawnPoint2
func _ready():
var player1 = preload("res://Player.tscn").instance()
player1.set_name(str(get_tree().get_network_unique_id())) #Gives the host player a unique id when they join the server
player1.set_network_master(get_tree().get_network_unique_id()) # Specifies this player owns a different character controller than the other player
player1.set_global_transform(playerSpawn.global_transform)
add_child(player1)
var player2 = preload("res://Player.tscn").instance()
player2.set_name(str(Globals.player2id)) #Gets the id the player got when they joined the game cant use the same function as player 1 because it will give us the same id and crash the game
player2.set_network_master(Globals.player2id) # Specifies this player owns a different character controller than the other player
player2.set_global_transform(playerSpawn2.global_transform)
add_child(player2)
What am I doing wrong everything else seems to be working just fine!
You make an RPC to _set_positon_and_animation_state
passing animationState
:
rpc_unreliable("_set_positon_and_animation_state", global_transform.origin, sprite.flip_h, animationState)
And then in the code for _set_positon_and_animation_state
you take that animationState
argument in the animState
parameter, and set the animationState
field with it:
remote func _set_positon_and_animation_state(pos, hFlip, animState):
global_transform.origin = pos
sprite.flip_h = hFlip
animationState = animState
But you don't use that value of animationState
. Instead what I see is that you overwrite it in _physics_process
(depending on input), before calling play:
animationPlayer.play(animationState)
That also begs the question of how you will handle input.
I think you would want to call play
in _set_positon_and_animation_state
:
remote func _set_positon_and_animation_state(pos, hFlip, animState):
global_transform.origin = pos
sprite.flip_h = hFlip
# animationState = animState
animationPlayer.play(animState)
In my mind synchronizing animation also implies timing. There would be some delay due to the network to account for if you want to handle that. But get the animation playing first.