C# Unity,我如何检测按下了什么OnGUI按钮

C# Unity,我如何检测按下了什么OnGUI按钮,c#,user-interface,unity3d,foreach,C#,User Interface,Unity3d,Foreach,我正在制作一个统一的对话系统,玩家可以与NPC对话,并且每个NPC都有独特的回应选择(想想老卷轴)。我有一个播放器可用响应选项的字符串数组,还可以使用foreach循环将它们打印到GUI按钮上 然而,我一直想弄清楚如何跟踪按下的按钮 void OnGUI() { int i = 0; if(choicesReceived) { foreach (string s in playerChoices) { i++;

我正在制作一个统一的对话系统,玩家可以与NPC对话,并且每个NPC都有独特的回应选择(想想老卷轴)。我有一个播放器可用响应选项的字符串数组,还可以使用foreach循环将它们打印到GUI按钮上

然而,我一直想弄清楚如何跟踪按下的按钮

void OnGUI()
{
    int i = 0;
    if(choicesReceived)
    {
        foreach (string s in playerChoices)
        {
            i++;
            if (GUI.Button(new Rect(850,(50 * i) + 275, (s.Length * 4), 50), s))
            {
                Debug.Log("Chose an option");
            }
        }
    }
}
硬编码并根据字符串值检测所选按钮似乎不是一个很好的主意,但是现在我很难找到更好的方法。各位,先谢谢你们

i
这就是答案

此变量保存按钮的索引。从1,2,3…N开始

请尝试此日志消息:

Debug.Log("Chose an option : " + i);
更新:

根据您的需求,您需要将uGUI用作当前场景和以后使用的最佳工具


我相信这就是你想要的:

我强烈建议使用Unity的新UI系统,而不是使用OnGui

这是更容易开发的,并且有一个内置的事件系统,你可以使用它来做你想做的事情

在OnClick事件中,您可以调用特定的脚本方法,并传入您按下的按钮

文档=>

此外,当接近对话系统时,您必须在类中编写的文本字符串数量可能会失控。因此,您可能希望采用反序列化JSON或XML文件的方法,其中包含对话

例如,下面是一些JSON:

`{
   "id": 001,
   "dialogue":"I used to be an adventurer like you...",
   "responses":[002, 003]
 },
 {
   "id": 002,
   "dialogue":"Wait.I know you...",
   "responses":[]
 },
 {
   "id": 003,
   "dialogue":"Be careful out there.",
   "responses":[]
 }`

然后,所有的响应都被隐藏在代码之外,您只需引用所需的id即可。

您使用的是旧的Unity UI系统(IMGUI)。使用推荐的新UI(uGUI)

1游戏对象->用户界面->按钮

2。将新创建的按钮设为预设按钮,然后删除原来的按钮。(不要删除画布。只需删除按钮)

3。使用
实例化
功能实例化按钮

4。使新按钮成为画布的子按钮

5。为按钮提供
onClick.AddListener
函数,为其提供回调函数。单击
按钮时将调用此函数

创建按钮/画布预制示例:

示例脚本(代码已注释):

确保使用UnityEngine.UI包含

public GameObject canvas;
public GameObject buttonPrefab;
string[] playerChoices = new string[3];

void Start()
{
    playerChoices[0] = "Message 1";
    playerChoices[1] = "Message 2";
    playerChoices[2] = "Message 3";

    createButtons();
}

void createButtons()
{
    int i = 0;
    const float yPosOffset = 40f;
    float offsetCounter = 0;

    foreach (string s in playerChoices)
    {
        //Create new Button
        GameObject tempObj = Instantiate(buttonPrefab, Vector3.zero, Quaternion.identity) as GameObject;
        //Rename Button
        tempObj.name = "button: " + i;
        //Make the Button child of the Canvas
        tempObj.transform.SetParent(canvas.transform, false);
        Button tempButton = tempObj.GetComponent<Button>();
        //Set Button Text
        tempButton.GetComponentInChildren<Text>().text = playerChoices[i];
        //Set Button Position
        Vector2 pos = Vector2.zero;
        pos.y = offsetCounter;
        Debug.Log(pos.y);
        tempButton.GetComponent<RectTransform>().anchoredPosition = pos;
        tempButton.onClick.AddListener(() => clickAction(tempButton));

        offsetCounter += yPosOffset; //Increment Position
        i++;
    }
}

//This function will be called when a Button is clicked
void clickAction(Button buttonClicked)
{
    //Debug.Log("Clicked Button: " + buttonClicked.name);
    Debug.Log("Clicked Button: " + buttonClicked.GetComponentInChildren<Text>().text);
}
公共游戏对象画布;
公共游戏对象按钮预览;
string[]playerChoices=新字符串[3];
void Start()
{
playerChoices[0]=“消息1”;
playerChoices[1]=“消息2”;
playerChoices[2]=“消息3”;
createButtons();
}
void createButtons()
{
int i=0;
常量浮点yPosOffset=40f;
浮动偏移计数器=0;
foreach(playerChoices中的字符串s)
{
//创建新按钮
GameObject tempObj=实例化(buttonPrefab,Vector3.zero,Quaternion.identity)为GameObject;
//重命名按钮
tempObj.name=“按钮:”+i;
//使按钮成为画布的子对象
tempObj.transform.SetParent(canvas.transform,false);
Button tempButton=tempObj.GetComponent();
//设置按钮文本
tempButton.getComponentChildren().text=playerChoices[i];
//设置按钮位置
矢量2位置=矢量2.0;
位置y=偏移计数器;
调试日志(pos.y);
tempButton.GetComponent().anchoredPosition=pos;
tempButton.onClick.AddListener(()=>clickAction(tempButton));
offsetCounter+=YPoOffset;//递增位置
i++;
}
}
//单击按钮时将调用此函数
无效单击操作(按钮已单击)
{
//Debug.Log(“单击按钮:”+buttonClicked.name);
Log(“单击按钮:”+按钮单击.getComponentChildren().text);
}
按钮按钮=SomeGameObject.GetComponent();
button.onClick.AddListener(()=>
{
//把你的逻辑放在这里
}
);

我知道这不是你所问问题的确切答案,但OnGui还未开发,新的UI仍然可以完全由脚本控制。感谢链接,我会看看是否可以更进一步。我试过了,它确实给了我按钮的索引,我还可以告诉它在按钮上打印字符串,然而,考虑到响应选项的数量是可变的,这一点就显而易见了。我必须硬编码一些会损害其可重用性的值。谢谢though@Wopsie检查我答案中的链接。是的,这几乎和程序员给我看的一样。这也应该起作用。不过,现在一切都很好,所以谢谢你的建议和例子!我现在得到一个错误,但这是一个奇妙的设置。我完全可以用这个。非常感谢!我试着让它尽可能基本。我没有得到任何错误。如图所示,按play键后,我使用的脚本工作正常。这与这里的脚本完全相同。你的错误是什么?它已经修复了,只是我把索引增量放在循环的顶部而不是底部位于代码顶部,而不是按钮,但不要出于任何原因使用
OnGUI
,除非您正在制作编辑器插件。快乐编码!
Button button = SomeGameObject.GetComponent<Button>();
button.onClick.AddListener(() =>
    {
        //Put your logic here
    }
);