- Home /
Access UI in scene from an instance prefab
Hi, I'm trying to access a UI element in my scene from an instance but not having much luck. I've managed to not get any errors with this script below but it doesn't SetActive a ui elements or pass variables back. My code on the prefab:-
public class NetworkRoomPlayerLobby : NetworkBehaviour { private Button startGameButton = null; private GameObject gameButton = null; private GameObject lobbyUI = null; private TMP_Text[] playerNameTexts = null; private TMP_Text[] playerReadyTexts = null;
[SyncVar(hook = nameof(HandleDisplayNameChanged))]
public string DisplayName = "Loading...";
[SyncVar(hook = nameof(HandleReadyStatusChanged))]
public bool IsReady = false;
private bool isLeader;
private void Awake()
{
lobbyUI = GameObject.FindGameObjectWithTag("Panel_Lobby");
playerNameTexts = lobbyUI.GetComponentInChildren<TMP_Text[]>();
playerReadyTexts = lobbyUI.GetComponentInChildren<TMP_Text[]>();
playerNameTexts = new TMP_Text[4];
playerReadyTexts = new TMP_Text[4];
gameButton = GameObject.FindGameObjectWithTag("StartButton");
Button startGameButton = gameButton.GetComponentInChildren<Button>();
}
Here is the code for the UI menu script:-
public class MainMenu : MonoBehaviour { [SerializeField] private NetworkManager networkManager;
[Header("UI")]
public GameObject lobbyUI = null;
public TMP_Text[] playerNameTexts = null;
public TMP_Text[] playerReadyTexts = null;
public Button gameButton = null;
[SerializeField] private GameObject landingPagePanel = null;
public void HostLobby()
{
networkManager.StartHost();
landingPagePanel.SetActive(false);
}
}
Answer by Cassos · Apr 28, 2020 at 07:49 PM
I personally use singletons to find scripts.
using UnityEngine;
public class FindMe : MonoBehaviour
{
public static FindMe singleton;
void Awake()
{
singleton = this;
}
}
The object will be found anywhere in the scene if it exists without any performance problems.
using UnityEngine;
public class TriesToAccessFindMe : MonoBehaviour
{
FindMe f;
void Start()
{
f = FindMe.singleton;
}
}
The second script shows how you find the script.
Greetings, Max
Hi $$anonymous$$ax, Thank you for getting back to me it's much appreciated. I've tried your idea, not getting any errors but doesn't even set the ui to active. I must be implementing it wrong. Here is what I've done. public class $$anonymous$$ain$$anonymous$$enu : $$anonymous$$onoBehaviour { [SerializeField] private Network$$anonymous$$anager network$$anonymous$$anager; public static $$anonymous$$ain$$anonymous$$enu singleton;
[Header("UI")]
public GameObject tempLobbyUI = null;
public T$$anonymous$$P_Text[] tempPlayerNameTexts = null;
public T$$anonymous$$P_Text[] tempPlayerReadyTexts = null;
public Button tempGameButton = null;
[SerializeField] private GameObject landingPagePanel = null;
public float test = 99f;
private void Awake()
{
singleton = this;
}
public void HostLobby()
{
network$$anonymous$$anager.StartHost();
landingPagePanel.SetActive(false);
}
}
In the other script I've put in snippets of the lines in question public class NetworkRoomPlayerLobby : NetworkBehaviour { $$anonymous$$ain$$anonymous$$enu main$$anonymous$$enu;
[SyncVar(hook = nameof(HandleDisplayNameChanged))]
public string DisplayName = "Loading...";
[SyncVar(hook = nameof(HandleReadyStatusChanged))]
public bool IsReady = false;
private bool is$$anonymous$$er;
private void Start()
{
main$$anonymous$$enu = $$anonymous$$ain$$anonymous$$enu.singleton;
main$$anonymous$$enu.tempPlayerNameTexts = new T$$anonymous$$P_Text[4];
main$$anonymous$$enu.tempPlayerReadyTexts = new T$$anonymous$$P_Text[4];
}
public bool Is$$anonymous$$er
{
set
{
is$$anonymous$$er = value;
main$$anonymous$$enu.tempGameButton.gameObject.SetActive(true);
}
}
public override void OnStartAuthority() { CmdSetDisplayName(PlayerNameInput.DisplayName);
main$$anonymous$$enu.tempLobbyUI.SetActive(true); }
for (int i = 0; i < main$$anonymous$$enu.tempPlayerNameTexts.Length; i++) { main$$anonymous$$enu.tempPlayerNameTexts[i].text = "Waiting For Player..."; main$$anonymous$$enu.tempPlayerReadyTexts[i].text = string.Empty; }
for (int i = 0; i < Room.RoomPlayers.Count; i++)
{
main$$anonymous$$enu.tempPlayerNameTexts[i].text = Room.RoomPlayers[i].DisplayName;
main$$anonymous$$enu.tempPlayerReadyTexts[i].text = Room.RoomPlayers[i].IsReady ?
"<color=green>Ready</color>" :
"<color=red>Not Ready</color>";
}
}
public void HandleReadyToStart(bool readyToStart)
{
if (!is$$anonymous$$er) { return; }
main$$anonymous$$enu.tempGameButton.interactable = readyToStart;
}
If there is anything you can see there why this wouldn't work I'd much appreciate your help again. $$anonymous$$any thanks Chris