Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Oliver1135 · Dec 30, 2014 at 03:08 PM · uiinspector4.6

binding properties to UI Text/Image etc

Managing GUI Elements

Can someone point me in the right direction as to 'binding' game object properties to UI as although what I have works, it has me stuck up to my nose in code where I would imagine there has to be a simpler recommended way using the inspector

I have a Group of GameObjects as shown below

     ▼ UICanvas //Canvas
      ▼ Active Character //Empty Game Object
       ▼ Panel // UI Panel
         CharacterName //UI Text
         CharacterImage //UI Image
         CharacterClassImage //UI Image
         CharacterWeaponName //UI Text

I have a UIManager monobehavior attached to my UI Canvas that I can store a reference to during the Start() of my game Manager

   _uiManager = GameObject.Find ("UICanvas").GetComponent<UIManager>();

similarly I have a way of getting a reference to the GameManager from the start method of my UIManager

   _gameManager= GameObject.Find ("GameManager").GetComponent<GameManager>();

and in my GameManager's update function I make a call to

 _uiManager.ActiveCharacterChanged();

Here is what my UIManager class looks like with 1 panel and zero interactivity which I can only imagine will get exponentially worse and unmanagable

public class UIManager : MonoBehaviour {

     private GameManager _gameManager;

 private Transform _activeCharacterPanel;
 private Text _activeCharacterName;
 private Image _activeCharacterImage;
 private Image _activeCharacterClassImage;
 private Text _activeCharacterWeaponName;

 // Use this for initialization
 void Start ()
 {
     _activeCharacterPanel = this.transform.FindChild("Active Character").FindChild("Active Character Panel");
     _activeCharacterName = _activeCharacterPanel.FindChild("CharacterName").GetComponent<Text>();
     _activeCharacterImage = _activeCharacterPanel.FindChild("CharacterImage").GetComponent<Image>();
     _activeCharacterClassImage = _activeCharacterPanel.FindChild("CharacterClassImage").GetComponent<Image>();
     _activeCharacterWeaponName = _activeCharacterPanel.FindChild("CharacterWeaponName").GetComponent<Text>();


     if (_activeCharacterPanel == null)
     {
         Debug.LogError ("Could Not find active char panel");
     }

     _gameManager = GameObject.Find("GameManager").GetComponent<GameManager>();
     if (_gameManager == null)
     {
         Debug.LogError ("GameManager is Null");
     }
 }

 public void ActiveCharacterChanged()
 {
     if (_gameManager.ActiveCharacter != null)
     {
         _activeCharacterName.text = _gameManager.ActiveCharacter.DisplayName;
 //_activeCharacterImage.texture = TODO;
 //_activeCharacterClassImage.texture = TODO;
         _activeCharacterWeaponName.text = _gameManager.ActiveCharacter.Weapon.Name;
     }
 }

}

Comment
Add comment · Show 4
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 Glurth · Dec 30, 2014 at 03:46 PM 1
Share

I came up with the following, http://forum.unity3d.com/threads/simplifying-ui-data-exchange-method-presented-feedback-requested.288195/#post-1902199. I suspect it's not as automated or robust as you would like, but it HAS certainly reduced (if not eli$$anonymous$$ated) the need to write new code for UI elements.

avatar image Oliver1135 · Dec 30, 2014 at 04:06 PM 0
Share

Thanks I'll take a look, its extremely odd theres no supported way to bind and update values with ease without code behind.

avatar image Oliver1135 · Dec 30, 2014 at 05:07 PM 0
Share

I feel I have kind of retread covered ground I've looked at data binding with NotifyPropertyChanged as similar to what I need since there should only be a call to Update the UI when there is a meaningful value change.

Currently I have set it so that I have a publicly accessible property that when set executes a method on the UI $$anonymous$$anager to update the respective value that I have 'bound', I think that there should be a way to call a single method from any value and have it updated by passing in a parameter but admittedly I'm not sure how to go about this there may be someone more familiar with this stuff than me that has an idea

 public Character ActiveCharacter
 {
     get
     {
         return _activeCharacter;
     }
     set
     {
         if (_activeCharacter != value)
         {
             _activeCharacter = value;
             _ui$$anonymous$$anager.ActiveCharacterChanged();
         }
     }
 }

Heres the link to NotifyPropertyChanged for Windows Presentation foundation that I'm looking at and bastardizing

http://msdn.microsoft.com/en-us/library/ms743695%28v=vs.110%29.aspx

avatar image Oliver1135 · Dec 30, 2014 at 11:01 PM 0
Share

Definately looks like something the unity $$anonymous$$m needs to addressed, it's a little puzzling and I can't seem to find a way around needing to write code

there may be a more complex up front solution ala an interface implementation notifying the unity ui system theres an updated property, getting the component it's attached to and re-getting the value for display, I'm not as proficient with c# to actually try and do that though someone might know if that is or is not possible.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Oliver1135 · Jan 05, 2015 at 03:09 AM

I'm not marking this as an accepted answer as as far as i'm concerned it's still a ways off from being a robust solution much like Glurths, it works and it is what I will be using but im convinced there has to be a way to structure this in a way that manages its own UI value updating.

I have a way to do this with only very little code and little setup, the downside being you need to know when the value you want to display changes as you set it via dictionary in a singleton. Code below

Example of a call to the UIManager to update the text being displayed

 UIManager.Instance.UITextBindings["ActiveCharacterName"].text = _activeCharacter.DisplayName;

Here is the UIManager class (I think its called a singleton)

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

 public class UIManager 
 {
     private static UIManager _instance;
     public static UIManager Instance
     {
         get
         {
             if (_instance == null)
             {
                 _instance = new UIManager();
             }
             return _instance;
         }
         set
         {
             _instance = value;
         }
     }
 
     public Dictionary<string, Text> UITextBindings = new Dictionary<string, Text>();
 }

Here is the behavior you attach to a gameobject with a text component on it. You give it a binding name which in the start function adds it to the dictionary and you can set the text initial value as well. It only takes strings of course so you need to do a little formatting or .ToString() calls for numbers you need to display

 using UnityEngine;
 using System.Collections;
 using UnityEngine.UI;
 using System;
 
 public class TextBindingBehavior : MonoBehaviour
 {
     public string BindingName;
     public string TextInitialValue;
 
     public Text TextComponent;
 
     public string TextValue
     {
         get
         {
             if (TextComponent == null)
             {
                 TextComponent = this.gameObject.GetComponent<Text>();
             }
             return TextComponent.text;
         }
         set
         {
             if (TextComponent == null)
             {
                 TextComponent = this.gameObject.GetComponent<Text>();
             }
             TextComponent.text = value;
         }
     }
 
     // Use this for initialization
     void Start ()
     {
         TextValue = TextInitialValue;
         UIManager.Instance.UITextBindings.Add(BindingName, TextComponent);
     }
 }




Comment
Add comment · Show 2 · 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 Glurth · Jan 05, 2015 at 04:14 PM 0
Share

Is there any particular reason you are defining your UImanager, as a non-static class, (I ask since it looks like you only want one instance of the class)? If you define it as a static class, you can eli$$anonymous$$ate that _instance variable (as well as the need to instantiate UImanager). e.g. usage: UI$$anonymous$$anager.UITextBindings.Add(BindingName, TextComponent);

Also, the link I posted to in my first comment has an additional post now, one of which mentions a way to bind the values to variables. It uses c# delegates and events, which I'm still learning.

Edit: ok, I updated it to include "subscriptions". please take a look- http://forum.unity3d.com/threads/simplifying-ui-data-exchange-method-presented-feedback-requested.288195/#post-1906038

avatar image Oliver1135 · Jan 05, 2015 at 07:58 PM 0
Share

Ok Thanks for the comment, the reason I have it set up this way is i'm trying the singleton pattern, right now I really dont see any difference really what so ever other than being able to clear the instance every time I load a new scene (still not finding a great global way to cover re-entering scenes where they have keys added that are already defined previously in the dictionary)

bit of inspiration from http://en.wikipedia.org/wiki/Singleton_pattern

as I only want one per scene, but I will want different "instances" of the UI$$anonymous$$anager per scene as the behaviors add keys to the dictionary On Start()

I'll definately take a look at the c# delegates and events thread to see if I can make sense of it, part of the problem is not fully understanding all the c# syntax and really "what" I can do with it.

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

26 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

Related Questions

How to make a single word in a Text object clickable / have hover. 2 Answers

How to use Text (OpenType .otf) Object as Mask for Image? 0 Answers

(4.6 UI) How to set up a window with x buttons, with a scroll bar? 1 Answer

How to create a "back" side of a canvas UI element 1 Answer

Changing Two Canvas Text Strings in Code 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