Looking for a better way of dynamically loading an image between scenes

Hey guys, for a couple hours now I’ve been trying to create a script that allows me to do the following things:


  • Dynamically copy one GameObject’s sprite to another (hidden) GameObject’s sprite
  • Load the GameObject with the dynamically loaded sprite to another scene
  • Do all of this without having the GameObject with the dynamically changing sprite visible until the scene changes to the appropriate one.

I want to do all of this because I’m creating a player avatar (read: like a forum avatar) selection menu where the player chooses one from a number of different sprites. After the player has selected a sprite, a placeholder sprite in the middle of the screen changes to represent the decision made by the player. Because that sprite is now considered the player’s avatar, I want it to be visible on other scenes as well, but I can’t just DontDestroyOnLoad the placeholder sprite, because it also serves the purpose of a button. Transferring the whole button seems like a bad idea.


I played around with SetActive, but couldn’t make it work. Somehow, I got the idea that a transparent image, which only regains its alpha on scene change to the appropriate scene is a smart way to deal with my issue. And, to my surprise, it actually worked.


The code in Awake() deals with the problem of having a child GameObject that you want to use DontDestroyOnLoad on.


The code I used to accomplish the task is as follows:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class AvatarPersistence : MonoBehaviour
{
    public GameObject PlayerAvatar;
    public string SceneToBeActive; //Assign in inspector
    private Image img_PlayerAvatar;
    private Image new_PlayerAvatar;
    
    void Start()
    {
        img_PlayerAvatar = PlayerAvatar.GetComponent<Image>();
        new_PlayerAvatar = this.GetComponent<Image>();
    }

    void Update()
    {
        new_PlayerAvatar.sprite = img_PlayerAvatar.sprite;
        if (SceneManager.GetActiveScene().name == SceneToBeActive)
        {
            var tempColor = new_PlayerAvatar.color;
            tempColor.a = 1f; 
            new_PlayerAvatar.color = tempColor;//Makes transparent Player Avatar visible again on Assigned Scene change
        }
    }

    void Awake()
    {
        Transform parentTransform = this.transform;

        while (parentTransform.parent != null)
        {
            parentTransform = parentTransform.parent;
        }
        DontDestroyOnLoad(parentTransform.gameObject);
    }
}

My question is, is there a more elegant way of accomplishing the tasks I previously outlined? It seems to me that playing around with the alpha of an image is not the best way of doing this.


Thanks,
B.

Hey again, I managed to do it by editing the enabled/disabled state of the Image component. It feels like it’s way better than my previous one. Here’s the code:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class PlayerAvatarHandler : MonoBehaviour
{
    public GameObject PlayerAvatar;
    public string SceneToBeActive;
    public string SceneToUpdateIn;
    static bool imageNotChanged = true;

    void Update()
    {
        if (SceneManager.GetActiveScene().name == SceneToUpdateIn)
        {
            this.GetComponent<Image>().sprite = PlayerAvatar.GetComponent<Image>().sprite;
        }

        if ((SceneManager.GetActiveScene().name == SceneToBeActive) && imageNotChanged)
        {
            this.GetComponent<Image>().enabled = true;
            imageNotChanged = false;
        }

    }

    void Awake()
    {
        Transform parentTransform = this.transform;

        while (parentTransform.parent != null)
        {
            parentTransform = parentTransform.parent;
        }
        DontDestroyOnLoad(parentTransform.gameObject);
    }
}