Hi all, so I’ve run into an issue for a long while and I can’t seem to wrap my head around it.
So what I am trying to do is for the user to pick their desired skin, confirm it, then load a new scene with the confirmed skin. All during runtime. And the skin is on an image in Canvas.
The issue is I have roughly 1.7k skins (sprites) for people to choose. I tried different ways to approach this issue.
Store it in a sprite array, and get the sprite out using skin.name == string(the name of the skin) in a for loop.
Store it in Resources and tried to load it but because I have so many skins, I am not sure of how to get the specific skin that the user chose. Resources.Load(skin) as sprite; did not work for me, skin(string of the name of the skin that they chose)
Convert the sprite into byte and back, it was quite confusing I did not manage to work it out.
I’ve also searched for saving an entire game object and loading it but to no avail.
Is my title wrong? I tried searching for changing a Source Sprite of an image and saving and loading it as well.
So this code is Sprite array - which is my latest.
string laminate;
public Sprite[] laminateSkin;
public Image customerDoorSkin;
// Start is called before the first frame update
void Start()
{
laminate = PlayerPrefs.GetString("laminate");
//print(laminate);
}
// Update is called once per frame
void Update()
{
customerDoorSkin.sprite = Resources.Load(laminate) as Sprite;
for (int i = 0; i < laminateSkin.Length; i++)
{
if(laminateSkin[i].name == laminate)
{
print("yes");
customerDoorSkin.sprite = laminateSkin[i];
}
}
}
Second, don’t store the sprite name; store its index in the array (from 0 to N-1).
Finally there are a metric buttload of Youtube tutorials for choosing characters and moving on. You might want to work through a few of those. You do not generally need to use PlayerPrefs unless you want it to be a permanent state of the program to restore upon the next run. Often just storing it in a GameManager type construct is adequate.
OR for a more-complex “lives as a MonoBehaviour” solution…
Simple Singleton (UnitySingleton):
Some super-simple Singleton examples to take and modify:
Simple Unity3D Singleton (no predefined data):
Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:
These are pure-code solutions, do not put anything into any scene, just access it via .Instance!
If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:
public void DestroyThyself()
{
Destroy(gameObject);
Instance = null; // because destroy doesn't happen until end of frame
}
Alternately, if you want to use PlayerPrefs, don’t splatter strings like “laminate” all over your code. Instead, wrap it up like so:
Here’s an example of simple persistent loading/saving values using PlayerPrefs:
Useful for a relatively small number of simple values.
Beyond that, whatever you do, if there is an issue, you must find a way to get the information you need in order to reason about what the problem is.
What is often happening in these cases is one of the following:
the code you think is executing is not actually executing at all
the code is executing far EARLIER or LATER than you think
the code is executing far LESS OFTEN than you think
the code is executing far MORE OFTEN than you think
the code is executing on another GameObject than you think it is
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
is this code even running? which parts are running? how often does it run? what order does it run in?
what are the values of the variables involved? Are they initialized? Are the values reasonable?
are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)
Knowing this information will help you reason about the behavior you are seeing.
You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene
You could also just display various important quantities in UI Text elements to watch them change as you play the game.
If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.
Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:
Thank you so much for the detailed explanation and links! I know that it definitely took some time.
Ill take my time and look through all of it to consider which would be the best way to improve upon what I have done!
Once I’ve reached a conclusion ll update this thread!