Search Unity

How to get pivot point of sprite in script?

Discussion in '2D' started by sonee, Dec 12, 2013.

  1. sonee

    sonee

    Joined:
    Sep 2, 2012
    Posts:
    18
    The Sprite class has public variables, but it seems that there is no variable to get pivot point that have been set in SpriteEditor. I tried to infer the pivot point from other rect variables, but they might not be related to it. any way to get it or calculate it?
     
  2. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    You can access the bounds property of the sprite renderer which will give you both center and extents of the sprite.

    Code (csharp):
    1.  
    2. void Start () {
    3.         SpriteRenderer sr = GetComponent<SpriteRenderer>();
    4.         Debug.Log(sr.bounds);        
    5. }
    6.  
     
    PHL1 likes this.
  3. sonee

    sonee

    Joined:
    Sep 2, 2012
    Posts:
    18
    Thanks!

     
  4. rgbDreamer

    rgbDreamer

    Joined:
    Jan 28, 2013
    Posts:
    4
    Really, that helped you? The center is not the same as the pivot point.

     
  5. unitylover

    unitylover

    Joined:
    Jul 6, 2013
    Posts:
    346
    You must calculate the pivot yourself based on the center. The following code will return a vector of the center of the sprite according to it's pivot point. From there you can do some math to figure out which pivot point it's using. Try it out and see for yourself. Just put the below code attached to a sprite and move the pivot point.

    Code (csharp):
    1.  
    2. SpriteRenderer sr = GetComponent<SpriteRenderer>();
    3. Debug.Log( sr.sprite.bounds.center.normalized );
    4.  
     
  6. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    They've said they'd expose a center of mass property soon (TM) in a future update.
     
    Last edited: Feb 19, 2014
  7. yllfever

    yllfever

    Joined:
    Jan 16, 2014
    Posts:
    2
    Hi, just for those who is still struggling on this problem.

    Here is how I did it in the editor mode.

     
  8. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
    The center of mass is not necessarily the pivot point that you want.
     
    neonblitzer and v01pe_ like this.
  9. TrevorP

    TrevorP

    Joined:
    Aug 18, 2013
    Posts:
    5
    Can you elaborate on the math part of this? The bounds.center.normalized seems to be a normalized vector relative to the (0.5,0.5) center of the sprite.rect. I'm not sure how to get the custom pivot Vector2 from this. Is it possible?
     
    neonblitzer and v01pe_ like this.
  10. mike_GAL

    mike_GAL

    Joined:
    Aug 25, 2013
    Posts:
    1
    Hi

    I've been struggling with this for a while now and just can't seem to find a solution. It looks to me like there is no way to access the custom pivot point of a sprite via script. If anyone knows otherwise please can you post here or point me in the right direction to find a way to do this?

    Thanks

    Mike
     
  11. Peacewise

    Peacewise

    Joined:
    Feb 27, 2014
    Posts:
    52
    The location of the pivot point is just the location of the gameObject itself. But I'm assuming you might be having trouble with what I was struggling with, which is that I wanted to position a sprite based on its actual center, not the pivot point. So I needed the offset between the two. To get that, you use two pieces of information:

    1) gameObject.transform.position; // The world position of the pivot point
    2) GetComponent<SpriteRenderer>().bounds.center; // This is the world position of the center of the sprite (not the same as the pivot unless you left the pivot alone)

    Then to get the offset, you just subtract (1) - (2). Then you would apply that offset to the sprite's position if you wanted to relocate the sprite based on the center rather than the pivot. For example, here's what I'm doing in my code to center a sprite based on its visible center, not its pivot (which is lower on the sprite):

    Code (csharp):
    1.  
    2.         SpriteRenderer renderer = GetComponent<SpriteRenderer>();
    3.         Vector3 pivotOffsetWorldSpace = transform.position - renderer.bounds.center;
    4.        
    5.         //    Now offset the sprite by the pivot difference that we found
    6.         transform.position = new Vector3(
    7.             transform.position.x + pivotOffsetWorldSpace.x,
    8.             transform.position.y + pivotOffsetWorldSpace.y,
    9.             transform.position.z
    10.             );
     
    Last edited: Apr 7, 2014
    neonblitzer, tbriz and Kurius like this.
  12. kipu

    kipu

    Joined:
    Apr 4, 2014
    Posts:
    1
    I was unable to calculate pivot-vector with method supposed by you.


    'Pivot-vector' I mean is represented at YAML of graphic-file (imported texture) asset.
    Here's appropriate string from one of my *.png.meta ('png' is here for example only):
    Code (csharp):
    1.  
    2.   spritePivot: {x: .5, y: .5}
    3.  
    If shows that spite pivot is something like object of 'Vector2'-class with x is in [0, 1] interval y is in [0, 1] also.
    This one pivot is 'Center' (not 'TopLeft' or other).


    Here's solution that works for me:
    Code (csharp):
    1.  
    2.         Bounds bounds = obj.GetComponent<SpriteRenderer>().bounds;
    3.         Vector2 position = obj.transform.position;
    4.         Vector2 min = bounds.min;
    5.         Vector2 size = bounds.size;
    6.         Vector2 offsetOfAbsolutePositionRelativelyToMinOfBounds = position - min;
    7.         Vector2 pivotVector =
    8.                 new Vector2(
    9.                         offsetOfAbsolutePositionRelativelyToMinOfBounds.x
    10.                                 /
    11.                               size.x,
    12.                         offsetOfAbsolutePositionRelativelyToMinOfBounds.y
    13.                                 /
    14.                               size.y
    15.                 );
    16.  
    Code is in specific code-style, but the main idea must be clear.
    Subtraction of appropriate vectors (position - min) normalization of coordinates to 1 must work.
     
  13. takezoux2

    takezoux2

    Joined:
    Jul 4, 2014
    Posts:
    1
    You can calculate pivot value shown in the SpriteEditor by the below code.

    Code (CSharp):
    1. Sprite sprite = ...;// Get sprite
    2. Bounds bounds = sprite.bounds;
    3. var pivotX = - bounds.center.x / bounds.extents.x / 2 + 0.5f;
    4. var pivotY = - bounds.center.y / bounds.extents.y / 2 + 0.5f;
    5. var pixelsToUnits = sprite.textureRect.width / bounds.size.x;
    6.  
    7. Sprite sameSprite = Sprite.Create(sprite.texture,sprite.rect,
    8.                                      new Vector2(pivotX,pivotY),
    9.                                      pixelsToUnits);
     
    Last edited: Jul 4, 2014
    mcaisw, kbartek, tylkomat and 2 others like this.
  14. st33d

    st33d

    Joined:
    Jan 22, 2014
    Posts:
    28
    The value of the pivot point is sprite.bounds.min.

    If I have a 8x8 pixel sprite with the pivot at the center, sprite.bounds.min gives me (-4.0, -4.0, -0.1)

    With the pivot point at bottom left I get: (0.0, 0.0, -0.1)

    With the pivot point at top right I get: (-8.0, -8.0, -0.1)

    As you can see. All sprites are actually anchored bottom left, with bounds.min offsetting them. I do not need to instantiate a SpriteRenderer to get these values.
     
    Jinja and numberkruncher like this.
  15. Suika

    Suika

    Joined:
    Nov 19, 2013
    Posts:
    33

    Thank!! This help a lot!!!
     
  16. hexdump

    hexdump

    Joined:
    Dec 29, 2008
    Posts:
    443
    From Unity 5 "what's new" docs

    Improvements

    2D
    • Added Sprite.pivot getter.
    • Sprite geometry can now be overridden using Sprite.OverrideGeometry(Vector2[] vertices, UInt16[] triangles).
    • SpritePacker: Atlas texture name will now also contain the atlas name.
    • The new AssetPostprocessor.OnPostprocessSprites(Texture2D texture, Sprite[] sprites) is called immediately after OnPostprocessTexture when sprites are generated
    Cheers
     
  17. baranoob

    baranoob

    Joined:
    Jan 26, 2015
    Posts:
    1
    kipu's code also works in my situation. Thanks a lot kipu.

    Cheers.

     
  18. ATeyken

    ATeyken

    Joined:
    Jul 28, 2015
    Posts:
    2
    I had a lot of sprites that needed a pivot 15 pixels over the image bottom center x axis, this Editor script worked for me:


    using UnityEngine;
    using UnityEditor;

    public class MenuItems : MonoBehaviour
    {

    [MenuItem("Sprites/Set Pivot(s)")]
    static void SetPivots()
    {

    Object[] textures = GetSelectedTextures();

    Selection.objects = new Object[0];
    foreach (Texture2D texture in textures)
    {
    string path = AssetDatabase.GetAssetPath(texture);
    TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter;
    //var w = texture.width;
    var h = texture.height;

    var py = 1 - (float)(h - 15) / h;
    ti.spritePivot = new Vector2(0.5f, py);
    AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
    }
    Debug.Log("Set pivots " + textures.Length + " textures");
    }

    static Object[] GetSelectedTextures()
    {
    return Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
    }
    }​
     
  19. mcaisw

    mcaisw

    Joined:
    Aug 15, 2017
    Posts:
    9
    Works great for me