I'm trying to find an image within my hierarchy every time the player respawns. What I've got is this: Code (csharp): if(damageImage == null) { //If the damageImage was not set because the player spawned in as a prefab; link it. damageImage = GameObject.FindGameObjectWithTag("DamageImage") as Image; Debug.Log("The damageImage was not found and has been linked to the player"); } else { Debug.Log("The damageImage was found and linked to the player"); } However I get this error: Cannot convert type `UnityEngine.GameObject' to `UnityEngine.UI.Image' via a built-in conversion Unless there is a better way to have a gameObject (in my case an image) load into a prefab every time it is instantiated, I'm a little stumped with this.
Code (CSharp): GameObject imageObject = GameObject.FindGameObjectWithTag("DamageImage"); if(imageObject != null) { damageImage = imageObject.GetComponent<Image>(); }
Hi DomDomDom, Do you delete the game object that has the script referencing the image when a player dies and make a new one when the player is respawned? A better way might be to keep the player game object instead of destroying it (avoiding memory fragmentation), create a delegate (callback) and an event that is associated with the delegate, then register the delegate (callback) in all the classes that would want to know about the respawn. In the callbacks you can then reset the existing player game object to the default values. Example: Code (CSharp): public class Player : MonoBehaviour { Image m_DamageImage; void Awake() { // Initialize player values InitializeValues(); // Add an event handler for the Spawn Manager's respawn event SpawnManager.Respawn += SpawnManager_OnRespawn; } void OnDestroy() { // Remove the event handler for the Spawn Manager's respawn event SpawnManager.Respawn -= SpawnManager_OnRespawn; } // Event handler for the Spawn Manager's respawn event void SpawnManager_OnRespawn() { InitializeValues(); } // Initialize player values void InitializeValues() { // Just a demonstration of what you might put in the Respawn event handler. // If you are not deleting the game object that has this script on it then the // reference to m_DamageImage should not be null here. if (m_DamageImage == null) { m_DamageImage = GameObject.FindGameObjectWithTag("DamageImage"); } } } // The spawn manager public class SpawnManager { // Declare the Respawn event and what a Respawn event handler (delegate) looks like public delegate void OnRespawn(); public static event OnRespawn Respawn; // Static function that will send a respawn event if there is at least one Respawn // event handler registered (see example Player class where it is added (+=) and // removed (-=)) public static void SendRespawnEvent() { if (Respawn!= null) { Respawn(); } } } public class SomeClass { public void SomeFunction { // Test sending respawn event SpawnManager.SendRespawnEvent(); } }
Thank you for your advice rnakrani! I'll definitely work on implementing this into my existing code. This seems like a much better way to do what I'm doing. Currently I destroy the player gameObject when it loses all health. Then I have a gameMaster script that instantiates in the player to a spawn point, which is where I lose the reference to damageImage. I was having a similar problem with my options menu keeping the settings the same from scene to scene.
Awesome! Glad to hear it. As far as persisting information from one scene to another, the way I like to do that is to have a singleton that doesn't derive from MonoBehaviour. The basic idea of a Singleton is this: It gets created the first time you try to access it; its not added to any scene, it exists outside any scene but within the memory allocated for the game. Thus, if you create a Singleton once its created you can access it from anywhere and from any scene during the lifetime of the application. Singletons are where I put data that I need across scenes. I can throw some code up if you like.