- Home /
How to turn String into UnityEngine.Sprite?
I'm very much a beginner as you can see. So inside my "SpriteChanger" script, I have two sprites: "Happy" and "Sad". In my "GameControl" script, I have a string "currentMood" which starts out as "Happy". But then I have a public void to change the "currentMood" into "Sad". Now in the SpriteChanger script, I put this.GetComponent ().sprite = which works when I manually put in the name of the sprite. However, I do not want to have a bajillion of those if I had a lot of sprites I need to switch to. I need a way to have this.GetComponent ().sprite = take the literal input of "currentMood". But Unity keeps saying that it cannot implicitly convert String to UnityEngine.Sprite.
Here's the code:
GameControl{
public string currentMood = "Happy";
public void changeMood () {
currentMood = "Sad";
}
/some function that calls changeMood somewhere here/
} ..
.
SpriteChanger {
public Sprite Happy;
public Sprite Sad;
/*and a buncha other sprites*/
public void changeMood () {
this.GetComponent<SpriteRenderer> ().sprite = GameControl.instance.currentMood)
}
}
Also, please notice how I named my Sprites exactly like the moods.
Something more efficient you could do is this, create a Enum of the type mood, name your spite files the same names as the enums, and place them in Assets/Resources/$$anonymous$$oods then you can manage them like this.
public enum $$anonymous$$ood
{
Happy,
Sad,
Angry,
None
}
and
public class GameControl : $$anonymous$$onoBehaviour
{
public static GameControl Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<GameControl>();
}
return _instance;
}
private set { _instance = value; }
}
private Dictionary<string, Sprite> moods;
private $$anonymous$$ood _mood;
public void Set$$anonymous$$ood($$anonymous$$ood mood)
{
_mood = mood;
}
void Awake()
{
Instance = this;
moods = new Dictionary<string, Sprite>();
Sprite[] sprites = Resources.LoadAll<Sprite>("/$$anonymous$$oods");
foreach (Sprite sprite in sprites)
{
moods.Add(sprite.name, sprite);
}
public Sprite Get$$anonymous$$oodSprite()
{
return moods[_mood.ToString()];
}
}
}
And finally
public void change$$anonymous$$ood () {
this.GetComponent<SpriteRenderer> ().sprite = GameControl.instance.Get$$anonymous$$oodSprite();
}
Thanks for the answer, RobAnthem. I really appreciate it. Unfortunately I couldn't make it work. I just ended up (embarrassingly) hardcoding it all. I know I'll be able to use your answer in a future game though, when I get better at coding.
Answer by Hellium · Feb 24, 2019 at 09:53 AM
// Drag and drop the sprites in the editor
// Make sure the name of the sprites matches your mood
[SerializeField]
private Sprite[] moodSprites;
private SpriteRenderer spriteRenderer;
public void ChangeMood ()
{
if( spriteRenderer == null )
spriteRenderer = GetComponent<SpriteRenderer> ()
spriteRenderer.sprite = GetMoodSprite( GameControl.instance.currentMood());
}
private Sprite GetMoodSprite( string mood )
{
for( int i = 0 ; i < moodSprites.Length ; ++i )
{
if( moodSprites[i] != null && string.Equals( moodSprites[i].name, mood )
return moodSprites[I];
}
Debug.LogWarningFormat( "No sprite representing mood '{0}' has been found", mood );
return null;
}
If the sprites does not have the correct names, you could use a simple struct like this:
public struct MoodSprite
{
public string Mood;
public Sprite Sprite;
}
// Drag and drop the sprites in the editor
// Make sure the name of the sprites matches your mood
[SerializeField]
private MoodSprite[] moodSprites;
private SpriteRenderer spriteRenderer;
public void ChangeMood ()
{
if( spriteRenderer == null )
spriteRenderer = GetComponent<SpriteRenderer> ()
spriteRenderer.sprite = GetMoodSprite( GameControl.instance.currentMood());
}
private Sprite GetMoodSprite( string mood )
{
for( int i = 0 ; i < moodSprites.Length ; ++i )
{
if( moodSprites[i] != null && string.Equals( moodSprites[i].Mood, mood )
return moodSprites[i].Sprite;
}
Debug.LogWarningFormat( "No sprite representing mood '{0}' has been found", mood );
return null;
}
If you really want to keep the way you were thinking about, you need reflection:
using System.Reflection;
// ...
public Sprite Happy;
public Sprite Sad;
private SpriteRenderer spriteRenderer;
public void ChangeMood ()
{
if( spriteRenderer == null )
spriteRenderer = GetComponent<SpriteRenderer> ()
spriteRenderer.sprite = GetMoodSprite( GameControl.instance.currentMood());
}
private Sprite GetMoodSprite( string mood )
{
System.Type type = GetType();
FieldInfo info = type.GetField( mood );
if( info == null )
{
throw new System.Exception( "The mood '" + mood + "' does not have any sprite associated" );
}
return (Sprite)info.GetValue(this);
}
Thank you so much for your answer. I really appreciate it. Unfortunately, I wasn't able to make it work. I guess I'm too stupid right now. But I know that in the future, I'll be able to use your answer when I get a better understanding of coding in Unity. Anyway, embarrassingly, I ended up just hardcoding all of the sprites in a big ole switch statement.
The thing is your question doesn't appear to have been answered. Or at least not how I was hoping it would. i.e. You have a string, which is the name of one of multiple png sprite files in your project. You want to be able to render those images to your scene image object and at various point change the sprite to other values. in my case I have 53 sprite images and it can be any one of them that is rendered to each of 21 images.
Is there a way to do that wholly in the C# script? i.e. without the need to load the sprite via the inspector and use the string to find the chosen sprite?
Unless you use the Resources.Load
method (which is not advised at all, even by Unity itself) or using Addressable Assets, there is no way I'm aware of to load an asset given its name/path.
In my case I have the name of the sprites I wont to use, how can I use it at runtime (so pre-loading in the inspector is not an option)? Also want to do it without all the hassle of using an atlas.
Your answer
Follow this Question
Related Questions
Using Strings To Call Function 1 Answer
parseInt givin' me issues! 2 Answers
Separating two strings 1 Answer
convert string to list of lists 1 Answer
Is it possible to name a list by a string variable? 2 Answers