Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved Error with increasing values of a Player_Script from a button (NGO)

Discussion in 'Multiplayer' started by x77o, Sep 11, 2023.

  1. x77o

    x77o

    Joined:
    May 28, 2021
    Posts:
    5
    Hello all,
    I am new to NGO and have been working on a couple small projects to try to get the hang of it however I have become stuck and cannot figure out why my script is not working. I haven't been able to figure out what I'm doing wrong exactly however I do have a theory at the bottom of this message.

    I have declared some variables in my Player_Script as the following:

    public NetworkVariable<int> maxMana = new NetworkVariable<int>(10);
    public NetworkVariable<int> maxIntel = new NetworkVariable<int>(10);

    public NetworkVariable<int> currentMana = new NetworkVariable<int>(1);
    public NetworkVariable<int> currentIntel = new NetworkVariable<int>(0);

    public NetworkVariable<int> floatingMana = new NetworkVariable<int>(0);
    public NetworkVariable<int> floatingIntel = new NetworkVariable<int>(0);

    public NetworkVariable<int> inactiveMana = new NetworkVariable<int>(0);
    public NetworkVariable<int> inactiveIntel = new NetworkVariable<int>(0);


    This script spawns on a gameobject containing a Network Object variable when a client joins the game using a network manager.
    I have another script attatched to a TurnSystem gameobject which is always in the scene, this also has a network object component. I have referenced the player script this way:

    void Awake() {
    pScript = new Player_Script();
    }


    I then call the following function on the press of a button:

    public void TurnStart() {
    Debug.Log("1");
    // Increaseing resources by 1 each turn until they reach the maximum.
    if (pScript.currentMana.Value < pScript.maxMana.Value) {
    Debug.Log(pScript.currentMana.Value);
    pScript.currentMana.Value += 1;
    }
    Debug.Log("2");
    if (pScript.currentIntel.Value < pScript.maxIntel.Value) {
    pScript.currentMana.Value += 1;
    }
    Debug.Log("3");
    // Setting floating resources to be equal to current minus inactive.
    pScript.floatingMana.Value = pScript.currentMana.Value - pScript.inactiveMana.Value;
    pScript.floatingIntel.Value = pScript.currentIntel.Value - pScript.inactiveIntel.Value;
    Debug.Log("4");
    // Updating mana and intel text to reflect correct numbers.
    string playerId = (pScript.OwnerClientId + Convert.ToUInt16(1)).ToString(); // get current playerid to update the correct value
    pScript.updateResourceTextClientRpc(playerId, "Mana", pScript.floatingMana.Value);
    pScript.updateResourceTextClientRpc(playerId, "Intel", pScript.floatingIntel.Value);
    Debug.Log("5");
    }


    The above function executes:
    > Debug.Log(pScript.currentMana.Value);
    Correctly before producing the following error to console.


    public void test() {
    pScript.TurnStart();
    }


    The error I receive in console:

    NullReferenceException: Object reference not set to an instance of an object
    Unity.Netcode.NetworkMetrics.GetObjectIdentifier (Unity.Netcode.NetworkObject networkObject) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Metrics/NetworkMetrics.cs:527)
    Unity.Netcode.NetworkMetrics.TrackRpcSent (System.UInt64 receiverClientId, Unity.Netcode.NetworkObject networkObject, System.String rpcName, System.String networkBehaviourName, System.Int64 bytesCount) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Metrics/NetworkMetrics.cs:342)
    Unity.Netcode.NetworkBehaviour.__endSendServerRpc (Unity.Netcode.FastBufferWriter& bufferWriter, System.UInt32 rpcMethodId, Unity.Netcode.ServerRpcParams serverRpcParams, Unity.Netcode.RpcDelivery rpcDelivery) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.6.0/Runtime/Core/NetworkBehaviour.cs:102)
    Player_Script.IncreaseCurrentManaServerRpc () (at Assets/Scripts/Player_Script.cs:126)
    Player_Script.TurnStart () (at Assets/Scripts/Player_Script.cs:75)
    TurnSystem.test () (at Assets/Scripts/TurnSystem.cs:28)
    UnityEngine.Events.InvokableCall.Invoke () (at <0e8168edc7c74c6c8898f77f2be4d6b4>:0)
    UnityEngine.Events.UnityEvent.Invoke () (at <0e8168edc7c74c6c8898f77f2be4d6b4>:0)
    UnityEngine.UI.Button.Press () (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
    UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
    UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
    UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
    UnityEngine.EventSystems.EventSystem:Update() (at ./Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:530)


    My current theory is that the error is to do with the script object being declared on awake and that it should somehow instead be called to reference the Player_Script which is contained within the client that pressed the button however I cannot figure out how to do that or if that is even really the problem.
    Any help would be greatly appreciated.
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    603
    To get a reference to the player when they spawn you can use their OnNetworkSpawn call and add them to TurnSystem there. This is a quick example of the classes, the player is only added to the host's TurnSystem:
    Code (CSharp):
    1. public class SpawnedPlayer : NetworkBehaviour
    2. {
    3.     public override void OnNetworkSpawn()
    4.     {
    5.         base.OnNetworkSpawn();
    6.  
    7.         if (IsHost)
    8.         {
    9.             TurnSystem.Singleton.AddPlayer(this);
    10.         }
    11.     }
    12. }
    Code (CSharp):
    1. public class TurnSystem : MonoBehaviour
    2. {
    3.     public static TurnSystem Singleton;
    4.  
    5.     [SerializeField] List<SpawnedPlayer> spawnedPlayers;
    6.  
    7.     private void Awake()
    8.     {
    9.         Singleton = this;
    10.         spawnedPlayers = new List<SpawnedPlayer>();
    11.     }
    12.  
    13.     public void AddPlayer(SpawnedPlayer spawnedPlayer)
    14.     {
    15.         spawnedPlayers.Add(spawnedPlayer);
    16.     }
    17. }
     
    x77o likes this.
  3. x77o

    x77o

    Joined:
    May 28, 2021
    Posts:
    5
    Hey!
    Thanks so much that's a ton of help just want to make sure of something, if I change (isHost) to (isServer) so that I can run all players as clients is that going to cause any issues later on with this approach? I don't assume so but I'd much rather be sure now than find out in a few days/weeks and have to backtrack!
     
  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    603
    If you're running a host then all players are clients, just the host is the server as well. IsServer, IsHost and IsClient are all true for the host. For clarity if you're running a host use IsHost, if you're running a dedicated server use IsServer.
     
    x77o likes this.
  5. x77o

    x77o

    Joined:
    May 28, 2021
    Posts:
    5
    That makes complete sense thanks so much!
     
    cerestorm likes this.