- Home /
UNet: Server only non-player GameObject NullReferenceException on client
Hello,
I try to setup a network game. In my Player object I use Commands and TargetRPCs to get some data from a GameObject with server authority. (MasterList) This works fine:
public override void OnStartLocalPlayer()
{
CmdGetRandomData();
}
[Command]
void CmdGetRandomData()
{
masterList = FindObjectOfType<MasterList>();
masterList.LoadDataAtGameStart();
string str = masterList.GetRandomDataIdsForRpcCall(startCount);
TargetReceiveRandomData(connectionToClient, str);
}
[TargetRpc]
void TargetReceiveRandomData(NetworkConnection target, string str)
{
string[] dataIds = str.Split(';');
foreach (string id in dataIds) {
CmdGetDataById(int.Parse(id));
}
}
But when I try something similar in another GameObject that isn't a Player, I get a NullReferenceException. I added the GameObject to the NetworkManager and spawned it in the network, so I can see the object on the client instance. The GameObject has no checkbox set in the NetworkIdentity component.
I use this code:
void Start()
{
Invoke("CmdGetDataForToday", 2);
}
[Command]
void CmdGetDataForToday()
{
masterList = FindObjectOfType<MasterList>();
string str = masterList.GetRandomDataIdsForRpcCall(maxItemsInMenu);
TargetReceiveMenuData(Player.GetComponent<NetworkIdentity>().connectionToClient, str);
}
[TargetRpc]
void TargetReceiveBuyMoviesMenuData(NetworkConnection target, string str)
{
string[] dataIds = str.Split(';');
foreach (string id in dataIds) {
CmdGetDataById(int.Parse(id));
}
}
I get the NullReferenceException at "string str = masterList.GetRandomDataIdsForRpcCall(maxItemsInMenu);". I don't understand that, because the MasterList is server only and called in a Command.
Answer by Vencarii · Mar 05, 2019 at 06:40 PM
First of all, thanks for your help so far @ConcanoPayno ! :)
But I still don't get it to work, maybe I have a conceptual error and do things fundamentally wrong. So I try to explain the stuff I try to achieve as exact as possible, maybe someone has the time and joy to help.
Explanation: I have a GameObject called "MasterList". It has some gameplay data in it that should be handled by the server. The data is shared by all other players and every record must be unique in the game world, so no two players are allowed to have the same record. My initial plan was to spawn the "MasterList" as server only, but now I didn't set any option in Network Identity.
At game start I receive 5 entries from "Master List" for every player. This works fine for all, Host/Client and Standalone Client.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Player : NetworkBehaviour
{
// start settings
[SerializeField] int startDataCount = 5;
MasterList masterList;
List<Data> dataList = new List<Data>();
public override void OnStartLocalPlayer()
{
gameObject.tag = "LocalPlayer";
CmdGetRandomStartData();
}
[Command]
void CmdGetRandomStartData()
{
masterList = FindObjectOfType<MasterList>();
if (masterList.AllDataList.Count == 0) {
masterList.LoadDataAtGameStart();
}
string dataString = masterList.GetRandomDataIdsForRpcCall(startDataCount);
TargetReceiveStartData(connectionToClient, dataString);
}
[TargetRpc]
void TargetReceiveStartData(NetworkConnection target, string data)
{
string[] dataId = data.Split(';');
foreach (string id in dataId) {
CmdGetDataById(int.Parse(id)); // gets detailed data info back, I spare this method for now
}
Invoke("DebugPlayerData", .5f);
}
}
When this is done I try to receive 10 more records. I want to use these records to fill a UI menu with the data. The GameObject BuySellData has no checkbox set in Network Identity as well.
Player Object:
// called in the Player object at the end of OnStartLocalPlayer()
BuySellData buySellData = FindObjectOfType<BuySellData>();
buySellData.Player = this;
buySellData.CmdGetBuyDataForToday();
UI Menu (BuySellData):
[Command]
public void CmdGetBuyDataForToday()
{
masterList = FindObjectOfType<MasterList>();
string moviesString = masterList.GetRandomDataIdsForRpcCall(maxItemsInMenu);
TargetReceiveBuyDataMenuData(Player.GetComponent<NetworkIdentity>().connectionToClient, dataString);
}
[TargetRpc]
void TargetReceiveBuyDataMenuData(NetworkConnection target, string data)
{
string[] dataIds = data.Split(';');
foreach (string id in dataIds) {
CmdGetDataById(int.Parse(id)); // spared for now again
}
}
So you can see that the method are mostly identical. They work in the Player object, but they don't work in BuySellData. I don't get any error message on the client, there's just no data received from "MasterList".
Is BuySellData.Player field synced ? If not, this line TargetReceiveBuyData$$anonymous$$enuData(Player.GetComponent<NetworkIdentity>().connectionToClient, dataString);
just get the connectionToClient
of the server object, because it's executed on the server. On the other hand, if BuySellData has no authority, you can't do buySellData.CmdGetBuyDataForToday();
You could do ins$$anonymous$$d something like this:
// called in the Player object at the end of OnStartLocalPlayer()
BuySellData buySellData = FindObjectOfType<BuySellData>();
buySellData.Player = this;
CmdGetBuyDataForToday( buySellData );
And this function to Player
//This funcion is on the Player script
[Command]
public void CmdGetBuyDataForToday ( BuySellData bsd )
{
bsd.GetBuyDataForToday( this.connectionToClient );
}
And this one to BuySellData
//This one is on the BuySellData script
public void GetBuyDataForToday( NetworkInstanceId connectionToClient)
{
masterList = FindObjectOfType<$$anonymous$$asterList>();
string moviesString = masterList.GetRandomDataIdsForRpcCall(maxItemsIn$$anonymous$$enu);
TargetReceiveBuyData$$anonymous$$enuData(connectionToClient, dataString);
}
I restructured it a little bit differently. I put all the Commands and TargetRpcs in the Player object and got the reference to the BuySellData there, this works. It may not be the best solution, but it works for now.
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
Networking-multplayer issue 1 Answer
[Mirror Networking] NullReferenceException on player when trying to start server a second time 1 Answer
How can I use a GameObject to hold all references in a network game? 0 Answers
Help with multiplayer chat functionality, null reference exception using networkmanager 0 Answers