The question is answered, right answer was accepted
No keyboard focus on Buttons instantiated from prefabs on canvas,
Currently I am Adding keyboard controlls in order to navigate a Dialog between Player and NPC by WASD and E. I have set up unitys Input controlls for this, but I run into an issue.
When I start the dialog I am able to set the focus to the "next" button (which is not creaated from a prefab) and confirm with "e".
In the next step the Player choices are displayed by instantiating prefab Buttons (see code below)
These buttons do not gain keyboard focus although I set it explictly. I still can click them with the mouse however. I googled and experimented for six hours now but seem unable to find a solution.
maybe some of ou guys has an idea... the Code looks like this:
void UpdateUI()
{
gameObject.SetActive(playerConversant.IsActive());
if(!playerConversant.IsActive())
{
return;
}
conversantName.text = playerConversant.GetCurrentConversantName();
AIResponse.SetActive(!playerConversant.IsChoosing());
choiceRoot.gameObject.SetActive(playerConversant.IsChoosing());
if(playerConversant.IsChoosing())
{
BuildChoiceList();
}
else
{
AIText.SetText(playerConversant.GetText());
nextButton.gameObject.SetActive(playerConversant.HasNext());
//put focus on the button...this works
EventSystem.current.SetSelectedGameObject(nextButton.gameObject);
}
}
private void BuildChoiceList()
{
foreach (Transform item in choiceRoot)
{
Destroy(item.gameObject);
}
foreach (DialogNode choice in playerConversant.GetChoices())
{
GameObject choiceInstan = Instantiate(choicePrefab, choiceRoot);
choiceInstan.GetComponentsInChildren<TextMeshProUGUI>().FirstOrDefault().SetText(choice.GetText());
choiceInstan.GetComponentsInChildren<Button>().FirstOrDefault().onClick.AddListener(() =>
{
playerConversant.SelectChoice(choice);
});
}
// Try to set fokus to first instantiated button
Button toSetFocusOn = choiceRoot.GetComponentsInChildren<Button>().FirstOrDefault();
toSetFocusOn.gameObject.SetActive(true);
EventSystem.current.SetSelectedGameObject(toSetFocusOn.gameObject);
}
}
The hirarchy setup looks lke this
Answer by Goldlaser2000 · 4 days ago
Okay, I found the solution. When I call the cleanup part of the code
foreach (Transform item in choiceRoot)
{
Destroy(item.gameObject);
}
It makes new instances of the buttons spawning in a non active state, also making them resistant to setting them active explicitly, which is quite interesting, as they also stay visible and clickable. I will therfore have to use something different than Destroy();