Advertisement

Problem with click to continue

Started by January 17, 2017 02:36 AM
4 comments, last by Kylotan 7 years, 10 months ago

I'm writing a conversation section for my game, but I'm having trouble implementing a click to continue. I may put everything in xml, but for now I just want to see what's up with this part. I'm not sure what the bug is. Something to do with update(). I'm not getting the next play for some reason. Sometimes the counter does go up though.

Thanks for reading :)

scene control


public class scene_engine : MonoBehaviour {
	private string currentScene;
	private int currentStep;
	private bool playing;
	private bool sceneEnded;
	public GameObject gameEngine;
	public GameObject textEngine;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {

		if (playing) {

			if(Input.GetKeyUp(KeyCode.Space))
			{

				// clear the current text in text engine
				textEngine.GetComponent<text_engine>().clear ();
				// clear the current co-routine

				currentStep++;
				play_scene();
				Debug.Log ("STEP: " + currentStep);

			}

		}
	
	}

	public void set_playing(bool playSet)
	{

		playing = playSet;

	}

	public bool return_playing()
	{

		return playing;

	}

	public void run_scene(string sceneSet)
	{
		currentScene = sceneSet;
		currentStep = 0;
		playing = true;
		play_scene();

	}



	public void play_scene()
	{
	
		switch (currentScene) {
			case "mt arlon intro":
					// Intro scene within mt arlon
			   
							switch(currentStep)
							{
								case 0:
									textEngine.GetComponent<text_engine>().write("Riu", "We haven't got much farther to go now.");
									currentStep++;
								break;
								case 1:
									textEngine.GetComponent<text_engine>().write("Rin", "How are you holding up Tweet?.");
								break;

							}

				// End mt arlon intro clip
			break;

		// End cutscene select
		}

	}

}

text engine


using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class text_engine : MonoBehaviour {
	public GameObject name_bottom;
	public GameObject speech_bottom;
	public GameObject gameEngine;
	public GameObject sceneEngine;
	private Coroutine textID;
	private string character;
	private string message;
	private float letterPause;
	private bool writing;
	// Use this for initialization
	void Start () {
	
		letterPause = 0.1f;
		writing = false;

	}
	
	// Update is called once per frame
	void Update () {
		 


	}

	public void clear()
	{

		name_bottom.GetComponent<Text>().text = "";
		speech_bottom.GetComponent<Text>().text = "";
		StopCoroutine(textID);


	}

	public void write(string nameSet, string messageSet)
	{

		character = nameSet;
		message = messageSet;
		writing = true;

	    textID = StartCoroutine (write_text());

	}
	
	IEnumerator write_text()
	{


		foreach (char letter in message.ToCharArray()) {

			    name_bottom.GetComponent<Text>().text = character;
				speech_bottom.GetComponent<Text>().text += letter;


			yield return new WaitForSeconds(letterPause);

		}

		if (gameEngine.GetComponent<game_engine> ().return_pause () && !sceneEngine.GetComponent<scene_engine> ().return_playing ()) {

			gameEngine.GetComponent<game_engine> ().set_pause (false);

		}
	
	}

	public bool return_writing()
	{

		return writing;

	}
}

You are checking for if the Space key is up. Don't you want to check for if the Space key is down?

(Additionally, you might want to store the previous key state... if you want to react to key up, only react if the previous key state was down, and vice versa).

Hello to all my stalkers.

Advertisement

Be careful about the input values.

You used Input.GetKeyUp() which will return true continuously if the key is up. Using .GetKeyDown() and .GetKeyUp() has problems for quickly bounced keys, they might have pressed and released the key within the time of a single update. That is not uncommon, since generally a frame is anywhere from 5ms to 15ms, but a fast key press can be under a millisecond.

You might be looking for .GetButtonUp(), which only returns true the frame immediately after the button had been down but is now up. This triggers based on events rather than queries, and will return true even if the button was pressed for less than a single frame.

Unity's Input functions already deal with previous+current frame*. I don't see a problem here.

Input.GetKeyUp returns true when: (down on previous frame && up on current frame).
GetKeyDown when: (up on previous frame && down on current frame).
GetKey when: (down on current frame).

GetButtonX vs. GetKeyX differ in that the Button ones are for remappable inputs and the Key ones are for the keys themselves (i.e. you would have to deal with kep mapping on your own).

(*caveat: I don't know if Unity uses buffered input to detect faster-than-one-frame input bounces like frob mentions)


The coroutine seems OK. It seems to me that the "playing" boolean needs to be set to true somewhere before any of the Update function will work, though. How are you setting that? Some external code calls run_scene?

It seems like at the end of the coroutine you should set writing back to false. Although I'm not sure what you use it for. Some external component checks it, I'm guessing?

It looks like you might also want to set playing back to false after all messages finish.

The only thing I'm absolutely certain about is that every time I have to work with it, I need to look it up. The names are terrible. :-)

The button variant is the one that is always captured, no matter how short the time is.

Buttons handle quick taps and should us GetButton. Longer term items should generally use GetAxis. Both allow user configuration.

Even their docs for GetKeyUp() point that out: When dealing with input it is recommended to use Input.GetAxis and Input.GetButton instead.

If you don't have an answer already:

  • remove the per-letter loop for now, just to simplify the code
  • use Debug.Log messages to see what is getting called and what is not

This topic is closed to new replies.

Advertisement