Need help spawning a gameObject on the server UNET
I really hope I can get an answer for this one!
My issue is I'm trying my best to spawn an object for each player on the server, but the only thing is it continues to return null when a non-local player joins the game
here's a bit of code showing my issue
void Start()
{
if (isLocalPlayer)
{
if (otherSettings.startWeapon)
{
TransmitStartWeapon(otherSettings.startWeapon);
}
}
}
[ClientCallback]
void TransmitStartWeapon(GameObject wep)
{
if (isLocalPlayer)
{
Cmd_SpawnStartWeapon(wep);
}
}
[Command]
void Cmd_SpawnStartWeapon(GameObject wep)
{
GameObject newWep = Instantiate(wep, transform.position, transform.rotation) as GameObject;
weaponH.currentWeapon = newWep.GetComponent<Weapon>();
NetworkServer.Spawn(newWep);
}
The weapon is registered as a spawnable prefab, and this script is attached to the player. I pray you guys can actually get baack to me with this question, I've never had anyone answer me on here :/
Does the weapon prefab itself have a NetworkIdentity? It should have a NetworkIdentity component. Also, what are you doing with weaponH.currentWeapon = newWep.GetComponent<Weapon>();
Are you setting a parent or a child or something? Because that won't work and could be the cause of your error.
To explain it simply the weaponH (or weaponHandler) adds this weapon to a list and the weapon component parents it to the players hand, also the weapon in fact does have a network identity, I have two questions...
Does the weapon itself need to have a local player authority or a server only authority.
How would I go about doing the parenting of the obj, because I have a theory... What if I just attached a script that that handles syncing the parent object and also the position and rotation of the weapon. Is there any way to do this, it would be much simpler.
Thanks for getting back to me!
Also I might add that the error appears here GameObject newWep = Instantiate(wep, transform.position, transform.rotation) as GameObject;
@Soloman23 When you want to set a parent for a NetworkObject you have to keep a reference to a NetworkIdentity of the parent.
The weapon itself shouldn't have any boxes checked (so neither local nor server) :)
I've had some problems with setting the parent, but the short version is: You need to pass a reference to the NetworkIdentity of the parent gameObject to a [Command], set the parent and then pass the reference to a [ClientRpc] and set the parent.
To set the parent from the NetworkIdentity you have to (depending on your hierarchy setup) find the child of the gameobject with networkidentity. Remember that FindChild() only finds DIRECT children, so not grandchildren (which your hand probably is). There are ways to do this, either by an iterative search through all children or by writing the full path to the child (ex "Spine/Arm/Forearm/Hand").
So again: You set the weapons parent to the hand on client. You then send a reference to the networkidentity of the gameobject (which probably is the players gameobject) to a [Command]. You then use the networkidentity to retrieve the gameobject and use FindChild() to retrieve the hand and then set the weapons parent to the hand. Now you do the same in a [ClientRpc] which is called from the [Command].
Answer by Soloman23 · Mar 01, 2016 at 10:37 PM
So I've been trying and trying to get this to operate correctly, and I've come this far:
Well basically I created a new SyncVar that is a gameObject, and saying in code: GameObject wep = (GameObject)Instantiate(Resources.Load(startWeapon.name, typeof(GameObject)), transform.position, transform.rotation);
, and this is in fact working correctly and is instantiating the weapon, but the problem is when assigning my syncVar to that instantiated object, the SyncVar still returns null?!!?! I'm so confused I wish I could get an answer on here, what I'm trying to achieve is so simple.
Never$$anonymous$$d totally got this part to work here's a bit of code showing the new way I'm doing this :
[Server]
void Cmd_PassStartWeapon(GameObject startWeapon)
{
GameObject wep = (GameObject)Instantiate(Resources.Load(startWeapon.name, typeof(GameObject)), transform.position, transform.rotation);
NetworkServer.Spawn(wep);
syncStartWeapon = wep;
weaponH.currentWeapon = syncStartWeapon.GetComponent<Weapon>();
}
So now this is the issue, I'm receiving 2 null references
void Start()
{
#region Spawn start weapon into world.
TransmitStartWeapon();
SetStartWeapon();
#endregion
}
void SetStartWeapon()
{
if(!isLocalPlayer)
{
weaponH.currentWeapon = syncStartWeapon.GetComponent<Weapon>();
}
}
[Command]
void Cmd_PassStartWeapon(GameObject startWeapon)
{
GameObject wep = (GameObject)Instantiate(Resources.Load(startWeapon.name, typeof(GameObject)), transform.position, transform.rotation);
NetworkServer.Spawn(wep);
syncStartWeapon = wep;
weaponH.currentWeapon = syncStartWeapon.GetComponent<Weapon>();
}
[ClientCallback]
void TransmitStartWeapon()
{
if (isLocalPlayer)
{
Cmd_PassStartWeapon(otherSettings.startWeapon);
}
}
The null references originate here: GameObject wep = (GameObject)Instantiate(Resources.Load(startWeapon.name, typeof(GameObject)), transform.position, transform.rotation);
And here: weaponH.currentWeapon = syncStartWeapon.GetComponent<Weapon>();
@Soloman23 Don't pass the gameobject to the [Command] just pass the string gameObject.name directly. I think that will solve your first error. The second error should be solve either by this or my other answer I typed recently. But probably by this, the second error seem to be due to the instantiation failing, and thus there is no gameobject to use GetComponent() on.
I want to redirect you to a new discussion that explains this further, thanks for this though it solved to of my issues, but in doing so opened a door to a new one. http://answers.unity3d.com/questions/1149700/need-help-with-syncing-gameobject-unet.html#comment-1149743