I'm currently learning how this whole networking thing works in unity. In my code I'm creating a spaceship made from multiple prefabs.
It all starts with a single Hardpoint
. A Hardpoint
can hold a single object, which will be instantiated later on in the loop.
In the PlayerController
(the starting point) i have this code to spawn the first object, the cockpit:
[Command]
void CmdOnConnect() {
string json = GameObject.Find("TestPlayer").GetComponent<ComponentObject>().ToJSON();
CompressedComponent compressedComponent = JsonUtility.FromJson<CompressedComponent>(json);
gameObject.GetComponent<Hardpoint>().Hold(GameObject.Find("Component Repository").GetComponent<ComponentRepository>().cockpit[compressedComponent.componentNumber]);
gameObject.GetComponent<Hardpoint>().SpawnComponent();
gameObject.GetComponent<Hardpoint>().RollThroughDecompression(compressedComponent);
Camera.main.GetComponent<PlayerCamera>().player = gameObject;
}
Next up is the SpawnComponent()
code, located in the Hardpoint
script:
public void SpawnComponent() {
Clear();
CmdSpawn();
}
CmdSpawn, also located in Hardpoint
:
[Command]
public void CmdSpawn()
{
Debug.Log("[COMMAND] Spawning " + holds.name);
heldInstance = Instantiate(holds, transform.position, transform.rotation) as GameObject;
heldInstance.transform.SetParent(transform);
NetworkServer.SpawnWithClientAuthority(heldInstance, transform.root.gameObject);
}
And finally RollThroughDecompression
, which just calls the Decompress()
function:
public void RollThroughDecompression(CompressedComponent c) {
heldInstance.GetComponent<ComponentObject>().Decompress(c);
}
And just to leave no information out, Decompress()
:
public void Decompress(CompressedComponent c) {
componentType = (Type)Enum.Parse(typeof(Type), c.componentType);
componentNumber = c.componentNumber;
UpdateHardPoints();
GameObject[] typeRepository = GetRepository(componentType);
//update children
int point = 0;
foreach (Transform child in transform)
{
Hardpoint hardpoint = child.GetComponent<Hardpoint>();
if (hardpoint != null) {
if (c.hardpoints[point] != null) {
//get the hardpoint's repository
GameObject[] hardpointRepo = GetRepository((Type)Enum.Parse(typeof(Type), c.hardpoints[point].componentType));
//set the hardpoint to hold this object
hardpoint.Hold(hardpointRepo[c.hardpoints[point].componentNumber]);
hardpoint.SpawnComponent();
hardpoint.RollThroughDecompression(c.hardpoints[point]);
point++;
}
}
}
}
Sorry the code's a little messy/confusing but I've been driven up the walls trying to figure out why newly spawned objects don't have client authority
with the exception of the first object spawned (likely because it's called from the PlayerController
). I've been stuck on this problem for days now. Newly spawned objects are being set as children of the local player object and are even spawned with NetworkServer.SpawnWithClientAuthority
yet when testing:
Trying to send command for object without authority.
when calling CmdSpawn()
.
The result i'm getting:
As you can see, the cockpit (very first part) gets spawned as expected. but parts mounted on those Hardpoints
don't. To clarify, the EmptyHardpoint
is just that. A hardpoint with no children, just an empty game object with the hardpoint
script and playercontroller
attached to it. The cockpit prefab also includes the img
and hardpoints