Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 /
avatar image
1
Question by Ben 40 · May 09, 2011 at 05:44 PM · animationmeshboneskinned-meshskinned

Dynamically instantiated skinned mesh not playing animations

I'm searching for a stop-gap solution to the problem described in these posts:

http://answers.unity3d.com/questions/7971/prefabs-workflow-changing-models-in-a-3d-app-after-they-have-been-used-in-a-pre

http://answers.unity3d.com/questions/27884/updating-a-prefab-fbx-or-animation-while-using-version-control-is-broken

Our artist is in the process of adding/removing bones to fit budget, and we don't want to have to go through the prefab creation process every time changes are made to the mesh. My hope is that I can write a script that will instantiate the necessary game objects from an FBX imported character model, the move these objects directly into an instance of our "character template" prefab.

I'm able to instantiate the mesh and move all of its children into the prefab, but when I do so, the skinned mesh does not animate. References to the animation field of our animation-handling component don't fail or throw warnings. Weirder still, when the root game object (with skinned mesh and bone transform hierarchy children) is selected and anything that changes the object's state is triggered from the editor, animations start working. For example, if I play an animation on the mesh from the animation viewer, or even just check and uncheck an inspector property on the Animation component, the driver we're using to determine which animations should play activates and functions correctly.

To explain a little more concretely:

We have a prefab in our library called Character_Prefab. This prefab has a bunch of gameplay and networking scripts attached to it, and no game object children.

We also have a mesh in our Art directory that we'll call Character_Mesh.

I've attached a script to Character_Prefab that takes has one inspector field, a transform that is supposed to point to the character mesh you want to appear on the prefab when it is created. In this case, this transform is the Character_Mesh object generated from the FBX import.

The small bit of script that executes this is as follows:

void OnEnable() { if(!_instantiated && gameObject != null) { if(_modelPrefab == null) { log.Error( "ModelPrefab hasn't been assigned a prefab! Please assign a mesh prefab to this character prefab's SpawnMesh component!" ); } else {

         Animation animationComponent = gameObject.GetComponent<Animation>();
         if(animationComponent == null) {
             log.MissingComponent(typeof(Animation));
         }

         Transform newMesh = (Transform)Instantiate(_modelPrefab, Vector3.zero, Quaternion.identity);
         newMesh.parent = gameObject.transform;
         newMesh.localPosition = Vector3.zero;

         // Create a list of the children we need to move. Setting child.parent to a new
         // value while iterating over the list seems to cause us to miss some elements.

         ArrayList children = new ArrayList();
         foreach(Transform child in newMesh) {
             children.Add(child);
         }

         // Move them.

         foreach(Transform child in children) {
             child.parent = gameObject.transform;
         }

         print("Prefab animation component = " + newMesh.animation);
         print("This animation component   = " + animationComponent);

         // Delete the prefab object.
         DestroyImmediate(newMesh.gameObject);

         _instantiated = true;
     }
 }

}

The class is also set to trigger OnEnable when the prefab is dragged into the editor scene window via the [ExecuteInEditMode] metadata tag, but I don't imagine this is part of the problem.

My hypothesis is that some internal state variable isn't being updated to notify the Skinned Mesh Renderer that the Animation component has changed. Normally, were you to drag the FBX-imported mesh directly into the scene, it would begin with an Animation component attached to the parent object. In my case, this component is being abandoned in favor of an Animation component that already exists on our Character_Prefab prefab. When I change something in the editor, that might trigger a "hard" reset on a bunch of the objects such that the change is propagated. This syncs everything up and permits the animations to influence the skeletal transforms. However, the animation field of the Component object is read-only, so I can't simply assign the mesh object's animation field to the "real" Animation component. Also, kludgey efforts to replicate the "reset" via state changes post-mesh-instantiation (setting a boolean to one value on update 0, then back on update 1) don't seem to trigger the "fix" I'm observing when I make a change in the editor.

That being said, here's the crux of my question:

Does anyone know what might be changing in either the Animation component, the Skinned Mesh Renderer, or the game object hierarchy when I make an adjustment to the instantiated game object via the inspector, such that animations start affecting the bone transforms? Or for that matter, tips/tricks about spawning a skinned mesh onto an existing prefab containing an initialized Animation component?

Alternatively, I was thinking it might work if I leave the instantiated prefab intact, parent it to the prefab with game logic scripts, and adjust all of our game logic scripts to compensate for the object hierarchy change. I'd rather not do that, but if push comes to shove, it would be an acceptable-ish solution.

Thanks in advance for any help and/or suggestions!

Comment
Add comment · Show 1
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 Ted-Brown · Sep 14, 2011 at 05:48 PM 0
Share

Does anyone know if an official answer has come from Unity on the subject? This seems like a fairly big production pipeline blocker.

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by frederik_krogh · Oct 11, 2020 at 07:17 PM

Better late than never.. the problem is still here 2020, but there is a undocumented function in Animator called Rebind you can just call it on the animator like this animatorcomponent.Rebind();

https://github.com/Unity-Technologies/UnityCsReference/blob/master/Modules/Animation/ScriptBindings/Animator.bindings.cs at line 1176 hope it helps in the future

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
0

Answer by sneftel · May 09, 2011 at 08:07 PM

I'm doing something very similar (creating skinned mesh, copying over skeleton and animation component from prefab), with no problems at all. One difference, though: I'm doing it in Update(), not in OnEnable(). Weird things happen if you mess with the hierarchy too much during the Awake/Enable/Start phase, with later initializations happening with stale data; I moved it into Update() because I was sick of looking at the Unity crash reporter. The behavior sets up the mesh, copies over the skeleton, then deletes itself (so that it doesn't get called next Update()). You might give that a try.

Here's my BakeOnCreate script, which is subclassed by my various procedural generation scripts. It seems pretty robust. The selection-check stuff is important if and only if you're gonna be deleting GameObjects.

using UnityEngine; using System.Collections; using UnityEditor;

[ExecuteInEditMode] public abstract class BakeOnCreate : MonoBehaviour {

 private bool shouldBake = true;
 private bool alreadyBaked = false;

 void Update()
 {

     if(!shouldBake)
     {
         return;
     }

     if(alreadyBaked)
     {
         Debug.LogError("Already baked!");
     }

     GameObject stagingNode = GameObject.Find("/Staging");
     if(stagingNode && transform.IsChildOf(stagingNode.transform))
     {
         shouldBake = false;
         return;
     }

     if(Selection.activeGameObject == null || !gameObject.transform.IsChildOf(Selection.activeGameObject.transform))
     {
         return;
     }

     Bake();
     shouldBake = false;
     alreadyBaked = true;

     if(this && gameObject)
     {
         Object.DestroyImmediate(this);
     }
 }

 // Use this for initialization
 protected abstract void Bake();

}

Comment
Add comment · Show 6 · 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 Ben 40 · May 09, 2011 at 10:40 PM 0
Share

Interesting note about Update versus OnEnable / Awake / Start. Didn't seem to resolve the problem though. In your post you mention that you're doing a similar copy operation in some subclass' Bake implementation. Does that entail anything besides instantiating the mesh prefab with the skinned mesh / bone data and reparenting the created objects to the target prefab's root transform? Also, it sounds as though in your case, the clip-initialized Animation component (and its object) is copied onto a new object ins$$anonymous$$d of the mesh being copied to the Animation's object. Is that accurate?

avatar image sneftel · May 10, 2011 at 12:13 PM 0
Share

Here's how it works: There's a prefab with an Animation component (preloaded with a clip) and a $$anonymous$$ixAnd$$anonymous$$atch$$anonymous$$esh component (which inherits from BakeOnCreate). $$anonymous$$ixAnd$$anonymous$$atch$$anonymous$$esh.Bake() does the following things:

avatar image sneftel · May 10, 2011 at 12:18 PM 0
Share
  1. It creates a new gameobject to hold a skeletal mesh, and creates a new mesh to put into it.

  2. It copies the skeleton from a provided FBX-imported object. It does this by instantiating only that skeleton root, then setting its transform parent. It also manually sets the name to remove the "(clone)" suffix.

avatar image sneftel · May 10, 2011 at 12:18 PM 0
Share
  1. It semi-randomly selects a set of skinned meshes from a provided prefab. It combines them into the skinned mesh. The bone references are remapped to refer to the new skeleton.

avatar image sneftel · May 10, 2011 at 12:18 PM 0
Share
  1. It parents the skinned mesh object to the current gameObject.

Show more comments
avatar image
0

Answer by sirival · Apr 04, 2012 at 06:03 PM

I know this is an old thread, however I had the same problem and I solved it by making sure that playAutomatically was false on the animation component of the root game object that contained the final skinned mesh renderer. When I combine the meshes I manually call animation.Play and it works. Note that it does not work if playAutomatically is set to true in the beginning even if you manually call Play...

Comment
Add comment · 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
0

Answer by Hardcore Games · Apr 02, 2013 at 02:45 AM

Just in case none of the above have help u. Have in mind that the animations configured to the prefab before making it a prefab were aiming to its normal name, Example:


horse_01.animation.CrossFade('idle', 1);

Being horse_01 a GameObject to which you make reference by

horse_01 = GameObject.Find('/PrefabName/some hierarchy.../');

Now, when you instantiate a prefab, it will be named "PrefabName(Clone)". Therefore the script wont find it anymore by the name you gave it in the level edition. Change script to incorporate the (Clone) sufix or find the way to get rid of it! I hope this will throw some light upon any lost pilgrim as myself ;)

Comment
Add comment · 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

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Animation issues With Game Character 1 Answer

Animating a character made of multiple objects 0 Answers

First Person Legs. 3 Answers

Character assets bundles problems on skinned mesh 1 Answer

Meshes not deforming properly when imported from blender 1 Answer


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