- Home /
How to pass classes of a class to a function's parameter?
Hello and thanks for taking the time to review my question. My question: how do I pass classes of a parent class to a function's parameter?
What I HAVE, and what I WANT to do:
HAVE:
I have a "DataContainerScript" which has several classes.
I have a "SavingScript" which has a 'Save' function that checks if a file exists. If it does, then deserialize it (which opens it) and assign the 'fullData' variable to this deserialized file as a FullDatClass type. If the file doesn't exist, then simply create one.
Then it checks what scene we're in, and starts the 'SaveToVariableScene' function, which saves the data shown in the script.
Then at the end, it serializes the 'playerSaveFile' with 'fullData' and closes it.
WANT:
So at the end of the day, what I FINALLY want to do is have a parameter of 'SaveToVariableScene' that I can feed from whichever if statement's body, which ideally would call the 'SaveToVariableScene' function with parameter: "fullData.[sceneDataContainer]"; and then 'SaveToVariableScene' function would set fullData's variables to match the GameControl's (GameControl is a static script found in every scene).
DataContainerScript:
using System;
using System.Collections.Generic;
[Serializable]
public class FullDataClass
{
public GameData gameData = new GameData();
public PlayerItemsData playerItemsData = new PlayerItemsData();
public PlayerPositionData playerPositionData = new PlayerPositionData();
public PlayerhouseData playerhouseData = new PlayerhouseData();
public IslandData islandData = new IslandData();
}
[Serializable]
public class GameData
{
public string playerScene;
}
[Serializable]
public class PlayerItemsData
{
public string currentlyHoldingItemName;
}
[Serializable]
public class PlayerPositionData
{
public float playerPosX;
public float playerPosY;
public float playerPosZ;
}
[Serializable]
public class PlayerhouseData
{
public bool hasPlayerVisitedThisScene;
// entities
public List<float> polygonCiviliansX;
public List<float> polygonCiviliansY;
public List<float> polygonCiviliansZ;
// items
public List<float> playerPoopX;
public List<float> playerPoopY;
public List<float> playerPoopZ;
}
[Serializable]
public class IslandData
{
public bool hasPlayerVisitedThisScene;
// entities
public List<float> polygonCiviliansX;
public List<float> polygonCiviliansY;
public List<float> polygonCiviliansZ;
// items
public List<float> playerPoopX;
public List<float> playerPoopY;
public List<float> playerPoopZ;
}
And SavingScript:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class SavingScript : MonoBehaviour {
public static SavingScript savingControl;
void Awake ()
{
if(savingControl == null)
{
DontDestroyOnLoad(gameObject);
savingControl = this;
}
else if(savingControl != this)
{
Destroy(gameObject);
}
}
public void Save (bool savePlayerItems, bool savePlayerScene, bool, savePlayerPositions)
FileStream playerSaveFile;
FullDataClass fullData = new FullDataClass();
BinaryFormatter newBF = new BinaryFormatter();
if (File.Exists(Application.persistentDataPath + "MySave.data"))
{
playerSaveFile = File.Open(Application.persistentDataPath + "MySave.data", FileMode.Open);
fullData = (FullDataClass)newBF.Deserialize(playerSaveFile);
}
else
{
playerSaveFile = File.Create(Application.persistentDataPath + "MySave.data");
}
#region Player info
if(savePlayerItems)
{
fullData.playerItemsData.currentlyHoldingItemName = GameControl.control.currentlyHoldingItemName;
fullData.playerItemsData.isAtomicPoopCompressorEquipped = GameControl.control.isAtomicPoopCompressorEquipped;
}
if(savePlayerPositions)
{
fullData.playerPositionData.playerPosX = GameControl.control.playerPosX;
fullData.playerPositionData.playerPosY = GameControl.control.playerPosY;
fullData.playerPositionData.playerPosZ = GameControl.control.playerPosZ;
}
if(savePlayerScene)
{
fullData.gameData.playerScene = GameControl.control.playerScene;
}
#endregion
#region Scene save section
// check what scene we're saving to...
if(Application.loadedLevelName == "Scene_tier1_playerhouse")
{
SaveToVariableScene(fullData.playerhouseData?);
}
else if(Application.loadedLevelName == "Scene_island")
{
SaveToVariableScene();
}
else if(Application.loadedLevelName == "Scene_tier1_polygonCivilianComplex_entrance0")
{
SaveToVariableScene();
}
#endregion
newBF.Serialize(playerSaveFile, fullData);
playerSaveFile.Close();
}
void SaveToVariableScene (FullDataClass fullData)
{
fullData.hasPlayerVisitedThisScene= GameControl.control.hasPlayerVisitedThisScene;
fullData.polygonCiviliansX = GameControl.control.polygonCiviliansX;
fullData.polygonCiviliansY = GameControl.control.polygonCiviliansY;
fullData.polygonCiviliansZ = GameControl.control.polygonCiviliansZ;
fullData.playerPoopX = GameControl.control.playerPoopX;
fullData.playerPoopY = GameControl.control.playerPoopY;
fullData.playerPoopZ = GameControl.control.playerPoopZ;
}
Thanks for any advice/answers/knowledge/help in advance! :)
What do you mean by "classes of a parent class?" Do you mean an instance of a subclass? Or instances of the parent class? Or the type of the parent class or subclasses? It's not clear what you want to pass into SaveToVariableScene
.
What exactly do you want your call to SaveToVariableScene
to look like at the end of everything?
It seems like what you're doing right now would work, so I'm thinking that you want a way to do the same thing while decreasing the code in SaveToVariableScene
. Is that correct?
(Actually, in the SaveToVariableScene
, you'd need fullData.islandData.hasPlayerVisitedThisScene = /*...*/;
. Since hasPlayerVisitedThisScene
is a field of IslandData
, not FullDataClass
, you can't directly access it using fullData.xxxxx
. The same thing applies to the other lines in SaveToVariableScene
, but I assume you know that already.)
You have absolutely hit spot on what I am trying to do, good sir :) The $$anonymous$$AIN thing that I am having problems with is that I want to send DIFFERENT classes to the "SaveToVariableScene" function, but I don't know what ONE type I should put in as a parameter, as the there are different classes.
For the question that you asked in the beginning of your comment: in the "DataContainerScript" I ASSU$$anonymous$$E (I am not a pro programmer) that it is ok to have one PARENT class that creates INSTANCES of all of the other classes, meaning that I can simply add additional scene-specific classes to the DataContainerScript, and then also create an instance of it inside the "FullDataClass". This way, when I open an already existing save file, I DESERIALIZE the WHOLE class, and thus the child classes as well (again, I assume that it works that way).
And to answer your 3rd paragraph: Yes :), the reason why I made the "SaveToVariableScene" function was so that I would decrease my code.
To answer your 2nd paragraph: what I want to call to the "SaveToVariableScene" function parameters are the different scene classes. The finished game with have approximately 25 scenes, and that is why I am trying to create a function so as to not have around 25 lines with the same code in it. What I want my call of "SaveToVariableScene" to like at the end of everything is this: / sceneParamter /.hasPlayerVisitedThisScene= GameControl.control.hasPlayerVisitedThisScene;
Thank you very much for your input, I highly appreciate it :)
Answer by Machineman · Apr 09, 2015 at 10:05 AM
I, the author of this post, have answered my own question! Thanks for the comment _Gkxd though, you really did lead me on the right path to solving this.
The solution: Since in my 'DataContainerScript' I had DIFFERENT class names, although each of them (except player data and game data) had the SAME data in them, I decided to create ONE class called "GeneralSceneData" which would be referenced depending on the scene to load, or the scene to save. This way, the amount of code that I would have to write would be reduced by 22 times... for 4 SCRIPTS IN TOTAL!
In a nutshell, I fixed my problem by optimizing my code to suit my needs.
I will leave this post up for anyone having similar problems, ie. trying to feed DIFFERENT classes through ONE function's parameter, in order to reduce repetitive code.
Final note: if someone is making a game with for example 100 levels, each with different data needed to be saved, then atleast with my current knowledge, I would have to say that that is an extremely rare case, or you simply don't know what you're doing.
Thanks and hope this helps anyone!