button pressed twice / Conversation text skip

Hey guys,

I've got a really stupid problem...looked up the scripting reference & unity boards but didn't find a answer yet.

I'm trying to make a conversation between the player and a NPC (like in the most RPGs, running around and asking people).

Trigger, GUIs, everything fine & working until I want to skip the text with the same button!

So basically the player is colliding with the trigger-zone of the NPC. If inside and pressing the "Interact-Button" to talk, a text message appears. To skip the 1st part of the text and listen to the next, the same button is pressed again ("Interact-Button")

Here is my script which is attached to the trigger-zone (cube) around the NPC :


static var talking = false;
var TextA = false; 
var TextB = false;

function OnTriggerStay (other : Collider) 
{
    if(other.gameObject.tag == "Player")
    {
        if(Input.GetButtonUp("Interact"))
        {
            talking = true;
            TextA = true;
            print("TextA"); // console check

            if(Input.GetButtonUp("Interact"))
            {
                TextB = true;
                print("TextB"); // console check
            }
        }
    }
}

function OnGUI () 
{
    if (talking)
    {
        if (TextA) 
        {
            // GUI label is shown with Text A
        }
        else if (TextB)
        {
            // GUI label is shown with Text B
        }
    }
}


If I try to talk to the NPC and press the Button "ONCE"! the console shows me TextA followed by TextB immediately :( .

It should be like: press -> TextA -> press -> TextB ->press -> TextC and so on... [of course I would set the previous Text to false for it to disappear but first things first]

I would greatly appreciate your help Uni-Community

Input.GetButtonUp returns true the frame that key is pressed down.

So, in this case:

    if(Input.GetButtonUp("Interact"))
    {
        // stuff
        if(Input.GetButtonUp("Interact"))
        {
             // more stuff
        }
    }

Both `if` statements will return true the frame you release that button. So both "stuff" and "more stuff" will execute. You'll have to change your logic to something else.

What you'll probably want to do is have some kind of flag that says whether or not the text is printing out. If it is and the button is pressed up, skip to the end. If it isn't, go to the next one.

From the `GetButtonUp` documentation

Returns true the first frame the user releases the virtual button identified by buttonName.

From your code

if(Input.GetButtonUp("Interact"))           // <----------
        {
            talking = true;
            TextA = true;
            print("TextA"); // console check

            if(Input.GetButtonUp("Interact"))  // <----------
            {
                TextB = true;
                print("TextB"); // console check
            }
        }

Between the two indicated points the value returned by GetButtonUp does not change. You are still in the same frame. So you're always going to get the contents of both if statements executing at the same time.

That's your problem, I'll leave fixing it as an exercise for the reader.

[edit: beaten by 30 seconds]

Since everyone else has already posted about your double GetButtonUp, here's a changed version of your code which uses arrays instead of loads of bools and string variables:

static var talking = false; //not sure this should be static - at least there needs to be an instance version for it *this* script is talking
var texts : String[]; //string array to be set in inspector
private var currentTextIndex = -1;
private var currentText = "";

function OnTriggerStay (other : Collider) 
{
    if(other.gameObject.tag == "Player")
    {
        if(Input.GetButtonUp("Interact"))
        {
            talking = true;
            ++currentTextIndex;
            if (currentTextIndex >= text.Length)
            {
                talking = false;
                currentText = "";
            }
            else if (currentTextIndex > -1) currentText = texts[currentTextIndex];
        }
    }
}

function OnTriggerEnter(other : Collider)
{
    if(other.gameObject.tag == "Player")
    {
        currentText = -1;
    }
}

function OnGUI () 
{
    if (talking)
    {
        //show GUI Label using currentText as the string
    }
}

so I finally was able to find a way...

it's not the most elegant one and I still don't really know how to use arrays (I've tried and failed)

but here is how it worked for me:


static var talking = false; 
//(btw. static because I need to access this var from another script)

var page : int = 0;

var TextA = false; 
var TextB = false;

function OnTriggerStay (other : Collider) 
{
    if(other.gameObject.tag == "Player")
    {
        // Text 1
        if(page == 0 && Input.GetButtonUp("Interact"))
        {
            talking = true;

            TextA = true;
            page = 1;
        }
        // Text 2
        else if(page == 1 && Input.GetButtonUp("Interact"))
        {
            TextA = false;
            TextB = true;
            page = 2;
        }

// and so on...

function OnGUI () 
{
    if (talking)
    {
        if (TextA) 
        {
            //GUI.Label A
        }
        else if (TextB)
        {
            //GUI.Label B
        }

// and so on...


so I used the "page" variable as a buffer to switch frames / as a flag to tell when to print or not, like you guys kinda implied me to do so.

thanks a lot everyone! :)

Pengu and others, thank you very much!