runtime Prefab with script runtime prefab with script
My problem is that my Prefab clone does not have a script component. The original prefab has a script component, therefore all the clones generated should have one or not?
Background: I created a shared augmented reality experience using the lobby network manager. The prefab is placed within 'Game Player Prefab' and generates per users within the server.
I'll explain and go in as much detail as I can before posting. Below is the script] attached to the prefab and the screenshot of where the prefab is implemented from Lobby Manager Inspector. For some reason stack won't allow me to include this part of the code, therefore it is included here: using System. Collections, System.Collections.Generic, UnityEngine, UnityEngine.Networking, UnityEngine.UI and public class player identity: NetworkBehaviour
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using System.Collections.Generic;
public class PlayerIdentity : NetworkBehaviour, MonoBehaviour
{
GameObject imageTracker_1, imageTracker_2, canvasUI;
public GameObject[] user;
public GameObject myTextObj, origin;
public float distanceFromOrigin;
int count = 0;
//public Text myText;
private void Awake()
{
transform.GetComponent<playerIdentity>().enabled = true;
user[0] = GameObject.FindWithTag("Respawn");
user[1] = GameObject.FindWithTag("Finish");
}
void Start()
{
if (!isLocalPlayer)
{
Destroy(this);
return;
}
//code stop unity responding!
//while (count < user.Length)
//{
// if (transform.name == "idle(Clone)")
// {
// transform.name = "player" + count;
// count++;
// }
//}
origin = GameObject.Find("PositionOrigin");
//used for finding text, "GetComponent<Text>" needs to be attached or fails.
// canvasUI = GameObject.Find("Canvas");
// myText = canvasUI.GetComponentInChildren<Text>();
//// myText.text = "Out of area";
// myTextObj.SetActive(false);
the for loop makes the folder of the script a child of the user (marker components within the scene, used to spawn prefab on run-time).
for (int i = 0; i < user.Length; i++) {
transform.SetParent(user[i].transform, false);
if (user[i].GetComponentInChildren<playerIdentity>() == null){
Debug.Log("no child");
}
}
// we track the vuforia image within the scene and attach the avatar as a child
//imageTracker_1 = GameObject.FindWithTag("Respawn");
//GameObject imageTracker_2 = GameObject.FindWithTag("Finish");
//transform.SetParent(imageTracker_1.transform, false);
//transform.parent = imageTracker_1.transform;
//imageTracker_2 = GameObject.Find("avatar_01");
//GameObject.Find("Idle(Clone)").transform.parent = imageTracker_2.transform;
}
}
the if statement was used because the gameObject was returning NUll but, I've referenced the gameObject but it fails on run-time. Therefore the if statement makes sure the components don't return Null.
private void Update()
{
distanceFromOrigin = Vector3.Distance(origin.transform.position, transform.position);
//during start the gameObject will return NULL, this will make sure during every frame the gameObject does not equal null
if ( origin || imageTracker_1 || myTextObj == null)
{
myTextObj = GameObject.Find("OutOfBound");
origin = GameObject.Find("PositionOrigin");
//imageTracker_1 = GameObject.FindWithTag("Player");
//transform.SetParent(imageTracker_1.transform, false);
}
}
}
this is the lobby manager script used to generate the prefab:
using UnityEngine, UnityEngine.UI, UnityEngine.SceneManagement, UnityEngine.Networking, UnityEngine.Networking.Types, UnityEngine.Networking.Match, System.Collections.
namespace Prototype.NetworkLobby
public class LobbyManager : NetworkLobbyManager
{
static short MsgKicked = MsgType.Highest + 1;
static public LobbyManager s_Singleton;
[Header("Unity UI Lobby")]
[Tooltip("Time in second between all players ready & match start")]
public float prematchCountdown = 5.0f;
[Space]
[Header("UI Reference")]
public LobbyTopPanel topPanel;
public RectTransform mainMenuPanel;
public RectTransform lobbyPanel;
public LobbyInfoPanel infoPanel;
public LobbyCountdownPanel countdownPanel;
public GameObject addPlayerButton;
protected RectTransform currentPanel;
public Button backButton;
public Text statusInfo;
public Text hostInfo;
//Client numPlayers from NetworkManager is always 0, so we count (throught connect/destroy in LobbyPlayer) the number
//of players, so that even client know how many player there is.
[HideInInspector]
public int _playerNumber = 0;
//used to disconnect a client properly when exiting the matchmaker
[HideInInspector]
public bool _isMatchmaking = false;
protected bool _disconnectServer = false;
protected ulong _currentMatchID;
protected LobbyHook _lobbyHooks;
void Start()
{
s_Singleton = this;
_lobbyHooks = GetComponent<Prototype.NetworkLobby.LobbyHook>();
currentPanel = mainMenuPanel;
backButton.gameObject.SetActive(false);
GetComponent<Canvas>().enabled = true;
DontDestroyOnLoad(gameObject);
SetServerInfo("Offline", "None");
}
public override void OnLobbyClientSceneChanged(NetworkConnection conn)
{
if (SceneManager.GetSceneAt(0).name == lobbyScene)
{
if (topPanel.isInGame)
{
ChangeTo(lobbyPanel);
if (_isMatchmaking)
{
if (conn.playerControllers[0].unetView.isServer)
{
backDelegate = StopHostClbk;
}
else
{
backDelegate = StopClientClbk;
}
}
else
{
if (conn.playerControllers[0].unetView.isClient)
{
backDelegate = StopHostClbk;
}
else
{
backDelegate = StopClientClbk;
}
}
}
else
{
ChangeTo(mainMenuPanel);
}
topPanel.ToggleVisibility(true);
topPanel.isInGame = false;
}
else
{
ChangeTo(null);
Destroy(GameObject.Find("MainMenuUI(Clone)"));
//backDelegate = StopGameClbk;
topPanel.isInGame = true;
topPanel.ToggleVisibility(false);
}
}
public void ChangeTo(RectTransform newPanel)
{
if (currentPanel != null)
{
currentPanel.gameObject.SetActive(false);
}
if (newPanel != null)
{
newPanel.gameObject.SetActive(true);
}
currentPanel = newPanel;
if (currentPanel != mainMenuPanel)
{
backButton.gameObject.SetActive(true);
}
else
{
backButton.gameObject.SetActive(false);
SetServerInfo("Offline", "None");
_isMatchmaking = false;
}
}
public void DisplayIsConnecting()
{
var _this = this;
infoPanel.Display("Connecting...", "Cancel", () => { _this.backDelegate(); });
}
public void SetServerInfo(string status, string host)
{
statusInfo.text = status;
hostInfo.text = host;
}
public delegate void BackButtonDelegate();
public BackButtonDelegate backDelegate;
public void GoBackButton()
{
backDelegate();
topPanel.isInGame = false;
}
// ----------------- Server management
public void AddLocalPlayer()
{
TryToAddPlayer();
}
public void RemovePlayer(LobbyPlayer player)
{
player.RemovePlayer();
}
public void SimpleBackClbk()
{
ChangeTo(mainMenuPanel);
}
public void StopHostClbk()
{
if (_isMatchmaking)
{
matchMaker.DestroyMatch((NetworkID)_currentMatchID, 0, OnDestroyMatch);
_disconnectServer = true;
}
else
{
StopHost();
}
ChangeTo(mainMenuPanel);
}
public void StopClientClbk()
{
StopClient();
if (_isMatchmaking)
{
StopMatchMaker();
}
ChangeTo(mainMenuPanel);
}
public void StopServerClbk()
{
StopServer();
ChangeTo(mainMenuPanel);
}
class KickMsg : MessageBase { }
public void KickPlayer(NetworkConnection conn)
{
conn.Send(MsgKicked, new KickMsg());
}
public void KickedMessageHandler(NetworkMessage netMsg)
{
infoPanel.Display("Kicked by Server", "Close", null);
netMsg.conn.Disconnect();
}
//===================
public override void OnStartHost()
{
base.OnStartHost();
ChangeTo(lobbyPanel);
backDelegate = StopHostClbk;
SetServerInfo("Hosting", networkAddress);
}
public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
{
base.OnMatchCreate(success, extendedInfo, matchInfo);
_currentMatchID = (System.UInt64)matchInfo.networkId;
}
public override void OnDestroyMatch(bool success, string extendedInfo)
{
base.OnDestroyMatch(success, extendedInfo);
if (_disconnectServer)
{
StopMatchMaker();
StopHost();
}
}
//allow to handle the (+) button to add/remove player
public void OnPlayersNumberModified(int count)
{
_playerNumber += count;
int localPlayerCount = 0;
foreach (PlayerController p in ClientScene.localPlayers)
localPlayerCount += (p == null || p.playerControllerId == -1) ? 0 : 1;
addPlayerButton.SetActive(localPlayerCount < maxPlayersPerConnection && _playerNumber < maxPlayers);
}
// ----------------- Server callbacks ------------------
//we want to disable the button JOIN if we don't have enough player
//But OnLobbyClientConnect isn't called on hosting player. So we override the lobbyPlayer creation
public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
{
GameObject obj = Instantiate(lobbyPlayerPrefab.gameObject) as GameObject;
LobbyPlayer newPlayer = obj.GetComponent<LobbyPlayer>();
newPlayer.ToggleJoinButton(numPlayers + 1 >= minPlayers);
for (int i = 0; i < lobbySlots.Length; ++i)
{
LobbyPlayer p = lobbySlots[i] as LobbyPlayer;
if (p != null)
{
p.RpcUpdateRemoveButton();
p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
}
}
return obj;
}
public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
{
for (int i = 0; i < lobbySlots.Length; ++i)
{
LobbyPlayer p = lobbySlots[i] as LobbyPlayer;
if (p != null)
{
p.RpcUpdateRemoveButton();
p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
}
}
}
public override void OnLobbyServerDisconnect(NetworkConnection conn)
{
for (int i = 0; i < lobbySlots.Length; ++i)
{
LobbyPlayer p = lobbySlots[i] as LobbyPlayer;
if (p != null)
{
p.RpcUpdateRemoveButton();
p.ToggleJoinButton(numPlayers >= minPlayers);
}
}
}
public override bool OnLobbyServerSceneLoadedForPlayer(GameObject lobbyPlayer, GameObject gamePlayer)
{
//This hook allows you to apply state data from the lobby-player to the game-player
//just subclass "LobbyHook" and add it to the lobby object.
if (_lobbyHooks)
_lobbyHooks.OnLobbyServerSceneLoadedForPlayer(this, lobbyPlayer, gamePlayer);
return true;
}
// --- Countdown management
public override void OnLobbyServerPlayersReady()
{
bool allready = true;
for(int i = 0; i < lobbySlots.Length; ++i)
{
if(lobbySlots[i] != null)
allready &= lobbySlots[i].readyToBegin;
}
if(allready)
StartCoroutine(ServerCountdownCoroutine());
}
public IEnumerator ServerCountdownCoroutine()
{
float remainingTime = prematchCountdown;
int floorTime = Mathf.FloorToInt(remainingTime);
while (remainingTime > 0)
{
yield return null;
remainingTime -= Time.deltaTime;
int newFloorTime = Mathf.FloorToInt(remainingTime);
if (newFloorTime != floorTime)
{//to avoid flooding the network of a message, we only send a notice to the client when the number of plain seconds changes.
floorTime = newFloorTime;
for (int i = 0; i < lobbySlots.Length; ++i)
{
if (lobbySlots[i] != null)
{//there is maxPlayer slots, so some could be == null, need to test it before accessing!
(lobbySlots[i] as LobbyPlayer).RpcUpdateCountdown(floorTime);
}
}
}
}
for (int i = 0; i < lobbySlots.Length; ++i)
{
if (lobbySlots[i] != null)
{
(lobbySlots[i] as LobbyPlayer).RpcUpdateCountdown(0);
}
}
ServerChangeScene(playScene);
}
// ----------------- Client callbacks ------------------
public override void OnClientConnect(NetworkConnection conn)
{
base.OnClientConnect(conn);
infoPanel.gameObject.SetActive(false);
conn.RegisterHandler(MsgKicked, KickedMessageHandler);
if (!NetworkServer.active)
{//only to do on pure client (not self hosting client)
ChangeTo(lobbyPanel);
backDelegate = StopClientClbk;
SetServerInfo("Client", networkAddress);
}
}
public override void OnClientDisconnect(NetworkConnection conn)
{
base.OnClientDisconnect(conn);
ChangeTo(mainMenuPanel);
}
public override void OnClientError(NetworkConnection conn, int errorCode)
{
ChangeTo(mainMenuPanel);
infoPanel.Display("Cient error : " + (errorCode == 6 ? "timeout" : errorCode.ToString()), "Close", null);
}
}
}
I will be asking questions related to Augmented reality within unity and would be great to have a website or some documentation to look at. At the moment using the Unity API and whatever I can find to help me.