#Moving a network gameobject from another network gameobject (netcode for gameobjects)

5 messages · Page 1 of 1 (latest)

torn fjord
#

So quick overview, I have a player object and when I press a button I'm shooting a raycast that if it hits another network object it should pull that object to the player that pressed the button. My issue is I'm struggling to totally understand serverRPC, clientRPC, and how to move other objects from a client. Currently what I'm testing with to simplify things is a 3D cube with network obj component and client network transform, it moves to where I want after pressing the button, but then snaps back to where it was. The code seems to work however, if a non-host client presses the button to pull another player, but I don't think it should be working. Also keep in mind, the player objs will have the character controller on them as well (which is why I'm disabling that temporarily if it exists)
Code thats doing the lerp (script is attached to players that are pulling objs):

IEnumerator LerpPosition(NetworkObject networkObject, Vector3 targetPosition, float pullSpeed)
    {
        float journeyLength = Vector3.Distance(networkObject.transform.position, targetPosition);
        Debug.Log("len: " + journeyLength);
        float startTime = Time.time;
        float journeyTime = journeyLength / pullSpeed;

        Debug.Log("NO POS: " + networkObject.transform.position);
        while (Time.time < startTime + journeyTime)
        {
            float fracComplete = (Time.time - startTime) / journeyTime;
            Vector3 newPosition = Vector3.Lerp(networkObject.transform.position, targetPosition, fracComplete);
            //print("new pos: " + newPosition);
            networkObject.gameObject.transform.GetChild(0).gameObject.GetComponent<ServerMove>().RequestMoveClientRpc(newPosition);
            yield return null;
        }
        networkObject.gameObject.transform.GetChild(0).gameObject.GetComponent<ServerMove>().RequestMoveClientRpc(targetPosition);
        if (networkObject.transform.GetChild(0).gameObject.TryGetComponent<CharacterController>(out CharacterController cc))
        {
            cc.enabled = true;
        }

        networkObject.GetComponent<NetworkObject>().ChangeOwnership(networkObject.NetworkObjectId);
    }

Functions that are being called (script is attached to object being pulled):

[ServerRpc(RequireOwnership = false)]
    public void RequestMoveServerRpc(Vector3 newPosition)
    {
        // Server processes the move request
        MoveObject(newPosition);
    }

    [ServerRpc(RequireOwnership = false)]
    public void RequestRotateServerRpc(Quaternion newRotation)
    {
        // Server processes the rotate request
        RotateObject(newRotation);
    }

    [ClientRpc]
    public void RequestMoveClientRpc(Vector3 newPosition)
    {
        MoveObject(newPosition);
    }

    private void MoveObject(Vector3 newPosition)
    {
        // Move the object on the server
        networkTransform.transform.position = newPosition;
        transform.position = newPosition;
        //networkTransform.Teleport(newPosition, networkTransform.transform.rotation, networkTransform.transform.localScale);
        //networkTransform.SetState(newPosition, networkTransform.transform.rotation, networkTransform.transform.localScale);
    }

I've also tried just setting the transform, or setting the client transform instead of using rpcs but that doesn't seem to work either. Help fixing the code would be great, but help understanding why it doesn't work and why it has to be another way would be even better. Thank you so much in advance!

inland spoke
#

it simply need to be like that
1- after hitting the raycast and getting the other player Network ID
2- call a server rpc and pass the client id as a parameter
3- the server RPC will call a client RPC , because only server can call ClientRPCs
4- the clientRPC will move the player

#

here an example code from ChatGPT because i mostly use FishNet , but both have same concept

using Unity.Netcode;
using UnityEngine;

public class MyNetworkBehaviour : NetworkBehaviour
{
    // This method will be called by the client to request the server to forward a message to another client.
    [ServerRpc(RequireOwnership = false)]
    public void SendMessageToClientServerRpc(ulong targetClientId, string message, ServerRpcParams rpcParams = default)
    {
        SendMessageToClientClientRpc(targetClientId, message);
    }

    // This method will be called by the server to send the message to the specified client.
    [ClientRpc]
    private void SendMessageToClientClientRpc(ulong targetClientId, string message, ClientRpcParams rpcParams = default)
    {
        // Ensure this message is only received by the intended client
        if (NetworkManager.Singleton.LocalClientId == targetClientId)
        {
            HandleMessage(message);
        }
    }

    private void HandleMessage(string message)
    {
        // Handle the received message (e.g., display it in the UI)
        Debug.Log("Received message: " + message);
    }
}
torn fjord
inland spoke
#

it doesnt matter because clientRPC is called on the client side not on server or the sending Client