You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity重写OnServerAddPlayer未生效,玩家颜色场景切换后无法保留

Fixing Persistent Player Color Across Scenes with Custom NetworkManager

It sounds like your color changes aren't sticking because you're not properly storing the player's color state server-side and initializing it when the player re-spawns during scene switches. Here's a step-by-step solution to get this working:

1. Use a Network-Synced Variable for Player Color

First, ensure your player's color is stored in a [SyncVar] so changes automatically propagate to all clients. Add this to your player's NetworkBehaviour script:

using UnityEngine;
using UnityEngine.Networking;

public class PlayerColorHandler : NetworkBehaviour
{
    // SyncVar with a hook to update visuals when color changes
    [SyncVar(hook = nameof(OnColorUpdated))]
    private Color _currentColor = Color.white;

    // Call this when the player touches a paint splatter (client-side only)
    public void ApplyPaintColor(Color newColor)
    {
        if (!isLocalPlayer) return; // Only local player can request color changes
        CmdUpdatePlayerColor(newColor);
    }

    // Command to send color change request to server
    [Command]
    private void CmdUpdatePlayerColor(Color newColor)
    {
        _currentColor = newColor;
        // Save this color to server-side storage tied to the player's connection
        var networkManager = FindObjectOfType<CustomNetworkManager>();
        networkManager.SavePlayerColor(connectionToClient, newColor);
    }

    // Hook that updates the player's visuals when the SyncVar changes
    private void OnColorUpdated(Color oldColor, Color newColor)
    {
        Renderer playerRenderer = GetComponent<Renderer>();
        if (playerRenderer != null)
        {
            playerRenderer.material.color = newColor;
        }
    }
}

2. Store Player Color Data Server-Side

In your custom NetworkManager, add a dictionary to track each player's color using their connection ID as the key. This ensures the color persists even when scenes change:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections.Generic;

public class CustomNetworkManager : NetworkManager
{
    private Dictionary<int, Color> _playerColorStorage = new Dictionary<int, Color>();

    // Call this from the player's command to save color
    public void SavePlayerColor(NetworkConnection conn, Color color)
    {
        if (_playerColorStorage.ContainsKey(conn.connectionId))
        {
            _playerColorStorage[conn.connectionId] = color;
        }
        else
        {
            _playerColorStorage.Add(conn.connectionId, color);
        }
    }

    // Clean up data when a player disconnects
    public override void OnServerDisconnect(NetworkConnection conn)
    {
        base.OnServerDisconnect(conn);
        if (_playerColorStorage.ContainsKey(conn.connectionId))
        {
            _playerColorStorage.Remove(conn.connectionId);
        }
    }
}

3. Initialize Player Color in OnServerAddPlayer

Now, override OnServerAddPlayer to retrieve the saved color and apply it to the newly spawned player before adding them to the network:

public override void OnServerAddPlayer(NetworkConnection conn)
{
    // Spawn your player prefab
    GameObject playerInstance = Instantiate(playerPrefab);

    // Get the saved color for this connection (default to white if no data exists)
    Color savedColor = Color.white;
    if (_playerColorStorage.ContainsKey(conn.connectionId))
    {
        savedColor = _playerColorStorage[conn.connectionId];
    }

    // Assign the saved color to the player's SyncVar
    PlayerColorHandler colorHandler = playerInstance.GetComponent<PlayerColorHandler>();
    if (colorHandler != null)
    {
        colorHandler._currentColor = savedColor;
        // The SyncVar hook will automatically update the visuals
    }

    // Add the player to the network connection
    NetworkServer.AddPlayerForConnection(conn, playerInstance);
}

Troubleshooting Tips

  • Confirm SyncVar is working: Add debug logs in OnColorUpdated and CmdUpdatePlayerColor to verify color changes are being sent to the server and synced back to clients.
  • Check NetworkManager persistence: Ensure your CustomNetworkManager is marked with DontDestroyOnLoad so it (and the color storage dictionary) survives scene switches.
  • Verify player prefab setup: Make sure your player prefab has a NetworkIdentity component, and that the PlayerColorHandler script is attached to it.

内容的提问来源于stack exchange,提问作者BenjaFriend

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:19:06