Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by Mad_Mark · Feb 11, 2017 at 09:28 PM · prefabspublic variable

Prefab Doesn't Store Public Fields?

I have created AI characters. As each character is hit by a raycast from the player, I show their name and healthbar on a canvas. As the player looks away, the canvas clears. Seems simple, and it works, as long as all of the objects are in scene, and I manually place the UI elements into the public field slots.

I want to start with an empty level and spawn prefab AI characters in. When I do, their public fields for UI elements are empty. What can I do to ensure that these fields hold the entries for the canvas and UI elements?

EDIT: Attaching the Enemy script from updated comment.

 <Deleted for brevity>
             void Start () 
          {
      //        HealthBarCanvas = GetComponent<EnemyHealthBars> ();
              healthBarSlider = GetComponent<EnemyHealthBars> ().healthBarSlider;
              healthBarText = GetComponent<EnemyHealthBars> ().healthBarText;
              HealthBarCanvas.SetActive (false);
          }
          
          // Update is called once per frame
          void Update () 
          {
              Ray ray = PlayerCamera.ViewportPointToRay (new Vector3(0.5f,0.5f,0));
      
              if (Physics.Raycast (ray, out hit, lookDistance))
              {
                  if (hit.collider.gameObject.tag == AITag && updateTimer > 0.5f)
                  {
                      currentlyLookingAtTarget = true;
                      currentTarget = hit.collider.gameObject;
                      currentAISystem = currentTarget.GetComponent<AI> ();
  
                      updateTimer = 0;
                  }
      
                  if (hit.collider.gameObject.tag == AITag)
                  {
                      updateTimer += Time.deltaTime;
                      lookAwayTimer = 0;
                  }
      
                  if (hit.collider.gameObject.tag != AITag)
                  {
                      lookAwayTimer += Time.deltaTime;
      
                      if (lookAwayTimer > lookAwaySeconds)
                      {
                          currentlyLookingAtTarget = false;
                          currentTarget = null;
                      }
                  }
              }
     
              if (deathTimerActive)
              {
                  deathTimer += Time.deltaTime;
      
                  if (deathTimer > 1)
                  {
                      HealthBarCanvas.SetActive (false);
                      currentlyLookingAtTarget = false;
                      deathTimerActive = false;
                      currentTarget = null;
                  }
              }
      
              if (currentlyLookingAtTarget && !deathTimerActive)
              {
                  HealthBarCanvas.SetActive(true);//HealthBarCanvas.SetActive(true);
                  healthBarSlider.value = currentAISystem.currentHealth;
      
                  if (currentAISystem.currentHealth <= 0)
                  {
                      deathTimerActive = true;
                  }
              }
      
              if (!currentlyLookingAtTarget)
              {
                  HealthBarCanvas.SetActive (false);
              }
          }
      }
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

Answer by HenryStrattonFW · Feb 12, 2017 at 12:29 AM

This is because prefabs exist outside of the scene, meaning they cannot store references to items that are in the scene as it has no knowledge of the scene. This is also why you will notice that if you set references to items that are not within the prefab itself, those values remain in bold when you apply changes, because they cannot be saved with the prefab.

To get around this, you will have to do one of two things, one is to have prefabs locate those items and store the references after they are instantiated, you could do this based on tags, names, component searches. OR what I see as the better method, is to have a script that manages your UI (for arguments sake lets call it UiController), this can be placed on the object in the scene, and hold references to the GUI elemnents, then instead of your enemy objects directly effecting the UI display, they simply find and make method calls to this UiController (again via a find by name, find by type, etc). and the UiController responds by updating the necessary UI elements.

Comment
Add comment · Show 4 · 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 Mad_Mark · Feb 12, 2017 at 02:26 AM 0
Share

POSTED AS ANSWER AS CO$$anonymous$$$$anonymous$$ENT DIDN'T WOR$$anonymous$$!!!! @HenryStrattonFW I know that a prefab can't retain a link to the in-game elements. Can you point me to an instructional video to setup a UIcontroller?

All I want to do is have this script, placed on each AI object, enable a worldspace UI overtop of the AI-unit that is hit by the raycast, show its text (name) and display a slider for hitpoints. The Canvas is a child of the Enemy game object. All UI components are children of the Canvas. Each Enemy AI object has its own canvas. I have public fields for Canvas, Slider, and Text, and have dragged and dropped the elements into their respective fields.

When I place multiple AI's into the scene, the raycast turns on ALL canvases(undesired), and they ALL appear to share the same updates! If I hit one, all of the sliders move. The expected behavior is raycast hits AI. Single AI's Canvas gets set active. AI takes a hit, only its single slider moves. $$anonymous$$ove targeting reticule (ray) off the AI, its Canvas is no longer active.

I am down to my last few hairs. This seemed a lot simpler in concept! At this point, I would be happy if I could just have a single, screenspace Canvas that does the same thing with prefab AI-characters (no public fields that require drag and drop UI elements).

avatar image HenryStrattonFW Mad_Mark · Feb 12, 2017 at 02:00 PM 0
Share

It seems comments have a size limit, I've moved the script into your original post, and converted your post to a comment.

First I apologies based on your second post it seems I misunderstood part of your issue. I thought you were talking about a single screenspace UI that each AI emeny shared, not a UI canvas within each enemy itself.

However that being the case, I'm unsure what issue you are having as I have no issues in a test project adding worldspace canvas + assets to a prefab, linking them via public fields in the inspector, and having those references persist when the prefab is later instantiated. Here is a link to screenshot (uploader wouldn't work) showing my template prefab (placed in scene for convenience only) its inspector with the UI elements connected, and a view of it in the scene (just a sphere with a text label). $$anonymous$$y test code instantiates X number of these setting their name based on their spawn order, each prefab then uses its references to set the label to its name and it all seems to work fine.

Can you compare this setup to the one you are using, as from what I can see there should be no reason why these public references should not be serialized with your prefab. THe code you posted uses GetComponent to try and find them, however get component only works on the object the script is attached to, in this scenario I assume the UI elements are children within the prefab, in which case you would want to use GetComponentInChildren ins$$anonymous$$d.

avatar image Mad_Mark HenryStrattonFW · Feb 12, 2017 at 05:39 PM 0
Share

I have it now instantiating the prefab, and making the canvas a child of the AI-object.
Added: HealthBarCanvas = Instantiate(HealthBarCanvasPrefab, new Vector3 (transform.position.x,transform.position.y +2.51f,transform.position.z), Quaternion.identity); HealthBarCanvas.transform.SetParent (transform);

I also have it filling in the variables using GetComponentInChildren.

However, for some reason, it still wants to turn on ALL of the AI's canvases, and use the name and health stats of the target AI.alt text

Am I doing something wrong with the RayCast? $$anonymous$$ark

znames.png (215.4 kB)
Show more comments

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

94 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 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

Prefabs and public variables 1 Answer

For some reason I cannot drag my prefabs from the Project folder into the scene hierarchy. 2 Answers

How to redraw a texture on a prefab instance when a property in the inspector is changed by the developer? 0 Answers

Limit an amount of prefabs instantiated in javascript for Unity 5. 0 Answers

my instantiation /prefab of dan wont play death animations like orignal dan 0 Answers


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