- Home /
Multi-position tank networking controls
Hey guys,
I apologize in advance for this long post. This is my first unity networking project (and practically first unity project). It is a networked tank game with (atm) 2 positions available to be controlled per tank, driver and gunner. The driver controls the hull traverse while the gunner controls the turret traverse as well as cannon elevation.
So far, I've just tried to get networked controls to work to no avail. I don't know if it is because I'm integrating various components in the wrong way or calling the wrong functions or something else altogether. The current implementation is running with the default networkmanagerhud, but a custom spawn script, overriding the default OnServerAddPlayer script. Currently I haven't worried about spawning more than two players so ignore the dumb control flow. The general flow I have chosen (I don't know if this is good or bad so let me know!) is:
When 1st player joins:
Tank prefab is spawned (aka "landshipv1") [Done by networkmanager]
A spawnmanager is spawned (I'm not sure this is appropriate, might even be the cause of problems) [Done by networkmanager]
The playerprefab with its own camera is designated a position (driver or gunner) and then spawned in that location [Done by networkmanager]
Playerprefab's position script is modified by spawnmanager as per networkmanager's request
Once a player is assigned a position, it moves itself around in the scene hierarchy, turns on appropriate control scripts, assigns appropriate tank component references to those scripts. [Done by playerprefab's "position" script].
When 2nd Player joins, Go to Step 3.
With all that out of the way, currently when the Player1 joins (let's say he's the gunner), he has full control of the turret and cannon but not the hull. This is perfect and what should be the case. In the scene hierarchy, his "position" script says "TURRET", only the "cannon" control script is enabled and references are assigned to appropriate components of the tank. Next, Player2 joins. He is assigned "DRIVER" as a position, but his "driver" script is not enabled. His driver script references are however assigned. His actual client window is unresponsive to controls. Instead, both the hull and turret are only able to be manipulated by Player1 even though the scene heirarchy shows that Player1's driver control script is disabled. Also, all cameras are working perfectly.
Do you guys have any idea what is causing this problem? I suspect the heirarchy doesn't show that Player2's drive script is enabled because the editor can only see what's on the local client but maybe I am wrong? Clearly the position script was run, all the references were set, and the camera was enabled. For reference, here are appropriate scripts. Let me know if you want the project file itself to test it out yourself.
Screenshots of editor (editor was host client) after starting up, and after 2nd player joined.
Networkmanager:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class CustomNetworkManager : NetworkManager
{
private int numTanks;
private int numOpenPositions;
private GameObject SpawnManager;
private Transform TankSpawn;
private GameObject tank;
private Transform turretSpawnPos;
private Transform driverSpawnPos;
public override void OnStartServer()
{
base.OnStartServer();
numTanks = 0;
numOpenPositions = 0;
TankSpawn = GameObject.FindWithTag("Tank Spawn").transform;
}
public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
if (numTanks == 0)
{
foreach (GameObject obj in spawnPrefabs)
{
if (obj.name == "landshipv1")
{
tank = (GameObject)Instantiate(obj, TankSpawn.position, TankSpawn.rotation);
NetworkServer.Spawn(tank);
numTanks++;
}
if (obj.name == "SpawnManager")
{
SpawnManager = (GameObject)Instantiate(obj);
NetworkServer.Spawn(SpawnManager);
Debug.Log("SpawnManager Spawned");
}
}
}
turretSpawnPos = tank.transform.GetChild(5).transform;
driverSpawnPos = tank.transform.GetChild(0).transform;
if (numPlayers == 1) // driver
{
var player = (GameObject)GameObject.Instantiate(playerPrefab, driverSpawnPos.position, Quaternion.identity);
NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
SpawnManager.GetComponent<SpawnManager>().Cmd_SetParent(tank.GetComponent<NetworkIdentity>().netId,"DRIVER", player);
}
else
{
var player = (GameObject)GameObject.Instantiate(playerPrefab, turretSpawnPos.position, Quaternion.identity);
NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
SpawnManager.GetComponent<SpawnManager>().Cmd_SetParent(tank.GetComponent<NetworkIdentity>().netId, "TURRET", player);
}
}
}
SpawnManager
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
public class SpawnManager : NetworkBehaviour {
[Command]
public void Cmd_SetParent(NetworkInstanceId parentid, string position, GameObject player)
{
player.GetComponent<Position>().parentid = parentid;
player.GetComponent<Position>().position = position;
}
}
Position script
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class Position : NetworkBehaviour {
[SyncVar]
public string position;
[SyncVar]
public NetworkInstanceId parentid;
public bool assigned = false;
public Camera playerCam;
public void Update()
{
if (!assigned)
{
if (position == "DRIVER")
{
AddPlayerasDriver(parentid);
assigned = true;
}
else if (position == "TURRET")
{
AddPlayerasTurret(parentid);
assigned = true;
}
}
}
public void AddPlayerasDriver(NetworkInstanceId parent)
{
GameObject tank = ClientScene.FindLocalObject(parent);
transform.parent = tank.transform;
Transform driverSpawnPos = tank.transform.GetChild(0).transform;
transform.position = driverSpawnPos.position;
var driveScript = GetComponent<TankDrive>();
if (isLocalPlayer)
{
driveScript.enabled = true;
}
playerCam = transform.GetChild(0).GetComponent<Camera>();
if (isLocalPlayer)
{
playerCam.enabled = true;
}
#if UNITY_EDITOR
driveScript.wheelShape = AssetDatabase.LoadAssetAtPath("Assets/Charles Models/wheelmodel 2.prefab", typeof(GameObject)) as GameObject;
#endif
driveScript.leftwheelsparent = tank.transform.GetChild(3).gameObject;
driveScript.rightwheelsparent = tank.transform.GetChild(4).gameObject;
driveScript.leftwheels = driveScript.leftwheelsparent.GetComponentsInChildren<WheelCollider>();
driveScript.rightwheels = driveScript.rightwheelsparent.GetComponentsInChildren<WheelCollider>();
/*GameObject turret = tank.transform.GetChild(2).gameObject;
var cannonScript = GetComponent<cannonScript>();
cannonScript.enabled = true;*/
}
public void AddPlayerasTurret(NetworkInstanceId parent)
{
GameObject tank = ClientScene.FindLocalObject(parent);
GameObject turret = tank.transform.GetChild(2).gameObject;
transform.parent = turret.transform;
Transform turretSpawnPos = tank.transform.GetChild(5).transform;
transform.position = turretSpawnPos.position;
playerCam = transform.GetChild(0).GetComponent<Camera>();
if (isLocalPlayer)
{
playerCam.enabled = true;
}
var cannonScript = GetComponent<cannonScript>();
if (isLocalPlayer)
{
cannonScript.enabled = true;
}
cannonScript.turret = turret;
cannonScript.cannon = turret.transform.GetChild(0).gameObject;
#if UNITY_EDITOR
cannonScript.cannonball = AssetDatabase.LoadAssetAtPath("Assets/Charles Models/cannonball 2.prefab", typeof(GameObject)) as GameObject;
#endif
cannonScript.spawnpoint = cannonScript.cannon.transform.GetChild(0).gameObject;
cannonScript.RHorizontal = turret.transform.GetChild(2).gameObject;
cannonScript.LHorizontal = turret.transform.GetChild(3).gameObject;
cannonScript.DVertical = turret.transform.GetChild(4).gameObject;
cannonScript.UVertical = turret.transform.GetChild(5).gameObject;
cannonScript.RHknob = cannonScript.RHorizontal.GetComponent<PickUpObject>();
cannonScript.LHknob = cannonScript.LHorizontal.GetComponent<PickUpObject>();
cannonScript.UVknob = cannonScript.UVertical.GetComponent<PickUpObject>();
cannonScript.DVknob = cannonScript.DVertical.GetComponent<PickUpObject>();
}
}
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
Unet: Discern between user disconnection and connection lost 1 Answer
How to synchronize disable and enabling game objects over the network? 0 Answers
Best solution for low bandwidth multiplayer game 1 Answer
network player only flip on LAN Host not in Lan Client 1 Answer