Forum rules - please read before posting.

[Issue(s)] - Index out of range and "Variable: Pop Up switch Action is referencing a Var not exist"

edited August 2019 in Technical Q&A

I have built a project ready to test (2019.2) and a link for it, as the system needs a little setup.
(using a patched AC version (dev build), but the first issue happens even with that on the store)

Basically:

  1. Setup a basic 3D game
  2. Add a single hotspot
  3. Set the hotspot to use static assets
  4. Add 1 action for Use, and add a static Actionlist with an integer parameter
  5. Create 3 inventory items carried at start
  6. Add 3 Inventory interactions, one for each different inventory Item
  7. Add a Variable Component with an integer
  8. Don't set the Hotspot parameter in the Hotspot parameters
  9. Add a SetInteractionParameters to the Hotspot
  10. Set Interaction type to Inventory
  11. The Selected interaction already has no name, and just reports "0."
  12. Click on the drop down menu of the Interaction property of the SetInteractionParameters.
  13. Change the selected interaction to 1. or 2.
  14. Several ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
    System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at :0)
    System.ThrowHelper.ThrowArgumentOutOfRangeException () (at
    :0)
    System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at
    :0)
    AC.SetInteractionParameters.ShowParametersGUI (AC.Button button, System.String label) (at Assets/AdventureCreator/Scripts/Logic/SetInteractionParameters.cs:173)
    AC.SetInteractionParameters.ShowGUI () (at Assets/AdventureCreator/Scripts/Logic/SetInteractionParameters.cs:145)
    AC.SetInteractionParametersEditor.OnInspectorGUI () (at Assets/AdventureCreator/Scripts/Logic/Editor/SetInteractionParametersEditor.cs:19)
    UnityEditor.UIElements.InspectorElement+c__AnonStorey1.<>m__0 () (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorElement.cs:496)
    UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

errors appear in the console.

Also:

  1. Play the test scene
  2. Click the hotspot
  3. using the provided script to increment a component value each time it gets clicked throws a

Variable: Pop Up switch Action is referencing a Variable that does not exist!

-> AC debug logger
UnityEngine.Debug:LogWarning(Object, Object)
AC.ACDebug:LogWarning(Object, Object) (at Assets/AdventureCreator/Scripts/Static/ACDebug.cs:25)
AC.ActionVarPopup:AssignValues(List`1) (at Assets/AdventureCreator/Scripts/Actions/ActionVarPopup.cs:98)
AC.d__33:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:335)
UnityEngine.MonoBehaviour:StartCoroutine(String, Object)
AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:320)
AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:557)
AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:470)
AC.d__33:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:439)

warning.

I can't find a way to pass a string variable as a parameter to be pronounced by the Dialogue Action.
I can't find a way to compose a string like "you clicked me X times" and say the proper number by using a single hotspot and an int value obtained via a component variable parameter passed to the interaction.
When checking if 2 component variables are equal, you can only pass the first one as a parameter. A dropdown menu doesn't appear for the second value to make the comparison with.

Comments

  • Thank you for the steps - I will attempt a reproduction.

    I can't find a way to pass a string variable as a parameter to be pronounced by the Dialogue Action.

    Parameter values can be inserted into speech text with the [param:X] token - see the Manual's "Text tokens" chapter.

    Global and string variables can also be inserted with the [var:X] and [localvar:X] tokens respectively. Component variables cannot, though you can first convert a component variable to a global variable with the Variable: Copy Action.

  • The Selected interaction already has no name, and just reports "0."

    In SetInteractionParameters.cs, replace line 139:

    ? i.ToString () + ": " + KickStarter.inventoryManager.GetLabel (hotspot.invButtons[i].iconID)
    

    with:

    ? i.ToString () + ": " + KickStarter.inventoryManager.GetLabel (hotspot.invButtons[i].invID)
    

    Several ArgumentOutOfRangeException: Index was out of range

    Replace the ShowParametersGUI function with the following:

    private void ShowParametersGUI (Button button, string label)
    {
        if (hotspot.interactionSource == InteractionSource.InScene && button.interaction != null)
        {
            ShowParametersGUI (button.interaction);
        }
        else if (hotspot.interactionSource == InteractionSource.AssetFile && button.assetFile != null)
        {
            ShowParametersGUI (button.assetFile);
        }
        else
        {
            EditorGUILayout.HelpBox ("Cannot set parameters for Interaction '" + label + "', since it has no associated ActionList.", MessageType.Warning);
        }
    }
    

    Variable: Pop Up switch Action is referencing a Variable that does not exist!

    The issue is that you're referencing an Integer variable, when a PopUp is expected. The error should be amended to reflect this, but the Variable: Set Action can be used to increase a PopUp value by 1 as well.

  • edited August 2019

    Global and string variables can also be inserted with the [var:X] and [localvar:X] tokens respectively. Component variables cannot, though you can first convert a component variable to a global variable with the Variable: Copy Action.

    Thanks, I knew about the var:X but not the param:X!

    ~~copying a variable from a variable component (which has to be passed as a parameter) to a temp global variable, just to locally display a number feels a bit like a gimmick and adds some overhead (not much, I have to admit).
    I understand that AC's policy is to try to reuse what's available and trying to keep it simple, yet, would it be possible to add a [compvar:X] token, to refer to a compvar that is assumed to be in the gameobject that is triggering the static actionlist? Would be cool if we could define our own tokens~~
    ^the above should appear as a strikethrough

    After reading the manual, I realised it's already there, and I can implement it myself, and more! :)
    I only have to remember to register such tokens (Speech Event Tokens) every time that the game loads (A list of static scriptableobjects containing the implementation of the custom tokens, to be found in the global settings, would be nice to have - they act as a plugin for the speech subengine)

    Would be nice to have the same feature with Text Tokens (I'd create a token to read from a var component on the calling gameobject). (Same as above, having a static list to change the game globally would be nice - I guess it can be done manually by coding some sort of wrapper)

    I clicked on the "Set custom token" at page 318, but results in a broken link (404):
    https://adventurecreator.org/scripting-guide/class_a_c_1_1_runtime_variables.html%23a6504b62f6d1aea7c3592978bccc1e80d

    Removing the extra parameter solved the issue.

    Thinking again about it:
    using [token:ID] allows us to define a token, but only via a single number, and with no extra parameter.

    Would it be possible (yes, I know, it's another feature request) to register our own "tokens", in the very same way we can do it with Speech Event Tokens (so, allowing us to use both an intellegible text, and a parameter)?

    That would greatly expand the possibilities, thus allowing global-scope syntaxes like [compvar:name-gameobjectname] or [compvar:name-local] or similar (so, basically, packing 2 parameters if we want to :P)
    or, [customtexttoken:param1:param2:param3] to be passed as args to the registered function.

    It would make it a bit more extensible, without breaking what's already there, and the changes wouldn't be hardcoded in the engine.

  • Apologies, we were writing at the same time :)

    Thanks for your insta-fixes and explanation!
    I'm going to make the required changes right now :)

    I would still appreciate if you had a look at my previous message, I hope it could contain some ideas which could helpful not only to me, but to all AC users :)

  • Being able to pass component variables as tokens has always been something I wanted, but it wasn't obvious how best to go about it. However, after giving this further thought I feel the best way would be to refer to its Constant ID number, provided that you have a Constant ID or Remember component attached to the gameObject.

    A typical token would then take the form:

    [compvar:constant-id:variable-id]

    I'll look into implementing this in the next release.

    As for custom text event tokens, it should be possible to introduce a "replacement" event similar to the one available for speech event tokens, but this'll likely have to wait for the next major AC release, v1.69.0.

  • Sounds great to me! :)

    Personally, I'm going to work more with static actionlists so putting a [compvar:ID:variableID] would be like binding the static actionlist to a specific ID, while I'm likely more inclined to use parameters.
    Unless, the ID could also be a prefab, in which case it targets the first object in the call chain with that prefabID.

    I'm not sure it's the best place to brainstorm nor if you're open to it, yet:

    what about:

    [compvarID:ID:varID] for hardcoding specific IDs/vars
    [compvarIDref:refParamID:varID] for using the ID passed via parameter (reference)

    or, to keep using parameters with runtime resolution of the gameobject, decoupled from the use of constantIDs, and to keep passing gameobjects as parameters instead of IDs:
    [compvarObj:refParamObj:varID], where refParamObj is the index of the gameobject passed as param (sure, it's hard to maintain for the user since the index could potentially change, but it's definitely not a syntax to be used in an everyday scenario]

    of course, being able to register our own text tokens would let us create a reference in the style we'd prefer

    Personally, I'd create:
    [compvarCaller:varID], where Caller is the first gameObjects in the call chain to have a ComponentVariable attached to it. Very straightforward in the simplest case, a bit harder to track when there are chained calls.

    or

    [compvar-hotspot:varID], which targets the first component variable in the call list which is a hotspot and has a component variable

    and, in the same way, the dash could be used as a filter for a few relevant classes or uses

    [compvar-constantID:ID:varID]
    [compvar:varID] (defaults to the first object down in the call chain with a compvar attached)
    [compvar-character:varID] same, but for characters

    Just my 2 cents :)

    Just curious: when you say next release and "next major release", how would they translate in weeks/months, approximately?

    Just to know if it's a change that's going to happen before the end of my current project or not :)

  • edited August 2019

    [compvarIDref:refParamID:varID] for using the ID passed via parameter (reference)

    I'd like to keep the provided tokens relatively simple to understand, but I suspect it wouldn't be harmful to force the "processing" order such that the [param] token is read before the [var] tokens. You could then combine tokens such as:

    [compvar:[param:paramID]:[varID]]
    

    [compvar-hotspot:varID], which targets the first component variable in the call list which is a hotspot and has a component variable

    So that AC is always sure of what counts as a token (so that it never mistakenly modifies text), I would prefer to keep the consistency of a [key:value] syntax. Of course, in a potential "text event token", "value" could be whatever you want e.g. "hotspot-varID".

    when you say next release and "next major release", how would they translate in weeks/months, approximately?

    The next release, v1.68.5, is planned soon - though it depends on the state of incoming bug reports.

    v1.69.0 has quite a lot planned - hence the need for an intermediary bugfix release - but I can't comment on how long it will be. It's typically about 2 months, but don't take that as golden.

  • edited August 2019

    Ouch.

    1.69.0 falls about nearby the deadline of my current project so I definitely have to find another way :)

    But I really really appreciate the fact you seem to be very open to proposals (obviously to the extent of what you deem to be the limit, according to your vision for the asset), thank you :)

    I believe I will attempt to implement that system by myself (custom text event tokens just lik eSpeech Event Tokens). Attempt to. I still don't have such a deep knowledge of the whole framework, which has been the result of years of refinements and additions :D

    Could you please suggest me some place from where to begin? Even hackish-yet-robust solutions would be welcome :)

    I guess I will have to inherit from some classes, and I'm not sure it's currently technically possible without creating conflicts with next updates (I believe a few methods need to be protected virtual for me to override them).

    I'm not even sure of which class to begin with (AC is big part of the project, but still only part of it), so any direction would be welcome :)

  • edited August 2019

    It would be easier for me to just do it myself. I will fit it into v1.68.5.

  • That's great news! Thank you :)

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.