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 jvcraft87 · Dec 28, 2014 at 06:41 AM · uitextonclick

How do I make a line of text in a list interactive?

I am trying to do the following:

I have a panel that I am placing a scroll rect on and within it I want to display lines of text that a user can select with a click. On click a callback is made with the line of text that was clicked on.

An example would be a list of items randomly generated and displayed in the GUI. The user can scroll through the list and click on one of the items. The callback function receives the name of the item clicked and goes off and does something with it.

Basically I want each item to have an OnClick event, but Text does not have that interaction. I have placed a "Button script" on a Text item but I can't replicate that in code (hence my question).

Thanks for any ideas!

Comment
Add comment · Show 5
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 jakovd · Dec 28, 2014 at 08:34 AM 0
Share

Instatiating prefabs and setting them up with code is the way to go. Read this first. If you still have problem figuring out how to do this, let me know. Creating UI elements from scripting

avatar image jvcraft87 · Dec 28, 2014 at 05:47 PM 0
Share

Thanks all for the replies!

$$anonymous$$mmpies not quite what I was looking for. Let's say I have a list and the contents are strings, hello_0, hello_1, hello_2, ..., hello_n. I want to display them in a panel as text but provide the ability for a user to click on one of them and I send the string as a parameter to my callback function.

I have created a prefab that is a UI Text and has a Button Script attached. But when I instantiate it the callback I placed in the prefab is not there. Further each prefab has the string of every item in the list.

So, I want the functionality of a button on a UI Text in a panel but I don't want the LOO$$anonymous$$ of the button.

avatar image Mmmpies · Dec 28, 2014 at 05:54 PM 0
Share

Delete the background image then it becomes just text but still acts like a button.

Or I suppose do that tutorial but ins$$anonymous$$d of a button use Text, and add an onPointerClick event to it. Not tested that though.

avatar image jvcraft87 · Dec 28, 2014 at 06:06 PM 0
Share

Yep, that's what I'm looking at now. Have to figure out how to get the callback established as it is a bit different than what I've done previously.

avatar image Mmmpies · Dec 28, 2014 at 06:16 PM 0
Share

You should be able to use what I put in that script. If you need to access information in another script well that's what I did in that example.

The new UI does handle things differently, the Lambda that @jakovd said I should extend is different to how I'd have done things in the past. Ins$$anonymous$$d of passing a reference value back to an instance of the object the instantiating script holds the references.

Just let me know what you're struggling with and I'll help if it's something I've come across already.

2 Replies

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

Answer by jvcraft87 · Dec 29, 2014 at 07:31 AM

My GUI Canvas has a child panel I call "Item List Panel". This panel is the parent for the items that we will list. It has a script that instantiates my Text Prefab (described below).

My Text prefab I call GUI_ItemText. It is the basic UI Text object. I added an "Event Trigger (Script)" component to it, but I didn't add any event types. This prefab has another script added to it, ListItem.cs. This script builds the trigger event and has a callback in it. The code is below:

 public class ListItem : MonoBehaviour {
 
     // Use this for initialization
     void Start () {
         BuildTrigger();
     }
     
     // Build the trigger response
     private void BuildTrigger()
     {
         EventTrigger eventTrigger = gameObject.GetComponent<EventTrigger>();
         EventTrigger.TriggerEvent trigger = new EventTrigger.TriggerEvent();
         trigger.AddListener((PointerEventData) => OnPointerClick());
         EventTrigger.Entry entry = new EventTrigger.Entry()
             { callback = trigger, eventID = EventTriggerType.PointerClick };
         eventTrigger.delegates.Add(entry);
     }
 
     // Called when trigger is fired
     public void OnPointerClick()
     {
         Debug.Log("I've been clicked! " + gameObject.name);
     }
 }

Next I need to figure out the ScrollRect with this UI Text Objects being instantiated and laid out with the Vertical Layout Group.

Thanks all for the suggestions!

Comment
Add comment · 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
0

Answer by Mmmpies · Dec 28, 2014 at 09:26 AM

Did exactly this for to explain the 4.6 UI for someone recently.

Watch the @BoredMormon video Tutorial1

You don't need the Horizontal Layout Group from that video just a button with a panel underneath it with the pivot set to the top and a vertical layout group and content size filter. The video explains it all.

Then follow the second tutorial Tutorial2

All you really need from that is the idea for the prefab buttons and a headstart in the script. Don't worry too much about the script I'll post mine in a minute as an example.

EDIT:

You need the following setup in your UI

Hierarchy

And the button has the following on it:

Button

The button has it's own on click event but I added the Trigger Event as it could be a panel or image or any UI element.

Just give me shout if you can't get it to work.


jvcraft87-1.png (4.9 kB)
jvcraft87-2.png (18.3 kB)
Comment
Add comment · Show 6 · 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 Mmmpies · Dec 28, 2014 at 09:28 AM 0
Share

$$anonymous$$enus script, this is the main script and attaches to the main button

 using UnityEngine;
 using UnityEngine.UI;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 
 
 public class $$anonymous$$enu : $$anonymous$$onoBehaviour {
     
     public GameObject ButtonPrefab;
     public RectTransform $$anonymous$$enuPanel;
     public RectTransform InfoPanel;
     private BaseTypes[] _baseTypes;
     private List<GameObject> menuList = new List<GameObject>();
 
 
     private void Awake()
     {
         _baseTypes = new BaseTypes[Enum.GetValues(typeof(BaseNames)).Length];
         SetupBaseNames();
     }
 
     void SetupBaseNames()
     {
         for(int i = 0; i < _baseTypes.Length; i++)
         {
             _baseTypes[i] = new BaseTypes();
             _baseTypes[i].Name = ((BaseNames)i).ToString ();
         }
     }
 
 
     // needs to be public for the event system to access it
     public void $$anonymous$$enuButtonClicked()
     {
         if (menuList.Count == 0)
         {
             for(int i = 0; i < _baseTypes.Length; i++)
             {
                 GameObject newButton = (GameObject)GameObject.Instantiate(ButtonPrefab);
                 newButton.GetComponentInChildren<Text>().text = _baseTypes[i].Name.ToString();
                 newButton.transform.SetParent($$anonymous$$enuPanel, false);
 
 
                 int index = i;
                 newButton.GetComponent<Button>().onClick.AddListener(() => {ClassButtonClicked(index);}    );
                 Debug.Log (" menuList.Count before adding the newButton " + menuList.Count);
                 menuList.Add (newButton);
                 Debug.Log (" menuList.Count after adding the newButton " + menuList.Count);
             }
         }
     }
 
     public void ClassButtonClicked(int index)
     {
         //Debug.Log (" the selectedclass is " + _baseTypes[index].Name.ToString ());
         InfoPanel.GetChild(0).GetComponent<Text>().text = _baseTypes[index].Name.ToString ();
     }
 
     public void $$anonymous$$enuExited()
     {
         if(menuList.Count > 0)
         {
             for(int i = 0; i < menuList.Count; i++)
             {
                 Destroy(menuList[i]);
             }
             menuList.Clear();
         }
     }
 }

avatar image Mmmpies · Dec 28, 2014 at 09:29 AM 0
Share

BaseTypes script

This is just an example list of button objects.

 public class BaseTypes : BaseStats  {
     
 }
 
 public enum BaseNames {
     $$anonymous$$age,
     Warrior,
     Archer,
     $$anonymous$$onk,
     Cleric,
     Vampire
 }
avatar image Mmmpies · Dec 28, 2014 at 09:32 AM 0
Share

And this is the getter/setter to return the Name from that class. The original scripts were to show how to get information on the new UI from a script that does not derive from $$anonymous$$onobehaviour so probably more complex than you need.

You could just put an Array of objects in the $$anonymous$$enu Script.

 public class BaseStats {
 
     private string _name;
 
     public BaseStats()
     {
         _name = "";
     }
 
     public string Name
     {
         get{ return _name;}
         set{ _name = value;}
     }
 }

avatar image jakovd · Dec 28, 2014 at 10:19 AM 0
Share

@$$anonymous$$mmpies, just a suggestion to make your code cleaner. In $$anonymous$$enuButtonClicked, there is no need to store that index for button and no need for ClassButtonClicked method. Just do that functionality in body of the lambda expression, where you set the listener on button click. You can put

 newButton.GetComponent<Button>().onClick.AddListener(() => {newButton.GetComponent<Text>().text = "something";}    );



and let the compiler do the rest. He'll know which button reference to embed in the context of that event response.

avatar image Mmmpies · Dec 28, 2014 at 10:37 AM 1
Share

Thanks @jakovd, that is true but the tutorial I was working on is for someone to build an information panel with images, descriptions, text, stats and so on.

At the moment it only shows the name text in the child of the InfoPanel. It's just an example but in reality would be a lot more complex so I was showing it that way because it'll be far more readable than pushing all that in a Lambda expression.

Not sure on the stats is Lambda significantly cheaper than sending a reference index to another function? That's a genuine question, I'd really like to know if it is.

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Engraving, Embossing, and Embellishing text on to models 1 Answer

How to get the width of UI Text with Horizontal Overflow? 4 Answers

How to change color of certain text on a canvas on click 1 Answer

Scripted UI.text not shows on duplicated object 0 Answers

Unable to reference a component. 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