Thursday, March 26, 2020

Mr Taft FAQ 1 - Signal

This is the first in a series of FAQ articles to accompany the Zelda Like Tutorial Series from Mr. Taft. This question comes up a lot on the Discord Server.

The Question:

Hey guys - I've come to a complete standstill when implementing Signals in this Zelda for Unity project. My code for Signal & SignalListener are exactly as they should be with no errors, but I can't seem to drag my "Signal" over to my Signallistener. Any ideas why? Using unity 2019.1"

Or.

"im doing the signal system but seems like it doesnt recognize the object as an scriptable object, what can cause this?"


The Answer:

Unity 2019 already has a Signal, your one and the Unity one are being confused with each other. There are two fixes.

1. Don't use Signal as the name of your scritpable object, use Notification or TaftSignal for example instead!

2. You can create an object called signal but place it in a folder in the asset menu, that way Unity will treat it as a separate entity. 

in the Signal.cs file modify the CreateAssetMenu directive to read as follows.


When you want to create a signal as directed by Mr Taft, be sure to select the signal from your Scriptable folder!



Happy coding! :D

PappaP x

Sunday, March 22, 2020

Serialization of Scriptable Objects in Unity (Nesting) pt2. Binary!

In my last blog I said I wasn't going to do a binary saver, well - actually I was asked on the Mister Taft creates Discord server to post up a binary version, so here it is!

Disclaimer: I am in NO way a professional Unity coder, I am hacky and this might not (probably isn't) the best way to do this! But it works for me and I and hopefully, this is useful to someone, if so or if you have any questions please come to the Discord channel and let me know!

Not one to shy away I have modified the classes from <Part 1> to allow a flip between JSON and binary based on a selection in the editor!

Thanks again to my friend Ashfid from the discord server, we had a discussion on utilising an approach which was also featured in a GameGrind video.

I have again left out a lot of error checking for sake of clarity, but make sure to put some in your own code :) 

Thanks, Ashfid, MisterTaft, Bomara and all on the Mister Taft Discord.

Much love to you all, this is an absolutely crazy time, stay safe!

PappaP x

ps. I'm moving to Pastebin for the code, whilst not as pretty - it supports cutting the code out directly!

Downloads:



First up, a change to our SerializeListString class!

I have moved the Struct out into its own class SerialItem. There is no other change to this class.

Exceprt from SerializableListString.cs




The BinarySaver class.

Almost completely a shameless rip off from the GameGrind video mentioned above, I'd suggest having a watch if you want to understand the nuances. The methods in this class are static, so we can call them from anywhere.

Essentially I am utilising a generic method to ensure I can save out my SerializeListString class object. I'll let the code speak for itself as it's quite simple - there are some comments inline to explain where I think it's required.

For the binary save, I'm using the ./saves/ directory in our application persistent data path.

BinarySaver.cs



Meat and potatoes, again! Or How to actually use the BinarySaver!

As promised here we actually get to control whether we want to save out in JSON or Binary.

I am creating an enum to represent the two different save states and creating a public variable in the inspector to allow us to switch between states.

Exceprt from InventorySaver.cs




Switch for Saves! (and loads...)

OK, that was an awful pun, did anyone else get it? I didn't think so.

So, what we need to do now is this. We know from part 1 that our SL object is all we care about as we recreate/or save our inventory from that object; therefore BuildSaveData() and ImportSaveData() don't need to change at all! Nice!

In fact, the only things we actually need to change are the two functions LoadScitpables() and SaveScriptables(). That's a little misleading, as what I'm also going to do is break out the code for saving and loading via JSON into their own methods. The code inside the method is the same as we created in part 1.

JSONSave()


JSONLoad()

And next, I'm going to create a couple of complementary methods for BinarySave() and BinaryLoad(). I'm sure there are loads among you who can see where I'm going with this, hold on to your hats we are almost there! :D

BinarySave()



BinaryLoad()



Having the static methods saved earlier in the BinarySaver class really help to make this more readable! I should really go back and pull out the JSON methods into their own static method class too. Feel free to do that if you want!

Igor, Flip the switch!

These are the last couple of changes, first up, SaveScriptables. We take advantage of the enum saveType we have set in the inspector, depending on which one is set we either call JSONSave or BinarySave()!

SaveScriptables()

LoadScriptables()


And that's really it! You can now choose between using JSON or Binary to save your inventory object!

Hope you enjoyed!

PappaP x

Monday, March 16, 2020

Serialization of Scriptable Objects in Unity (Nesting)

Whilst continuing with the tutorials from Mister Taft I came across an odd situation whereby his tutorial didn't actually work.

<This is the tutorial in question>

I can only assume that Unity has changed the way they work with SO's and serialization as no matter how hard I tried to follow, I couldn't replicate the saving of the SO's.

What follow's is how I worked around it to make a working saveable inventory that works along with Mister Taft's series. This may be useful to you as a general concept, but will be of most use to students of Mister Taft!

I will be using Total JSON to convert my serializable list into a nice pretty JSON string that we can save out, available on the asset store for free. The built-in JSON utilities will NOT work for this as it doesn't like more complex data. Total JSON is pretty lightweight so the tradeoff for me is negligible, you could also do this with a binary formatter but it's not something I'll be covering.

I haven't put much if any error checking into this as I wanted the concepts to be clear, you SHOULD be adding your own!

If this helps anyone, let me know! :)

A big thank you to Ashfid on the Mister Taft Discord for giving me the idea on how to solve this issue!

You can download the whole InventorySaver.cs file below and refer to my GitHub for other scripts if required. Come to the Mister Taft discord server if you have any questions!


Download the complete InventorySaver.cs file


Item Database

I'm going to be utilising the idea of not actually saving a scriptable object at all, I don't think Unity wants you to either! Instead what I did was save a reference and recreate the inventory when loading!

To that end what we first have to start with is an item database, this in itself is a simple scriptable object with a single method built-in.


Create this Scriptable Object in Unity and drag over the Red & Green Potion SO's so they appear as elements in the Items list.



We are going to use this database to recreate the player inventory when we load the save file!


The Serializable Class 

or, where I'm planning on storing data before and after serialization!

As mentioned I'm not actually going to store the Scriptable Objects, I'm going to create a snapshot if you will of what is in the player inventory when we want to save and I'm going to recreate the inventory at load time from that snapshot!

To visualise imagine a hand of cards from a normal deck, if I wanted to record an inventory my hand mid way through a game to recreate later I might write down "7 of clubs, 3 of hearts, 4 of diamonds". I'm not storing the actual cards anywhere, but when I come back later I can pick the recorded cards back out of the deck to recreate my hand.

I'm going to do exactly the same with this list, additionally I'm going to store the count as well so we can have multiple of the same item!




Putting it all together, the InventorySaver class.

The inventory saver is where the real work gets done. It needs a reference to the PlayerInventory and The Item Database we created earlier.

It needs to be attached to the GameSaveManager created during Mister Tafts earlier tutorial.



Saving:

for Saving there will be 3 steps and all of them will occur on the OnDisable() call from the script.



BuildSaveData() is performing the snapshot discussed earlier.

and finally writing the file to disk


I have used the pretty string format option just for ease of reading the saved files, speaking of which when you exit out and have any of the potions in your inventory you should end up with a json file in your persistant data folder similar to the following.



Loading:

Loading is almost a reverse of saving of course but there are 4 steps this time. We additionally want to clear the playerInventory before we recreate from the snapshot.

For my example I will be performing the loading in the OnEnable() method.


for the LoadScritables() we are taking the text json from disk and placing it into our JSON object. then deserializing into our snapshot.


with the snapshot in memory, it's time to recreate the inventory and this is where our Item Database really comes into play!




It's official I moved development to Unity!

I have made some decent progress so far and will be uploading a few observations and idea's intially following along with the excellent Unity tutorials from Mr Taft Creates!

https://www.youtube.com/channel/UCZczqDvepgNqy80gTMGnUXw

stay tuned!





ASP.NET Core(porate) , yup I'm hilarious :|

 So, lately, I have been in full corporate mode. That means looking after my team of engineers and when I have some gaps in my calendar work...

Most Viewed