#help with storage
1 messages Β· Page 1 of 1 (latest)
so, basically i have no idea what i'm doing, i've never done anything with this kind of stuff, and I can't seem to figure it out :/
like what for example?
its pretty simple, what exactly is confusing
i'm not sure how to explain it, i just kinda don't understand how to make it read the files
one thing at a time
did you get the saving working first ?
uh, do i have to build it first and check? because i dont know if saving will work in the editor
also i dont know where the files go π
Oh wait there is errors
yea you are missing the namespaces
i want to save the data ideally when the player closes the app, but it could work when a button is pressed maybe, i dont really mind, i just want it to save and load it lol
okay start with the button first then ?
ok
its easier to test in playmode
so just make a button to save it?
make a button to save , yes
alright, the button exists
okay do you have a save objec ?
the one tha will save all the data you want
where is the data you want to save come from ? like what are you storing for player exactly ?
the data is coming from the text bit of 2 objects
like a money counter i guess
this
or this
ahh they're properties, unity doesn't like that
just make them public fields for now
so like serializefield?
is that not what that is?
no π
they're part of a property, its the accessor
if i get rid of it won't it break though?
nope
properties are similar to Methods
you can specificy something running when you assign/read it
i suggest you def learn about them at some point
they're very powerful
i will
just like that?
i keep doing that
yes you have to configure your IDE first
did you install VIsual Studio through Unity Hub or manually?
as in make it not say miscellaneous files?
exactly.
it should say Assembly-CSharp
i've done that like 5 times it keeps resetting
go inside the External Tools page and click Regen Project files
fixed
good. does it say assmbly csharp and highlight errors?
yes
always make sure you code with that on, its important
yep, i will
ok so did you make a save Object ?
i made a save button, do you want me to also make an empty game object?
ok, i've got an object
so you need an Object (a class) to store what you want to save
show me the object
just tthis?
well you can use this for saving sure, since its monobehavior
you also need a Plain Class just to store what you want to save
yup
awesome
yup anything you want to store should be a field
like this?
good
now you have to create an object of SaveData that stores that in the file
You can do it two ways
One is to make this SaveData class a [Serializable] and then you can a make a public/serializiedPrivate field for it inside Saving
this will create an Instance of this object by Unity since it will be in the inspector
Or
You create one yourself each save by doing the normal way of creating instance for regular Object/Classes
which is for example SaveData newSaveData = new()
alright, is there a better one or are they both equal?
they're both valid
Serializable class has benefit of you see it inside the inspector
ok so should i go with that one?
if you want sure
you need [Serializable] attribute above the class SaveData
this tells Unity you can serialize this class
then create a field for it inside Saving
with me so far?
i did the serializable thing, but create a field
let me see
its just this so far right?
ok good
btw Serializing just means saving/storing data
incase you were confused that word being thrown around
thanks
now if you make a field for SaveData inside Saving, that will be what will save so you will pass any data changed to it
you know how to pass data between scripts right?
i'm not sure i think my brain stopped working
public double CurrentFoxCount;
this is a field
a public one
CurrentFoxCount is the Field and its of type double
making a field is just saying " I want to store this object here"
alright, i'm really sorry about this lol
no worries, show me what you got
i have no idea if this is correct
well no, why is SaveData field a double

show me what u did in code
i'm so confused sorry π
i dont know what type to put the savedata as i think
you need to store SaveData inside a field, you had it correct but the type was wrong
yes
well SaveData is the type
classes are types
so just public savedata;
you're missing the type
private/public Type variableName
eg
public SaveData CurrentSaveData
it can ofc just be public SaveData SaveData
the former being more explicit though
so wait is savedata both a type and what i decided the name to be?
yeah SaveData is now a type since you create a class for it
defined what SaveData is
ohhh
Variable name is kinda inconsequential
thats for your own clarity
it can be public SaveData PotatoSalad but that would not make sense to you to access .PotatoSalad
yeah, thanks, so is it this?
yea
yeah, i think i get it now lol
now the first step would be to fill that new Instance of SaveData called GameSaveData with the data from your player or whatever
so when you want to save , you need to extract that data into GameSaveData
where are you storing the double for CurrentFoxCount
great so you need to reference/get that value from FoxManager
preferably on Save() method you will make in Saving
you can link that to the button for example
I see you already have a static Instance of FoxManager
so you can easily just access it like that
and how would i go about doing that?
for example
GameSaveData.CurrentFoxCount = FoxManager.instance.CurrentFoxCount;```
do it for both fields , then you simply save GameSaveData in json with JsonUtil
public void Save()
{
GameSaveData.CurrentFoxCount = FoxManager.Instance.CurrentFoxCount;
GameSaveData.CurrentFoxPerSecond = FoxManager.Instance.CurrentFoxPerSecond;
string jsonData = JsonUtility.ToJson(GameSaveData);```
You could technically just keep GameSaveData itself on FoxManager so you don't even have to do this middleman thing
whatever is easier for you
well i've ran into an issue, not too sure if i just did something wrong
yeah corrected my code example, noticed yours doesn't have it stored as Instance
capitlizaition matters π
oh yeah
ok cool so it has no errors now
great
now the data would get formatted into json
basically it would look like this
{"SomeValue":2.3,"SomeOtherValue":9.3}```
its a Key / Value structure
it just needs to be saved into a file
thats where File.WriteAllText comes in
alright, i think i'm understanding so far
so from my earlier example do you kinda see whats going on now ?
yeah
its pretty simple once you see it a couple of times
the more you do it also will be engrained in your mind
Application.persistentDataPath gives us that base path first
as you can see it starts inside special folder
yeah
the Path.Combine method basically just avoids us having to use string concat with folders/filename and slashes
instead of string path = Application.persistentDataPath + "/" + "fileName.ext"
it can just be string path = Path.Combine(Application.persistentDataPath, "fileName.ext")
it also helps compatibility with different OS systems and their pathing slashes
alright, that makes sense
great, give it a test at let me know
alright, i'll try it now
yeah no i'm still not getting it...
definitely just being dumb
well you see the File.WriteAllText
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.writealltext?view=net-8.0
public static void WriteAllText (string path, string? contents);
takes in a path and contents
both are string
GameSaveData is not a string
besides path, you have another string in there π
jsonData?
JsonUtility is basically taking your Object and formatting it to json string
when i press the save button it still does nothing though
well did you check the folder
also always put a Debug.Log at the end , after FIleWrite to make sure it saved/ran
oh i found it
is data inside?
sorry i was looking at my project folder
no worries
noice
basically for load you're just doing the inverse
JsonUtility has a method for converting json back to an object
so first you read the string in the File
it should be the jsonString
so that goes into to Json
since you already have SaveData stored as GameSaveData you can just assign to it when you load object FromJson
GameSaveData = JsonUtility.FromJson<SaveData>(jsonData);
ofc you probably want to do proper safe checks, eg like seeing if there even is a file or a valid json one. etc.
haha after this Im gonna remake my Save data video
lol
alright, so i'm understanding more now, and how would i go about doing safe checks?
- what actually happens if i don't and there isn't a file, or it's corrupted?
well right now it will just give you a null object or cause FIle.IO error
first I'd check if saveFile exists so you would pass the same Path as File.ReadAllText
eg
if(File.Exists(thePath) == false)
{
// handle if file does not exists, maybe tell user no Save file found?
return;// return out of the Load() function not to proceed
}```
alright, thanks. but also the actual reading bit, how do i finish that? ir ead the documents you sent but i'm still a little confused on how i'd get it to read and update the values to the ones in the file
ideally you can also use https://docs.unity3d.com/ScriptReference/JsonUtility.FromJsonOverwrite.html
alr send the snippet of your save function
use the code tags
like this
string jsonData = JsonUtility.ToJson(GameSaveData);
string path = Path.Combine(Application.persistentDataPath, "fileName.json");
File.WriteAllText(path, jsonData);
like that?
yes
you only need to switch 2 lines
lets look at first line you'd need
https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readalltext?view=net-8.0
this only unlike text only takes in a path string
but it returns you the string
where do i put this?
well you need a Load Method
that is pretty much similar to your Save method
look at your save method
do you have a path for the File.ReadAllText method?
its yes, you have a path
so bring that over to Load
you made a Load() method yes ?
yes
in Saving
ok
so path you have , bring that over
you have a path, first id put the File.Exist snippet i shown you, for checking if file exists
this?
string path = Path.Combine(Application.persistentDataPath, "fileName.json");
yes
thats your file path
ideally you store this inside a const
but dont worry about that now ig
so the steps again are
-Make Path β
-Check File Exits β
-Read the File β
-assign Data from JsonUtilβ
alright, i have the file exists thing, it's showing an error though
lol alr
so that should read the file and make sure it exists
it checks if a file exists at that path with that name
awesome
now if its getting passed the if statement and not returning, it means file does exist
You can proceed to ReadAllText After (make sure its outside the if statement underneath )
it of course doesn't know to do this automatically , you have to tell it to with the appropriate method
Done a bit of reading up, and tried a couple different things, all threw up errors π what would be the appropriate method?
idk what you did and what error you speak of
im not mind reader
Local function 'ReadAllText(string)' must declare a body because it is not marked 'static extern'.
you have to show how you wrote it as well
why did you write it this way
ReadAllText is a static method inside the File class
because I am still not 100% sure what I am doing
yes you should probably do a quick jumpstart course on C#
I did point out the you're doing the same thing almost as Save method is doing..
File.WriteAllText is coming from File class
so insted of write method you want read, it still in the File. class
so like this? ```cs
File.ReadAllText(path);
i'm honestly not sure
i'm definitely gonna take a course after this, i do game development in college but they mainly teach us unreal engine, and thats just blueprints and stuff
so i'm very new to c# and unity, sorry
thank you very much for helping me through this though, it is much appreciated
Just look at string path = Path.Combine(Application.persistentDataPath, "fileName.json");
this returns a string
so you store it inside path
any time you store something using =
so File.ReadAllText
string data = File.ReadAllText(path)
by doing = you can store the return of the method since its a string, we store it inside string
is that everything?
well from that data construct the object
and assign it
JsonUtility.FromJsonOverwrite(data , GameSaveData);
ok, and after that what happens?
show me what you got so far
the whole script or just the load?
load
public void Load()
{
string path = Path.Combine(Application.persistentDataPath, "fileName.json");
if (File.Exists(path) == false)
{
return;
}
string data = File.ReadAllText(path);
JsonUtility.FromJsonOverwrite(data, GameSaveData);
}
great, maybe a Debug.Log("Data Loaded") under JsonUtil

it says data loaded but nothing happened
is the GameSaveData loaded values properly
you're still missing what you do in Save Script for that
which is assigning those values back to FoxManager
could i just switch it around to do that?
FoxManager.instance.CurrentFoxCount = GameSaveData.CurrentFoxCount;
well yea thats what you would do
awesome, the main CurrentFoxCount works, but the CurrentFoxPerSecond one doesnt
yeah, no idea what's going on with that
show the Load method again
lovely
oof
i kinda know whats up
i think its messing with another one of my scripts π
Error:
NullReferenceException: Object reference not set to an instance of an object
FoxPerSecondTimer.Update () (at Assets/Scripts/Upgradeds/FoxPerSecondTimer.cs:19)
where do you assign instance for FoxManager
yes
try to make a field there instead and assign it in the inspector