Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Observe Variables (beginner question) #244

Open
TLCMunchkin opened this issue Dec 21, 2016 · 6 comments
Open

Observe Variables (beginner question) #244

TLCMunchkin opened this issue Dec 21, 2016 · 6 comments

Comments

@TLCMunchkin
Copy link

TLCMunchkin commented Dec 21, 2016

Sorry for a probably very novice question, but I'm very new to both unity and ink.

I'm trying to learn by modifying the ink demos (The Intercept & the demos from the Unite Europe talk) and I'm getting along pretty well, especially because ink has been a real blessing for interactive fiction.

(Apologies in advance if my description of the issue is horrible, but I'm still learning all the correct terms)
Something I can't figure out for the life of me right now is how the Observe Variables function works.
I've added a test variable ("fullness") into the ink script that starts on 0 and then depending on your first branching choice it gets set to 1, later in the text 2, then 3.
I've added a Text object to the UI of The Intercept that is supposed to show the progress of that variable.
In it I've set up a variable, names "full" and an if statement that tells the text object that if the variable is 0, it puts out "- - -" in the UI. If it's 1, it puts out "I - -". If it's 3, it puts out "I I I" into the UI.
This works if I manually set variable (independently form the ink file so far). So that part works.

Then I've tried the variablesState, so that the variable is being set by the according variable in the ink file. I did this in the same script and I'm not sure if that's the right way to do it, since I had to load the full ink story file into the script to make it work. BUT once I added that link to the story in the beginning I was able to use variablesState and when I started the game it loaded up the correct output ("- - -", "I - -", "I I I"). But it didn't track the progress of the variable throughout the choices.

And I know that I need the ObserveVariable delegate function to make that work, but I just can't seem to get it to work no matter what I try.
I've tried to adapt this example:

void Update(){
int full = 0;

story.ObserveVariable("fullness", (string varName, object newValue) =>
            {
                full = (int)newValue;
            });
}

I don't know what I'm doing wrong. Do I need to have the variable observed in another script and then just feed it into the text game object? Maybe the GameState script? Maybe just not in the "void Update()" part of that script?
Or does it not matter and I'm just messing this up in another way?

I've tried deleting the "int full = 0;" line and replaced it by the previous variablesState version:
int full = (int) story.variablesState["fullness"];
and this way it would at least read my first "VAR fullness = 0" in the ink story. But it still wouldn't update when the variable changed throughout the game.

Thanks for any help or pointers in advance. Even seeing a working example of the ObserveVariable for a UI command would be a huge help.

~Gabriela

PS:
This is the code, for reference:

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using Ink.Runtime;
using UnityEngine.UI;

using Debug = UnityEngine.Debug;

public class TextUI : MonoBehaviour {

	public Text fullnessUI;
	public int full;

       public TextAsset storyJSON;
	// The ink runtime story object
	private Story story;


	// Use this for initialization
	void Start () {
	}
		
	// Update is called once per frame
	void Update () {
		alphaTween.Loop();
                int full = (int) story.variablesState["fullness"];

                story.ObserveVariable("fullness", (string varName, object newValue) =>
                      {
                            full = (int)newValue;
                      });

		if (full == 1) {
			fullnessUI.text = ("I - -").ToString ();
		} 
		if (full == 2) {
			fullnessUI.text = ("I I -").ToString ();
		}
		if (full == 3) {
			fullnessUI.text = ("I I I").ToString ();
		}
		else {
			fullnessUI.text = ("- - -︎").ToString ();
		}
	}

	public FloatTween alphaTween = new FloatTween();

	private CanvasGroup canvasGroup {
		get {
			return GetComponent<CanvasGroup>();
		}
	}

	private void Awake () {
		alphaTween.OnChange += OnChangeAlphaTween;
	}

	void OnChangeAlphaTween (float currentValue) {
		canvasGroup.alpha = currentValue;
	}

	public void FadeIn () {
		alphaTween.Tween(0, 1, 5, AnimationCurve.EaseInOut(0,0,1,1));
	}

	public void Show () {
		canvasGroup.alpha = 1;
	}

	public void Hide () {
		alphaTween.Stop();
		canvasGroup.alpha = 0;
	}
}
@cduquesne
Copy link
Contributor

Hi !
I see two issues.

First, the 'ObserveVariable' method needs to be called only once in the 'Start' method of your script.

Second, you don't need the "int full = (int) story.variablesState["fullness"];" line at all. More than that, redeclaring this variable in the Update with "int full" implies that it is not the public variable you declared but a new variable in the local scope of the method. (so it was impossible that it stored a value durably)

@TLCMunchkin
Copy link
Author

That makes a lot of sense. I made both of those changes:

  • delete the "int full = (int) story.variablesState["fullness"];" all together
  • put the 'Observe Variable' method in the 'Start' method of the script instead of the 'Update' method.

But, so far, it doesn't work, and I'm getting the warning that the variable 'full' is assigned but its value is never used. Without the 'variablesState' it doesn't even seem to register the variable in the story. I connected the story JSON file in the inspector of the game object.
I also got the Error "NullReferenceException: Object reference not set to an instance of an object TextUI.Start() (at Assets/Scripts/Main/States/Game/View/TextUI.cs:22)".

The Text object is called 'FullnessUI', the Script is called 'TextUI'.
screen shot 2016-12-21 at 14 10 56
screen shot 2016-12-21 at 14 14 32

@joethephish
Copy link
Member

Try something like this - the ObserveVariable and variablesState approaches are two ways to solve the same problem, so you only need one of them.

public class TextUI : MonoBehaviour {

       public Text fullnessUI;

       // This isn't needed
       //public int full;

      public TextAsset storyJSON;
       // The ink runtime story object
       private Story story;

       // Use this for initialization
       void Start () {

            story.ObserveVariable("fullness", (string varName, int full) =>
            {
                if (full == 1) {
                       fullnessUI.text = ("I - -").ToString ();
               }
               if (full == 2) {
                       fullnessUI.text = ("I I -").ToString ();
               }
               if (full == 3) {
                       fullnessUI.text = ("I I I").ToString ();
               }
               else {
                       fullnessUI.text = ("- - -︎").ToString ();
               }
            });
       }

       // etc!

@TLCMunchkin
Copy link
Author

TLCMunchkin commented Dec 21, 2016

I did that and get this:

- Assets/Scripts/Main/States/Game/View/TextUI.cs(24,58): error CS1678: Parameter `2' is declared as type `int' but should be `object'
- Assets/Scripts/Main/States/Game/View/TextUI.cs(24,37): error CS1661: Cannot convert `lambda expression' to delegate type `Ink.Runtime.Story.VariableObserver' since there is a parameter mismatch

changed 'int' to 'object', but then the "==" operator gives me an error message:
Operator '==' cannot be applied to operands of type 'object' and 'int'

So I tried the NewValue thing as a middle man like this, which at least gets rid of the compiler error, but the Text object just says "New Text", so it's not picking up anything.

public class TextUI : MonoBehaviour {

	public Text fullnessUI;
	// public int full;

	public TextAsset storyJSON;
	// The ink runtime story object
	private Story story;

	// Use this for initialization
	void Start () {
		story.ObserveVariable("fullness", (string varName, object newValue) =>
			{
				int full = (int)newValue;
				if (full == 1) {
					fullnessUI.text = ("I - -").ToString ();
				}
				if (full == 2) {
					fullnessUI.text = ("I I -").ToString ();
				}
				if (full == 3) {
					fullnessUI.text = ("I I I").ToString ();
				}
				else {
					fullnessUI.text = ("- - -︎").ToString ();
				}
			});
	}
	// Update is called once per frame
	void Update () {
		alphaTween.Loop ();
	}

Any idea where to go next?
Thank you for all your support so far.

~Gabriela

@joethephish
Copy link
Member

I did notice that story isn't being assigned to in your class? Not sure if that's related...

@TLCMunchkin
Copy link
Author

Hmm, you mean like:
story = new Story(storyJSON.text);

I've now added that into the start method, right before the Observe Variable. No change. :(
I'm sorry, thanks for your help though! hugs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants