I have a problem where an object - the Trader dialog - is returning null when I call GetComponent(); on it and I can’t work out why. The only thing I could find is that the Start method of the dialog is called after GetComponent, however I changed the Execution Order to ensure it was called before and this did not resolve. I also can’t see what would make it behave differently to the other three.
I’m unsure where else to go with trouble shooting this and would appreciate input either on how I can resolve my issue or on better ways to implement this solution. If the code below isn’t enough I can share specific parts or provide the repo via GitHub.
A brief overview of the organisation is that in my scene I have a manager object (Farm) and multiple UI dialogs (UIDialog) that are variants of a prefab. The Farm script initialises the values to apply to the dialogs in its Awake function and then applies them to the dialogs in the Start function.
Farm.cs
public class Farm : MonoBehaviour
{
Ledger ledger;
Trader trader;
int turnCount;
void Awake()
{
this.ledger = new Ledger();
this.trader = new Trader(ledger);
}
GameObject InitDialog(string name, IButtonLister buttonLister)
{
GameObject dialogObj = GameObject.Find(name);
if (dialogObj == null)
{
Debug.LogError("missing dialog: " + name);
return null;
}
UIDialog dialog = dialogObj.GetComponent<UIDialog>();
if (dialog == null)
{
print(name + ": where's the dialog????");
} else if (buttonLister != null && buttonLister.Buttons != null)
{
dialog.buttonLister = buttonLister;
}
dialog.HidePanel();
return dialogObj;
}
void Start()
{
GameObject tcObject = GameObject.Find("GameInfo/TurnCount/Text");
turnCount = tcObject.GetComponent<Text>();
InitDialog("Trader", trader);
InitDialog("Ledger", ledger);
InitDialog("Field", null);
InitDialog("Turn", null);
}
}
Trader.cs
public class Trader : IButtonLister
{
List<Contract> availableContracts = new List<Contract>();
public List<IButton> Buttons { get { return availableContracts.Cast<IButton>().ToList(); } }
Ledger ledger;
public Trader(Ledger ledger)
{
this.ledger = ledger;
RefreshContracts();
}
}
UIDialog.cs
public class UIDialog : MonoBehaviour
{
public GameObject pfButton;
public GameObject list;
public GameObject closeButton;
public Text closeText;
public Text title;
public IButtonLister buttonLister {get; set;}
void Awake()
{
var button = transform.Find("Panel/CloseButton").GetComponent<Button>();
button.onClick.AddListener(() => HidePanel());
}
public void HidePanel()
{
gameObject.SetActive(false);
}
public void ShowPanel()
{
if (buttonLister != null)
{
SetButtons(buttonLister.Buttons);
}
gameObject.SetActive(true);
}
public void SetButtons(List<IButton> lib)
{
if (lib == null) { return; }
foreach (Transform child in list.transform)
{
Destroy(child.gameObject);
}
foreach (IButton button in lib)
{
GameObject b = Instantiate(pfButton);
Text t = b.transform.Find("Text").GetComponent<Text>();
t.text = button.Name;
if (button.Desc != null && button.Desc != "")
{
t.text += "
" + button.Desc;
}
Button cButton = b.GetComponent<Button>();
cButton.onClick.AddListener(() => button.OnClick());
cButton.onClick.AddListener(() => HidePanel());
b.transform.SetParent(list.transform);
}
}
}