Search Unity

  1. All Pro and Enterprise subscribers: find helpful & inspiring creative, tech, and business know-how in the new Unity Success Hub. Sign in to stay up to date.
    Dismiss Notice
  2. Dismiss Notice

PuppetMaster - Advanced Character Physics Tool [RELEASED]

Discussion in 'Assets and Asset Store' started by Partel-Lang, Oct 1, 2015.

  1. Mike_Y

    Mike_Y

    Joined:
    Oct 16, 2014
    Posts:
    3
    Hi,

    I have Opsive UCC and Puppet master components. The integration doesn't work. UCC Controller works but I see jitter. I've completed the whole instruction step by step.
    Unity version: 2021.1.3f1
    UCC version is: 2.3.2 (Third Person Controller)
    Pupper Master was bought few days ago.

    BTW integration is outdated because void OnPuppetRead() has wrong signature. Actual signature should be
    void OnPuppetRead(float deltaTime)

    Could you update Opsive integration please.
     
  2. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    I'm trying to reproduce this issue.. Is the puppet in Active mode or Kinematic or Disabled when you call SetState?
    And what do you use for Animator update mode?

    Hey,

    I updated the UCC integration a few months ago, please check out this tutorial and get the latest package from the link in the description. But getting rid of jitters completely unfortunately requires a few changes to UCC code, instructions here.

    Best,
    Pärtel
     
  3. kollege14a5

    kollege14a5

    Joined:
    Jul 23, 2019
    Posts:
    2
    Hi Partel,

    the puppet is in Active Mode and the Animator update mode is "Animate Physics".

    Here is a short video I recorded which shows the problem:


    I took the Puppet Extended Demo scene from Puppet Master and

    - added an empty game object with a script that changes the state to Unpinned
    - increased the jump power to "8" in the Character Controller (Character Puppet)

    Here is the code I use to change the state:

    Code (CSharp):
    1. using UnityEngine;
    2. using RootMotion.Dynamics;
    3.  
    4. public class Unpinner : MonoBehaviour
    5. {
    6.     public BehaviourPuppet puppetBehaviour;
    7.  
    8.     void Update()
    9.     {
    10.         if(Input.GetKey(KeyCode.R) && puppetBehaviour.state != BehaviourPuppet.State.Unpinned)
    11.         {
    12.             puppetBehaviour.SetState(BehaviourPuppet.State.Unpinned);
    13.         }
    14.     }
    15. }
    When I press "R" to change the state to unpinned while I'm in the air the character teleports.
     
  4. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    Ah, that issue probably already fixed for the next version, sent you a PM.

    Best,
    Pärtel
     
    kollege14a5 likes this.
  5. Mike_Y

    Mike_Y

    Joined:
    Oct 16, 2014
    Posts:
    3
    Hi, thank you for quick reply. I tried to repeat all these steps but have no success.

    I have two issues:
    1. Jitter on character's legs

    I've rechecked all required pre-actions but didn't find anything wrong.

    UPDATE:
    Finally on Unity 2020.3.7f1 (LTS) I achieved that all things work together but some jitter still happen from time to time. I will continue investigation.
     
    Last edited: May 8, 2021
  6. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    Hello, what is the best way to access muscles and set mapping weights? I see there is an array of muscles. Is there a way to direct access it by muscle name?
    e.g.
    Code (CSharp):
    1. puppetMaster.muscles.hip.props.mappingWeight = 1.0F;
    2. or
    3. puppetMaster.muscles["hip"].props.mappingWeight = 1.0F;
    4.  
    Or I have to iterate it and check for the name manually?

    I appreciate your help!
     
  7. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    Well, let me answer myself, I found it in the documentation:
    Code (CSharp):
    1. this.puppetMaster.SetMuscleWeights(Muscle.Group.Hips, 1.0F, 1.0F, 1.0F);
    Regards!
     
  8. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    Hello, I am having another problem with puppet master. Whenever the ragdoll is active any animation that is playing becomes a little jumpy. I tried messing with parameters but nothing is fixing this. I hope you can help me with this.
    Thank you
     
  9. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    Have you tried enabling interpolation for the ragdoll rigidbodies?

    Hey,
    Did you follow the instructions to change the bits of code in UCC?

    Best,
    Pärtel
     
  10. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    Thanks, that fixes it. Is there any impact to performance by setting it to interpolate? Or any other concern you can think of?
    Regards
     
  11. Mike_Y

    Mike_Y

    Joined:
    Oct 16, 2014
    Posts:
    3
    Yes, for now most issues are gone but sometimes in Unity Editor (Game view) I get jitter sometimes not.

    Another question how to fix this unnatural moving near obstacle:
     
  12. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    There is a cost, but it is negligible, I never noticed any performance impact from interpolation.

    Also make sure your camera updates in LateUpdate and the camera controller script is set to a higher value than PuppetMaster has in the Script Execution Order.

    About that obstacle, depends, whether you want the player to stumble over it, fall or be mostly unaffected.
    If you need him to fall, reduce collision resistance and knock out distance for the leg and foot groups in BehaviourPuppet's Group Overrides.
    Increase those values if you want him to be unaffected.
    To stumble realistically, it would require you to have a couple of stumbling animations (for example the "Jogging Stumble" anim on Mixamo) that you could trigger when you register a hit to the legs.

    Cheers,
    Pärtel
     
    Hazneliel likes this.
  13. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    I recently upgraded Final IK from 1.9 to 2.0, before the upgrade I never had the following problem but with the upgrade I get this issue to occur 2 out of 5 times.

    It looks like it randomly happens, there is probably a race condition somewhere so I checked I have the correct script excecution order and they look correct.

    Also I have not been using any TwistRelaxer in the past since I noticed you did a change around it.

    When I upgraded I did a clean upgrade, on a new scene deleted old folders and reinstalled.

    I hope you can help me with this.

    upload_2021-5-16_16-3-21.png

    The IK configuration looks like this:
    upload_2021-5-16_16-7-25.png

    I noticed it might have to do with the Rotation Weight

    Maybe you changed something around it that is causing the issue?

    I am running Unity 2019.4.20f1

    Thanks for looking into this.
     

    Attached Files:

    Last edited: May 16, 2021
  14. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    Do you have the FBBIK component on the character in editor or are you adding it by script at runtime?
    FBBIK samples the pose at Start to find out which way to bend the limbs and stuff. Usually this kind of random bug happens when people add the component at some arbitrary time, there is animation already playing on the character and so the sampling is done differently every time.

    Best,
    Pärtel
     
  15. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    It is not being added at run time, it was added before but is set disabled, all I do on run time is enable it. Could this be the same issue? What is the solution to have this added in run time?
     
  16. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    if the IK is disabled at start, the pose will be sampled when the component is first enabled, so try having it enabled by default then disable after it is initiated:

    Code (CSharp):
    1. void Awake() {
    2.     ik.solver.OnPostInitiate += OnIKInitiated;
    3. }
    4.  
    5. private void OnIKInitiated() {
    6.    ik.enabled = false;
    7.    ik.solver.OnPostInitiate -= OnIKInitiated;
    8. }
    Best,
    Pärtel
     
    Hazneliel likes this.
  17. giraffe1

    giraffe1

    Joined:
    Nov 1, 2014
    Posts:
    215
    General question regarding the above statement. Do other components work like this? Currently I start everything disabled and only enable them when needed. I use AimIK, LimbIK, Leg IK, Grounder, FBBIK and puppetmaster.

    Should they all be started and then disabled?
     
  18. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    Yes, let them all initiate at the start of the game to be on the safe side. Also, there's a bit of cost to initiation so you'd probably want to do it at start to avoid possible hiccups mid-game.

    Best,
    Pärtel
     
  19. FaffyWaffles

    FaffyWaffles

    Joined:
    Apr 10, 2020
    Posts:
    16
    Yo, I've been using PuppetMaster / FinalIK for a while now (my favorite assets ever, they are amazing²) and I've run into a bit of a roadblock.

    I have been trying to integrate PuppetMaster with BZKovSoft's "Mesh Slicer" to create a type of dynamic slicing effect, but am unsure where to go next.

    https://assetstore.unity.com/packages/tools/modeling/mesh-slicer-59618

    (I am already aware of Noble Muffins' LimbHacker and TurboSlicer, and have succeeded in integrating them both. LimbHacker is just not accurate enough for my liking, and TurboSlicer does not play nice with SkinnedMesh. Also, I'm a moron who couldn't create a SkinnedMesh slicer on my life)
     
  20. FaffyWaffles

    FaffyWaffles

    Joined:
    Apr 10, 2020
    Posts:
    16
    Here is an example of what I'm trying to accomplish. (This is my LimbHacker Integration. Its extremely unstable)

     
  21. Hazneliel

    Hazneliel

    Joined:
    Nov 14, 2013
    Posts:
    248
    Hello
    What is the best and proper way to translate a character that has a puppetmaster ragdoll? For scenarios in which you need to position a character at a certain point, or for scenarios in which they need to be placed for a timeline animation.

    What I do now is disable the puppet, translate it to where I need and then re enable it. Some issues with this approach is that as soon as the puppet is re enabled, the ragdoll will try to reposition itself and will move physically towards the character, this causes many issues, sometimes it collides with other objects, sometimes it will permanently wiggle around the character, etc.

    So what is the best way to do this?

    Thank you.
     
  22. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    There are a number of mesh slicing tools on the Store, but as far as I know none of them can make sure vertices skinned partially to the neck and partially to the head don't get stretched to the severed head as it flies away. Slicing meshes at runtime is also slow and produces a lot of GC alloc, giving you nasty spikes down the road.

    I have edited the discontinued Limb Hacker tool by Noble Muffins (MIT licence) to cut a SkinnedMeshRenderer properly in Editor at pre-defined joints (only elbows, knees and neck are currently supported). That is 5 cut points and results in 32 possible permutations for the base mesh + 5 severed body part meshes. 5 cuts is pretty limited, but at least it has virtually zero performance cost at runtime.
    Here's the package.

    There are 2 scenes included - "Mesh Hacker", that is the scene where you produce the pre-cut meshes and "PuppetMaster Example" is about using them together with PuppetMaster. It doesn't create infills for the wounds, but since they are cut at just 5 points, you can create wound meshes, use them to cap the wounds.

    I don't currently have a better or less limited solution, sorry.

    Hey,
    puppetMaster.Teleport()

    Best,
    Pärtel
     
    Hazneliel likes this.
  23. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    92
    Having some problems with PuppetMaster and Photon PUN 2.

    My issue is that puppets instantiated over the network still get simulated by puppetmaster, how can I safely disable simulation and still be able to sync all rigidbodies and the skinned mesh?

    If I run a compiled build and hit play on the editor, I can see the two instantiated puppets, alright. When I try to disable puppetmaster in the one not owned by the editor, the character just freezes and ignores the updates coming from photon.

    By the way I am heavily using the stagger behaviour.

    I see on your PUN 2 demo you have your setup quite differently, for example on the example scene you have your puppetmaster not as a child in the hierarchy like it normally is?

    I would really like to keep puppets in sync over the network but only each client should calculate itself puppetmaster wise.

    I suspect I might need to retain the normal puppet for local simulation, and a separate prefab to be instantiated over the network and synced?
     
    Last edited: May 27, 2021
  24. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    I just updated the PUN2 integration package to improve rigidbody syncing, please have a look.
    Not sure why the character would freeze when you disable PM. Did you set it to Disabled mode or just disable the component? Using Disabled PuppetMaster.Mode is the proper way.

    In the demo the puppet is not a child of the hierarchy because PUN requires all observed components to be on the same gameobject as photonview and photonview on the root of the prefab. PuppetMaster can't be a child of the character controller though, as it must not inherit any motion from it, the ragdoll must be moved by physical forces only. So that's why I have PuppetMaster parented to the prefab, then unparenting it by script when the prefab is instantiated.

    The core idea behind syncinc PM is that each client is running their own PuppetMaster simulation, however, the losing balance and getting up events should be controlled by only the ones that have isMine == true and sent over to the others via RPC.
    So local puppets run just as they normally do. The remotes run too, but with their canGetUp set to false and knockOutDistance set to Infinity as they receive lose balance and get up commands from their owners.

    Best,
    Pärtel
     
  25. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    92
    I actually wanted it to work this way:

    Each client is a puppet, but they will only calculate their OWN puppet simulation, not all the others, so in the other remote machines everybody is just a replicated ragdoll, saving cpu time on everybody.

    But i am having problems figuring out how to make this work because the ragdoll is parented to puppetmaster and not normally along with the bones of the character like after you create a ragdoll with the ragdoll creator, when you set it up with puppetmaster later it will separate the ragdoll from the bones, and for what i need to do, replicated characters should have the ragdoll and bones together (each rigidbody/collider/joint on the same gameObject as the bone transform)

    EDIT:

    managed to roll out my own solution to that, the character prefab will contain everything to make it work with puppetmaster, including behaviours, but all off. Then i just switch these parts on/off depending on if the character is running locally or remotelly, keep in mind I don't disable PP in the normal way by using the toggle, I switch off the script entirely from the start because that will not disable the ragdoll. then all game instances will just receive ragdolls from the other characters.

    I also created a "mirror" script which matches the bones with the ragdoll.

    that is saving a lot of perforamance but i wonder if thats the best way?
     
    Last edited: May 28, 2021
  26. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    I guess it depends on what you need to do exactly. If it works then it's all good, but I'm thinking what if 2 puppets bump into each other, how is the collision resolved if everybody has only their own active puppet and the others are just mirrored?

    Best,
    Pärtel
     
  27. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    92
    I was thinking about that too but using photon rigidbody view its actually being handled pretty well, in reality the collisions would be resolved and sent over the network by each puppet, so you would imagine a delay happening, but its actually pretty smooth, maybe their lag compensation is OK.

    I just gotta decide between CPU and bandwidth now, since my solution takes less CPU but way more bandwidth.
     
  28. graphicsayy97

    graphicsayy97

    Joined:
    Dec 24, 2020
    Posts:
    30
    hey dev, thank you for this amazing asset, i have no regrets buying it

    but i am confused as to your disconnecting muscles scene
    could you mind maybe providing some kind of guide to the workflow for making use of this?

    how do you make sure the separate meshes are aligned to the armature? in blender it doesnt appear to be skinned at all

    please share your secrets, I wish to animate segmented meshes and combine it using custom disconnecting muscles found in your asset

    do you have any guides to this workflow somewhere perhaps? thank you again for your hard work
     
  29. FaffyWaffles

    FaffyWaffles

    Joined:
    Apr 10, 2020
    Posts:
    16
    I'm working the problem, and am having a bit of trouble with the instantiating process. Sometimes it works a treat, but other times unity throws up hundreds of errors.

    What would you say is the proper technique of instantiating a puppet? I'm confused on what it means to move the Root transform, I guess.

    **on a tangent, you misspelled "immediately" within the error message.
    Just a hilariously tiny fix for the next update :p

    Code (CSharp):
    1.             if (targetRoot.position != transform.position) {
    2.                 if (log) Debug.LogError("The position of the animated character (Target) must match with the position of the PuppetMaster when initiating PuppetMaster. If you are creating the Puppet in runtime, make sure you don't move the Target to another position immediatelly after instantiation. Move the Root Transform instead.");
    3.                 return false;
    4.             }

    -- Line 39 of PuppetMasterValidation;)
     
  30. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    If you're trying to create a similar skeleton-like character with MeshRenderers for each body part instead of 1 SkinnedMeshRenderer, then basically you'd want to create the character mesh with separate objects for every body part (like the CowboyPuppet.fbx in the package). Then you'd also need a matching bone hierarchy (like CowboyAnimationTarget.fbx), by matching I mean the positions and rotations of the body part MeshRenderers should match with the respective bones in the hierarchy. Then drag the bone hierarchy fbx to the scene, set up a ragdoll on it using BipedRagdollCreater and add PuppetMaster. Finally, drag in the fbx with the MeshRenderers and parent each MeshRenderer object to the bone that it represents.

    It can be done with SkinnedMeshRenderers too, but it is tricky, You'll need to make sure the body part that flies away doesn't have any vertices with bone weights to the rest of the body or the skin will stretch

    There are a number of mesh slicing tools on the Store, but as far as I know none of them can make sure vertices skinned partially to the neck and partially to the head don't get stretched to the severed head as it flies away. Slicing meshes at runtime is also slow and produces a lot of GC alloc. I have edited the discontinued Limb Hacker tool by Noble Muffins (MIT licence) to cut a SkinnedMeshRenderer properly in Editor at pre-defined joints (only elbows, knees and neck are currently supported). That is 5 cut points and results in 32 possible permutations for the base mesh + 5 severed body part meshes. 5 cuts is pretty limited, but at least it has virtually zero performance cost at runtime.

    Here's the MeshHacker package.

    There are 2 scenes included - "Mesh Hacker", that is the scene where you produce the pre-cut meshes and "PuppetMaster Example" is about using them together with PuppetMaster. It doesn't create infills for the wounds, but since they are cut at just 5 points, you can create wound meshes, use them to cap the wounds.

    Hey,

    Please grab this patch.

    Cheers,
    Pärtel
     
    graphicsayy97 and FaffyWaffles like this.
  31. FaffyWaffles

    FaffyWaffles

    Joined:
    Apr 10, 2020
    Posts:
    16
    Woah, this fixed the problem instantly! Would you mind quickly going over what the patch fixed?

    **edit Ah, the specific validation check has just been commented out.
     
    Last edited: Jun 5, 2021
  32. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    Not just commented out, also making sure the muscle positions-rotations match with their targets.

    Best,
    Pärtel
     
  33. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    77
    Hi Partel,

    I am trying to make the puppet to have zero muscle weight when kill, so I see deadMuscleWeight to 0 in the stateSettings. But later on it seems the puppet regain muscle weight soon after lying down. And I doing something wrong?

    Thanks
     
  34. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Hey,
    When you do a Debug.Log(puppetMaster.muscles[1].state.muscleWeightMlp); while the puppet is dead, what does it log? What does it look like, is the animation still playing or is the puppet twitching on the ground or what?

    Best,
    Pärtel
     
  35. graphicsayy97

    graphicsayy97

    Joined:
    Dec 24, 2020
    Posts:
    30
    thanks alot i am working on this right now it is a great help and gives me more options
     
  36. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    77
    The log looks starts at 1, decrease gradually to 0, then goes back to 1.0, then goes to 0.03, then stables at 1 again.
    Animation not playing. Not twitching but you can see the muscle weight change as reflected in the log. Could this be related to the puppet also has a Stagger behavior?
    0.03 is also the value of Unbalance Muscle Weight Multiplier in the Stagger behvior.

    I do have a few modification made to the base code, but nothing can't think of anything I did that would cause this.
     
  37. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    77
    It looks like it's Stagger behavior related. If I Kill the "Puppet&Stagger" puppet in the Stagger demo I get the same behavior. So the question is how do you kill a puppet with Stagger behavior?

    Thanks.
     
  38. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,269
    Oh, the stagger.. Yeah, as it happens I fixed that bug just last week. Here's the patch. :)

    Best,
    Pärtel
     
  39. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    77
    Thank you!
     
  40. cybie

    cybie

    Joined:
    Sep 17, 2010
    Posts:
    77
    There is still one small bug after the patch: If I Kill() the stagger puppet after I unpinned it, the puppet will dead but its muscle weight is not zero (as set in the Kill parameter). It's fine if I only kill and not unpin.
     
    Last edited: Jun 18, 2021 at 11:44 PM
  41. Ell223

    Ell223

    Joined:
    Jan 27, 2014
    Posts:
    6
    How am I able to pause the physics? I have a character which I can drop from height, and I want to be able to pause the physics and the puppetmaster updates, e.g in midair. My character has the getup behaviour activated on it.

    I have tried setting puppetmaster mode to kinetic, but I think the behaviour puppet sets it back to active as it doesn't seem to change and character continues to fall. I have tried setting behaviour puppet normal mode to kinetic but the character seems to hit the ground midair almost and lays flat. I have tried disabling the behaviour puppet script also, and directly setting the rigidbody kinetic value.

    Basically I am looking for the correct settings in order to set the rigidbody to kinetic immediately on a button press and puppet will not move. I could use Time.timeScale = 0 but was wondering if there was a way to do this directly for each puppet.
     
unityunity