Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Tain_M · Mar 03, 2016 at 11:17 PM · uitextcanvaschild objectprefab-instance

Access and modify Text within a prefab

I am making my first non-tutorial game in Unity, and it's going well in most ways. I am stuck however, trying to write to a Text within a prefab during an instance of that prefab. In my game, the player triggers a battle, which generates an instance of a battle environment. Within that environment a copy of the player and a monster are also instantiated from prefabs. Everything's great, the internal UI works, and even the UI childed to the characters is showing up. I can't modify it, though. I kept getting the "object not a reference to an instance" error, until I added an if statement to see if the variable I stored the Text object in was null (which is always is). Any idea where I'm going wrong? Thanks so much!

 using UnityEngine;
 using UnityEngine.UI;
 using System.Collections;
 using UnityEngine.SceneManagement;
 
 public class GameManager : MonoBehaviour {
 
     public int test;
 
     //Starting player health
     private static float MAX_HEALTH = 100f;
     public float playerHealth = MAX_HEALTH;
     private float healthRatio;
     public GameObject healthBar;
     //Placeholder starting monster health
     public float monsterHealth = 50;
     //To track choices in battle
     public int numAttacks = 0;
     public int numRun = 0;
 
     //For setting up and breaking down battles
     public GameObject battleParticles;
     public GameObject battleGround;
     public GameObject player;
     public GameObject playerImage;
     public Text playerText;
     public GameObject mainCam;
     public GameObject monster;
     public Text monsterText;
     //For setting up and breaking down battles
     private GameObject clonePlayer=null;
     [HideInInspector] public GameObject cloneBattle=null;
     private GameObject cloneMonster=null;
     private Vector3 playerOrigin;
 
     //Allow other classes to manipulate health/score
     public static GameManager instance = null;
 
     //Sets up singular instance of GameManager for other classses to use
     void Awake (){
         if (instance == null)
             instance = this;
         else if (instance != this)
             Destroy (gameObject);
     }
 
     //Freeze the player, set up battle, start battle
     public void startBattle(){
         player.GetComponent<PlayerController> ().enabled = false;
         Instantiate (battleParticles, player.transform.position, Quaternion.identity);
         Invoke("initializeBattle", 2f);
     }
 
     //Start battle
     public void initializeBattle(){
         if (cloneBattle == null) {
             cloneBattle = Instantiate (battleGround, new Vector3 (0, 50, 0), Quaternion.identity) as GameObject;
             clonePlayer = Instantiate (playerImage, new Vector3 (-4f, 51f, 0f), Quaternion.identity) as GameObject;
             cloneMonster = Instantiate (monster, new Vector3 (4f, 51f, 0f), Quaternion.identity) as GameObject;
             playerText = clonePlayer.transform.GetChild (0).gameObject.GetComponent<Canvas> ().GetComponent<Text> ();
             monsterText = cloneMonster.transform.GetChild (0).gameObject.GetComponent<Canvas>().GetComponent<Text> ();
         }
     }
         
 
     //End battle, unfreeze player
     public void endBattle(){
         Destroy (cloneMonster);
         Destroy (clonePlayer);
         Destroy (cloneBattle);
         player.GetComponent<PlayerController> ().enabled = true;
     }
 
     //Functions called to reduce health if player/monster is injured
     public void playerInjury(float lostHealth){
         if (playerText) {
             playerText.text = "-" + lostHealth.ToString () + "!";
         }
         playerHealth -= lostHealth;
         healthRatio = (playerHealth / MAX_HEALTH);
         healthBar.GetComponent<RectTransform> ().localScale = new Vector3(healthRatio, healthBar.GetComponent<RectTransform> ().localScale.y, healthBar.GetComponent<RectTransform> ().localScale.z); 
         //Placeholder
         Debug.Log ("Player: " + playerHealth);
         if (playerHealth <= 0f) {
                 SceneManager.LoadScene ("Lose_Screen");
         }
     }
     public void monsterInjury(float lostHealth){
         if (monsterText) {
             monsterText.text = "-" + lostHealth.ToString () + "!";
         }
         monsterHealth -= lostHealth;
         //Placeholder
         Debug.Log ("Monster: " + monsterHealth);
         if (monsterHealth <= 0f) {
             endBattle ();
         }
     }
 
     //Functions called to track player choices in battle
     public void playerAttack(){
         numAttacks++;
         Debug.Log ("Attacked: " + numAttacks);
     }
     public void playerRun(){
         numRun++;
         Debug.Log ("Ran: " + numRun);
     }
 
 }


In the above code, I have assembled a Game Manager which works marvelously well in all ways except for one. In each of these places:
if (monsterText) {
monsterText.text = "-" + lostHealth.ToString () + "!";
}
if (playerText) {
playerText.text = "-" + lostHealth.ToString () + "!";
}

The if statement is always false. monsterText and playerText are always null (or simply throw the "object reference not set to an instance" error), meaning something fails in their assignment, which occurs here:

 clonePlayer = Instantiate (playerImage, new Vector3 (-4f, 51f, 0f), Quaternion.identity) as GameObject;
 cloneMonster = Instantiate (monster, new Vector3 (4f, 51f, 0f), Quaternion.identity) as GameObject;
 playerText = clonePlayer.transform.GetChild (0).gameObject.GetComponent<Canvas> ().GetComponent<Text> ();
 monsterText = cloneMonster.transform.GetChild (0).gameObject.GetComponent<Canvas>().GetComponent<Text> ();




I've tried breaking that statement up and using temporary variables, but it's never paid off. I would like to update the text during each battle instance to show the value of blows landing as they happen. I thought setting and calling the variables after creating the instance would be enough, but Unity is still telling me the object is not set to an instance.
What am I missing?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by phil_me_up · Mar 04, 2016 at 01:14 AM

I'm guessing your problem is with the GetChild(0).game object.GetCompenent().GetComponent() line(s). Sorry, I can't copy and paste on mobile but hopefully you know what I'm referring too!

I've never liked using GetComponent because a) it's slow and b) you can easily get in a muddle. In your case your code is expecting to find the Text component in a very specific place - Within the first child object of your instantiated prefab.

Note that GetCompenent().GetComponent() means find a Text Component on the same object as the Canvas Component, not a Text components on a child of the Canvas component, which is what I think you were aiming for.

You could potentially fix this with GetCompenent().gameObject. GetComponent(), but again this isn't really ideal for a number of reasons and really relies on you having that exact hierarchy in your prefab.

Another potential fix is to use GetComponentsInChildren or GetComponentInChildren, perhaps tagging the object your interested in to help search.

Personally, I'd prefer to have some management script within the root of your prefab which holds a reference to the text object you want to access.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Tain_M · Mar 04, 2016 at 02:55 AM 1
Share

I really wanted to use a direct reference, but somehow the nesting of Text within Canvas within Sphere all as a prefab made that not work. GetComponentInChildren worked perfectly though! Especially since I know there will be no other Text objects childed to the character instances. Thanks so much!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

54 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to attach a canvas to a game object properly? 1 Answer

How to DontDestroyOnLoad a specific ui of a canvas? 1 Answer

Canvas UI Priority layers 1 Answer

How do I get more freedom with positioning UI Text? 1 Answer

Quick Question on UI Text Alignment 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges