Owner has control over all spawned playerObjects

Hi all, I am kind of running out of idea’s. I’m interacting with netcode and ServerRpc for the first time. I decided to use ServerRpc for spawning my playerPrefabs as I want to potentially have different prefabs for each player, as well as place them in specific locations of the map. But for some reason, whenever a client connects, it is unable to control its own playerPrefab and the host controls them all.

on top of this, even with having all the prefabs within the networkPrefabs of the network manager, and having network transforms on them too, they only seem to move on the host and not on the clients. Would anyone be able to give me any insight into this?

The code for the spawning of players is:

using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;

public class PlayerSpawns : NetworkBehaviour
{
    public GameObject playerPrefab;

    // List to store used spawn points
    private List<Transform> usedSpawnPoints = new List<Transform>();


    public override void OnNetworkSpawn()
    {
        base.OnNetworkSpawn();
        PlayerSpawnsServerRpc();
        // Find an available spawn point
    }

    [ServerRpc(RequireOwnership = false)]
    private void PlayerSpawnsServerRpc()
    {
        if (!IsOwner) Destroy(this);
        ulong clientId = OwnerClientId;
        Transform spawnPoint = GetAvailableSpawnPoint();
        if (spawnPoint != null)
        {
            // Spawn the specified prefab as a player object at the selected spawn point
            NetworkObject spawnedObject = Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation).GetComponent<NetworkObject>();
            spawnedObject.SpawnAsPlayerObject(clientId);

            // Mark the spawn point as used
            usedSpawnPoints.Add(spawnPoint);
        }
    }


    private Transform GetAvailableSpawnPoint()
    {
        Transform[] spawnPoints = transform.GetComponentsInChildren<Transform>();
        List<Transform> availableSpawnPoints = new List<Transform>();

        foreach (Transform spawnPoint in spawnPoints)
        {
            if (spawnPoint != transform && !usedSpawnPoints.Contains(spawnPoint))
            {
                availableSpawnPoints.Add(spawnPoint);
            }
        }

        if (availableSpawnPoints.Count > 0)
        {
            int randomIndex = UnityEngine.Random.Range(0, availableSpawnPoints.Count);
            return availableSpawnPoints[randomIndex];
        }

        return null;
    }
}

And the code I’m using for player movement is:

using UnityEngine;
using Unity.Netcode;

public class PlayerMovement : NetworkBehaviour
{
    public tankValues tankData;
    private float movementSpeed;
    private float turnSpeed;
    private Rigidbody rb;

    private void Start()
    {
        rb = GetComponent<Rigidbody>();
        movementSpeed = tankData.movementSpeed;
        turnSpeed = tankData.tankRotationSpeed;
    }

    private void FixedUpdate()
    {
        // Only allow the owner to update movement
        if (!IsLocalPlayer)
            return;

        float moveInput = Input.GetAxis("Vertical");
        float turnInput = Input.GetAxis("Horizontal");

        Vector3 movement = transform.forward * moveInput * movementSpeed * Time.fixedDeltaTime;
        rb.MovePosition(rb.position + movement);

        float turn = turnInput * turnSpeed * Time.fixedDeltaTime;
        Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f);
        rb.MoveRotation(rb.rotation * turnRotation);
    }
}

Hi,
What is “PlayerSpawns” object? Is this Scene-object?
If it is scene-object the owner is Host.
And “PlayerSpawnsServerRpc()” trigger only host side. So, “ulong clientId = OwnerClientId;” line returns always HostId.

The PlayerSpawns script is within the scene yeah, it’s attached to a spawnfield object that contains 4 different gameobjects with spawn locations.

Aha, okay, so how would I make it so that it does it for both server and client side? I want it to obviously be separate, since the host is technically just a client whos hosting the server, so each client can control their own playerPrefab…

Also, any idea on why it’s not updating the transforms for the client?

I can give some simple suggestion.
Listen the “NetworkManager.Singleton.OnClientConnectedCallback” callback for connected clients on Host side. Then Instantiate PlayerObject with “SpawnAsPlayerObject” method.