Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(7 edits)

Happy to help! I would suggest making use of lambdas - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lamb...

So in your case, something like this...

It is not necessary to store the lambda in a local variable ("conLambda"), typically I would just pass it directly as the second parameter of AddFieldCallback, but I broke it out into its own line for clarity.

The basic way I think about lambdas is that they declare a function that operates on a given set of parameters.

(param0, param1, etc.) => [turns into] [action on parameters]

In this case, your function operates on no parameters, hence the empty parentheses at the start of the lambda declaration.

From the perspective of the InkObjects system, using an Action with no parameters makes the most sense for a FieldCallback, as the system does not have any data that it needs to pass along when it invokes the action (though I could imagine a very complete system might want to pass along the name and value of the field that is being updated, and maybe I will push an update later that has that functionality, but it wouldn't accomplish what you are trying to do).

Anyway, let me know if you have further questions or encounter any other issues!

Hi Julian. Thank you so much! I had never heard of lambdas before. It's silly that simply adding " () => " in front of the function magically makes it work as an Action (well, I guess the action is to call that function). I had been trying to do just that for the longest time.

Now I just need to solve one last challenge that has to do with InkObjects... something that I'm starting to fear might be impossible. I hope I'm wrong! I want players to be able to create their own characters, and use them inside the Ink story. 

The way I'm trying to accomplish that is by replacing the values in the InkObject I call "Hero", which is a type of InkObjectHero I created, with the values introduced by the player right before the story starts. This seems like the simpler approach, but the Internet doesn't seem to like the idea of modifying scriptable objects at runtime. Instead of finding tutorials on how to do it, all I find are people saying "don't do that!". 

So the other thing I tried is creating a new InkObjectHero at runtime and assigning it as the LibraryObject to observe. However, I've run into a couple problems with this method. Firstly, the ObjectLibrary needs to be rebuilt at runtime in order to include the new Hero, which I don't know how to do (or even if it's possible). And secondly, assuming I could do that, when I add new heroes to the Resources folder they are assigned a new ID, and my story is currently written to use the first ID (0) as the original Hero. I'd somehow need to pass the ID of the Hero the player created to the story. Or maybe change the order in which the Objects are specified in the "Specified Objects List" before updating the Library at runtime, in order to make the new Hero be the first. 

I don't know, maybe there is a much easier way to approach this that I'm not seeing. I hope you can shed some light! Or, at least, let me know if it's even possible to do! Thank you so much in advance!

(4 edits)

Well there is no inherent issue with changing values of a Scriptable Object at runtime in Unity. Some people might not like it for stylistic reasons but it's certainly possible. But I don't think that is what is causing you problems in this case.

The issue you are running into is specifically with InkObjects and where they "live."

The InkObjectLibrary can only be modified while authoring the game/story. InkObjects is a tool which can be used to populate your Ink story with data that can be manipulated in Ink and read back by Unity. But once you export your library to Ink, your InkObjects live in Ink and can only be modified in Ink.

If you notice that the InkObject asset in your Unity project is grayed out and not editable during play mode, this is because there is a custom UnityEditor for InkObjects that is doing that manually and reflecting the values from the Runtime instance of that Library Object. This is because changing the Library Object after exporting the Library to Ink will have zero effect on your game (apart from being very confusing).

If you want the user to modify the player character, that will need to happen in Ink, just like any other part of the Ink story. I know some things might be difficult to achieve (for example text entry) but many things will be easy to change interactively within Ink through choices. Your app could skin the choices to make it look like a more typical character design interface.

I will look into potentially expanding the InkObject system so that you can push overrides to InkObjects from Unity to Ink at runtime. I agree that would be very useful, though in my basic research into Ink my understanding was that pushing data to Ink was unsafe (for example, the Ink docs do not recommend changing values via external function).

As an update I think it may easier than I anticipated to add this functionality so stay tuned

Ohh I can't wait to find out if you worked it out! My face looks exactly like the frog in our avatars right now.

Check out Version 1.2.0! https://jsk.itch.io/ink-objects/devlog/357515/version-120-released

Julian!! You're a genius!! I'm so, so grateful! You should have a YouTube channel with tutorials about InkObjects. I'm sure many people would appreciate it. Your solution works like a charm. 

Very happy to help, and thanks for asking questions on here as I'm sure solving your issues will help to improve the package for others as well. Good idea on the YouTube tutorial.