2

I have made a scriptable object which has a one property a public sprite. I want to have one version of sprite added everywhere I want.

With the possibility that if I ever want to change it I will just pin another sprite to scriptable object and in every place where it is pinned the sprite will change.

Is there any way to walk thought this problem or any other idea to make one object where I will store one Sprite and pin it to multiple objects.

Finally is this concept possible in Unity?

I have already thought about:

  • Deriving prom Sprite Renderer but the class is sealed, so i cannot make my own version of it this way

  • Creating my own custom version of Sprite Render cause if an any update come I would have to make yet again another version.

roffensive
  • 564
  • 4
  • 22
  • have you thought about a singleton object? – Bizhan Jul 26 '18 at 12:48
  • 1
    if i understand: for example, you want to have 100 game objects X that have the same public sprite A, but later you want to change this to sprite B on all 100 game objects by making only 1 change? you could make a game object Y that has a public sprite and make one instance of it - then your 100 game objects X would link to game object Y - and when you would want to change the sprite, you would only change it in game object Y – Jinjinov Jul 26 '18 at 13:14
  • Yes, that;s why I wanted to achieve @JinJi. I don't understand the part about linking Y and X, you mean by prefab or what? – roffensive Jul 26 '18 at 13:22
  • yes, by prefab. – Jinjinov Jul 26 '18 at 13:53

3 Answers3

2

I think you can use prefabs to achieve the same thing as you need:

You can create prefab by dragging and object to your assets.(Your prefab will be just an object with transform and e.g. Sprite Renderer)

After creating prefab you can copy it as many times as you want. Than when you decide to change the sprite just simply go to your prefab and edit sprite there. Now every instance of your prefab will have sprite changed.

sswwqqaa
  • 1,545
  • 3
  • 15
  • 29
2

It is possible with C# events. First, make your ScriptableObject call event whenever sprite is set. Allow Sprite to be set only using property (or method), so that you could track the change, like this:

public sealed class SpriteObject : ScriptableObject
{
    public event Action SpriteChanged;



    [SerializeField]
    private Sprite _sprite;



    public Sprite Sprite
    {
        get { return _sprite; }
        set
        {
            if(_sprite == value)
                return;

            _sprite = value;
            SpriteChanged?.Invoke();
        }
    }
}

Then, you need script, that will react to changed and assign the changed sprite to SpriteRenderer. So, something like this:

NOTE: name is purely for example. Do NOT name your classes like this!

[RequireComponent(typeof(SpriteRenderer))]
public class ScriptThatUsedSpriteObject : MonoBehaviour
{
    public SpriteObject spriteObject;

    private SpriteRenderer spriteRenderer;



    /// Called once the script is created.
    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();

        if(spriteObject != null)
        {
            spriteRenderer.sprite = spriteObject.Sprite;
            spriteObject.SpriteChanged += HandleSpriteChanged;
        }
    }

    /// Called whenever sprite is changed inside SpriteObject.
    private void HandleSpriteChanged()
    {
        spriteRenderer.sprite = spriteObject.Sprite;
    }
}

Now, if some script changes sprite in SpriteObject, every ScriptThatUsedSpriteObject will automatically update their sprites.

tsvedas
  • 1,049
  • 7
  • 18
0
public class PublicSprite : MonoBehaviour {
public Sprite publicSprite;
#region Singelton
public static PublicSprite instance;
private void Awake()
{
    if (instance != null)
    {
        Debug.LogWarning("More than one instance found");
        return;
    }
    instance = this;
}
}

get the sprite like this:

  PublicSprite.instance.publicSprite;

as Mentioned here, you probably want to use a Singelton. It is best to avoid the use of them only if its necessary as its a very bad programming practice. (you can learn more on why to avoid them here: What is so bad about singletons?

However, I can't think of another way of doing what you seek for.

SpoocyCrep
  • 604
  • 7
  • 23