Search Unity

PuppetMaster - Advanced Character Physics Tool [RELEASED]

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

  1. yuri_midnite

    yuri_midnite

    Joined:
    Sep 17, 2020
    Posts:
    8
    Hello @Partel-Lang
    my character makes some big jumps. I'd like to enable ragdoll (death like) while in air, just to make the jump more funny, without making it die forever.

    I was thinking about some tuning according to the distance from the ground.
    What you suggest?
     
    Last edited: Oct 2, 2020
  2. PlayingKarrde

    PlayingKarrde

    Joined:
    Aug 19, 2013
    Posts:
    38
    @Partel-Lang Hi there, I'm having some trouble getting a nice ragdoll from Puppetmaster using the same method you are with the fade from death demo. My original method was to just set the puppet to dead which gives a nice ragdoll but I would prefer to keep it active with animations.

    Here is an example of setting to dead, and similar to what I'd like regarding stability and basic physics:


    However when fading out the pinweight and muscleweight I get this:


    I've tried playing around with different values for these but can't seem to find anything that keeps my puppet stable. I'm using behaviourpuppet and behaviourfall as well in case that's relevant.

    Also, I think this has been answered before but I can't seem to find the response again, but I find that once I play an animation (such as the one above) when returning out of it my feet are wobbly. This does not occur prior to playing an animation and I cannot for the life of me figure out why that's happening.


    Any help would be greatly appreciated.
     
    SSSekhon likes this.
  3. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    I'm going to guess this is one of the stranger things that has used Puppetmaster and FinalIK :)

    I just released a game that makes animations called "Nightmare Puppeteer"
    https://store.steampowered.com/app/1355310/Nightmare_Puppeteer/

    All of the characters use FinalIK and Puppetmaster- I did some hackery with the Puppetmaster rigs to make them bounce to the beat in music like this + other wacky stuff


    Thanks for making awesome tools Partel!
     
    hippocoder and PlayingKarrde like this.
  4. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    You could add some "fake impact" when the spear hits the body. Add OnCollisionEnter() to a script on the spear and when it detects a ragdoll hit, find MuscleCollisionBroadcaster on collision.collider.attachedRigidbody and call broadcaster.Hit() on it. You can find a code snippet in RaycastShooter.cs, it is used in the "Puppet Raycast Hit" demo to add impact on the ragdoll on mouse button down.

    Hey,
    Sounds like exactly what BehaviourFall already does. You can see what that does in the "Falling" demo. So you'd need both BehaviourPuppet and BehaviourFall under the Behaviours. BehaviourPuppet needs to have "BehaviourFall" as "Switch To Behaviour" under it's "On Lose Balance" event, so it switches to BehaviourFall when it loses balance. Get rid of Animations in that On Lose Balance event. Likewise, BehaviourFall needs to have "BehaviourPuppet" in it's "On End" event. You also need to have the "BehaviourFall" sub-state machine in the Animator. You can copy that over from the
    "Humanoid Third Person Puppet" animator controller if you don't already have that. That sub-state machine is where you can swap out the falling animation if you want to use another.
    So to enable BehaviourFall, just call behaviourPuppet.SetState(BehaviourPuppet.State.Unpinned) when you are too high from ground to land on your feet.

    Hey,
    Looks like what is happening with that ragdoll when it lands is mostly because it doesn't have Internal Collisions and Angular Limits enabled, so it just folds. Try enabling those when you switch to ragdoll. Going to Dead state does that if you have "Enable Angular Limits On Kill" and "Enable Internal Collisions On Kill" enabled in PuppetMaster's "State Settings", so that is where that difference mostly comes from. To get the same amount of muscle weight as you do from switching to Dead, set BehaviourPuppet's "Unpinned Muscle Weight Mlp" to the same value you have for "Dead Muscle Weight" in PuppetMaster's State Settings. Also set PuppetMaster's "Muscle Damper" to the same value as "Dead Muscle Damper" in State Settings when you switch to ragdoll. That should get you identical ragdoll behaviour while allowing you to maintain active animation.

    Not sure what is going on with the wobbling feet there, is there any steps I could take to reproduce? Does it happen when the ragdoll gets up? What happens if you play another animation?

    Haha, that is some super creepy and funny stuff, thanks for sharing! Mind if I add that to my public list of games powered by FIK/PM? :D

    Cheers,
    Pärtel
     
  5. PlayingKarrde

    PlayingKarrde

    Joined:
    Aug 19, 2013
    Posts:
    38
    @Partel-Lang Thanks that helped a lot and gives me a good basis on how to move forward with other features now.

    It looks like it's not just the feet but the entire lower body from spine2 or thereabouts down bizarrely (https://gyazo.com/4ea5b69b56707bb05409944788c0381b). It looks like once stand up is finished playing it works Although I can't properly test that right now as my 1p won't actually stand up like 2p (this happens). Playing any other animations it retains this jelly like behaviour. It's very strange...
     
  6. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    I'd be honored- thank you :)
     
  7. Censureret

    Censureret

    Joined:
    Jan 3, 2017
    Posts:
    363

    Thank you so much for your response :) what i am looking for is to add extra force to the ragdoll as i am pinning the spear directly to him something like this:

    https://vimeo.com/117440682
     
  8. ValiantTechStudios

    ValiantTechStudios

    Joined:
    May 10, 2020
    Posts:
    7
    Hi Partel-Lang,
    Thanks for the reply. The pose seems to be correctly applied if I call HumanPoseHandler.SetHumanPose() repeatedly within the puppetMaster.OnRead delegate, but if I call HumanPoseHandler.SetHumanPose() only once, it is quickly overridden to the base T pose again by Puppetmaster.

    Is this expected behaviour?

    Thanks
     
    Last edited: Oct 4, 2020
  9. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    Does it go away if you disable "Disable Colliders" in the Foot group override under BehaviourPuppet's "Group Overrides"?

    Hey,
    Could also just call behaviourPuppet.SetState(BehaviourPuppet.State.Unpinned), then just AddForce() on the muscle rigidbodies. You can use spear.velocty and ForceMode.VelocityChange in the AddForce command.

    I can't think how calling SetHumanPose repeatedly would work while calling it once wouldn't.. Only think in PM overriding to base T pose comes from "Fix Target Transforms", but that is done before OnRead gets called. What happens if you disable that checkbox in PuppetMaster? What do you have for "Update Mode" in the Animator?

    Cheers,
    Pärtel
     
  10. PlayingKarrde

    PlayingKarrde

    Joined:
    Aug 19, 2013
    Posts:
    38
    It does. But of course then my feet get twisted in the floor.
     
  11. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    I haven't been able to reproduce here, might be a Unity bug.. I think Rigidbody inertia tensors might be getting messed up when colliders are disabled and enabled again.Which Unity version were you using? Have you tried any other versions?

    Best,
    Pärtel
     
  12. PlayingKarrde

    PlayingKarrde

    Joined:
    Aug 19, 2013
    Posts:
    38
    I'm on 2020.1.6f but I am pretty sure something very similar used to happen in older versions too. I took about a year's break from it so can't remember exactly (previously it would have been 2018.8 or something). I'll do some more tests and report back.

    -edit- I think the issue was Angular Pinning. Without it I get said issues, but enabling it seems to lock things into place correctly. I'll do some more tests to make sure this doesn't have any adverse affects but I think that's probably it.
     
    Last edited: Oct 9, 2020
  13. ValiantTechStudios

    ValiantTechStudios

    Joined:
    May 10, 2020
    Posts:
    7
    Hi Partel-Lang,
    If I turn off "Fix Target Transforms" the character slowly collapses to the floor. Poses I apply at that point are applied, but then the character slowly falls to the floor again.

    In a way, doesn't it make sense that if I only call SetHumanPose once in the first call to OnRead, that subsequent internal loop iterations within PuppetMaster will override back to the T pose because I have "Fix Target Transforms" set? The subsequent calls to OnRead will not call SetHumanPose and therefore will not revert to my desired pose after "Fix Target Transforms" reverts beck to the T pose...

    It sounds like PuppetMaster would have to have a way of overriding the initial pose that it reverts back to during the "Fix Target Transforms" logic in order for me to only make a call once.

    For update mode in the animator, I have "Normal", and culling mode is "Cull Update Transforms"

    One thing that may be important, is that I do not have a character controller applied to the character - does this matter?

    I also do not have an animation applied...

    Thanks
     
    Last edited: Oct 12, 2020
  14. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    Thanks for the info, I'll try to reproduce and investigate here...

    Hey,

    Fix Target Transforms is there in case you don't have animation or anything else applied that overwrites the target pose each frame. It is called in Update and it just applies the default pose. It prevents PM from reading-writing additively on top of itself, that would cause slowly collapsing on the ground or some bones rolling infitely and stuff like that.

    After that PuppetMaster Update(), normally Animator updates the pose and Final IK is updated on top of that in LateUpdate().
    In PuppetMaster's LateUpdate() it will read all that and OnRead delegate is called.
    The data that is read at that point will be fed to the muscles for physics calculations in the next FixedUpdate.

    After all that, in the same LateUpdate(), PuppetMaster maps the character to the ragdoll.

    Maybe the problem is with GetHumanPose instead, maybe that is called at the wrong time (after OnRead maybe so it is all inverted). Perhaps it would help me understand if you could share some code?

    Best,
    Pärtel
     
  15. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Hello- I'm working on a cutscene with a stop motion style of animation- The actors use Puppetmaster-

    The animations have been modified so the interpolation is very rough like stop motion animation. I want to use Puppetmaster for secondary animation, this works but the additional movement added by Puppetmaster is very smooth of course.

    is there a way to make Puppetmaster's interpolation choppy and stepped like stop motion animation? Thank you.
     
  16. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    Only thing I can think of is disabling interpolation on all the ragdoll rigidbodies and matching Fixed Timestep to the frequency of your stop motion.

    Best,
    Pärtel
     
  17. imaginationrabbit

    imaginationrabbit

    Joined:
    Sep 23, 2013
    Posts:
    349
    Thank you for the reply and the idea, I will try it out. :)
     
  18. nubdev

    nubdev

    Joined:
    Mar 30, 2013
    Posts:
    87
    Hi Partel, I am having trouble with the Character Melee Demo (character player). When it goes over or under a certain height, the character starts a falling animation which restricts jumping ability.
    Changing its "airborne threshold" and "spherecast radius" allows it to move on high points, but destroys the jump as it allows infinite double jumping if you hold the jump button.

    is there a way to allow the character melee demo character puppet to move onto higher platforms or terrain without destroying jumping either through the infinite falling or infinite jumping? Thanks
     
    Last edited: Oct 20, 2020
  19. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    138
    Just updated puppetmaster and finalIK

    Got two errors on the stagger behaviour that it could not find a suitable method to override for
    OnFixedUpdate
    OnLateUpdate

    Fixed it by adding the parameter "float deltaTime" from the methods signature on the BehaviourBase class.

    Is that ok?

    Also, more important:

    How do I make the visualized target pose match the ragdoll position and rotation?

    What I am getting is this:

    upload_2020-10-22_16-0-40.png

    after running this code(copied form BehaviourPuppet) in my custom behaviour


    Code (CSharp):
    1. private void RotateTarget(Quaternion rotation)
    2.         {
    3.             puppetMaster.targetRoot.rotation = rotation;
    4.         }
    5.  
    6.         protected void MoveTarget(Vector3 position)
    7.         {
    8.             //if (!canMoveTarget) return;
    9.  
    10.             puppetMaster.targetRoot.position = position;
    11.         }
    12.  
    13.         private IEnumerator GetUp()
    14.         {
    15.             yield return new WaitForSeconds(5);
    16.  
    17.             var hipsForward = Quaternion.Inverse(puppetMaster.muscles[0].transform.rotation) * puppetMaster.targetRoot.forward;
    18.             var hipsUp = Quaternion.Inverse(puppetMaster.muscles[0].transform.rotation) * puppetMaster.targetRoot.up;
    19.  
    20.             // Set the target's rotation
    21.             Vector3 spineDirection = puppetMaster.muscles[0].rigidbody.rotation * hipsUp;
    22.             Vector3 normal = puppetMaster.targetRoot.up;
    23.             var isProne = false;
    24.             Vector3.OrthoNormalize(ref normal, ref spineDirection);
    25.             RotateTarget(Quaternion.LookRotation((isProne ? spineDirection : -spineDirection), puppetMaster.targetRoot.up));
    26.  
    27.             // Set the target's position
    28.             puppetMaster.SampleTargetMappedState();
    29.  
    30.             var getUpOffsetProne = Vector3.zero;
    31.             var getUpOffsetSupine = Vector3.zero;
    32.  
    33.             Vector3 getUpOffset = isProne ? getUpOffsetProne : getUpOffsetSupine;
    34.             MoveTarget(puppetMaster.muscles[0].rigidbody.position + puppetMaster.targetRoot.rotation * getUpOffset);
    35.             GroundTarget(groundLayers);
    36.             var getUpPosition = puppetMaster.targetRoot.position;
    37.  
    38.             var getupAnimationBlendWeight = 1f;
    39.             var getUpTargetFixed = false;
    40.         }
    Yeah its pretty hacky, and poorly copied for now, but I just wanna figure out how it works.

    also tried using puppetMaster.FixTargetToSampledState(1) but that also didn't work.
     
    Last edited: Oct 23, 2020
  20. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    Are you sure you have your ground collider layers included in CharacterMeleeDemo's "Ground Layers"?

    Hey,
    When you update FIK/PM, also reimport the FIK integration package in PuppetMaster/_Integration folder. Probably the cause of the errors.

    About matching the visualized target pose to the ragdoll, why exactly do you need to do that?
    Those cyan lines just visualize the animated pose of the character. The rotation is irrelevant really because the muscles follow the pose in local space.

    Best,
    Pärtel
     
  21. Deleted User

    Deleted User

    Guest

    Hello, I am using PuppetMaster and Final IK for a VR police de-escalation simulation. The NPC has an odd twitching behavior when Look IK is called in LateUpdate. Im wondering if I'm doing something wrong? Everything worked fine until I added the PuppetMaster.
     

    Attached Files:

  22. ValiantTechStudios

    ValiantTechStudios

    Joined:
    May 10, 2020
    Posts:
    7
    Hello Partel-Lang,
    Thanks for all of your help.
    The cause of my issue turned out to be something that I neglected to mention to you. My character also had a Look At IK script applied to it and I use an IK Excecution order script to run first FBBIK and then LAIK. If I enable "Fix Transforms" in FBBIK and disable it in LAIK then I am able to set the pose only once with SetHumanPose and everything works as you expected it to.
    Enabling "Fix Transforms" in FBBIK and LAIK causes my original pose reset issue.
    Thanks again!
     
  23. nubdev

    nubdev

    Joined:
    Mar 30, 2013
    Posts:
    87
    I thought I had but apparently not. Thank you there are no longer any issues.
     
  24. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    That looks a lot like you have your Animator on Animate Physics update mode. If so, calling ik.solver.Update in LateUpdate will be out of sync with the update frequency of animation. IK will be solved multiple times on top of itself until there is another FixedUpdate step, causing the twitch.
    Please try using PuppetMaster.OnRead delegate to update the IK from:

    Code (CSharp):
    1. void Start() {
    2.     puppetMaster.OnRead += OnPMRead;
    3. }
    4.  
    5. private void OnPMRead() {
    6.     ik.solver.Update();
    7. }
    Best,
    Pärtel
     
  25. Censureret

    Censureret

    Joined:
    Jan 3, 2017
    Posts:
    363
    Hey i have an odd collision issue when i convert my characters to puppet master basically they are able to move through the character:

    upload_2020-10-26_19-17-29.png

    Here is my setup:

    upload_2020-10-26_19-18-24.png

    My PuppetMaster is on the layer "Ragdoll"
    And the "Spearman (5)" is on the layer "CharacterLayer"

    The Player character is also on the layer "CharacterLayer"

    Here is my Layer Setup:

    upload_2020-10-26_19-19-40.png

    So they should be colliding with each other but they don't.

    Can anyone tell me what might be the problem?
     
  26. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    Can you check the Layer Collision Matrix in play mode? If you have that LayerSetup component that used in the demos anywhere in your scene, that will change the matrix at Start. LayerSetup is there just to make the demos work in default project settings, you don't need it if you already have your layers set up.
     
  27. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    262
    Hey I just wanted to offer a solution to mysterious ragdoll spinning/rotation when in midair. This is particular to having your Puppet use Internal Collisions. If that is false, this doesn't apply.

    But if you are using Internal Collisions, in midair, if you are not applying any external forces to your Puppet and finding that it's having a torque applied from somewhere you cannot find, make a pass through the Collision ignores in the Puppetmaster component. Set those up in a way that makes sense and see if it fixes the rotation.

    It's not surprising that jointed collisions would cause odd behaviour as it tries to resolve, but this was a very gentle torque on the whole character. Drove me nuts for a few hours, so hopefully this would help someone in the future.

    Partel this is an amazing piece of code and so super thoroughly documented. I particularly love the tips you put on hover over all of the fields in the inspector. You rock.
     
  28. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Thanks man! :)

    Somehow I didn't encounter any weird torques back when I was experimenting with space puppets. But what it could also be is joint projection. If you have that enabled, that can cause all kinds of weird spinning.

    Cheers,
    Pärtel
     
  29. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    262
    Yeah well I did an unconventional thing and made the clavicles part of the ragdoll, and while I cleaned up most of the internal collision pairs when I did it, I missed a few. These clavicle colliders were entirely inside the spine box, and well I guess I forget which pair was causing the rotation. But anyway, it was my own fault.

    On another topic, would there be any debugging feature or little hacks I could do to figure out when a Configurable Joint's limits were blocking an animation from reaching its goal on the puppet ragdoll? I'm figuring things out by wiggling the limits at runtime, but if there was something like the joint turning red that would be amazing.
     
  30. renat_k

    renat_k

    Joined:
    Mar 22, 2016
    Posts:
    8
    I have an problem
    I decreased Fixed TimeStep for more accurate physics stuff, i.e. grab and slam tricks. If fixed time is default many of grabs is jittering.
    And I use custom script for hits, which does:
    From others script gets link for custom hitReaction script
    In my HitReaction
    Set puppet state.Kill()
    AddForce for the spine

    Its works with default fixed timstep(0.02) well. All hits are add right force to puppet's rigidbodies
    I decreased fixedTimeStep to 0.0065 which is good for jittering prolems. But, problem is most of times forces not applies for puppet. It looks like forces applies, then after ~0.1 sec stops immediately.

    So i did in my hitReaction script cheat - when i press 9 in update, forces works fine in whatever FixedTS.

    I've tried to create simple script, which gets muscleCollisionBroadcaster, from MCB gets puppet, and does only puppet.kill and adds forces at this muscle.

    I tried so many hacks, but no ones works. I tried at different puppet setups from demos. I tried change execution order of my scripts. All rigidbodies are Interpolated and Continious Dynamic.

    So why its works in Update() when i press button, but doesnt work in OnTriggerEnter.

    best regards
     
    Last edited: Oct 31, 2020
  31. renat_k

    renat_k

    Joined:
    Mar 22, 2016
    Posts:
    8
    So, I solve my problem with dirty hack in Update()
    I made container which contains variables like in Hit() method, like directions of horizontal and vertical forces, froces and etc.
    In my HitReaction script i made bool, which turn on for 1 frame. In section with bool hit method gets parameters from attackers Hit() and then these parameters goes to in hit reaction.

    And it works fine for now, but i still looking for solutions without this hack.
    Best regards
     
  32. sancha-km

    sancha-km

    Joined:
    Jun 5, 2016
    Posts:
    41
    Hi,
    What is the best way to deactivate Puppet master?
    1. I just deactivate gameobject with Puppet master
    2. Also disable component all Behavours
    3. Use some function, for example standart Unity animator component still works when you disable gameobject.
     
  33. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    What I normally do when I suspect joint limits get in the way of animation is just toggle "Angular Limits" off/on. If disabling fixes it, then I have to loosen the limits a bit. If not, it's probably the internal collisions so I try to toggle that too.
    It is OK to have your joint limits much looser than biometrically accurate because muscle spring normally keeps the joints well within acceptable range anyway. Sometimes I enable joint limits/internal collisions only when the puppet falls over or dies so I never have to worry about those things clamping my animation.

    AddForce is only supposed to be called from 1 place and that is FixedUpdate(). OnTriggerEnter is called from inside the physics simulation step so likely for that step the addforce commands have already been processed.
    Might be a good idea to use a coroutine and yield WaitForFixedUpdate():

    Code (CSharp):
    1. OnTriggerEnter(Collider collider) {
    2.    StartCoroutine(AddForce(collider.attachedRigidbody, force));
    3. }
    4.  
    5. private IEnumerator AddForce(Rigidbody r, Vector3 force) {
    6.     yield return new WaitForFixedUpdate();
    7.  
    8.     r.AddForce(force);
    9. }
    Hey,
    Switching puppetMaster.mode to PuppetMaster.Mode.Disabled; is the safe way to disable PuppetMaster and all physics smoothly. It deactivates the entire ragdoll and most of what PuppetMaster does, but it still runs a little process on the background that allows you to re-activate smoothly at any time.

    Best,
    Pärtel
     
  34. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    138
    I am currently facing a problem where my character could possibly be hit by 48 possible ways for the upperbody(just what i can focus my energy now) So possibly double that or triple that for the whole body.

    and with that that is the possibility of falling over edges and objects, in these cases as the combinations could be infinite I would leverage puppetmaster's power to have them simulated real time.

    But still, I am left with a big number of animations. Is there a probably more generic way that I could do it? Like having a couple animations and let puppetmaster handling the rest?

    I am thinking in my case its not possible because some impacts are supposed to knock the character on the ground and some aren't(he will just stumble for a bit, maybe use the BehaviourBipedStagger to handle these low force impacts?
     
  35. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    BehaviourBipedStagger always ends up with the puppet falling though. But I think you would be fine with a couple of head, body, arm and leg hit animations + PuppetMaster.
    If you only need specific attacks to knock the puppet down, can set behaviourPuppet.knockOutDistance to Mathf.Infinity when hit by other attacks.

    Best,
    Pärtel
     
  36. renat_k

    renat_k

    Joined:
    Mar 22, 2016
    Posts:
    8
    Thanks! I thought this way later :D

    Is there method or function to update animator controller aka target root while I'm pulling, pushing or dragging puppet by connecting rigidbody or just by other non connected rigidbodies? If set puppet unpin and bigger knockout distance puppet just returns back, so I want drag puppet. I tried to findout update root target, but can't find. May be its too obvious :)
     
  37. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    I'm not exactly sure what you meant.. The Animator is always updating (unless you are in Dead state and it has been disabled).
     
  38. renat_k

    renat_k

    Joined:
    Mar 22, 2016
    Posts:
    8
    If I drag puppet's hand the pin forces bring hand back to position. So i want to drag hand and i want to move target root of puppet.
    So, how i can update targets root position properly? May be there is some method for manually updating targets root position?
     
  39. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    138
    Hi, I managed to balance my puppet with BehaviourBipedStagger enabled, I have another script that waits for it to be balanced and then enables my other custom behaviour inheriting from BehaviourBase.

    After the stagger is balanced and almost completely stopped(good enouugh) I will call

    Code (CSharp):
    1.  puppetMaster.SampleTargetMappedState();
    2.             targetNeedsToBeFixed = true;
    3.             targetFixWeight = 1;
    4.             //puppetMaster.mode = PuppetMaster.Mode.Kinematic;
    5.             fixPosition = puppetMaster.muscles[0].transform.position - Vector3.up + Vector3.up * 0.05f;
    6.             var directionProjected = Vector3.ProjectOnPlane(puppetMaster.muscles[0].transform.forward, Vector3.up);
    7.             fixRotation = Quaternion.LookRotation(directionProjected);
    and later(possibly on next frame i assume) handle it on OnReadBehaviour

    Code (CSharp):
    1.  
    2. protected override void OnReadBehaviour(float deltaTime)
    3.         {
    4.             if (targetFixWeight > 0)
    5.             {
    6.                 if (targetFixWeight < 1)
    7.                 {
    8.                     // This pins the puppet after the first iteration of this block
    9.                     // because targetFixWeight will only be < 1 after the first call.
    10.                     // This duct tapes the problem when the puppet flies away and shoots back to the pinned position.
    11.                     puppetMaster.pinWeight = 1;
    12.                 }
    13.  
    14.                 // This causes the puppet to shoot away and come back if pinned before calling.
    15.                 puppetMaster.targetRoot.position = fixPosition;
    16.                 puppetMaster.targetRoot.rotation = fixRotation;
    17.  
    18.                 targetFixWeight = Mathf.MoveTowards(targetFixWeight, 0f, deltaTime * 2);
    19.                 if (targetFixWeight < 0.01f) targetFixWeight = 0f;
    20.  
    21.                 // Lerps the target pose to last sampled mapped pose. Starting off from the ragdoll pose
    22.                 puppetMaster.FixTargetToSampledState(targetFixWeight);
    23.  
    24.                 Debug.Log(targetFixWeight);
    25.             }
    26.         }
    27.             }
    The problem here is that It is blending from the sampled state back to the previous pose. I can modify this part:

    Code (CSharp):
    1. puppetMaster.FixTargetToSampledState(1);
    But as soon as I stop calling it on OnReadBehaviour it will snap back to the previous target(before staggering), shouldn't it stay like that instead of reverting?

    That is fixed by just continuously calling
    Code (CSharp):
    1. puppetMaster.FixTargetToSampledState(1);
    But that's not supposed to work like that i assume? I can't call it indefinitely i guess.

    Here is a video:
    When i hit space, the puppet will stagger with a force added to its chest.
    When i dected it stopped staggering the sampling and fixing will be triggered.
    As you can see it blends to the pose from just before staggering.

     
    Last edited: Nov 14, 2020
  40. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    There is no method in PM to change target root position. But it is just about moving the Transform, you are free to do that from any script. For example if you want to maintain the dragged puppet's position relative to the dragging puppet, store the position of the dragged puppet relative to the dragging one when you connect the two:

    Code (CSharp):
    1. Vector3 p = puppet.targetRoot.InverseTransformPoint(draggedPuppet.targetRoot.position);
    2. Quaternion r = Quaternion.Inverse(puppet.targetRoot.rotation) * draggedPuppet.targetRoot.rotation;
    Then while dragging, you can lock the two relative to each other like so:

    Code (CSharp):
    1. draggedPuppet.targetRoot.position = puppet.targetRoot.TransformPoint(p);
    2. draggerPuppet.targetRoot.rotation = puppet.targetRoot.rotation * r;
    Also would be a good idea to decrease pin weight for the upper body muscles of both puppets to allow them to pull each other some and prevent the pinning forces from fighting with the joint that connects the 2 puppets too much.

    Hey,
    I doesn't blend to the pose it had before staggering, it is just blending from the sampled pose to the animation as you reduce targetFixWeight to 0. If you change the animation, you should be able to see it play out.

    What calling FixTargetToSampledState from OnReadBehaviour does is it overwrites animation with the sampled pose (stored when SampleTargetMappedPose was last called). So every frame you call FixTargetToSampledState(1f), it just locks the target to that sampled pose. 0.5f would be a half blend of the sampled pose and the animation. 0 does nothing.

    What I saw in the video was the puppet blending from the sampled pose back to animation as the script reduced targetFixWeight to 0. Is that not what you wanted to do?

    Best,
    Pärtel
     
  41. renat_k

    renat_k

    Joined:
    Mar 22, 2016
    Posts:
    8
    Yeah!
    Thats what i asked about! Thanks!
     
  42. unity_rFuPAqTZJykZ_A

    unity_rFuPAqTZJykZ_A

    Joined:
    Sep 15, 2020
    Posts:
    4
    Hello,

    First, i'd like to say I really like this plugin ! I'm just having a bit of hard time to understand a few things:

    I don't really understand how behavior switching works. How does the BehaviorPuppet and behaviorFall are triggered ? I cannot find any entry point that makes the animator enter thoses states (Fall, GetUpProne/Spine).

    What i'm trying to do:
    I'd like to be able to kill a ragdoll after a jump animation (so mid air), and untill it touches the ground, the ragdoll is basically unpinned. Then once it touches the ground, it would starts the getting up animation.
    Also, how could I force the puppet to loose balance whenever I want ?

    I tried using puppetMaster.Kill, but calling this method disable the animator, and then I don't know how to make the character automaticly getting up.

    I feel like the behaviorPuppet cover this use case, but I cannot find the way to trigger the "Fall" state by myself, or force the loseBalance (I used the Humanoid third person puppet animator)

    Edit: I'm quite close to what I expect using BehaviorPuppet.Unpin() on the jump OnStateExist trigger , however there is a very annoying glitch I cannot get rid of. The base controller (rig + capsule ) teleport/blink directly on the floor just after the ragdoll gets unpinned. And it creates the glithchy ragdoll looks. Here is the example:



    Thank you
     
    Last edited: Nov 17, 2020
  43. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Hi, i’m debating with a character modeller the best way to create a skinnedmesh character to be able to detach limbs without the streched skin issues. Any guidelines to folow to achieve that? The demo uses a skeleton but it doesn’t have the standard character config you see in almost all the high quality models. For example one model we tried to dismember has a root skeleton as usual and then head, arms torso and pants as separated skinnedmesh models. But when detaching the head, the skin is streched gluing the head in the floor with the rest of the model. Any help would be much appreciated. Best regards!
     
  44. mcaldei01

    mcaldei01

    Joined:
    Dec 8, 2017
    Posts:
    12
    I have just bought this asset today, and it works great on pinning to the animations, however, I cant seem to find the correct way to apply impulse force to a character (example: a "puppetmaster" AI character) to project it to a relative far position and make it stand up in the same position which is thrown to.
    Instead of this, the character seems to always return to the position it was before force was applied to it. Can you help me please ?

    For "ragdoll" activation and deactivation I am using

    Activate:
    pupMast.pinWeight = 0;
    pupMast.muscleWeight = 0.3f;
    Deactivate:
    pupMast.pinWeight = 1;
    pupMast.muscleWeight = 1;

    I am also playing a "GetUp" animation in animator when I run the deactivate code.

    Thank you.
     
  45. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey,
    On the bottom of BehaviourPuppet you'll find the "On Lose Balance" event. The event has a "Switch To Behaviour" field and if it's set to "BehaviourFall" it will switch to fall behaviour when the puppet loses balance or you call Unpin(). Likewise BehaviourFall has the "On End" event that switches back to BehaviourPuppet.

    About the bug, haven't seen that one before. Mind sharing a screenshot of your BehaviourPuppet settings?

    Hey,

    Slicing the ragdoll can be done with PuppetMaster, but slicing the SkinnedMeshRenderer needs to be done in a specific way for that to work without problems. 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 package if you are interested in trying that. 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, thanks for the purchase!
    What you are trying to do is already done automatically by BehaviourPuppet. That's what takes care of losing balance and getting up. Find the "Puppet" prefab in the package, drag it to your puppet, parent to the "Behaviours" gameobject. Also find the "Humanoid Third Person Puppet" animator controller and copy the "BehaviourPuppet" and "BehaviourFall" sub-state machines over to the animator controller that you are using. Then make a transition from BehaviourPuppet to your idle animation state.
    Check the "Puppet", "Puppet Extended" and "Melee" demo scenes for reference.

    Cheers,
    Pärtel
     
  46. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    548
    Thanks a lot! I'll dive into that.
     
  47. unity_rFuPAqTZJykZ_A

    unity_rFuPAqTZJykZ_A

    Joined:
    Sep 15, 2020
    Posts:
    4
    Thanks, here are the settings (events are empty)
    Also i unchecked hand and foots for ragdoll generation (I don't think it's related)
     

    Attached Files:

  48. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hi!
    Thanks for that, I managed to find and fix the bug. Please import this patch (for PM v1.0).

    Best,
    Pärtel
     
  49. Mikekan13

    Mikekan13

    Joined:
    May 30, 2015
    Posts:
    90
    So it has been a bit since I've been on here so I'm sure this has been answered before. I converted my project over to steam VR 2.0 and now I am having my body jitter a bit in VR. I fixed this in the past and everything was pretty smooth but that was so long ago. I am using puppetmaster and Final IK on my player body and I have SteamVR update modes set to onUpdate for the input mode and onlateupdate for poseupdate. I am also using an old locomotion animation script from you (I suspect this could be the problem) EDIT: NM I turned that script off and still get jitter. any help is appreciated. EDIT2: It seems to be when the camera is moving. Stationary there is almost no Jitter.
     
    Last edited: Nov 23, 2020
  50. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,552
    Hey. Setting Pose Update Mode to OnLateUpdate (and just OnLateUpdate, not both OnLateUpdate and OnPreCull) normally fixes that jitter. If not, it must be something updating after VRIK has solved for the frame or something updated at a different frequency (LateUpdate vs FixedUpdate), because VRIK always reaches it's targets 100% within a single update step when they are in reach.
    By "when the camera is moving" did you mean just moving your head or did you mean something like thumbstick locomotion? Maybe your thumbstick loco is updated in FixedUpdate, so it is out of sync with IK being updated every frame?

    Usually those jitters are best debugged in extreme slow motion. If you can't see it in slow-mo, also increase the fixed time step, it helps to understand what is going on exactly. For example if you set time scale to 0.1 and fixed time step to 0.1, you'll see everything going on in FixedUpdate updating every second and everything else continuously. If the motion is snappy, then it is a variable frequency jitter and you'll need to make rigidbodies interpolate or move some code out of FixedUpdate to LateUpdate or set Animator update mode to Normal. If you can't figure it out, make me a slow-mo video, I might be able to spot something.

    Cheers,
    Pärtel