Search Unity

OnPreprocessTexture not setting the spritePivot correctly?

Discussion in '2D' started by CyberMew, Mar 3, 2014.

Thread Status:
Not open for further replies.
  1. CyberMew

    CyberMew

    Joined:
    May 18, 2013
    Posts:
    23
    I am automating the texture2d imports to set the Sprite's Pivot from Center to Bottom.
    Code (csharp):
    1. textureImporter.spritePivot = new Vector2(0.5f, 0f);
    I then checked the meta file, which appears to be correct. However, back in the editor, the texture import settings remain as Center! It does not show Custom or anything else. When I drag the texture into scene, the pivot point is still center!

    Is there something I must do to "refresh" it or is this a bug?
     
  2. JakeUken

    JakeUken

    Joined:
    Apr 15, 2014
    Posts:
    2
    I have the same issue. If you view/modify the meta data for the file, you'll notice that what you really want to change for the sprites "pivot" is called "alignment" in the meta file. Unfortunately, there does not seem to be any "alignment" property of the TextureImporter. I'm about to break down and modify the meta file directly. Any one know better?
     
  3. CyberMew

    CyberMew

    Joined:
    May 18, 2013
    Posts:
    23
    I've managed to solved it. I am not near my computer now but I'll post the codes later. Post here again to remind me if I don't reply within 24 hours.
     
  4. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,191
    Hello @CyberMew,

    How did you solve this? I am trying to do the same, except I am setting the pivot to Bottom Left, which should be new Vector2(0f, 0f). The pivot will not change from Center however.

    Thanks!
     
  5. CyberMew

    CyberMew

    Joined:
    May 18, 2013
    Posts:
    23
    I solved it 2 days after I posted the question. I found out that you cannot directly adjust the value, and you have to do so using another variable. I cannot remember it off the top of my head, and am not sure if there are any changes with the newer Unity versions since I haven't been touching it for a few months now, but anyway I'll post the code snippet tomorrow - it's 12am here. Remind me again if I don't!
     
  6. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,191
    Okay, sounds good; I really appreciate it @CyberMew !
     
  7. CyberMew

    CyberMew

    Joined:
    May 18, 2013
    Posts:
    23
    Here you go, hope it helps..

    TextureImporter textureImporter = assetImporter as TextureImporter;

    TextureImporterSettings tis = new TextureImporterSettings();
    textureImporter.ReadTextureSettings(tis);
    // your Custom settings
    tis.spriteMode = 1;
    tis.spritePixelsToUnits = 72f;
    tis.spritePivot = new Vector2(0.5f, 0.5f);
    tis.spriteExtrude = 1;
    tis.filterMode = FilterMode.Point;
    tis.wrapMode = TextureWrapMode.Clamp;
    textureImporter.textureType = TextureImporterType.Sprite;

    textureImporter.SetTextureSettings(tis);
     
  8. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,191
    Unfortunately the sprite pivot still doesn't get set with this code. Perhaps they changed something with the newer versions of Unity. It's not a big deal thankfully, as I've already imported most of my textures.

    I'll submit a bug report on this issue.

    Thanks for taking the time to find the code though!
     
  9. Luxalpa

    Luxalpa

    Joined:
    May 13, 2014
    Posts:
    8
    This one worked for me:

    Code (CSharp):
    1.     void setPivotsBottom()
    2.     {
    3.         Object[] textures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
    4.         foreach(Texture2D tex in textures) {
    5.             string path = AssetDatabase.GetAssetPath(tex);
    6.             TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
    7.             TextureImporterSettings settings = new TextureImporterSettings();
    8.             textureImporter.ReadTextureSettings(settings);
    9.             settings.spriteAlignment = (int)SpriteAlignment.BottomCenter;
    10.             textureImporter.SetTextureSettings(settings);
    11.             AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
    12.         }
    13.     }
     
  10. Dreoh

    Dreoh

    Joined:
    Aug 15, 2012
    Posts:
    15
    See
    I'm trying to get this to work for me but I guess the spritePivot setting literally just doesn't get saved. Anything outside of a pivot of (0.5f, 0.5f) doesn't work, it just always defaults to (0.5f, 0.5f)

    I'm trying to get a pivot of (0.5f, 0.08f), but none of the many suggestions I've seen everywhere I've looked have worked.

    And using the alignment setting won't work for me either because I don't want to set the pivot to any of the preset pivots in the alignment settings.
     
  11. Dreoh

    Dreoh

    Joined:
    Aug 15, 2012
    Posts:
    15
    I guess to better help people understand what I'm dealing with, this is my code. I'm essentially trying to set the names of all sprites in spritesheets for easy referencing and setup using the LPC spritesheets found here http://gaurav.munjal.us/Universal-LPC-Spritesheet-Character-Generator/ to test.

    Everything works fine except for setting the pivot. The pivots are always .5, .5 no matter what I do. The debugs even show the correct information at all steps.


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class NameSpritesAutomatically : MonoBehaviour {
    7.     [MenuItem("Sprites/Rename Sprites")]
    8.     static void SetSpriteNames() {
    9.         int[] FramesCount = new int[] { 6, 7, 8, 5, 12, 5};
    10.         string[] FramesName = new string[] { "cast", "stab", "walk", "slash", "bow", "die" };
    11.      
    12.         foreach (Texture2D texture in Resources.LoadAll<Texture2D>("LPC/")) {
    13.             Slice(texture, FramesCount, FramesName);
    14.         }
    15.     }
    16.  
    17.     static void Slice(Texture2D texture, int[] framesCount, string[] framesName) {
    18.         int animAmount = framesCount.Length;
    19.         string path = AssetDatabase.GetAssetPath(texture);
    20.         TextureImporter texImporter = AssetImporter.GetAtPath(path) as TextureImporter;
    21.  
    22.         int uRow = 0;
    23.         int lRow = 1;
    24.         int dRow = 2;// 24;
    25.         int rRow = 3;// 36;
    26.  
    27.         texImporter.isReadable = true;
    28.  
    29.         List<SpriteMetaData> newData = new List<SpriteMetaData>();
    30.  
    31.         for (int y = 0; y < animAmount; y++) {
    32.             int row = y * 4;
    33.             for (int x = 1; x < framesCount[y] + 1; x++) {
    34.                 if (framesName[y] == "die") {
    35.                     newData.Add(SliceRow(texture, framesName[y], x, row + uRow, ""));
    36.                 } else {
    37.                     newData.Add(SliceRow(texture, framesName[y], x, row + uRow, "_u"));
    38.                     newData.Add(SliceRow(texture, framesName[y], x, row + dRow, "_d"));
    39.                     newData.Add(SliceRow(texture, framesName[y], x, row + lRow, "_l"));
    40.                     newData.Add(SliceRow(texture, framesName[y], x, row + rRow, "_r"));
    41.                 }
    42.             }
    43.         }
    44.  
    45.         Debug.Log(newData.Count);
    46.         for (int i = 0; i < newData.Count; i++) {
    47.             Debug.Log(newData[i].name);
    48.             Debug.Log(newData[i].pivot);
    49.         }
    50.  
    51.         TextureImporterSettings texImporterSettings = new TextureImporterSettings();
    52.         texImporter.ReadTextureSettings(texImporterSettings);
    53.         texImporterSettings.spritePixelsPerUnit = 64f;
    54.         texImporterSettings.spritePivot = new Vector2(0.5f, 0.08f); ;
    55.         texImporterSettings.spriteMode = 1;
    56.         texImporterSettings.spriteExtrude = 1;
    57.         texImporterSettings.filterMode = FilterMode.Point;
    58.         texImporterSettings.wrapMode = TextureWrapMode.Clamp;
    59.         texImporterSettings.textureType = TextureImporterType.Sprite;
    60.         texImporter.SetTextureSettings(texImporterSettings);
    61.  
    62.         if (texImporter.spriteImportMode == SpriteImportMode.Multiple) {
    63.             // Bug? Need to convert to single then back to multiple in order to make changes when it's already sliced
    64.             texImporter.spriteImportMode = SpriteImportMode.Single;
    65.             AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
    66.         }
    67.  
    68.         texImporter.spriteImportMode = SpriteImportMode.Multiple;
    69.         texImporter.spritesheet = newData.ToArray();
    70.         AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
    71.     }
    72.  
    73.     static SpriteMetaData SliceRow(Texture2D texture, string frameName, int x, int row, string appendix) {
    74.         Debug.Log(texture.name + " : " + frameName + " : " + x + " : " + row + " : " + appendix);
    75.         int SliceWidth = 64;
    76.         int SliceHeight = 64;
    77.  
    78.         Vector2 pivot = new Vector2(0.5f, 0.08f);
    79.  
    80.         SpriteMetaData smd = new SpriteMetaData();
    81.         smd.pivot = pivot;
    82.         smd.name = frameName + appendix + "_" + (x);
    83.         Debug.Log(smd.pivot);
    84.         smd.rect = new Rect(x * SliceWidth, texture.height - row * SliceHeight - SliceHeight, SliceWidth, SliceHeight);
    85.  
    86.         return smd;
    87.     }
    88. }
     
  12. Dreoh

    Dreoh

    Joined:
    Aug 15, 2012
    Posts:
    15
    I figured it out after coming back to it months later and seeing some other threads.

    You have to add
    texImporterSettings.spriteAlignment = (int)SpriteAlignment.Custom;

    to first set the importer to custom pivots

    then in your spritemetadata you have to set
    smd.alignment = 9;


    Here's the working code if you need to see it in use.


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.IO;
    6.  
    7. public class NameSpritesAutomatically : MonoBehaviour {
    8.    
    9.     static string ignoreListPath = "Assets/Resources/Editor/spriteSliceIgnoreList.txt";
    10.     static char ignoreListSplitSeperator = '%';
    11.  
    12.     [MenuItem("Sprites/Rename Sprites")]
    13.     static void SetSpriteNames() {
    14.         List<string> ignoreList = ReadSpriteSheetIgnoreList();
    15.  
    16.         int[] FramesCount = new int[] { };
    17.         string[] FramesName = new string[] { };
    18.  
    19.         string ignoreListString = "";
    20.         foreach (Texture2D texture in Resources.LoadAll<Texture2D>("LPC/")) {
    21.             bool bOversize = false;
    22.             if (texture.width == 1152) {
    23.                 FramesCount = Constants.OversizeFramesCount; //new int[] { 5 };
    24.                 FramesName = Constants.OversizeFramesName; //new string[] { "slash" };
    25.                 bOversize = true;
    26.             } else {
    27.                 FramesCount = Constants.FramesCount; //new int[] { 6, 7, 8, 5, 12, 5 };
    28.                 FramesName = Constants.FramesName;    //new string[] { "cast", "stab", "walk", "slash", "bow", "die" };              
    29.             }
    30.  
    31.             bool bIgnore = false;
    32.             for (int i = 0; i < ignoreList.Count; i++)
    33.                 if (ignoreList[i] == texture.name)
    34.                     bIgnore = true;
    35.             if (!bIgnore)
    36.                 Slice(texture, FramesCount, FramesName, bOversize);
    37.  
    38.             ignoreListString += texture.name + ignoreListSplitSeperator;
    39.         }
    40.  
    41.         WriteSpriteSheetIgnoreList(ignoreListString);
    42.     }
    43.  
    44.     static void Slice(Texture2D texture, int[] framesCount, string[] framesName, bool bOversize) {
    45.         int animAmount = framesCount.Length;
    46.         string path = AssetDatabase.GetAssetPath(texture);
    47.         TextureImporter texImporter = AssetImporter.GetAtPath(path) as TextureImporter;
    48.  
    49.         int sliceWidth = Constants.sliceWidth;    //64;
    50.         int sliceHeight = Constants.sliceHeight; //64;
    51.         if (bOversize) {
    52.             sliceWidth = Constants.oversizeSliceWidth;  //192;
    53.             sliceHeight = Constants.oversizeSliceHeight;  //192;
    54.         }
    55.  
    56.         int uRow = Constants.uRow;
    57.         int lRow = Constants.lRow;
    58.         int dRow = Constants.dRow;// 24;
    59.         int rRow = Constants.rRow;// 36;
    60.  
    61.         texImporter.isReadable = true;
    62.  
    63.         List<SpriteMetaData> newData = new List<SpriteMetaData>();
    64.  
    65.         for (int y = 0; y < animAmount; y++) {
    66.             int row = y * 4;
    67.             for (int x = 1; x < framesCount[y] + 1; x++) {
    68.                 if (framesName[y] == "die") {
    69.                     newData.Add(SliceRow(texture, framesName[y], x, row + uRow, ""));
    70.                 } else {
    71.                     newData.Add(SliceRow(texture, framesName[y], x, row + uRow, "_u", sliceWidth, sliceHeight));
    72.                     newData.Add(SliceRow(texture, framesName[y], x, row + dRow, "_d", sliceWidth, sliceHeight));
    73.                     newData.Add(SliceRow(texture, framesName[y], x, row + lRow, "_l", sliceWidth, sliceHeight));
    74.                     newData.Add(SliceRow(texture, framesName[y], x, row + rRow, "_r", sliceWidth, sliceHeight));
    75.                 }
    76.             }
    77.         }
    78.  
    79.         TextureImporterSettings texImporterSettings = new TextureImporterSettings();
    80.         texImporter.ReadTextureSettings(texImporterSettings);
    81.         texImporterSettings.spriteAlignment = (int)SpriteAlignment.Custom;
    82.         texImporter.SetTextureSettings(texImporterSettings);
    83.         texImporterSettings.spritePixelsPerUnit = 32;
    84.         texImporterSettings.spritePivot = new Vector2(0.5f, 0.08f); ;
    85.         texImporterSettings.spriteMode = 1;
    86.         texImporterSettings.spriteExtrude = 1;
    87.         texImporterSettings.spriteMeshType = SpriteMeshType.FullRect;
    88.         texImporterSettings.filterMode = FilterMode.Point;
    89.         texImporterSettings.wrapMode = TextureWrapMode.Clamp;
    90.         texImporterSettings.textureType = TextureImporterType.Sprite;
    91.         texImporter.SetTextureSettings(texImporterSettings);
    92.  
    93.         if (texImporter.spriteImportMode == SpriteImportMode.Multiple) {
    94.             // Bug? Need to convert to single then back to multiple in order to make changes when it's already sliced
    95.             texImporter.spriteImportMode = SpriteImportMode.Single;
    96.             AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
    97.         }
    98.  
    99.         texImporter.spriteImportMode = SpriteImportMode.Multiple;
    100.         texImporter.spritesheet = newData.ToArray();
    101.         AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
    102.     }
    103.  
    104.     static SpriteMetaData SliceRow(Texture2D texture, string frameName, int x, int row, string appendix, int sliceWidth = 64, int sliceHeight = 64) {
    105.         Debug.Log(texture.name + " : " + frameName + " : " + x + " : " + row + " : " + appendix);
    106.  
    107.         Vector2 pivot = new Vector2(0.5f, 0.08f);
    108.  
    109.         SpriteMetaData smd = new SpriteMetaData();
    110.         smd.alignment = 9;
    111.         smd.pivot = pivot;
    112.         smd.name = frameName + appendix + "_" + (x);
    113.         Debug.Log(smd.pivot);
    114.         smd.rect = new Rect(x * sliceWidth, texture.height - row * sliceHeight - sliceHeight, sliceWidth, sliceHeight);
    115.  
    116.         return smd;
    117.     }
    118.  
    119.  
    120.  
    121.     static void WriteSpriteSheetIgnoreList(string ignoreListString) {
    122.         //Write some text to the test.txt file
    123.         StreamWriter writer = new StreamWriter(ignoreListPath, false);
    124.         writer.WriteLine(ignoreListString);
    125.         writer.Close();
    126.  
    127.         //Re-import the file to update the reference in the editor
    128.         AssetDatabase.ImportAsset(ignoreListPath);
    129.         TextAsset asset = Resources.Load("Editor/spriteSliceIgnoreList") as TextAsset;
    130.  
    131.         //Print the text from the file
    132.         Debug.Log(asset.text);
    133.     }
    134.  
    135.     static List<string> ReadSpriteSheetIgnoreList() {
    136.         //Read the text from directly from the test.txt file
    137.         StreamReader reader = new StreamReader(ignoreListPath);
    138.         List<string> ignoreList = new List<string>(reader.ReadToEnd().Split(ignoreListSplitSeperator));
    139.         reader.Close();
    140.  
    141.         return ignoreList;
    142.     }
    143.  
    144.     [MenuItem("Sprites/Clear Ignore List")]
    145.     static void ClearSpriteSheetIgnoreList() {
    146.         WriteSpriteSheetIgnoreList(" ");
    147.     }
    148. }
     
  13. gabgab06

    gabgab06

    Joined:
    Mar 14, 2018
    Posts:
    3
    Thank you!
     
  14. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,474
    Please use the "Like" button to show appreciation as you don't end up necroing threads.

    Thanks.
     
Thread Status:
Not open for further replies.