Detect which prefab triggers the button UI
Hi ! It's been a while now that I am on the same problem, after trying everything and looking in all the corners, I ask here: How to detect which prefab player to press on a UI button? Say otherwise and targeting more precisely my problem: How to get a value of a script attached to one of my players from the submit of a ui button?
I describe a bit more: I have a local multiplayer game (using gamepads, like a classic local multiplayer game like, Boomerang Fu, Stick Fight, or even Street Fighter!), I have indexes assigned to each new player , to see who is the P1, the P2 etc ... I have several buttons that represent "characters", which is information that I need to put in Player scripts. So far nothing really crazy, I know how to do it and besides I have already done it for a player. However, when it comes to removing a value that can change from one script to another, knowing that P2 can press one character and P1 another, it gets more complex.
Example of a script on the player (and necessarily on the player otherwise the Listener does not take any value specific to the player):
// Lignee = Character like in an classic RPG Game
public void BtnTrigger()
{
GameObject[] btnLignee = GameObject.FindGameObjectsWithTag("ButtonListLignee");
foreach (GameObject btn in btnLignee)
{
btn.GetComponent<Button>().onClick.RemoveListener(() => ButtonChoice(btn.GetComponent<Button>(), Player));
btn.GetComponent<Button>().onClick.AddListener(() => ButtonChoice(btn.GetComponent<Button>(), Player));
}// end
MainMenu.ChoiceMenuActive = false;
}
public void ButtonChoice(Button btn, DataPlayer.Lignee p)
{
foreach (var l in Record.Lignee)
{
int actualPlayerID = l.ActualPlayerID;
string name = l.name;
var desc = l.desc;
if (l.id != btn.GetComponent<BtnListIndex>().indexBtn && actualPlayerID == p.ActualPlayerID) // reset
{
actualPlayerID = 0;
l.ActualPlayerID = actualPlayerID;
}
else if (l.id == btn.GetComponent<BtnListIndex>().indexBtn && actualPlayerID == 0)
{
Debug.Log("Player: " + p.ActualPlayerID + " choose : " + name);
actualPlayerID = p.ActualPlayerID;
l.ActualPlayerID = actualPlayerID;
p.name = name;
p.desc = desc;
}
else if (actualPlayerID != 0 && actualPlayerID != p.ActualPlayerID)
{
Debug.Log("Already chosen");
}
}
}
It works for 1 player only, but all the players are P1, because the Listener is only started on the script of player 1, otherwise it would make too many Listener ...
I started looking at something else like this for example: https://zupimages.net/viewer.php?id=21/20/oxw6.png
Because from here, i can take the Index of each player, but impossible to get on which button ui the submit is launched ... I obviously tried to call the Listener from an object other than the P1, without success knowing that it never managed to reach the values intrinsic to the scripts of each player...
Anyway, i need help, thanks !
I forgot to say that i am using the new input system, with a MultiplayerEventSystem present in a childobject under the player, i tried to get the information from the eventSystem to detect which player pressed what, without success.
Sorry if it's not well explained, strangely i rarely saw anyone explain my problem elsewhere, otherwise no answer or not quite the same things.
I've already asked the question here, without success : https://forum.unity.com/threads/detect-which-prefab-triggers-the-button-ui.1111288/
Answer by peacemakers1980 · May 21, 2021 at 05:19 PM
Im not a network pro at all but my understanding is that if you have a Client and a Server, each one is running there own set of varaibles, the Client dosent know any information about the server and vis versa. Because of this they need to 'Sync' data If the Client for example clicks a UI, and sends it to the server to run a script/method, the server on its own dosent know the diffrence on who is who so would run it as if it ran it on its own. When a player connects to the server the server should on its own setup a array or something to store the data for each player, in a Command/RPC call in its message it tells the server who it is sending the request, then the server would receive the string from the client or message, and parse it out to determine what its supposed to do and with what. Then the server replies to the client(s) with the new data needed or Syncs. If using Unity built in networking, remember it is more or less abandoned/obsolete and to be replaced with something else. I would suggest using Mirror, a free asset on the asset store, its alot more capable, and has a ton of easy to do things such as how to sync data with who and on its own tracks who is doing what so it makes coding harder to get used to at the start but easier as it goes since you have to tell it to do so much less. With Mirror each client/server that connects is assigned a id and each time they call a command the server knows who is calling it from what and why and can run the commands or can be handled on the client end if not needed to be server ended, then the client just calls the server for syncing the data with the other clients.
Thanks for your answer ! I specify that it is for a problem on the local multiplayer, couch game, on the same sofa ! So there is no network (at least for the moment) that comes into play. But maybe that could be a solution for the local too finally ! Maybe with Mirror I can give an ID to each new controller / player that joins the game, and identify it like that with the server ? It seems tedious for a solution aimed at a local problem and without networks... But if there is only this solution why not...
Your answer
Follow this Question
Related Questions
Unity 5.2 - How can I keep other players from using a menu? 0 Answers
Check if EventSystem is in InputField 1 Answer
Double EventSystem Environnement Issues 1 Answer
Make Standalone Input Module ignore mouse input? 2 Answers
How can multiple users control a single UI canvas using InputSystem? 3 Answers