#help with storage

1 messages Β· Page 1 of 1 (latest)

hazy sinew
#

hey

rough pewter
#

whats the issue

#

I need to remake my Saving video better πŸ₯²

hazy sinew
#

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 :/

rough pewter
#

like what for example?

hazy sinew
#

just the whole saving thing

#

i don't understand it

rough pewter
#

its pretty simple, what exactly is confusing

hazy sinew
#

i'm not sure how to explain it, i just kinda don't understand how to make it read the files

rough pewter
#

did you get the saving working first ?

hazy sinew
#

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 😭

rough pewter
#

when and how do you want to save in the first place

#

forget th code for second

hazy sinew
#

Oh wait there is errors

rough pewter
#

yea you are missing the namespaces

hazy sinew
rough pewter
hazy sinew
#

ok

rough pewter
#

its easier to test in playmode

hazy sinew
#

so just make a button to save it?

rough pewter
#

make a button to save , yes

hazy sinew
#

alright, the button exists

rough pewter
#

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 ?

hazy sinew
#

the data is coming from the text bit of 2 objects

#

like a money counter i guess

#

or this

rough pewter
#

ahh they're properties, unity doesn't like that

hazy sinew
#

:(

#

what should i do then?

rough pewter
#

just make them public fields for now

hazy sinew
#

so like serializefield?

rough pewter
#

nah just public double MyDouble

#

etc

hazy sinew
rough pewter
#

you have {get; set;}

#

do you know what those are ?

hazy sinew
#

no 😭

rough pewter
#

they're part of a property, its the accessor

hazy sinew
#

if i get rid of it won't it break though?

rough pewter
#

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

hazy sinew
#

i will

rough pewter
#

but yea for now you dont need them

#

it will just complicate the serializing for now

hazy sinew
#

just like that?

rough pewter
#

why is it not underlining red

#

screenshot your whole editor

#

you're missing ; lol

hazy sinew
hazy sinew
rough pewter
#

yes you have to configure your IDE first

#

did you install VIsual Studio through Unity Hub or manually?

hazy sinew
#

as in make it not say miscellaneous files?

rough pewter
#

it should say Assembly-CSharp

hazy sinew
#

i've done that like 5 times it keeps resetting

rough pewter
#

go inside the External Tools page and click Regen Project files

hazy sinew
#

fixed

rough pewter
#

good. does it say assmbly csharp and highlight errors?

hazy sinew
#

yes

rough pewter
#

always make sure you code with that on, its important

hazy sinew
#

yep, i will

rough pewter
#

ok so did you make a save Object ?

hazy sinew
#

i made a save button, do you want me to also make an empty game object?

rough pewter
#

when I say Object, I mean a C# object not Unity

#

for unity I would say , GameObject

hazy sinew
#

oh

#

sorry

rough pewter
#

no worry

#

just remember in c# you're working with Objects

#

a class is an object

hazy sinew
#

ok, i've got an object

rough pewter
#

so you need an Object (a class) to store what you want to save

rough pewter
hazy sinew
#

just tthis?

rough pewter
#

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

hazy sinew
rough pewter
#

yup

hazy sinew
#

awesome

rough pewter
#

You can put it outside of the class

#

this way you dont have to do TheOther.SaveData

hazy sinew
#

ok, thanks

#

should i put the doubles inside?

rough pewter
#

yup anything you want to store should be a field

hazy sinew
#

like this?

rough pewter
#

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()

hazy sinew
#

alright, is there a better one or are they both equal?

rough pewter
#

they're both valid

#

Serializable class has benefit of you see it inside the inspector

hazy sinew
#

ok so should i go with that one?

rough pewter
#

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?

hazy sinew
#

i did the serializable thing, but create a field

rough pewter
hazy sinew
#

its just this so far right?

rough pewter
#

ok good

#

btw Serializing just means saving/storing data

#

incase you were confused that word being thrown around

hazy sinew
#

thanks

rough pewter
#

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?

hazy sinew
#

i think so

#

i'm honestly still a bit confused on making the field

rough pewter
#

why ?

#

you made so many so far lol

hazy sinew
#

i'm not sure i think my brain stopped working

rough pewter
#

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"

hazy sinew
#

alright, i'm really sorry about this lol

rough pewter
#

no worries, show me what you got

hazy sinew
#

i have no idea if this is correct

rough pewter
#

well no, why is SaveData field a double

hazy sinew
#

its not rght

#

yeah

#

lol

#

idk what i did

rough pewter
rough pewter
hazy sinew
#

i dont know what type to put the savedata as i think

rough pewter
hazy sinew
#

yes

rough pewter
#

classes are types

hazy sinew
#

so just public savedata;

rough pewter
#

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

hazy sinew
#

so wait is savedata both a type and what i decided the name to be?

rough pewter
#

yeah SaveData is now a type since you create a class for it

#

defined what SaveData is

hazy sinew
#

ohhh

rough pewter
#

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

hazy sinew
#

yeah, thanks, so is it this?

rough pewter
#

yea

rough pewter
#

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

hazy sinew
rough pewter
#

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

hazy sinew
#

and how would i go about doing that?

rough pewter
#

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

hazy sinew
#

well i've ran into an issue, not too sure if i just did something wrong

rough pewter
#

yeah corrected my code example, noticed yours doesn't have it stored as Instance

#

capitlizaition matters πŸ˜›

hazy sinew
#

oh yeah

rough pewter
hazy sinew
#

ok cool so it has no errors now

rough pewter
#

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

hazy sinew
#

alright, i think i'm understanding so far

rough pewter
#

so from my earlier example do you kinda see whats going on now ?

hazy sinew
#

yeah

rough pewter
#

its pretty simple once you see it a couple of times

#

the more you do it also will be engrained in your mind

#

as you can see it starts inside special folder

hazy sinew
#

yeah

rough pewter
#

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

hazy sinew
#

alright, that makes sense

rough pewter
#

great, give it a test at let me know

hazy sinew
#

alright, i'll try it now

#

yeah no i'm still not getting it...

#

definitely just being dumb

rough pewter
#

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 πŸ˜‰

hazy sinew
#

jsonData?

rough pewter
#

JsonUtility is basically taking your Object and formatting it to json string

hazy sinew
#

when i press the save button it still does nothing though

rough pewter
#

well did you check the folder

#

also always put a Debug.Log at the end , after FIleWrite to make sure it saved/ran

hazy sinew
#

oh i found it

rough pewter
#

is data inside?

hazy sinew
#

sorry i was looking at my project folder

rough pewter
#

no worries

hazy sinew
#

data is here

#

yippee

rough pewter
#

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

hazy sinew
#

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?
rough pewter
#

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 
}```
hazy sinew
#

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

rough pewter
rough pewter
#

use the code tags

#
like this
hazy sinew
#
 string jsonData = JsonUtility.ToJson(GameSaveData);
 string path = Path.Combine(Application.persistentDataPath, "fileName.json");
 File.WriteAllText(path, jsonData);
#

like that?

rough pewter
#

yes

#

you only need to switch 2 lines

#

this only unlike text only takes in a path string

#

but it returns you the string

hazy sinew
#

where do i put this?

rough pewter
#

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?

hazy sinew
#

yes

#

wait

#

no

rough pewter
#

its yes, you have a path

#

so bring that over to Load

#

you made a Load() method yes ?

hazy sinew
#

yes

rough pewter
#

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

hazy sinew
rough pewter
#

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❔

hazy sinew
#

alright, i have the file exists thing, it's showing an error though

rough pewter
#

ofc it is

#

you dont have a path

#

what jappened to the path

hazy sinew
#

dont worry about it

#

i was dumb

#

its fixed

#

ignore that

rough pewter
#

lol alr

hazy sinew
#

so that should read the file and make sure it exists

rough pewter
#

it checks if a file exists at that path with that name

hazy sinew
#

awesome

rough pewter
#

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

hazy sinew
#

Done a bit of reading up, and tried a couple different things, all threw up errors 😭 what would be the appropriate method?

rough pewter
#

im not mind reader

hazy sinew
#

Local function 'ReadAllText(string)' must declare a body because it is not marked 'static extern'.

rough pewter
hazy sinew
rough pewter
#

ReadAllText is a static method inside the File class

hazy sinew
#

because I am still not 100% sure what I am doing

rough pewter
#

yes you should probably do a quick jumpstart course on C#

hazy sinew
#

Yes I should

#

And I will

rough pewter
#

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

hazy sinew
#

so like this? ```cs
File.ReadAllText(path);

rough pewter
#

remember it returns a value

#

how do we store a returned value

hazy sinew
#

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

rough pewter
#

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

hazy sinew
#

is that everything?

rough pewter
#

and assign it

#

JsonUtility.FromJsonOverwrite(data , GameSaveData);

hazy sinew
#

ok, and after that what happens?

rough pewter
hazy sinew
rough pewter
hazy sinew
#
    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);

    }

rough pewter
hazy sinew
#

it says data loaded but nothing happened

rough pewter
#

you're still missing what you do in Save Script for that

#

which is assigning those values back to FoxManager

hazy sinew
#

could i just switch it around to do that?

FoxManager.instance.CurrentFoxCount = GameSaveData.CurrentFoxCount;

rough pewter
hazy sinew
#

awesome, the main CurrentFoxCount works, but the CurrentFoxPerSecond one doesnt

#

yeah, no idea what's going on with that

rough pewter
hazy sinew
#

lovely

rough pewter
#

oof

hazy sinew
#

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)

rough pewter
#

where do you assign instance for FoxManager

hazy sinew
#

i'm not sure

#

i'm very confused

rough pewter
#

thats strange

#

is the FoxManager script on a gameobject ?

hazy sinew
#

yes

rough pewter
#

try to make a field there instead and assign it in the inspector