Unet: Spawn bullet - client does not have a reference of bullet
Hi there,
i try to make turrets fire bullets on unet. It is working for the host but if i shoot on the client it says: NullReferenceException: Object reference not set to an instance of an object TurretController.CmdShoot (UnityEngine.GameObject _firePos, UnityEngine.GameObject _shell) (at Assets/Skripts/Player/Turret/TurretController.cs:116)
The shell is registered on the NetworkManager and it is referenced on the Turret itself.
Here is my code so far:
void FixedUpdate()
{
ControlTurrets();
}
void ControlTurrets()
{
for (int i = 0; i < turrets.Length; i++)
{
if (turrets[i] != null)
{
Turret _turret = turrets[i].GetComponent<Turret>();
GameObject _target = _turret.GetTarget();
GameObject _shell = _turret.GetShell();
targetController.SelectTarget(_turret);
Turn(_turret, _target);
Pitch(_turret, _target);
if (Input.GetMouseButtonDown(0))
{
Shoot(_turret, _shell);
}
}
else
{
Debug.LogError("No turret referenced.");
}
}
}
[Client]
void Shoot(Turret _turret, GameObject _shell)
{
Debug.Log(gameObject.name + ": " + _shell);
if (!isLocalPlayer)
{
return;
}
Transform _turretHead = _turret.transform.FindChild("Head");
GameObject _firePos = _turretHead.transform.FindChild("FireTransform").gameObject;
CmdShoot(_firePos, _shell);
}
[Command]
void CmdShoot(GameObject _firePos, GameObject _shell)
{
GameObject shellInstance = Instantiate(_shell, _firePos.transform.position, _firePos.transform.rotation) as GameObject;
// Set the shell's velocity to the launch force in the fire position's forward direction.
shellInstance.GetComponent<Rigidbody>().velocity = shellSpeed * _firePos.transform.forward;
NetworkServer.Spawn(shellInstance);
}
I googled for an answer but i didnt find a solution to my problem :( It seems like the client is for some reason not getting any reference to the shell Object and i have no idea why that is so
_Shell and _firePos $$anonymous$$UST have a NetworkIdentity or it can not be used as a sync in Cmd arguments.
If _firePos is a GO intended to mark a position, just send the Vector3 ins$$anonymous$$d.
thanks for the answer...ill try that and tell the results ;)
No probs. The info is here
It drives me crazy...the shell has an identifier, it also has a NetworkTransform on it.
I changed the code to only send Vecor3 and Quaternions to the Command but the shell is still null for the client :(
Error: ArgumentException: The thing you want to instantiate is null. UnityEngine.Object.CheckNullArgument (System.Object arg, System.String message) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:102)
void ControlTurrets()
{
for (int i = 0; i < turrets.Length; i++)
{
if (turrets[i] != null)
{
Turret _turret = turrets[i].GetComponent<Turret>();
GameObject _target = _turret.GetTarget();
GameObject _shell = _turret.GetShell();
targetController.SelectTarget(_turret);
Turn(_turret, _target);
$$anonymous$$ch(_turret, _target);
if (Input.Get$$anonymous$$ouseButtonDown(0))
{
Shoot(_turret, _shell);
}
}
else
{
Debug.LogError("No turret referenced.");
}
}
}
[Client]
void Shoot(Turret _turret, GameObject _shell)
{
if (!isLocalPlayer)
{
return;
}
Transform _turretHead = _turret.transform.FindChild("Head");
GameObject _fireTransform = _turretHead.transform.FindChild("FireTransform").gameObject;
Vector3 _firePos = _fireTransform.transform.position;
Quaternion _fireRot = _fireTransform.transform.rotation;
Vector3 _fireForward = _fireTransform.transform.forward;
if (!_turret.fired)
{
// Create an instance of the shell and store a reference to it's rigidbody.
CmdShoot(_firePos, _fireRot, _fireForward, _shell);
}
}
[Command]
void CmdShoot(Vector3 _firePos, Quaternion _fireRot, Vector3 _fireForward, GameObject _shell)
{
//Debug.Log(gameObject.name + ": " + _shell + " " + _firePos);
GameObject shellInstance = Instantiate(_shell, _firePos, _fireRot) as GameObject;
// Set the shell's velocity to the launch force in the fire position's forward direction.
shellInstance.GetComponent<Rigidbody>().velocity = shellSpeed * _fireForward;
NetworkServer.Spawn(shellInstance);
}
I even tried to call the GetShell method inside the Cmd...same result....this Unet...
Full Error: ArgumentException: The thing you want to instantiate is null. UnityEngine.Object.CheckNullArgument (System.Object arg, System.String message) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:102) UnityEngine.Object.Instantiate (UnityEngine.Object original, Vector3 position, Quaternion rotation) (at C:/buildslave/unity/build/Runtime/Export/UnityEngineObject.cs:79) TurretController.CmdShoot (Vector3 _firePos, Quaternion _fireRot, Vector3 _fireForward, UnityEngine.GameObject _shell) (at Assets/Skripts/Player/Turret/TurretController.cs:119) TurretController.InvokeCmdCmdShoot (UnityEngine.Networking.NetworkBehaviour obj, UnityEngine.Networking.NetworkReader reader) UnityEngine.Networking.NetworkIdentity.HandleCommand (Int32 cmdHash, UnityEngine.Networking.NetworkReader reader) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:620) UnityEngine.Networking.NetworkServer.OnCommand$$anonymous$$essage (UnityEngine.Networking.Network$$anonymous$$essage net$$anonymous$$sg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1297) UnityEngine.Networking.NetworkConnection.HandleReader (UnityEngine.Networking.NetworkReader reader, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:430) UnityEngine.Networking.NetworkConnection.HandleBytes (System.Byte[] buffer, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:386) UnityEngine.Networking.NetworkConnection.TransportRecieve (System.Byte[] bytes, Int32 numBytes, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:536) UnityEngine.Networking.NetworkServer.OnData (UnityEngine.Networking.NetworkConnection conn, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:754) UnityEngine.Networking.NetworkServer+ServerSimpleWrapper.OnData (UnityEngine.Networking.NetworkConnection conn, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1842) UnityEngine.Networking.NetworkServerSimple.HandleData (Int32 connectionId, Int32 channelId, Int32 receivedSize, Byte error) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServerSimple.cs:382) UnityEngine.Networking.NetworkServerSimple.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServerSimple.cs:248) UnityEngine.Networking.NetworkServer.InternalUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:706) UnityEngine.Networking.NetworkServer.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:656) UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1058)
Answer by meat5000 · May 20, 2016 at 07:39 AM
I looked at your project. The problem is that you disable the scripts that handle these calls on the RemotePlayer. As a result on the other client machines and probably the server, they never run the code they need to acquire the shell.
There are a number of problems that are standing in your way. For example passing a GameObject reference through 3 functions in the same script is probably not a good idea. Repeated transform.Find and GetComponent calls in the loop is a bad idea. Get references once and cache them to save on processing. You don't use enough Attribute tags, like [Server] or [Client] to isolate code or use the isLocalPlayer condition to segment scripts to differentiate between roles in the code.
Also, the use of [SyncVar] can often be preferable to a NetworkTransform. Having many NetworkTransforms on one object may not be desirable.
Thank you for looking through my project, i dont take that for granted ;)
I know that i am disabling some classes but i kinda moved the shell referencing around and put it into the ship controller which wasnt disabled and it was still missing :( I ll look into that once again.
Edit: I checked into that issue and the problem occurs even if i disable the DisableComponents $$anonymous$$ethod and/or the AssignRemoteLayer $$anonymous$$ethod.
$$anonymous$$aybe its better to use the isLocalPlayer in methods to distinguish. I am pretty new to the network coding and did it like in some tutorials where they disabled code by the player setup script.
Ill check for the other issues as well. One more question though...were did you find more than one networktransform on one object? Or are you talking about the networktransformchilds?
Are there some really good tutorials out there to understand Unet properly? I saw some of them on youtube but i have the feeling they are not giving me the full understanding.
Edit: Ok i made some changes and what worked was to not pass the shell as argument into the command but to use a global shell variable ins$$anonymous$$d.
Ty very much ;)
Look at the UNet tutorials again on YouTube, particularly the ones on handling other players. They were the original set of tutorials, before the Rpc was introduced to UNet. Familiarise yourself with the Rpc. The scripts need to address the three cases of usage : Run on Server, Run on Client as Local Player, Run on Client Not as Local Player. You need to distinguish the role of each one and make sure they have access to the code required to perform that function. Authority is an important concept.
The best resource of all is the Networking pages of the $$anonymous$$anual
http://docs.unity3d.com/$$anonymous$$anual/UNet.html
It is important to read through it all to realise the important concepts in UNet's model. The attributes and conditions make a lot more sense afterwards.
Thank you very much for the quick info ;) Its still a bit confusing but i think i can do it .
Your answer
Follow this Question
Related Questions
How do I get authority over another player in Mirror? 0 Answers
What is difference between Network.InitializeServer and Unet. please help me 0 Answers
HELP Network spawn player (host or client) in same position 0 Answers
MLAPI Client Character Spawning Problem 0 Answers
How to identify players on Photon Unity? 2 Answers