Search Unity

how to detect edge of image using the Fill Amount?

Discussion in 'UGUI & TextMesh Pro' started by lancekidd, Mar 16, 2017.

  1. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    Is there a way to detect where the edge is of a sprite being horizontally/vertically filled? I have a circular health bar that gets depleted by vertically filling the sprite, but I would like to add "icon" on the top of the bar that follow the edge. Is this possible?
     
  2. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    this should be easy to calculate. put your "icon" inside you image which is depleted.
    in code set the anchorMin and anchorMax Y values to the amount of fill (a value between 0 and 1) and the anchoredPosition to zero.

    you can adjust the actual offset by changing the pivot of your "icon".
     
  3. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    hi @Hosnkobf, thanks for the tip, but Im having trouble in the code .I used to follow your instruction so my code ended up below.

    Code (CSharp):
    1.  
    2. void Awake()
    3.     {
    4.         icon = GetComponent<Image> (); // the parent image or the circular health bar
    5.         imgRect = GetComponent<RectTransform> ();
    6.         edgeRect = transform.GetChild (0).GetComponent<RectTransform> (); // the icon to display at the edge of filled                 image
    7.     }
    8.  
    9.  
    10.  
    11.         float fillAmount = icon.fillAmount;
    12.  
    13.         edgeRect.anchorMin.x = fillAmount;
    14.         edgeRect.anchorMin.y = fillAmount;
    15.         edgeRect.anchoredPosition.x = 0;
    16.         edgeRect.anchoredPosition.y = 0;

    This got me an error
    Cannot modify a value type return value of `UnityEngine.RectTransform.anchorMin'. Consider storing the value in a temporary variable

    Please see attach image for reference. Thank you
     

    Attached Files:

  4. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    anchor min / max and position are of type Vector2. Vector2 is a struct - this means it is passed by value (copy). The variables can only accessed per getter / setter. if you get the variable to set the x or y value you get a copy, so you do not change the actual value. that is why the compiler says no.

    You also have a bug in your code. you need to set the anchor min AND max in only one direction.

    this should work:
    Code (CSharp):
    1.         edgeRect.anchorMin = new Vector2(edgeRect.anchorMin.x, fillAmount);
    2.         edgeRect.anchorMax = new Vector2(edgeRect.anchorMax.x, fillAmount)      
    3.         edgeRect.anchoredPosition = Vector2.zero;
     
  5. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    Hi sir I tried your code but the icon is not moving circular, instead it moves horizontal, from up to down
     
  6. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    You change z rotation value of circular health bar from 0 - 360
     
  7. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    Hi @BiDuc, I will try your solution. I'll update you asap.Thank you so much
     
  8. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    Hi @BiDuc , the icon is moving vertical, from up to down :(
     
  9. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    Do you want it like:
     
  10. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    I want it like this sir.
     

    Attached Files:

  11. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    Here you are


    Code (CSharp):
    1.  
    2.     public Image _bar;//Bar
    3.     public RectTransform _button;//Button-Container
    4.     void HealthChange(float amount){
    5.         float buttonAngle = amount * 360;
    6.         _button.eulerAngles = new Vector3(0, 0, -buttonAngle);
    7.     }
    Call function:
    Code (CSharp):
    1. HealthChange(_bar.fillAmount);
    Demo:
     
    Last edited: Mar 20, 2017
    hms0589 and MaratG2 like this.
  12. lancekidd

    lancekidd

    Joined:
    Mar 5, 2017
    Posts:
    13
    Hi sir thanks for your reply. I will now try it :). Thank you so much
     
  13. mateofDean

    mateofDean

    Joined:
    Mar 28, 2017
    Posts:
    5
    Hello sir @BiDuc and sir @lancekidd . How about moving the icon in 190 degrees in a arc image?I found this thread very useful and I reuse your code. I changed
    Code (CSharp):
    1. float buttonAngle = amount * 360;
    to
    Code (CSharp):
    1. float buttonAngle = amount * 190;
    but the icon is not rotating. How can I solve this sir? thanks. I want to achieve something like in the image below.
     

    Attached Files:

    • arc.png
      arc.png
      File size:
      1.6 KB
      Views:
      1,335
  14. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    You just clamp fillAmount value of image
    Code (CSharp):
    1. _bar.fillAmount = Mathf.Clamp(_fillAmountValue, 0, 190.0f/360);
     
  15. mateofDean

    mateofDean

    Joined:
    Mar 28, 2017
    Posts:
    5
    Is this the correct code sir?

    Code (CSharp):
    1.  public Image _bar;//Bar
    2.     public RectTransform _button;//Button-Container
    3.     void HealthChange(float amount){
    4.         float amount = _bar.fillAmount = Mathf.Clamp(_fillAmountValue, 0, 190.0f/360);
    5.         float buttonAngle = amount * 360;
    6.         _button.eulerAngles = new Vector3(0, 0, -buttonAngle);
    7.     }
     
  16. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    I mean you just control the value pass on fillAmount from 0 to 190/360.
    For example if you want to make a health bar the value varies from 0 to 100
    You will write code like this:
    Code (CSharp):
    1.     public Image _bar;//Bar
    2.     public RectTransform _button;//Button-Container
    3.  
    4.     void HealthChange(float healthValue){//health:0->100
    5.         float amount = (healthValue/100.0f) * 190.0f/360;
    6.         _bar.fillAmount = amount;
    7.         float buttonAngle = amount * 360;
    8.         _button.eulerAngles = new Vector3(0, 0, -buttonAngle);
    9.     }
     
  17. mateofDean

    mateofDean

    Joined:
    Mar 28, 2017
    Posts:
    5
    Hi sir I tried your code but still the icon not following the edge of filled image :(
     
  18. mateofDean

    mateofDean

    Joined:
    Mar 28, 2017
    Posts:
    5
    I just want to achieve this sir
     

    Attached Files:

    • arc1.png
      arc1.png
      File size:
      1.7 KB
      Views:
      1,203
  19. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    I think you will hardly visualize the words so I created a short tutorial video for you:
     
    G76Dev, Rsl081, NecroToad and 5 others like this.
  20. THREEWGAMESTEKNOLOJIANONIMSIRKETI

    THREEWGAMESTEKNOLOJIANONIMSIRKETI

    Joined:
    Dec 31, 2016
    Posts:
    14
    Hi,
    How can we make this horizontally.
     
  21. RadioactiveChickenGames1

    RadioactiveChickenGames1

    Joined:
    Sep 29, 2020
    Posts:
    15
    Zonlib,
    I have been scouring the Internet for a design like this so I can use it as a health bar in my game, and here you are with exactly what I want. I commend you for having found or crated this! I have just one question: how did you do this and how can I implement it in my game?
    Thanks a ton!
     
  22. Zonlib

    Zonlib

    Joined:
    Apr 15, 2014
    Posts:
    39
    Can you please be more specific?
     
  23. RadioactiveChickenGames1

    RadioactiveChickenGames1

    Joined:
    Sep 29, 2020
    Posts:
    15
    I actually found out how to do that already, but thanks for answering!
     
  24. Rsl081

    Rsl081

    Joined:
    Jun 10, 2020
    Posts:
    3
    My hero! Thankyou so much!
     
  25. itorrri

    itorrri

    Joined:
    Feb 12, 2021
    Posts:
    2
    wow, very elegant and smart, I admire!
     
    Hosnkobf likes this.