I want to load sprites in my 2D game at run time, so that I can create GameObjects from my script, swap Sprites, etc. (I’m in 2020.3.19f1). Note that this is different from wanting prefabs that have the sprites already applied.
I’ve seen several methods:
Create a variable or array in my script, then connect it in the Inspector
Load at run time using a Resources folder and Resources.Load(“filename”)
(1) no longer seems to work - the variables don’t show up in the Inspector, I’d guess they are no longer serializable, [SerializeField] doesn’t work, and since I actually don’t need them serialized it doesn’t seem worth the trouble of trying for a work around.
(2) seems to have some disadvantages, per the link above (Increased memory usage and bigger application size, Assets more difficult to manage, Longer loading and startup time)
(3) seems more complicated than (2).
If all else fails I will do either (2) or (3). But given the change of Sprite so that it no longer works in the Inspector, is there some new method that is recommended, to replace the above?
GameObject go = new GameObject(name);
SpriteRenderer renderer = go.AddComponent<SpriteRenderer>();
renderer.sprite = newSprite;```
or to change a sprite (per the link in my original question, see there if you want more background):
```public Sprite newSprite; // needs to be filled
spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
spriteRenderer.sprite = newSprite;```
But first I need to get the Sprite for the above code ('newSprite'), and since the old method of doing it in the Inspector no longer works I was wondering if there is a newer, better way, perhaps one not covered in my original question. I am not too fussy about whether the sprites are loaded in the editor (method 1, connecting in the Inspector, per my original question or below, and which no longer seems to work) or in code (methods 2 and 3, or something new), but I would like the current best practice if possible - I will likely have about 50-100 sprites at first, but possibly many more as I progress.
If you need to know more, read on.
===========================
Per my original question and the link I gave (sorry for the repetition but I want to be clear), I can:
1) Create a variable or array in my script (see below), then connect it in the Inspector (from that link: 'In the inspector select the new Sprite that you want to use by dragging it into the field or by using the circle select button' - see the link for an image of that action)
```public class EngineScript : MonoBehaviour
{
public Sprite[ ] Sprites;
public Sprite SingleSprite;
}```
This does not seem to work any more.
2) Load at run time using a Resources folder and Resources.Load<Type>(“filename”). From the link:
[quote]
1. First, create a new folder inside of your Assets folder called **Resources**. This can be placed anywhere in your Assets directory.
- Next place the Sprites into the Resources folder.
- Lastly, from a script, load the Sprite with Resources.Load<Type>(“filename”) passing in a String for the filename (without its extension).
[/QUOTE][/INDENT]
This seems viable, but with the disadvantages mentioned in my original question and expanded on in the link.
3) Using Addressable Assets - see the link for more, it's too much to cover here.[/INDENT]
===================
I need to know if there is a newer, better method of doing this than the above, given that changes to the API seem to have broken (1). Or if there is still a way that makes (1) work, a way that is not too awful, complex, or riddled with disadvantages, that would work too.
PS. I have looked and followed the suggestions for making (1) work, including checking I have no compilation errors, etc. No joy.
[/quote]
The sprite editor has to now be installed separately through the Unity package manager… is that the missing part here? Then you set the image to sprite and hack it up how you like, as before.
I don’t need to edit it. I can see it in the asset window, I can drag it in to the view window to make a prefab (which I’m guessing is what you normally do).
But I don’t want a Prefab. I want a Sprite, as in the Type of variable that is used in the API, in scripts.
Before I could just add a public Sprite variable and it would show up in the Inspector (on the right) for me to put the value in, but that doesn’t work now.
So how do I get it to my code, in a Sprite variable? Is it one of the two options previously covered or is there something better?
Apparently I can’t use Sprite s = Resources.Load<Sprite>("Sprites/bm_h_00b");
I get the error “Error CS0311 The type ‘Sprite’ cannot be used as type parameter ‘T’ in the generic type or method ‘Resources.Load(string)’. There is no implicit reference conversion from ‘Sprite’ to ‘UnityEngine.Object’.”
OK, now I can’t use Sprite.Create(texture, rect, pivot) to make the sprite. I get “Error CS0122 ‘Sprite.Create(string)’ is inaccessible due to its protection level”. I checked, it’s internal. Unity - Scripting API: Sprite.Create says it should be public.
There’s got to be something wrong. Is it the version of Unity I’m using? I’m on 2020.3.19f1 which was recommended by the hub.
Thanks so much for your answer.
The Resources.Load works for the texture 2d (still wondering why you can’t do it with Sprites any more, but OK…)
However the Sprite.Create line won’t even compile. It underlines the Create with red, and I still get the same error “Error CS0122 ‘Sprite.Create(string)’ is inaccessible due to its protection level” - as I mentioned, when I look at the Sprite.Create definition it shows it as an ‘internal’ method (which I would not be able to access) when the docs show it as ‘public’.
Thank you Kurt for your help, I appreciate your telling me that it should have worked; that told me that I needed to stop worrying about mistakes I might be making or thinking that it was meant to be doing this, and instead take a totally different direction.
So I’ve uninstalled and reinstalled the entire Unity/Visual Studio 2019 set up. I created a new project, imported the assets and set up the script again and now it seems to be working just fine.
No idea what went on there. Honestly, I probably should have done a step by step and tried to figure out what it was but this has been driving me crazy for 2 days and I just want to get moving.
Thanks again, Kurt, and you too rarac, you were very kind to weigh in.