Trying to load sprites into my 2D game (2021).

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:

  1. Create a variable or array in my script, then connect it in the Inspector
  2. Load at run time using a Resources folder and Resources.Load(“filename”)
  3. Using Addressable Assets
    (eg see How to change a Sprite from a script in Unity (with examples))

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

Are you talking about at runtime or during editing time?

If during editing, just select the image and set the import type to Sprite and (optionally) chop it all up if there’s multiple sprites.

If at runtime, you need to explain your needs a lot more carefully.

I need them available at runtime. For example:

To create a new GameObject with a sprite:

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’.”

Which is weird as I got that from Unity - Scripting API: Resources.Load

Nor could I use LoadAll for a similar reason (I couldn’t cast it).

Loading Texture2D works, but then I’ve got to convert it… :frowning:

Am I missing something?

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.

use resources load to load as a texture 2d

then use sprite.create on the texture 2d

Sprite s = Sprite.Create(Resources.Load<Texture2D>("Sprites/bm_h_00b"), Rect rect, Vector2 pivot);

if you get errors its because your texture doesnt have read/write enabled or you have it open on another program like windows image viewer

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’.

You can do it with Sprite… did you name one of your own scripts Sprite?

If you still cannot, sounds like maybe something is rotten with your installation, perhaps reinstall??

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.

Welcome to Visual Studio Life™!

Usually you can be slightly less drastic than this, but sometimes a full-nuke is indeed required.

This may help you with intellisense and possibly other Visual Studio integration problems:

Sometimes the fix is as simple as doing Assets → Open C# Project from Unity. Other times it requires more.

https://discussions.unity.com/t/778503

Also, try update the VSCode package inside of Unity: Window → Package Manager → Search for Visual Studio Code Editor → Press the Update button

Also, this: https://discussions.unity.com/t/805330/7

1 Like