Issues Using ICustomVariableManager within Naninovel custom command

Using Naninovel C# APIs: adding custom actor implementations or commands, overriding engine services, integrating with other systems, etc.
Post Reply
sim1-81
Posts: 5
Joined: 26 Apr 2023 16:32

Issues Using ICustomVariableManager within Naninovel custom command

Post by sim1-81 »

Hi to All, I'm new in c# and Naninovel,

I'm try to write a c#class to add a custom command to set some variables and use it in naninovel scripts.

this custom command have to read thess variables do his calculation and play specific naninovel script based on result.

as i read into Naninovel documentation to do that i can do this

Code: Select all

var variableManager = Engine.GetService<ICustomVariableManager>();
var myValue = variableManager.GetVariableValue("MyVariableName");
myValue += "Hello!";
variableManager.SetVariableValue("MyVariable", myValue);

but when i put this code in my c# class

Code: Select all


using Naninovel;
using UnityCommon;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

[CommandAlias("multichoise") 
public class MultichoiseGenerator : Command
{
    public StringListParameter Var1;
    public StringListParameter Var2;

public override async UniTask ExecuteAsync(AsyncToken asyncToken = default)
{
    var variableManager = Engine.GetService<ICustomVariableManager>();
    var player = Engine.GetService<IScriptPlayer>();
   
    /* my stuff */

}
}

i get this error

System.NullReferenceException: Object reference not set to an instance of an object
at Naninovel.ScriptPlaylist+<>cDisplayClass9_0.<GetCommandAfterLine>b0 (Naninovel.Command a) [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlaylist.cs

how can I solve this?

Thanks in advance for any suggestions

sim1-81
Posts: 5
Joined: 26 Apr 2023 16:32

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by sim1-81 »

Hi again,

just a little update, i tried to add the Git repo inventory-master indo the Demo-master, then i followed te steps in this guide
https://naninovel.com/guide/inventory.html#usage

then i put @goto TestScript in Demo-master Main script and whe te execution arrive to the go to line i get this error

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object
at NaninovelInventory.InventoryFunctions.ItemCount (System.String itemId) [0x0000e] in D:\\Demo-master\Assets\NaninovelInventory\Runtime\InventoryFunctions.cs:12
at NaninovelInventory.InventoryFunctions.ItemExist (System.String itemId) [0x00000] in D:\\Demo-master\Assets\NaninovelInventory\Runtime\InventoryFunctions.cs:15
at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <eae584ce26bc40229c1b1aa476bfa589>:0
--- End of inner exception stack trace ---

what i miss?

here the code of inventoryFunction.cs

Code: Select all

using Naninovel;

namespace NaninovelInventory
{
    [ExpressionFunctions]
    public static class InventoryFunctions
    {
        public static int ItemCount (string itemId)
        {
            var uiManager = Engine.GetService<IUIManager>();
            var inventory = uiManager.GetUI<InventoryUI>();
            return inventory.CountItem(itemId);
        }

    public static bool ItemExist (string itemId) => ItemCount(itemId) > 0;
}
}

it is absolutely identical to that of my custom command from the previous post. I think I'm missing somting with this Engine.GetService

please help!

Thanks

idaot
support
Posts: 262
Joined: 01 Aug 2020 08:25

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by idaot »

Be aware that example projects are not designed to be combined together or imported into other projects and are instead designed to be imported as projects in Unity Hub. In case you've done that then be sure to delete one of the NaninovelData folders as otherwise that can cause problems or confusion.

In regards to the errors, the first example appears to be fine however since you didn't include the entire code so I can't be certain. Make sure to await/return UniTask.CompletedTask at the end of ExecuteAsync. Also try reimporting the naniscripts that are playing when that error occurs as it could be a cache issue.

As for the second error, be sure to include the NaninovelInventory type assemblies into the Engine configuration as advised in the installation guide: https://naninovel.com/guide/inventory.html#installation

sim1-81
Posts: 5
Joined: 26 Apr 2023 16:32

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by sim1-81 »

Thanks for reply,

about the second problem with the inventory I'd forgot to put the inventory UI inside the project settings.

But concenrning my custom command C# class I don't understend what I'm wrong. this is the steps that I made:

1) I look into project folders and I found the others commands in Assets/Naninovel/Runtime/Command folder
2) I put in this folder a MultichoiseGenerator.cs blank file then I added this code to file

Code: Select all

using Naninovel;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;

[CommandAlias("multichoise")]
public class MultichoiseGenerator : Command
{
    public StringListParameter choises;
    public StringListParameter scripts;

    protected virtual ICustomVariableManager variableManager => Engine.GetService<ICustomVariableManager>();
    protected virtual IScriptPlayer player => Engine.GetService<IScriptPlayer>();

    public override async UniTask ExecuteAsync(AsyncToken asyncToken = default)
    {
        var variableManager = Engine.GetService<ICustomVariableManager>();
        var player = Engine.GetService<IScriptPlayer>();
        foreach (string choise in choises)
        {
            string[] choiseScriptArray = choise.Split('.');
            Debug.Log(choiseScriptArray[0] + " "+ choiseScriptArray[1]);

                variableManager.TrySetVariableValue("tmpChoiseLabel", choiseScriptArray[0]);
                variableManager.TrySetVariableValue("tmpScriptName", choiseScriptArray[1]);
          
            await player.PreloadAndPlayAsync("ChoiseLine");
           
        }

        await UniTask.CompletedTask;
        //await player.PreloadAndPlayAsync("Stop");

        /*
            var aaa = new NamedString("Script001", "AfterStorm")
            var Goto = new Goto { Path = aaa };
            Goto.ExecuteAsync();
        */
    }
}

3) i create the ChoiseLine.nani file and placed it into project /Scripts folder, I also added it to the script resources inside project settings -> naninovel -> scripts with this line of code

Code: Select all

# Choises
@choise {tmpChoiseLabel}  goto:{tmpScriptName}

then I put tmpChoiseLabel and tmpScriptName into project settings -> naninovel ->custom variables adding to new line with these names
4) Into the Main.nani at the top of file I added these lines

Code: Select all

@printer Wide
@bgm Wind fade:1 wait:false
@multichoise choises:home.morningAtHome,office.work,school.homecoming scripts:teststring
@stop

5) while executin the game when it reach the line starting with @multichois i see in unity console my debug log, then i get the mentioned error, here the complete error string

Code: Select all

casa mattina
UnityEngine.Debug:Log (object)
System.NullReferenceException: Object reference not set to an instance of an object
  at Naninovel.ScriptPlaylist+<>c__DisplayClass9_0.<GetCommandAfterLine>b__0 (Naninovel.Command a) [0x00000] in D:\\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlaylist.cs:111 
  at System.Linq.Enumerable.TryGetFirst[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate, System.Boolean& found) [0x0003f] in <d630687edd41403db17561f5afda04df>:0 
  at System.Linq.Enumerable.FirstOrDefault[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate) [0x00000] in <d630687edd41403db17561f5afda04df>:0 
  at Naninovel.ScriptPlaylist.GetCommandAfterLine (System.Int32 lineIndex, System.Int32 inlineIndex) [0x00014] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlaylist.cs:111 
  at Naninovel.ScriptPlayer.PreloadAndPlayAsync (Naninovel.Script script, System.Int32 startLineIndex, System.Int32 startInlineIndex, System.String label) [0x000bc] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlayer.cs:338 
  at Naninovel.UniTaskCompletionSource.Naninovel.Async.IAwaiter.GetResult () [0x00013] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskCompletionSource.cs:91 
  at Naninovel.UniTask.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:46 
  at Naninovel.UniTask+Awaiter.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:201 
  at Naninovel.ScriptPlayerExtensions.PreloadAndPlayAsync (Naninovel.IScriptPlayer scriptPlayer, System.String scriptName, System.Int32 startLineIndex, System.Int32 startInlineIndex, System.String label) [0x000c6] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlayerExtensions.cs:23 
  at Naninovel.UniTaskCompletionSource.Naninovel.Async.IAwaiter.GetResult () [0x00013] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskCompletionSource.cs:91 
  at Naninovel.UniTask.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:46 
  at Naninovel.UniTask+Awaiter.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:201 
  at MultichoiseGenerator.ExecuteAsync (Naninovel.AsyncToken asyncToken) [0x000ad] in D:\Demo-master\Assets\Runtime\MultichoiseGenerator.cs:26 
  at Naninovel.UniTaskCompletionSource.Naninovel.Async.IAwaiter.GetResult () [0x00013] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskCompletionSource.cs:91 
  at Naninovel.UniTask.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:46 
  at Naninovel.UniTask+Awaiter.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:201 
  at Naninovel.ScriptPlayer.ExecuteIgnoringCancellationAsync (Naninovel.Command command, Naninovel.AsyncToken asyncToken) [0x0002e] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlayer.cs:598 
  at Naninovel.UniTaskCompletionSource.Naninovel.Async.IAwaiter.GetResult () [0x00013] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskCompletionSource.cs:91 
  at Naninovel.UniTask.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:46 
  at Naninovel.UniTask+Awaiter.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:201 
  at Naninovel.ScriptPlayer.ExecutePlayedCommandAsync (Naninovel.AsyncToken asyncToken) [0x002b7] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlayer.cs:558 
  at Naninovel.UniTaskCompletionSource.Naninovel.Async.IAwaiter.GetResult () [0x00013] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskCompletionSource.cs:91 
  at Naninovel.UniTask.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:46 
  at Naninovel.UniTask+Awaiter.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:201 
  at Naninovel.ScriptPlayer.PlayRoutineAsync (Naninovel.AsyncToken asyncToken) [0x00227] in D:\Demo-master\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlayer.cs:622 
  at Naninovel.UniTaskCompletionSource.Naninovel.Async.IAwaiter.GetResult () [0x00013] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskCompletionSource.cs:91 
  at Naninovel.UniTask.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:46 
  at Naninovel.UniTask+Awaiter.GetResult () [0x00000] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTask.cs:201 
  at Naninovel.UniTaskExtensions.ForgetCore (Naninovel.UniTask task) [0x00016] in D:\Demo-master\Assets\Naninovel\Runtime\Common\Async\UniTask\Public\UniTaskExtensions.cs:189 
UnityEngine.Debug:LogError (object)
Naninovel.Async.UniTaskScheduler:PublishUnobservedTaskException (System.Exception) (at Assets/Naninovel/Runtime/Common/Async/UniTask/UniTaskScheduler.cs:65)
Naninovel.Async.CompilerServices.AsyncUniTaskVoidMethodBuilder:SetException (System.Exception) (at Assets/Naninovel/Runtime/Common/Async/UniTask/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs:29)
Naninovel.UniTaskExtensions/<ForgetCore>d__11:MoveNext () (at Assets/Naninovel/Runtime/Common/Async/UniTask/Public/UniTaskExtensions.cs:189)
Naninovel.Async.CompilerServices.AsyncUniTaskVoidMethodBuilder:Start<Naninovel.UniTaskExtensions/<ForgetCore>d__11> (Naninovel.UniTaskExtensions/<ForgetCore>d__11&) (at Assets/Naninovel/Runtime/Common/Async/UniTask/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs:77)
Naninovel.UniTaskExtensions:ForgetCore (Naninovel.UniTask)
Naninovel.UniTaskExtensions:Forget (Naninovel.UniTask) (at Assets/Naninovel/Runtime/Common/Async/UniTask/Public/UniTaskExtensions.cs:171)
Naninovel.ScriptPlayer:Play () (at Assets/Naninovel/Runtime/ScriptPlayer/ScriptPlayer.cs:290)
Naninovel.ScriptPlayer:Play (Naninovel.Script,int,int) (at Assets/Naninovel/Runtime/ScriptPlayer/ScriptPlayer.cs:324)
Naninovel.ScriptPlayer/<PreloadAndPlayAsync>d__106:MoveNext () (at Assets/Naninovel/Runtime/ScriptPlayer/ScriptPlayer.cs:346)
Naninovel.Async.CompilerServices.MoveNextRunner`1<Naninovel.ScriptPlayer/<PreloadAndPlayAsync>d__106>:Run () (at Assets/Naninovel/Runtime/Common/Async/UniTask/CompilerServices/MoveNextRunner.cs:16)
Naninovel.Async.Internal.FuncExtensions:Invoke<UnityEngine.AsyncOperation> (System.Action,UnityEngine.AsyncOperation) (at Assets/Naninovel/Runtime/Common/Async/UniTask/Internal/FuncExtensions.cs:18)
UnityEngine.AsyncOperation:InvokeCompletionEvent ()

6) I moved my file outside naninovel and placed it into a folder /Runtime in project main directory just as I saw within the IntegrationExample-master's git repo example, but i get the same error
7) I'm bushing my head on my desk from days by this error

my Idea is to create small nani script and call them multiple times to avoid to write thousand of times the same lines of code in the whole storyline.

the result I would like to get is write this:

Code: Select all

@multichoise choises:home.morningAtHome,office.work,school.homecoming scripts:teststring

instead of this:

Code: Select all

@choise home goTo:morningAtHome
@choise office goTo:work
@choise school goTo:homecoming

I'm forgetting some steps in Unity or somewherelse? this is my first project in C# , Unity and Naninovel even if I'm a long time developer

I'm using Unity 2021.3.23f1 for my project

I also tryed to remove Main.nani from the scripts list and reappend it, I aslo quited the cache from preference -> GI Cache -> clean cache button

thanks again

idaot
support
Posts: 262
Joined: 01 Aug 2020 08:25

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by idaot »

Try reinstalling Naninovel. You are not supposed to modify the Naninovel folder that is generated from the extension and doing that is known to cause problems like these.

Also to clear the cache of possibly misbehaving objects, you need to right click the file or folder and choose Reimport. GI cache is unrelated.

sim1-81
Posts: 5
Joined: 26 Apr 2023 16:32

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by sim1-81 »

Thanks for suggestions,

i tryed to do all that you told me, without success.

at First i reimported/reinstall Nannovel into my project, and error is still there,
then i Reimporder all my Assets folder by clicking on Reimport from the context menu, and the error is still there.

so i start a new project from the begin, i Installed Naninovel, i copyed the NaninovelInventory's folder from the git repo into my new project,
I made all connection manually in Unity. resourcets assets backgrounds, custom variables, etc.. etc.., also all nani scripts into the naninovel -> scripts resources manager
Then I've created a new folder named Runtime in /Assets and I placed here my file /Assets/Runtime/MultichoiseGenerator.cs

and when i run my project i have the same error again afther my Debug.log()

System.NullReferenceException: Object reference not set to an instance of an object
at Naninovel.ScriptPlaylist+<>cDisplayClass9_0.<GetCommandAfterLine>b0 (Naninovel.Command a) [0x00000] in D:\Game1\Game 1\Assets\Naninovel\Runtime\ScriptPlayer\ScriptPlaylist.cs:111

What i missed?

idaot
support
Posts: 262
Joined: 01 Aug 2020 08:25

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by idaot »

Try the sample script in the Custom Command guide (https://naninovel.com/guide/custom-comm ... om-command), save it as HelloWorld.cs and place it in the Assets/Runtime folder. If it's not working then you're probably using an outdated version of Naninovel.

If it works then I suggest studying relevant commands and expression functions for their C# code, like Goto.cs, AddChoice.cs and ExpressionFunctions.cs. I suggest testing things incrementally and using debugging tools (https://www.youtube.com/watch?v=bn1ZJxAM1zw) to ensure the correct variables are being passed through functions.

sim1-81
Posts: 5
Joined: 26 Apr 2023 16:32

Re: Issues Using ICustomVariableManager within Naninovel custom command

Post by sim1-81 »

Hi Idaot,

Reading docs I was able to fix my issue. The problem was the Assembly Definition.

So to fix I did these steps:

1) Create /Assets/Runtime folder in my project using the context menu
2) Click with right mouse button on this folder, Select "Create -> Assembly Definition"
2) Renamed and configured this Assembly Definition accordind with what i saw in the "Elringus.NaninovelInventory.Runtime"
3) Add a new line with my file to Engine -> Type Assemblies into the Project settings

I start again the Unity Editor and the problem was fixed.

Thanks!

Post Reply