Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiplayer Moving Platform #223

Closed
andrewmunro opened this issue May 14, 2024 · 6 comments
Closed

Multiplayer Moving Platform #223

andrewmunro opened this issue May 14, 2024 · 6 comments

Comments

@andrewmunro
Copy link

Hey, cool library!

I've been playing about with it and got some players running around really easily. Would you happen to have any examples of how you could create moving platforms that the player can walk around on? I'm thinking for things like vehicles, e,g a boat or a space ship.

I've tried creating a basic static body that moves around, then updating the player's velocity based on the platform's velocity, but unfortunately the player just slides off. This seems to work without networking, but I can't seem to get it to work with my RollbackSynchronizer.

Any thoughts?

@albertok
Copy link
Contributor

Hey @andrewmunro

Could you post what your player rollback_tick code looks like and what state properties you have configured in the RollbackSynchronizer Node for that player?

As far as I know if player is a CharacterBody type node it should just work. The fact you mention that it works without networking makes me think the client is doing movement changes outside the rollback_tick function.

@andrewmunro
Copy link
Author

andrewmunro commented May 15, 2024

Heya, appreciate the help! Ok so I got it working, it turns out I was calculating my velocity slightly wrong using move_and_collide, the fix was to no longer multiply by NetworkTime.physics_factor, which seems to only be a problem for move_and_slide()

It does now move with the platform it's standing on, although there's a slight delay for remote players when the platform starts moving (see gif below), I assume this is because of the interpolation delay. Not sure the best way to get around this, here's my code if you have any suggestions or improvements.

func _rollback_tick(delta, _tick, _is_fresh):
	# Add the gravity.
	if not is_on_floor():
		velocity.y -= gravity * delta

	# Handle jump.
	if input.movement.y > 0 and is_on_floor():
		velocity.y = jump_velocity * input.movement.y
		
	pitch_pivot.rotation.x = input.pitch
	yaw_pivot.rotation.y = input.yaw

    # Handle movement
	var input_dir = input.movement
	var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.z)).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 with parent vehicle
	if raycast.is_colliding():
		var parent = raycast.get_collider()
		if parent.is_in_group("vehicles"):
			velocity += parent.velocity

	velocity *= NetworkTime.physics_factor
	move_and_slide()
	velocity /= NetworkTime.physics_factor
extends StaticBody3D

@export_group("Settings")
@export var speed = 5.0

@onready var input = $Input
@export var velocity = Vector3.ZERO

func _rollback_tick(delta, _tick, _is_fresh):
	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir = input.movement
	var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.z)).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)

	# velocity *= NetworkTime.physics_factor
	move_and_collide(velocity * delta)
	# velocity /= NetworkTime.physics_factor

In the boat, I'm syncing the velocity and global_transform in both the RollbackSyncronizer and TickInterpolator.
In the player, I'm syncing just the global_transform in both the RollbackSyncronizer and TickInterpolator.

raft2

I have a hosted version available here: https://island.mun.sh/.

@andrewmunro
Copy link
Author

andrewmunro commented May 17, 2024

Ok I'm back after doing some more experimenting. I've decided to scrap syncing and applying boat velocity to the player because I was having all sorts of issues with sliding due to the physics calculations.

Instead I'm attempting to try make the player a child of the boat. I can't use reparent(), because this seems to break the Synchronizer. I've created a container node for the player and I'm setting this transform to the boat's transform in each rollback_tick.

This almost works, I no longer have any sliding issues. Instead, I'm having lots of really bad interpolation issues, I think because I'm explicitly setting the parent's position rather than interpolating it. Here's what I have so far, any suggestions would be much appreciated 🙈

Player:

image
image
image

Raft (Boat):

image
image

@albertok
Copy link
Contributor

@andrewmunro

Few things to try, I'm not sure if they will help:

  1. Move the 'move with vehicle' code to be before applying user input
  2. Sync the velocity in the Players RollbackSynchronizer state, it might make the interpolation more predicatable

@elementbound
Copy link
Contributor

Hey @andrewmunro,

Closing this ticket as it has been a while since the last comment. Nonetheless, feel free to open another issue, referring to this one! And thanks @albertok for the help!

@elementbound
Copy link
Contributor

FYI, a moving platform example was recently added to Forest Brawl: #313

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants