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 /
  • Help Room /
avatar image
1
Question by mephistoII666 · Aug 28, 2020 at 12:15 AM · spriteasset2d animationassetdatabaseeditor scripting

How to modify a sprite asset's animation2d bone and weights through editor scripts

Greetings unity communitiy!

I am using the official animation2d package. I need to rig a sprite's bone structure through an editor script. So I need to persist the asset modifications to the project files.

I have managed to read the sprite's mesh, bones, and weight data perfectly fine through the SpriteDataAccessExtensions extension methods. I have also managed to compose the desired bone list, and corresponding weight VertexAttribute lists.

However, writing those attributes to the sprite asset through sprite.SetBones() and sprite.SetVertexAttribute() doesn't seem to be persisted to the asset. After executing the editor script, the original sprite is unaltered.

I assume the problem may be I am trying to write an in-memory instance of the asset (instead of the asset itself), as I'm accessing the sprite through a serialized property in a monobehaviour with an editor script.

Highlighted sprite is modified upon pressing the button and executing the editor script.
Pressing the button calls the following extension method on the sprite serialized on the monobehaviour.

 public static class SpriteRiggingExtensions
 {    //Extension method modifying the Sprite class
     public static void BonesFromVertexList (this Sprite _this, string boneBaseName)
     {
         //iterate through the vertex list creating corresponding bones and weights
         NativeSlice<Vector3> vertexList = _this.GetVertexAttribute<Vector3>(VertexAttribute.Position);
         //create lists to hold created bones and weights
         SpriteBone[] boneList = new SpriteBone[vertexList.Length];
         BoneWeight[] weightList = new BoneWeight[vertexList.Length];
 
         //loop over vertex list
         for (int i = 0, iLimit = vertexList.Length; i < iLimit; i++)
         {
             boneList[i] = CreateBoneForVertex(i, boneBaseName, vertexList[i]);
             weightList[i] = CreateSimpleVertexWeight(i);
         }
 
     //apply the lists of bones and weights to the sprite
         _this.SetBones(boneList);
         _this.SetVertexAttribute<BoneWeight>(VertexAttribute.BlendWeight, new NativeArray<BoneWeight>(weightList, Allocator.Temp));
 
         AssetDatabase.CreateAsset(_this, "Assets/Tmp/GeneratedAss.asset");
     }
     private static SpriteBone CreateBoneForVertex (/**/) {/* Create a bone */} 
     private static BoneWeight CreateSimpleVertexWeight (/**/) {/* Create weight for bone & vertex */}
 }



So I need to persist the changes to the asset. Using AssetDatabase.CreateAsset() won't let me write a new asset arguing the same asset already exists (even if writing to a different path).

can't persist asset

I found no other apparent way to use AssetDatabase to alter an existing asset. So, How can I persist the sprite asset changes? Please, and thank you very much.

spriteskinrigger.png (19.9 kB)
cantstoreasset.png (14.8 kB)
Comment
Add comment
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

2 Replies

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

Answer by mephistoII666 · Dec 09, 2020 at 02:52 AM

Update: In the end I did not find how to do this within unity.

Since unity's .meta files are serialized in plain YAML (if serialization configured as plain text), I could bypass this by processing the .meta files through an external python script.

There I could read all the properties related to the sprite's asset serialization, such as the skinning rig, and re-write it as necessary. Then simply loading unity with the externally-altered assets.

At first it sounds daunting and dangerous messing with unity's files, but since YAML is human readable it's easy to get a hold of it. Now I've even gotten used to make small tweaks to my assets by simply altering the .meta files with sublime text. It's easy as long as you are careful to respect tabulation, as YAML formatting is tabulation-based.

Comment
Add comment · Show 5 · 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 Dan_Stradh · Dec 09, 2020 at 03:56 AM 0
Share

I could try that, would you be able to explain me or give me an example ? I would need to modify the same things. Bones [] and weight [] to be able to have persistent changes. I made a small tool to override parts of a generic white psb, and when I make a new skin with, let's say a new shirt, the moment I set the bones with the bones and weight it works, but not when I press play. So yeah if you could give me an example of what you did, it would be really appreciated =)

avatar image mephistoII666 Dan_Stradh · Dec 09, 2020 at 11:10 AM 0
Share

The specifics of meta files vary depending on asset type. In this case (Sprites with animation2d skinning properties) you need bone data and mesh vertex weight data.

The yaml format for the corresponding meta files is the following: [comments in square brackets]

 TextureImporter:
   [...]
   spriteSheet:
     bones:
     - length: [float > bone length in units]
       position: { x: [float], y: [float], z: [float] }
       rotation: { x: [float], y: [float], z: [float], w: [float] }
       parentId: [int > index of the parent bone. The root bone's parentId is -1]
                        [A bone's index is its position within this list]
     - [...bone...]
     - [...bone...]
     [...]
     vertices:
     - {x: [float], y: [float]}
     - [...vertex...]
     - [...vertex...]
     [...]
     indices: [this defines the mesh's triangles. it should be a ushort array as in Sprite.triangles containing a multiple of 3 entries. each group corresponds to the indexes of each vertex of a single triangle]
     [...]
     weights: [a list containing as many entries as the vertices list. each entry defines weight for the vertex with the same index pointing to up to 4 bones and no more]
     - weight[0]: [float, defining the weight value for the first bone]
       weight[1]: [float, weight for 2nd bone]
       weight[2]: [float, weight for 3rd bone]
       weight[3]: [float, weight for 4th bone]
       boneIndex[0]: [int, index of the first bone]
       boneIndex[1]: [int, 2nd bone index]
       boneIndex[2]: [int, 3nd bone index]
       boneIndex[3]: [int, 4nd bone index]
     - [...weights...]
     - [...weights...]


You could alter this data anyway you want, even by hand. I just chose python as it offers native yaml support with full compliance. - Guide - PyYA$$anonymous$$L wiki

Please upvote if it helps you, and do let me know if you figure something else within unity!

avatar image mephistoII666 Dan_Stradh · Dec 09, 2020 at 11:12 AM 0
Share

Example of my solution: I had to create a bone for each vertex and correspondingly generate vertex weights

 #processes an individual file
 def processFile (filePath):
     try:
         print ("* Processing \"" + filePath + "\"");
         #check if file exists
         if (not os.path.isfile(filePath)):
             print ("! Nonexistent file")
             raise FileNotFoundError
 
         #move original file to backup location
         originalFilePath = moveToBackup (filePath)
 
         #read the file
         with open(originalFilePath) as file:
             fileContents = yaml.full_load(file)
             print ("  File read")
             #print (fileContents['TextureImporter']['spriteSheet']['vertices'])
             
             #process the contents
             fileContents['TextureImporter']['spriteSheet']['bones'] = boneListFromVertexList(fileContents['TextureImporter']['spriteSheet']['vertices'])
             fileContents['TextureImporter']['spriteSheet']['weights'] = weightListFromVertexList(fileContents['TextureImporter']['spriteSheet']['vertices'])
 
         #re-write the yaml to the original file path
             with open(filePath, 'w') as file:
                 yaml.dump(fileContents, file)
                 print ("  File written")
 
     #return true if success, false if failed
     except:
         print ("! Failure")
         print ("  ", sys.exc_info()[0])
         print ("  ", sys.exc_info()[1])
         return False
     else:
         print ("> Success")
         return True
avatar image Dan_Stradh mephistoII666 · Dec 09, 2020 at 01:42 PM 0
Share

Nice ! I'll try that today ! Do you call the python script from you c# script ? What did you use to call the python script ? Do you need a plugin or something ?

I don't know python that much...like where does your boneListFromVertexList comes from ? Here is my email ... danstradh@gmail.com

Show more comments
avatar image
0

Answer by Dan_Stradh · Dec 09, 2020 at 12:57 AM

Have you ever found out how to make it persist ?? Running into the same problem...

Comment
Add comment · Show 1 · 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 mephistoII666 · Dec 09, 2020 at 02:54 AM 0
Share

I wrote an accepted answer. Feel free to remove this answer to prevent clutter :)

Edit: if you are in need of further detail contact me or something and I can develop, but the specifics of editing a .meta file depend too much on what are you trying to do to write a full guide here

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

252 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Adding sprites to same layer as bone in 2D animation rig 1 Answer

Copy Bind Poses from Sprite in Runitme 0 Answers

Animation is overriding sprite 0 Answers

Precise animation issue with 2D sprites 0 Answers

Does Unity 2D count the whole asset as an object in the Rigid Body component even if it has a transparent space? 0 Answers


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