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

Example Script Request: Server Auth Moving Platform #2688

Open
DageTheReaper opened this issue Jan 5, 2025 · 0 comments
Open

Example Script Request: Server Auth Moving Platform #2688

DageTheReaper opened this issue Jan 5, 2025 · 0 comments

Comments

@DageTheReaper
Copy link

DageTheReaper commented Jan 5, 2025

I am looking to setup a server auth elevator in my game, but am struggling to get it to work.

This was my plan:

  • Have animated elevator on the server, which syncs to clients. The animation drives the movement, and it's sent to clients.
  • Parent player to elevator (local gravity)

Video example:

chrome_IKSmjHRbGt.mp4

But it's not working. If you could create an example script that I could expand, would hugely appreciate it. Just need pointing in the right direction.

Here's my code:

using System.Collections.Generic;
using UnityEngine;
using LiteNetLibManager;

namespace MultiplayerARPG
{
    /// <summary>
    /// This script synchronizes the platform's transform across the network
    /// and ensures that any players standing on it move and rotate seamlessly
    /// with the platform without lag or poor interpolation.
    /// Attach this script to any platform GameObject.
    /// </summary>
    [RequireComponent(typeof(LiteNetLibIdentity))]
    [RequireComponent(typeof(Collider))]
    public class PlatformSync : MonoBehaviour
    {
        private LiteNetLibIdentity identity;

        // Store the platform's last position and rotation on the server
        private Vector3 lastPosition;
        private Quaternion lastRotation;

        // List of players currently on the platform
        private List<BasePlayerCharacterEntity> playersOnPlatform = new List<BasePlayerCharacterEntity>();

        private void Awake()
        {
            identity = GetComponent<LiteNetLibIdentity>();

            // Initialize last known position and rotation
            lastPosition = transform.position;
            lastRotation = transform.rotation;

            // Ensure the Collider is set as a Trigger
            Collider collider = GetComponent<Collider>();
            if (!collider.isTrigger)
            {
                collider.isTrigger = true;
                Debug.LogWarning($"{gameObject.name}: Collider was not set as Trigger. Automatically set to Trigger.");
            }
        }

        private void FixedUpdate()
        {
            // Only the server should handle synchronization
            if (!identity.IsServer)
                return;

            // Calculate movement and rotation deltas
            Vector3 currentPosition = transform.position;
            Quaternion currentRotation = transform.rotation;

            Vector3 deltaPosition = currentPosition - lastPosition;
            Quaternion deltaRotation = currentRotation * Quaternion.Inverse(lastRotation);

            // If the platform has moved or rotated
            if (deltaPosition != Vector3.zero || deltaRotation != Quaternion.identity)
            {
                // Apply movement and rotation deltas to all players on the platform
                foreach (var player in playersOnPlatform)
                {
                    if (player == null)
                        continue;

                    // Apply positional delta
                    player.transform.position += deltaPosition;

                    // Apply rotational delta
                    player.transform.rotation = deltaRotation * player.transform.rotation;

                    // Optionally, you can adjust the player's velocity or other movement parameters here
                    // to ensure smooth movement. This depends on how your character controller handles movement.
                }

                // Update last known position and rotation
                lastPosition = currentPosition;
                lastRotation = currentRotation;

                // Optionally, you can notify clients about the platform's movement here
                // if not handled automatically by LiteNetLibIdentity
            }
        }

        private void OnTriggerEnter(Collider other)
        {
            // Detect when a player steps onto the platform
            BasePlayerCharacterEntity player = other.GetComponent<BasePlayerCharacterEntity>();
            if (player != null && !playersOnPlatform.Contains(player))
            {
                playersOnPlatform.Add(player);
                // Optional: Notify the player that they're on a platform
                // This can be used for additional effects or state changes
            }
        }

        private void OnTriggerExit(Collider other)
        {
            // Detect when a player steps off the platform
            BasePlayerCharacterEntity player = other.GetComponent<BasePlayerCharacterEntity>();
            if (player != null && playersOnPlatform.Contains(player))
            {
                playersOnPlatform.Remove(player);
                // Optional: Notify the player that they've left the platform
            }
        }

        /// <summary>
        /// Optional: Visualize the trigger area in the Unity Editor for debugging purposes.
        /// </summary>
        private void OnDrawGizmosSelected()
        {
            Gizmos.color = Color.green;
            Gizmos.DrawWireCube(transform.position, GetComponent<Collider>().bounds.size);
        }
    }
}
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

1 participant