Search Unity

Edit text inside a graphic rebuild loop

Discussion in 'Scripting' started by manpower13, Jun 8, 2015.

  1. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Hello everybody,

    This is my very first post where I have a question. If I do anything wrong, or I provide not enough information, please tell me and I will update it.

    I am creating a tycoon like game and I want to show information about statistics inside a graph/diagram. I have made a class that inherits the Graphic class from the new UI system. It draws lines for me based on vectors I set. It scales it right to make it compatible with any data size.
    Now the problem is, I want to show an inscription (or legend, I do not really know what the right English word is) under and at the side of the graph. That text needs to adapt to the size of the graph, with the correct scale.



    See this graph for example. What would be the best approach of creating this kind of legend? With the right numbers (in this example: 0-50-100-150-200-250-300) adapting to the scale?

    Also I made this graph class inhereting from the Graphic class, but how would I create text inside this class now? Is that possible? Or do I need a seperate text component?

    Thanks for reading and I hope you understand what my question is :).
    If it is not clear, I will post some more information!

    Floris Weers,
    WeersProductions
     
  2. NeilM0

    NeilM0

    Joined:
    Mar 31, 2009
    Posts:
    135
    The way I would tackle it is to use a RenderTexture and an off screen camera. Then you can put any 3D object in your graph. Want a 3D pie chart or bar graph, they would just be standard gameobjects on a hidden layer. Then you can just use the UI RawTexture to display the render texture as part of your UI.
     
  3. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    @NeilM0
    Hello Neil,

    Thank you for your help!
    But I do not completely understand what you mean. I understand what you want to achieve, but I do not know how exactly. I am not that advanced in the UI.

    Do you think my approach of creating the graph is not the right way?
     
    Last edited: Jun 9, 2015
  4. NeilM0

    NeilM0

    Joined:
    Mar 31, 2009
    Posts:
    135
    It's a few steps, so lets just start with a blank scene:

    - Create a Layer called RTT (The layer drop down is in the upper right of the UI above the inspector)
    - Create a new camera. Rename it to "Graph Camera"
    - Set the camera's culling mask to Nothing to clear the list. And then RTT.
    - Set the main camera's culling mask to Everthing, except RTT.
    - Create a sphere in the world and place it in front of Graph Camera. Set its layer to RTT
    - When you select the Graph Camera you should now see the sphere in the preview.
    - Create a new UI Canvas and rename it to Graph Canvas
    - Set the layer of the graph canvas to RTT
    - Set the Canvas Render Mode to Screen Space - Camera
    - Set the render camera to Graph Camera
    - In Graph Canvas, add a UI Text gameobject
    - If you click on graph camera you should now see a sphere and text in the Camera preview
    - In your project window, right click and create a new Render Texture. Call it Graph Texture.
    - Select Graph Camera
    - Set the Target Texture to Graph Texture
    - You will probably have to mess with the Render Texture's width/height (It can only be a power of two square and it defaults to something low res like 256x256) and that might mess with the canvas' width and height, so you'll probably have to change that as well.
    - Create a new canvas. This is the one that will show the graph.
    - Inside of it place a UI Raw Image.
    - Set the texture to Graph Texture and set its width and height to the same size as the render texture. You can play with the UV Rect to crop out the bottom to make a rectangle.

    You should now see the sphere and text in a UI element.
    What you can now do is take the graph that you're drawing with lines and place it on the RTT layer in front of the camera and the graph should show up, with the text and the sphere.
     
    manpower13 likes this.
  5. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    @NeilM0
    Hello Neil,

    Thank you very much for your extraordinary post! This is a very detailed explanation and it helped me alot!
    I got the camera working and this is indeed great for creating e.g. 3d objects inside a ui.
    It will help me a lot when creating other graphs and charts. But I can't figure one last thing out.

    I have made this graph, with lines working properly. Now I want to add a legend to it. The problem with this legend is, that it needs to change its text to the scale of the graph.

    This means, if I have data that has numbers around 1000, the legend shows: 0 500 1000 1500 for example.
    But when I have numbers around 100, it needs to display: 0 25 50 75 100.
    I know I could make an object with a text component and change its text dynamically, but how would I position the text to the right place? I do not want to make every number in a different text component and position them all, that would take way to much performance.

    So I thought of creating the text inside the Graphic class, but I could not find any way of doing that. Is that even possible?

    The crux of my question: How can I create a legend text that updates its position to the graph?

    I hope I am clear, otherwise I will try to explain it in a different way :).

    Thank you for reading,
    Floris Weers
     
  6. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    If you're using the new UI you could always do something like this, place a Text object from the UI menu into the scene, set it up how you need to look then in your code have:
    Code (csharp):
    1. Using Unity.UI; //Place this at the very top
    Code (csharp):
    1.  
    2. public GameObject textObject; //Drag the Text UI you created into the inspector
    3. public Text textHere; //Leave this empty in the inspector
    4. public float VariableHere;
    5.  
    6. void Start() {
    7. textHere = textObject.GetComponent<Text>();
    8. }
    9.  
    10. void Update() {
    11. textHere.Text = VariableHere;
    12. }
    13.  
    This way you can edit the TextUI directly through script, because of the new UI as well you should be able to scale it to how you need to.
     
  7. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    @TheBlueInferno
    Thank you for your time and energy, but that is not exactly what I meant. I know how to change text in a text component.
    The thing I do not know is how to create the following:

    I currently have made a script that creates this graph based on vector 2 data. It is a class that extends Graphic. See below for what I currently have:

    platinum_nolegend.png

    Now I want to add a legend to this. I would like to have the following:
    platinum.png
    I could ofcourse make several text objects with text components and change the text to the right value. But what if the data goes beyond the year 2005 and we add 2010 to the graph. The points in the graph move somewhat to the left to
    make space for the new point. (I have got that working). BUT the legend needs to move too and add the new text '2010'. See the picture below. All the black arrows show where the text should go.
    platinum_2010.png
    I could achieve this by creating a new text object with a text component and reposition all other text objects. But would that be the best solution? Or is there a better way?

    Thank you for your time and I hope this makes sense now ;)

    Sincerely,
    Floris Weers
     
  8. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    Create a float for just that? Example

    Code (csharp):
    1.  
    2. float xValue;
    3.  
    4. void OnGUI() { //I'm not saying use Legacy GUI but I'm trying to point you in the right direction
    5. GUI.Label(new Rect(100 + xValue, 50, 100, 30), "Test");
    6. }
    7.  
    In your code where you move the graph a little to the left, do the same with that float in that code to make sure there is a 100 pixel gap between each legend. Commonly a legend sits at the bottom of a graph or to the right:



    But as far as I understand you want yours to be inside the graph and move with it? If so then by setting a float to the same value as your graphs and using a bit of maths you'll be able to move it along with the graph as needed. From your first post you wanted to edit the size/scale of the text in the legend but I'm not quite sure I understand what you're looking for exactly, if you could try and explain or show me maybe I could be of more help?​
     
  9. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    @TheBlueInferno
    Thank you for your very fast reaction! That sounds good indeed.
    Here is gif I made of the thing I currently have:
    MovingGraph.gif

    You can see the graph adjusting to the size of the component. If I add a new point in the Graph, it will automaticly resize.
    GraphNewAdded.gif

    Here you can see me adding new points, first I add the new point, set the new x and the new y.
    Now I want a legend that changes its position and text to the points in the graph.
    So when adding a new point in the Graph, automaticly create a new legend text and position it good.
    I could indeed write a formula for that, but would I have to create a new text object with text component for each text?
    A text object with text component containing the text: "1".
    Another one with the text: "2". And so on?
    Or is there another way?
    If this is not yet enough information, I will try to explain some more ;).

    Again thanks for all your help!
     
  10. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    I think I understand a bit better now, if you have access to the location of the points you could have a List or an Array and fill them with GameObjects with TextUI components and change the position of them to match the points and add to the Y or minus, that way you'd have text at the same position just a bit higher or lower. You could create a TextUI prefab, set it to the font etc that you want then use that to spawn in when a new point is created and make it a child object of an empty to keep it tidy and save it to an array, then when a new point is added update the array to the points?
     
  11. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Hello @TheBlueInferno ,

    Thank you for your help again and it helped me a lot actually!
    The position of all texts objects are good now and they update live when changing the size of the graph. I now just can't fix an error I get while updating the text inside the text component.
    I get this error while instantiating inside the OnFillVBO function of the Graphic class. It does instantiate the gameobject anyway and it does update its position. The only thing it does not do is updating its text.


    Error.PNG

    EmptyTextComponents.PNG

    You can see it here. It does create all the gameobjects and position them right, but there is no text in there. When I save my project, the text does appear.
    I know it has something to do with changing UI things while building the UI. But how would I be able to change the text in those gameobjects if this is not possible?

    error2.PNG
    Thank you for your time!

    Sincerely,
    Floris Weers
     
  12. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Changed the title, because my first problem is solved :).

    Do I have to create a new post and put it inside the UI section? Or can I keep it in this post like I have right now?
     
  13. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Hello all,

    I gave up creating a Chart that has a legend that edits real time in the editor. I cannot get it to work.
    I created a button that refreshes the legend and updates it. That works great.

    The thing I was wondering now, how would I calculate the legend scales? I am talking about the numbers.
    CalculateLegend.PNG

    You can see the legend works, but the numbers are not nice to read.
    How would I calculate what scale to use based on the data in the Graph? In this case I want to have a legend that starts with 0 and adds 10 every time. So 0-10-20-30-40-50. How would I calculate that number ten?

    Thank you for your time,
    Floris Weers
     
  14. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    If you only want to show the first two digits (7, 15, 23, 31) use .ToString("F0") if you want it to equal 10 each time then just do a forloop of some kind and add 10 to a float/int.
     
    manpower13 likes this.
  15. Kadaj

    Kadaj

    Joined:
    Jul 24, 2014
    Posts:
    19
    Hello @manpower13 ,

    Could you tell us more about your class to create a graphic, inherits from the new UI system please? And if you wish, to share some code?

    Indeed, I also work on a way to create a graphic from the new UI system without Line Renderer.

    Thank you :)
     
    Last edited: Jun 29, 2015
  16. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Hello @Kadaj

    I figured out it was too much work to create a good looking graph with nice legends. Therefore I simply bought the plugin
    Graph Maker from Stuart S.

    But if you want to achieve what I had made by myself I will share the code! Hope you can learn something of it :).

    I have not made many comments to explain how it works because I have no time.
    If you have any questions on how the code works or if you do not understand how to set it up, simply ask and I will try to answer!

    Sincerely,
    Floris Weers, WeersProductions

    (I am not sure if these were all the files, but I think this works)
     

    Attached Files:

  17. Kadaj

    Kadaj

    Joined:
    Jul 24, 2014
    Posts:
    19
    Hello @manpower13 ,

    Thank you for your answer. Indeed, I had also found the code named UILineRenderer who works very well in the following link: http://forum.unity3d.com/threads/new-ui-and-line-drawing.253772/

    Concerning your problem , I managed to place two captions aligned with each point of the UILineRenderer (one caption for each axis of the graph). To do this , I instantiated two Text prefabs (representing captions) for each value of vector2 and calculated the max and min value of the graph to determine a ratio that I assign to my text for to define his position and his size.

    However, I doubt that it is useful for you as you have invested in the plugin Graph Maker. ;)

    Anyway, thank you for your sharing.
     
  18. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    Hi @Kadaj

    Good you could fixed it. The problem for me was not calculating what values the legend should have. The problem was updating the text in the legend in the editor. I still do not know how to properly do this. When instantiating an object in the editor and editing his text component in the same frame, the editor pops up with errors.

    Could you show, if you want, some of your code where you edit the text components?

    Thank you in advance :)

    Sincerely,
    Floris Weers, WeersProductions
     
  19. Kadaj

    Kadaj

    Joined:
    Jul 24, 2014
    Posts:
    19
    Um okay, I think I have a little better understood your problem.

    Therefore , I do not think having successfully fix your problem. I instantiated my legends during the runtime and I never modify the size of my graph. Moreover, I did not create a custom editor class.

    Sorry to have badly understood your problem.
     
  20. manpower13

    manpower13

    Joined:
    Dec 22, 2013
    Posts:
    140
    @Kadaj
    Thank you for your fast reply.
    Ah I see, no problem. If you ever find out how to do it, could you leave a message? I would appreciate that :).