- Home /
[SOLVED] NETWORK SERVER IS NOT ACTIVE! It is only active on host! CANNOT SPAWN OBJECT
Hi! I'm making a 2D Tank game where bullets are fired when you tap an on-screen button. The platform target is mobile.
I have Installed the app on my iPhone 7 and hosted a room. I then go in on the Unity connector and enter my phone's local ip address: 192.168.1.11. No errors and I connect successfully. Both the players are at the correct positions with the correct rotations etc... When I try firing a bullet from my iPhone (the host) it works perfectly without any errors but when I attempt firing a bullet from the client i get this error:
alt text
The error points to line 103 where: Network.Spawn(bullet_fired); Here's the relevant part of the script (Tank.cs):
[Command]
void CmdShootBullet() {
if (!isLocalPlayer) {
return;
}
Vector3 pos_offset = new Vector3(0, 0, -3f);
Vector3 bullet_pos = bulletSpawn.transform.position - pos_offset;
GameObject bullet_fired = (GameObject)Instantiate(bullet, bullet_pos, this.transform.rotation);
// Physics2D.IgnoreCollision(bullet_fired.GetComponent<Collider2D>(), this.GetComponent<Collider2D>());
//
// Debug.Log("playerControllerId: " + playerControllerId);
// if (playerControllerId == 0) {
// NetworkServer.SpawnWithClientAuthority(bullet_fired, connectionToClient);
// } else if (playerControllerId > 0) {
// NetworkServer.SpawnWithClientAuthority(bullet_fired, connectionToServer);
// }
NetworkServer.Spawn(bullet_fired);
// Destroy the bullet after 2 seconds
Destroy(bullet_fired, 2.0f);
}
Thanks for any help I can get! I have been debugging this for 2 days and scanned!
Answer by UDN_9a915d40-27e1-405b-b1cc-83be8be3e71d · Dec 31, 2017 at 03:59 PM
I finally got everything to work by changing the code a bit: Here is the new code below. I had the create the bullet from scratch programmatically, add the components and set all the variables. Here's the new code:
public void ShootBullet() { // This is the function that is called when you click the shoot button.
if (isLocalPlayer) {
Vector3 pos_offset = new Vector3(0, 0, -3f);
Vector3 bullet_pos = bulletSpawn.transform.position - pos_offset;
GameObject bullet_fired = (GameObject)Instantiate(bullet, bullet_pos, this.transform.rotation);
Destroy(bullet_fired, 2.0f);
CmdShootBullet_Server(bullet_pos, this.transform.rotation);
}
}
[Command]
private void CmdShootBullet_Server(Vector3 pos, Quaternion rot) {
if (isServer) {
print("Shoot Bullet called on Server");
GameObject shoot_bullet = CreateBullet();
shoot_bullet.transform.position = pos;
shoot_bullet.transform.rotation = rot;
print("BULLET ABOUT TO FIRE: " + shoot_bullet.transform.position);
// Spawn on clients
NetworkServer.Spawn(shoot_bullet);
}
}
private GameObject CreateBullet() {
GameObject b = new GameObject();
SpriteRenderer renderer = b.AddComponent<SpriteRenderer>();
renderer.sprite = Resources.Load("Sprites/Bullet", typeof(Sprite)) as Sprite;
/*NetworkIdentity network_identity = */b.AddComponent<NetworkIdentity>();
NetworkTransform network_transform = b.AddComponent<NetworkTransform>();
Rigidbody2D rigidbody2d = b.AddComponent<Rigidbody2D>();
CircleCollider2D circleCollider2D = b.AddComponent<CircleCollider2D>();
b.AddComponent<Bullet>();
rigidbody2d.gravityScale = 0;
network_transform.sendInterval = 0;
b.tag = "Bullet";
b.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
return b;
}
Answer by niocy · Dec 27, 2017 at 11:05 AM
Stuff which is bracketed inside CmdShootBullet() is being called at the server. It never happens locally. So we can check inside there that is it server. Its like a letter which is being given to server, and the server will read the stuff inside.
Call the stuff from client
void CallShootBullet(){
if(!isLocalPlayer) return;
CmdShootBullet();
}
Client serializes stuff and sends it to server, this is just to demonstrate how it works in reality
[Command]
void CmdShootBullet() {
if (!NetworkServer.active) return;
Vector3 pos_offset = new Vector3(0, 0, -3f);
Vector3 bullet_pos = bulletSpawn.transform.position - pos_offset;
GameObject bullet_fired = (GameObject)Instantiate(bullet, bullet_pos, this.transform.rotation);
NetworkServer.Spawn(bullet_fired);
Destroy(bullet_fired, 2.0f);
}
Ok, thx! That removed the error but now it doesn't even spawn on the client or on the host since it says that NetworkServer.active == false.
BTW: I just noticed a log in the console: $$anonymous$$ultiple Network$$anonymous$$anagers detected in the scene. Only one Network$$anonymous$$anager can exist at a time. The duplicate Network$$anonymous$$anager will not be used. UnityEngine.Networking.Network$$anonymous$$anager:Awake()
The Next log is: Network$$anonymous$$anager destroyed
. This might be why the NetworkServer isn't active? Because it is destroyed? Could that be why - and if so - how would I fix it?
I have been searching for 1h and can't find the duplicate Network$$anonymous$$anager.
This tells that you have multiple networkmanagers active, does your networkmanager exist in the first scene with dont destroy on load active. If so check if you accidently spawn more networkmanagers, or find some extra managers when load to new scene. There should only be 1 networkmanager active all the time.
@niocy I have searched everywhere for another Nerwork$$anonymous$$anager. I have one first scene that is pure GUI with one button and input textfield. No networkmanagers. Here's a screenshot of what my Scene Hierarchy looks like: https://gyazo.com/22f13716903b86da4afa9d4923d134d6
I really need help before I end up giving up!
BTW! Thanks for being so kind and helping me. No-one else seems to care...
@niocy I A$$anonymous$$ BTW FOLLOWING THIS TUTORIAL (EVEN THOUGH $$anonymous$$Y GA$$anonymous$$E IS 2D): https://unity3d.com/learn/tutorials/topics/multiplayer-networking/adding-multiplayer-shooting?playlist=29690
@niocy After more testing and debugging I've found that I don't think the CmdShootBullet() function is being called on the server at all.
Command]
void CmdShootBullet() {
// if (!NetworkServer.active) return;
if (isServer) {
print("Being called on server.");
}
if (isLocalPlayer) {
Vector3 pos_offset = new Vector3(0, 0, -3f);
Vector3 bullet_pos = bulletSpawn.transform.position - pos_offset;
GameObject bullet_fired = (GameObject)Instantiate(bullet, bullet_pos, this.transform.rotation);
}
// Destroy(bullet_fired, 2.0f);
}
That was the new code. I removed the NetworkServer.Spawn part for now. And when I run this code it doesn't ever get called on the server. Do you know why?
When I try the same thing on the host machine it works successfully... So I guess the problem is that the Client doesn't have access to the server or the server isn't reachable for the client for some reason. Basically the same problem as before...