Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

PuppetMaster - Advanced Character Physics Tool [RELEASED]

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

  1. the_unity_saga

    the_unity_saga

    Joined:
    Sep 17, 2016
    Posts:
    261
    hey dev, thanks again for your continued customer support!

    uhm, this is a easy one, but whats the best way to move an example puppet master character with an animator on to a moving platform? the puppets just fall off by default and I think most solutions use raycast to match velocity

    and also, whats the best way to manage puppet master to become "kinematic" for a time, and only initialized as a ragdoll/animated ragdoll based on case (switch). I've been experimenting but wanted your expertise.

    Thank you again for your hard work.
     
  2. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Probably at some point, but can't promise when I'll get there, so much stuff to do. I hear it requires custom physics simulation, which is supported by PM. Here's a snipped about that:

    Code (CSharp):
    1. using UnityEngine;
    2. using RootMotion.Dynamics;
    3.  
    4. public class PhysicsSimulate : MonoBehaviour {
    5.  
    6.     public PuppetMaster[] puppetMasters = new PuppetMaster[0];
    7.  
    8.     void Start () {
    9.         Physics.autoSimulation = false;
    10.  
    11.         if (puppetMasters.Length == 0) Debug.LogError("Please assign all PuppetMasters in the scene to PhysicsSimulate.puppetMasters array.");
    12.  
    13.         foreach (PuppetMaster puppetMaster in puppetMasters)
    14.         {
    15.             puppetMaster.enabled = false;
    16.         }
    17.     }
    18.  
    19.     private float timer;
    20.    
    21.     void Update()
    22.     {
    23.         timer += Time.deltaTime;
    24.  
    25.         // Catch up with the game time.
    26.         // Advance the physics simulation in portions of Time.fixedDeltaTime
    27.         // Note that generally, we don't want to pass variable delta to Simulate as that leads to unstable results.
    28.         while (timer >= Time.fixedDeltaTime)
    29.         {
    30.             timer -= Time.fixedDeltaTime;
    31.  
    32.             foreach (PuppetMaster puppetMaster in puppetMasters)
    33.             {
    34.                 puppetMaster.OnPreSimulate(Time.fixedDeltaTime);
    35.             }
    36.  
    37.             Physics.Simulate(Time.fixedDeltaTime);
    38.  
    39.             foreach (PuppetMaster puppetMaster in puppetMasters)
    40.             {
    41.                 puppetMaster.OnPostSimulate();
    42.             }
    43.         }
    44.  
    45.         // Here you can access the transforms state right after the simulation, if needed
    46.     }
    47. }
    48.  
    How bad is the framerate lol?
    Haven't noticed that problem myself, but have you tried using AnimatePhysics update mode in the Animator? With normal mode there can be lots of physics updates per frame without updating the animation in between, so maybe that's what's causing the problem.

    Hey,
    If you go to BehaviourBase.cs and comment out the code in protected virtual void GroundTarget(LayerMask layers) line 404, does it change/fix it? Just so I know where to look the problem from.

    Hey,
    Haven't seen that here. Do you have any other errors/warnings from PuppetMaster in the Console?
    Does anything look broken?
    If you could send me a package with that puppet along with the character fbx, I'd have a look.

    About the other question, did you mean you wanted the hand of the character stay in place kinematically and the rest of the body to be a free ragdoll hanging from it? There's the "Hanging" demo about that. Basically you ragdoll the entire puppet and just fix the hand in place with a FixedJoint to a kinematic rigidbody.

    Hey, about the moving platform, there have been some developments and bug fixes about that. Please PM me with your invoice number so I could send you the latest. These fixes will be included in the next version that I'm just about to wrap up and publish probably next week.

    About setting puppet to Kinematic, should use PuppetMaster.mode for that. Can keep it in Kinematic or Disabled mode, add a sphere trigger collider to the character and set mode to Active if there's something meaningful entering that trigger.

    Cheers,
    Pärtel
     
  3. WonkyDonky

    WonkyDonky

    Joined:
    Aug 24, 2014
    Posts:
    65
    No, I would like what happens when you set puppetmaster mode to kinematic but just for eg. hand muscle, so that it still follows the animation, cause now if I set eg. hand rigidbody to kinematic manually - it stops following the animation - it's stuck in place

    And is there pre-existing way to add the puppet/muscle script to any rigidbody, so that chosen rigidbody would with the motors try to mimick the position and rotation of eg. object that moves by animation? Would it require a lot of modification? (I can do it myself)
     
  4. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    You can set Mapping Weight to 0 for that hand muscle, then it will follow the animation because it's rotation will not be mapped to the ragdoll.

    There is the Actuator component. It's basically the simplest form of a muscle. Controls ConfigurableJoint.targetRotation and slerpDrive to match the localRotation of a target Transform.

    Best,
    Pärtel
     
    WonkyDonky likes this.
  5. WonkyDonky

    WonkyDonky

    Joined:
    Aug 24, 2014
    Posts:
    65
    Yes, but then it doesn't have collision

    Looking at the code, it seems muscle.MoveToTarget() would need to called every frame and its only called when the mode is kinematic and for all of the muscles

    Maybe I will just increase the muscles rigidbody's mass to get the desired effect

    or is individually setting muscle spring and damper values per muscle possible?
     
  6. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Yes, if you expand the Muscles array, there are settings for each individual muscle. Muscle Weight is is a multiplier for muscle spring basically and damper is damper.

    If making punches stronger is what you're trying to do, you should also try using the Boosters. They can be used to give temporary immunity and/or impulse multiplier to specific muscles or muscle groups.
    Declare a public Booster booster; somewhere in your scripts and call booster.Boost(behaviourPuppet);
    Like this booster in the Melee demo, it gives 0.5 immunity to the prop muscle and impulse multiplier of 5 makes in unpin other puppets 5 times more on collision with them.
    Boost effect falls off over time, defined by Boost Falloff in BehaviourPuppet. Value of 1 means the effect is gone in 1 second.

    upload_2022-10-10_16-47-42.png

    Best,
    Pärtel
     
    WonkyDonky likes this.
  7. Blackleon

    Blackleon

    Joined:
    Aug 20, 2017
    Posts:
    1
    I had the same issue on 2021 and we've discussed over it with my Lead. We found a weird solution;
    Disable puppet master root object. Save your scene. Hit Play. Enable root object on runtime. Exit play mode. Enable your root object again and save the scene. I havent checked the results on build but it no longer bends in the editor.
     
  8. baumxyz

    baumxyz

    Joined:
    Mar 31, 2017
    Posts:
    107
    Hi @Partel-Lang

    I own Puppet Master for a long time and I'm trying to integrate it for the first time. I only need Puppet Master for a few scenarios. For example: character falls down and on impact ragdoll mode is activated for a short time.
    The problem is that I have a certain structure predefined in my character due to various dependencies of other assets.

    This is how it currently looks like:
    cc_struct.jpg

    Can this work, or does the hierarchy necessarily have to look different?

    Thanks in advance!
     
  9. InfinityGameDev

    InfinityGameDev

    Joined:
    Jun 28, 2016
    Posts:
    54
    Hi Partel, been working on a demo game but am getting a curious bug. Whenever the player gets hit it glitches out:


    I have the animator set to always animate and animate physics, but can't really figure out what else is going on. The player and puppet are on 2 different collision layers so that's not it. The animator is pretty much just copied from the third person puppet demo, with attached Fall and Behavior Puppet(with fall) behaviors. Any ideas?
     
  10. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Please just enable "Support Translation Animation" in PuppetMaster to fix it for now.

    Hey,
    The thing is, PuppetMaster must not be parented to the character controller. That is because it must not inherit any motion from any gameobject. You can keep that hierarchy in editor, but unparent PuppetMaster from it in Start.

    Hey,
    Does changing Animator update mode to Normal change it? Are you moving the puppet or is the world moving around it? What happens when you just call behaviourPuppet.SetState(BehaviourPuppet.Unpinned) instead of having a collision unpin it?

    Best,
    Pärtel
     
    baumxyz likes this.
  11. WonkyDonky

    WonkyDonky

    Joined:
    Aug 24, 2014
    Posts:
    65
    Didn't this fix it?: ↓
     
  12. baumxyz

    baumxyz

    Joined:
    Mar 31, 2017
    Posts:
    107
    Hey, thank you, that makes sense!

    I have one more question:

    Is there an example of the following situation? Or what would be the best way to proceed here?

    1. character is hit and falls to the ground
    2. puppet master/raggdoll mode is activated and character rolls over ground
    3. if character stops moving, then initiate get up state
    4. deactivate Puppet Master/Ragdoll Mode and play stand up animation

    But now I have the following problem. When I switch from step 3 to 4, my non-puppet master model has to be on the ground just like the puppet master model. How can I create this state? And then I want to blend a transition from the current lying state into a stand up animation.
     
  13. xuantruongx98

    xuantruongx98

    Joined:
    Jun 18, 2022
    Posts:
    3
    Just get started to PuppetMaster, I got a problem when Set Up PuppetMaster, when I press the button, it only created a copy of my character, nothing else. How do I fix it?
     
  14. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    BehaviourPuppet already does all that automatically for you. Find the "Puppet" prefab in the package and drag it to the "Behaviours" gameobject in the puppet hiearchy. Make sure the layers make sense, check Ground Layers and Collision Layers. Make sure you have getting up animations, can copy the "BehaviourPuppet" and "BehaviourFall" sub-state machines from the "Humanoid Third Person Puppet" animator controller and paste them into you own, then add a transition from the "BehaviourPuppet" sub-state machine to your idle animation. You can set puppetMaster.mode to PuppetMaster.Mode.Disabled to deactivate PM when you don't need it.

    Hey,
    Maybe you didn't create the ragdoll with BipedRagdollCreator first, before you added PuppetMaster?

    Best,
    Pärtel
     
    baumxyz likes this.
  15. xuantruongx98

    xuantruongx98

    Joined:
    Jun 18, 2022
    Posts:
    3
    I've created the ragdoll. This is the error from colsole: upload_2022-10-26_13-55-41.png
     
  16. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    1. Drag a new instance of the model into the scene
    2. Use BipedRagdollCreator to turn it into a ragdoll
    3. Add PuppetMaster component to the ragdoll
    4. Assign the original character prefab as "Animated Target" in PuppetMaster, set layers, click on Set Up PuppetMaster.
    That way PM will not have to duplicate the prefab and destroy components in it to set up the rig.

    Best,
    Pärtel
     
  17. ciapoide121

    ciapoide121

    Joined:
    Aug 30, 2014
    Posts:
    12
    Dear Partel,
    thank you for your continued support to PuppetMaster & FinalIK.
    I own both, and I cannot seem to find two pieces of info in the documentation, videos nor forums, so I'd like to ask you directly.
    1) What is JointBreakBroadcaster? I found it in one of the sample scenes but I cannot seem to find any documentation about this. Looking at the code seems like a way to "kill" a muscle after being hit or something. Is there a way I can get to know about this, and other hidden functionalities that I am not aware of? For example what you just described recently with the boosters - is there any documentation about it? How could I discover it earlier?

    2) In regards of integrating FinalIK and PuppetMaster together, after importing the Final-IK package found inside Puppetmaster _integration folder, is there anything else I need to do? I did read the documentation page on the topic, and the examples scenes related to updating physics before or after update - but it's not very clear to me if I should do something else, or what should I exactly use. For example, in the sample folders there are two scripts for RagdollAiming.cs and AimIKDemo.cs - I am trying to reverse engineer the sample scenes to understand how to make them work, but I would really benefit from having a more descriptive documentation.

    I think both issues derive from my need to have a more simple, step by step and comprehensive documentation for your asset which is absolutely outstanding. Thank you very much for your time and keep doing awesome! :)
     
  18. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,

    1) JointBreakBroadcaster is a component added by PuppetMaster, it checks if a joint has been broken (if you have set joint break force/torque to something other than Infinity), PuppetMaster needs to know about a broken joint because the joint will be destroyed and you'd get null reference exceptions without it. So it's just one of PM's internal screws that keep things together.

    2) Final IK integration in PuppetMaster is just a few examples of how the 2 assets could work together to create stuff like ragdoll aiming. In that demo RagdollAiming.cs runs everything. It first solves a pass of AimIK (before physics) to make the ragdoll aim at a target. Since aiming with physics can never be 100% accurate, it solves another pass of AimIK (after physics) to make sure aiming is perfect. As it solves after physics, it will not affect the ragdoll anymore and has only a cosmetic effect (final pose will not match the ragdoll 100%, but it's close enough). Finally, a pass of LimbIK is applied on the left arm to make sure the hands stays connected to the weapon as it is 2-handed.

    AimIK demo is just a simpler example of the above, without the Max Payne 3 ragdoll aiming stuff.

    I'm sorry I don't have full docs on every singe demo, as you might have noticed there are over 60 of them in FIK and some more in PM. Trying to reverse engineer the demos and reading through the tooltips and comments in the scripts is how I intended them to be used as a learning resource.

    Cheers,
    Pärtel
     
  19. InfinityGameDev

    InfinityGameDev

    Joined:
    Jun 28, 2016
    Posts:
    54
    Hi Partel, thanks so much for all your help so far. I've been a user for a couple of years now and am encountering a curious issue. When creating a puppet (as I've done many times before) on a character from mixamo, the limbs retract in on themselves. This is happening for every model I can test on. This is a new 2021.3.11 project and the first time using PuppetMaster in it. These are all models/characters that I've used for this before. Layers 0 and 6 also do not have collisions. I've embedded a video of me setting it up and was hoping you could take a look and tell me what I'm missing.


    Thank you,
    James
     
  20. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Please grab the latest version, that bug has been fixed.

    Best,
    Pärtel
     
  21. adventurefan

    adventurefan

    Joined:
    Jan 17, 2014
    Posts:
    229
    Hi, bought Puppetmaster recently and looking at the demos I'm curious what the technique would be with it to avoid landing collisions while in jumping mode or while standing on top of things. For example it's very odd that you can't stand on top of flat boxes in the demo, but fall off them. I could figure out a workaround of detecting the ground and turning off the PM system... but was wondering if anything was built-in to handle the feet landing behavior more specifically.
     
  22. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,

    Stuff you want to stand on should be on a layer that collides with the character controller capsule and that layers should also be included in BehaviourPuppet's "Ground Layers".

    Best,
    Pärtel
     
  23. khos

    khos

    Joined:
    May 10, 2016
    Posts:
    1,475
    Hi Pärtel,
    If possible could you provide some pointers on how I can improve the leg drag issue here, see in the is video:

    I think my scaling is bad, but it seems the back right leg is not working as I expect.
    Any tips would be welcome.
     
  24. adventurefan

    adventurefan

    Joined:
    Jan 17, 2014
    Posts:
    229
    Ah, great! That was very easy to implement. Just a raycast down and I have my own tagged physics objects. So if the tagged object is found within .2 below I switch it's layer to ground, then have a distance tracker for when they get far enough away from the object, flip it's layer back to collision. Works perfectly to be able to stand on top of anything if you jump on it, but also make it so you can run into the sides if you want that.
     
  25. OmnifariousStudios

    OmnifariousStudios

    Joined:
    Mar 12, 2018
    Posts:
    46
    Hey again Partel,

    I have a Pedestrian system in my game where each person is just an animated skinned mesh renderer. If they're hit, they create a basic ragdoll at runtime. This works okay, but now I'm trying to make it possible for my pedestrians to become puppetmaster ragdolls when they're hit, but without creating a basic ragdoll and then doing the full setup process at runtime.

    I know it's possible to share ragdolls in editor, and that we can create puppets at runtime, but can I do both? Share a pre-built ragdoll at runtime?

    What I'm trying so far:

    - I have multiple pre-made Puppetmaster ragdolls (without the character scripts or skinned mesh renderer). They were made from the same pedestrian model, copied, disabled, and placed in the scene.

    - At runtime, I parent one of these puppetmaster ragdolls to the pedestrian along with pre-built behaviors, set up all connections, enable them, and then call Initiate on all of the muscles.

    The Problem:
    - This technically works, the puppet is connected and all functionality seems to be there. But the issue is that the muscles/colliders are very off and rotated in the wrong directions.

    - If I pause the editor and use "Fix Muscle Positions and Rotations" I can see that they all move to where they should be, but the next frame they go back to their wrong position/rotation.

    - If I set it to Kinematic mode, I can see they are still off, with the arm colliders now pointing out and away from the body.

    My best guess is that there are some cached values I need to reset/recalculate when attaching and reconnecting the puppet rig. Any advice?

    Thanks!

    Ragdoll setup in editor:
    upload_2022-12-6_13-13-9.png


    Playmode:
    Left: Ragdoll setup in Editor
    Right: Ragdoll setup using pre-built ragdoll rig attached and connected at runtime.
    upload_2022-12-6_13-30-33.png



    Runtime ragdoll when set to "Kinematic" mode.
    upload_2022-12-6_13-32-46.png
     
  26. SmurfJuggler

    SmurfJuggler

    Joined:
    Jan 2, 2014
    Posts:
    7
    I'm using VRIK and Puppetmaster for a VR game, I introduced animation yesterday and have had nothing but trouble since (previously I was using procedural locomotion)

    Specifically, in a build on Quest 2 or Pico 4, the player character is jittery, like its jumping out of position and snapping back periodically, then after a while, seemingly exacerbated by moving or shake my hands around it just flies off into space at warp speed, sometimes it vanishes without a trace, sometimes I see it orbiting around me, jittering around in the distance. I've disabled all collisions in Project Settings/Physics thinking it may have been some weird collision thing but it wasn't that. In fact, so far the only ways I've found to make it stop are disabling Puppetmaster entirely, switching Puppetmaster to kinematic, or reverting back to procedural locomotion in VRIK.

    The frustrating thing is, these issues don't occur on PC if I run a preview (again to quest, but via air link) - it's *only* when it's running standalone on a headset which makes debugging a soul destroying time sink. If you have any ideas of things I can try, please put me out of my misery so I can get back to working on my game!

    (I'm using mixamo animations if it's anything weird about them, although the previews on the individual animations, the previews in the animator/blend tree, and the animations in-game when previewing on PC all look fine)

     
  27. TymNetwork

    TymNetwork

    Joined:
    Jan 16, 2014
    Posts:
    84











    I would say... check the collision physics. it looks like its bumping into itself
    I have VRIF and I seen that PUPPETMASTER has updated its product.

    www.DontGiveA.Com Studio
     
    simonkingandaoking likes this.
  28. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Not sure without knowing more. But the leg rest positions are calculated at Start, maybe rotate the leg bones to get the feet closer together.

    Hey,
    Creating a ragdoll and setting up PuppetMaster at runtime when they're hit is not the best idea if you ask me. PuppetMaster initialization takes quite a lot of time, so you'll probably get a spike every time a character is hit.
    I'd recommend setting up the puppets in editor, then just set puppetMaster.mode = PuppetMaster.Mode.Disabled and only set to Active when needed.

    Hey,
    Maybe there's a problem like updating VRIK in LateUpdate, but Animator in FixedUpdate (using AnimatePhysics update mode). Does anything change if you switch Animator update mode?

    Anyway, on a fixed framerate device like Quest2, I'd consider turning off Physics.autoSimulation and just call a Physics.Simulate(Time.fixedDeltaTime) once per frame. Only way to get really smooth physics in VR. Physics will slow down if you miss the framerate, but you really shouldn't miss the framerate in any case.

    You can update PuppetMaster with custom physics simulation if you disable the PuppetMaster components at start and call puppetMaster.OnPreSimulate() before Physics.Simulate() and OnPostSimulate() after;

    Best,
    Pärtel
     
    khos likes this.
  29. SmurfJuggler

    SmurfJuggler

    Joined:
    Jan 2, 2014
    Posts:
    7
    Crikey you're right. Well at least it's something physicsy. I had disabled everything in the layer collision matrix thinking that would rule out physics but it was still happening, and yet sure enough when I disable Physics.autosimulation it goes away :/

    It does, the behaviour I've been seeing thus far (animation working as expected, character randomly flying away into space) were with the animator update mode set to Normal. If I switch this to Animate Physics, the character no longer flies away, but animations don't work correctly (I just get the idle animation playing all the time, there's no transitioning to other animations when I move around)

    This sounds great, but I'm a bit lost. I've given it a try but the ways I've tried all seem to result in my colliders being nowhere to be found, or just playing the animation on its own with no mapping to the vr rig. Let's call it a lack of knowledge and experience on my part :)

    So given what you've said and looking at https://docs.unity3d.com/2017.3/Documentation/ScriptReference/Physics.Simulate.html, I guess I need something that has some kind of resemblance to this?

    Code (CSharp):
    1.  
    2.     void Update()
    3.     {
    4.         if (Physics.autoSimulation)
    5.             return;
    6.  
    7.         timer += Time.deltaTime;
    8.  
    9.         while (timer >= Time.fixedDeltaTime)
    10.         {
    11.             timer -= Time.fixedDeltaTime;
    12.             foreach (PuppetMaster p in playerManager.puppets)
    13.             {
    14.                 p.SwitchToDisabledMode();
    15.                 p.OnPreSimulate(Time.fixedDeltaTime);
    16.             }
    17.             Physics.Simulate(Time.fixedDeltaTime);
    18.             foreach (PuppetMaster p in playerManager.puppets)
    19.             {
    20.                 p.OnPostSimulate();
    21.                 p.SwitchToActiveMode();
    22.             }
    23.         }
    24.     }
    25.  
     
  30. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    No I meant just do this:

    Code (CSharp):
    1. void Update() {
    2. foreach (PuppetMaster puppetMaster in puppetMasters)
    3.             {
    4.                 puppetMaster.OnPreSimulate(Time.fixedDeltaTime);
    5.             }
    6.  
    7.             Physics.Simulate(Time.fixedDeltaTime);
    8.  
    9.             foreach (PuppetMaster puppetMaster in puppetMasters)
    10.             {
    11.                 puppetMaster.OnPostSimulate();
    12.             }
    13. }
    and make sure you set Time.fixedDeltaTime to 1f / device refresh rate.

    Best,
    Pärtel
     
  31. SmurfJuggler

    SmurfJuggler

    Joined:
    Jan 2, 2014
    Posts:
    7
    Thanks, it didn't help though, with that the Puppetmaster component is (somehow) disabling itself when the game starts, and I'm ending up with a character who flips between VR and animated positions every frame. I don't really understand enough about how the different plugins I'm using work together, I see puppetmaster disables the animator, but I need the animator to be enabled for VRIK animated locomotion, so my logs fill up with thousands of "Trying to use VRIK animated locomotion with a disabled animator"?

    I notice also that my character's feet are slowly sliding away and pinging back which I guess is something to do with the Mixamo animations, and could be a contributing factor in the flying away issues I'm seeing. I don't know, too many moving parts.
     
  32. SmurfJuggler

    SmurfJuggler

    Joined:
    Jan 2, 2014
    Posts:
    7
    - misleading gibberish removed -
     
    Last edited: Feb 19, 2023
  33. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,

    I'm going to delete these lines of IKSolverVRLocomotion_Animated.cs:
    upload_2022-12-30_13-8-38.png

    So please do the same, will get rid of the "Trying to use VRIK animated locomotion with a disabled animator" issue when using together with PM so you wouldn't have to use that second Animator, which can cause all kinds of problems.

    Best,
    Pärtel
     
    the_unity_saga likes this.
  34. MirzaBeig

    MirzaBeig

    Joined:
    Dec 27, 2014
    Posts:
    602
    Hi, PM has been really useful in my project, but now I'm porting it to online multiplayer and it's not working well with Photon Fusion.

    When running as a server/host, everything is as expected, but as a client, the animation plays too fast (although other than that, it works fine).

    upload_2023-1-1_8-26-3.png
    (ignore the red underline- I was playing around with changing the function as you'll see further below...)

    The issue as far as I can tell is that BeforePhysicsStep may be called many times due to re-simulation.

    > https://doc.photonengine.com/en-us/fusion/current/manual/animation/
    > https://doc-api.photonengine.com/en/fusion/current/interface_fusion_1_1_i_before_physics_step.html
    > https://doc-api.photonengine.com/en/fusion/current/interface_fusion_1_1_i_after_physics_step.html

    If I do the following without checking IsForward, the animation plays too fast, but if I make sure to only Update when the simulation is moving forward as you see in the screenshot below, the animation plays at the correct speed.

    upload_2023-1-1_8-29-27.png

    That tells me the issue is the re-simulation.

    Unfortunately, I can't wrap the entire OnPreSimulate and OnPostSimulate calls into the bool as that doesn't seem to work either. If I modify OnPreSimulate to OnPreSimulate(float deltaTime, bool updateAnimator), and then pass Runner.IsForward as the bool, things are more stable, but there are still issues.

    upload_2023-1-1_8-31-43.png

    upload_2023-1-1_8-40-53.png

    The above two images/changes (with updateAnimator) almost fix the problem, but the whole thing glitches when jumping, so I'm missing something.

    What changes would need to be made for PM to play nice with Fusion re-simulation? I think if I can isolate the updating of the animator from whatever updates PM needs to make after that, that should work, yes?
     
  35. Jyunaut

    Jyunaut

    Joined:
    Jun 2, 2014
    Posts:
    2
    Hi guys, my team has been currently playing around with PuppetMaster for our project and we have been having a blast with it. We're currently working on a sword-fighting game and we would like the weapons to physically interact with each other during swings and realistically give reactions to the body based on those physical collisions.

    However, we have come across some issues regarding the collisions and would like some advice on what we could do to solve them.

    Case 1: Preventing the Prop from leaving the Prop Hand during a collision


    Expected result: The Prop should remain attached to the hand during the swing while reducing the jitteriness on the weapon.

    What we tried: Compared to the other parameters, adjusting the Pin Weight on the weapon seems to help the most with regards to reducing the jitter when colliding, however, we could never really solve the Prop leaving the hand issue.

    Case 2: How to let the Prop collisions have more influence on the arm depending on where the sword was hit and how fast


    Expected result: Instead of mostly just the wrist, the entire enemy arm should move along with some rotation on the weapon.

    What we tried: A mix of lowering the Pin Weight and increasing the Muscle Damper (to reduce the springiness when returning to its desired position) on the arm and upper body seemed to make some difference, but not until the whole arm begins to sag. We are wondering if we should have this sort of interaction dynamically adjust the pin weights through code, but we would like some feedback first before so.

    Any sort of advice on handling these weapon collisions will be greatly appreciated!
     
  36. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    PuppetMaster.OnPreSimulate() has
    Hey,
    Please try this:
    upload_2023-1-6_12-13-22.png

    If Animator is not updated before some physics steps. FixTargetTransforms() will still put the character in its default pose, without the Animator overwriting it and that will mess up the continuity of animation and physics.

    Hey,
    In BehaviourPuppet's "Group Overrides" you can decrease collision resistance and increase Unpin Parents for the Prop group.
    But you can improve things more on the animation side. Add a float parameter called "AttackSpeed" to the Animator. set its default value to 1, use it as a Speed Multiplier for all your attack animations. When the prop gets a significant collision while attacking, set AttackSpeed to something like -0.3f and crossfade to the idle animation. That will reverse your attack animation and crossfade at the same time, making it look like you hit a wall and should look pretty good even without any physics.

    Best,
    Pärtel
     
    Jyunaut likes this.
  37. MirzaBeig

    MirzaBeig

    Joined:
    Dec 27, 2014
    Posts:
    602
    @Partel-Lang

    Thank you- yes, that works better, but still problematic.

    upload_2023-1-6_5-59-31.png

    With the above modification of the highlighted line, I'm getting jumps which I think are occurring due to some frames just being re-sims. How might PM handle the re-simulation frames elegantly?



    In the video, the TOP client is also the server/host, while the BOTTOM client is connected.

    The top client's frames are always forward, while the bottom may re-simulate some frames, which causes hiccups with PM that unfortunately scale with latency issues.
     
    Last edited: Jan 6, 2023
  38. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    117
    Hi Mr. Partel,

    I'm having a ton of issues syncing knocked down npcs through the network.

    A long time ago you made a nice script that would sync the body parts position of knocked down opponents, however that's very heavy net wise. I tried syncing the general position of npcs, however it's causing a lot of issues.

    What I want is a knocked down npc to be synchronized, however it doesn't matter if for one player the npc is turning belly up and for the other is belly down. As long as the center mass position is accurate, it's good for me.

    Or if you have an alternative, I would be happy as well.



    I also have another issue, I'm using HurricaneVR, and when I stab opponents one of 2 things happen. Or the weapon tries to follow the opponent making a very strange jiggle movement or if I decrease the strength of the puppetmaster the opponent will ragdoll all over the place sometimes.

    I have tried for 10 hours messing with the settings of HVR and Puppetmaster, but had no success. Do you have a solution for this?

    https://media.discordapp.net/attach...280908/Desktop_2023.01.07_-_19.48.53.01_3.gif



    Many thanks Mr. Partel!
    Gabriel.
     
    Last edited: Jan 11, 2023
  39. Massonator

    Massonator

    Joined:
    Feb 7, 2013
    Posts:
    4
    Hi Partel, love the asset, but I have having some problems after recently updating to 2020.3.43, and was hoping you could help point me in the right direction for a fix. (I've narrowed the specific breaking update to be 2020.3.42 -> 2020.3.43).

    I'm using UMA to generate my characters, and I am waiting for an event from the UMA generator to say the character is created. On that event, the ragdoll and PM instance is created. This is done using the UMA Puppet Master tools scripts you provided earlier in this thread.

    On v2020.3.43, the generated ragdoll is being created with what appears to be the wrong rotation, as if it has rotated 90 degrees in both X and Y axes after it has been created. Debugging shows that the Ragdoll hips match the base characters hips position/ rotation, until after the ragdoll instance has been destoryed.

    I've been sifting through release notes for v2020.3.43, but I cannot find anything that may have caused the bug. I have attached a screenshot of how the ragdoll is being generated.

    pm bug.png


    This is possibly an UMA issue, but the UMA character seems to be being generated as expected, and it does not appear to be broken in any way so I'm inclined to believe its an issue in how the ragdoll is being created. Adding ragdolls manually and creating puppets from them seems to all work as expected.

    Any help you can provide would be very much appreciated! Cheers!
     
  40. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Made a little Fusion test project here and ran into the same issue. Only way I got rid of the jumpiness was like this> (lastTargetPos/Rot stuff)

    upload_2023-1-12_15-39-53.png

    PuppetMaster needs the animated target to be moving smoothly and continuously, It can't handle jumping back and forth due to resimulation or whatever, it will mess up rigidbody velocities. I don't even know why the solution above works, I'd take a look at their NetworkRigidbody code to see how it's supposed to be done with Fusion, but sadly they don't provide the source code for it.

    Hey,
    When syncing all ragdoll rigidbodies is too much bandwidth-wise, could try syncing just a few, I mean maybe just the pelvis and spine would be enough to keep the remote ragdolls roughly in sync.

    About the stab, not sure what's going on there without more information. Is the stab constraint made with a ConfigurableJoint? Did you try loosening the pin weights of the upperbody when you stab it?

    Best,
    Pärtel
     
  41. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,

    Not sure, but BipedRagdollCreator does require the character to be rotated so that it faces the positive Z axis of the root and I notice it's looking at negative Z in your screenshot.
     
  42. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    117
    So the issue was happening because I was using animator.Play(Hash, 0, 0);
    So there was no blend time, and the opponent was "teleporting" their body parts to the next animation.

    However, I'm not sure if it's a new thing, now you can play Hash animations with blend time like this:

    animator.CrossFade(hash, 0.1f, 0, 0);

    And it solved the issue =)
     
    Partel-Lang likes this.
  43. nicknick_

    nicknick_

    Joined:
    Mar 31, 2017
    Posts:
    11
    Hi there!

    Is there a way to get a collision info regardless of which muscle was hit? Im looking for a really general way of detecting the hit velocity at the time of collision. Using playmaker by the way, but with Playmaker you can get properties and public variables from components, so maybe there is a way?
    Additionally, can you get a single “amount of force” value at the time a BehaviorPuppet lost balance?

    Cheers,
    Nick
     
    Last edited: Feb 2, 2023
  44. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Here's an example script about doing some things like playing animation on collision:

    Code (CSharp):
    1. using UnityEngine;
    2. using RootMotion.Dynamics;
    3.  
    4. public class PuppetCollisionHandler : MonoBehaviour {
    5.  
    6.     public BehaviourPuppet puppet;
    7.     public int ragdollLayer = 9;
    8.  
    9.     void OnEnable()
    10.     {
    11.         puppet.OnCollision += OnCollision;
    12.     }
    13.  
    14.     private void OnCollision(MuscleCollision m)
    15.     {
    16.         var muscle = puppet.puppetMaster.muscles[m.muscleIndex];
    17.         Debug.Log("Collision with muscle: " + muscle.props.group);
    18.  
    19.         // Handle collisions depending on which muscle group was hit.
    20.         switch(muscle.props.group)
    21.         {
    22.             // Play animation when there is a collision between the head of this puppet and any body part of another puppet
    23.             case Muscle.Group.Head:
    24.                 if (m.collision.collider.attachedRigidbody == null) return;
    25.                 if (m.collision.gameObject.layer != ragdollLayer) return;
    26.  
    27.                 // Make sure the other rigidbody belongs to a puppet
    28.                 var otherBroadcaster = m.collision.collider.attachedRigidbody.GetComponent<MuscleCollisionBroadcaster>();
    29.                 if (otherBroadcaster == null) return;
    30.  
    31.                 // Discard if collision too weak
    32.                 if (m.collision.impulse.sqrMagnitude < 1f) return;
    33.  
    34.                 // If you need to access the other muscle
    35.                 //var otherMuscle = otherBroadcaster.puppetMaster.muscles[otherBroadcaster.muscleIndex];
    36.  
    37.                 // Play different hit reaction animation for hits from left and right side
    38.                 bool hitFromRight = Vector3.Dot(puppet.puppetMaster.targetRoot.right, m.collision.contacts[0].normal) < 0f; // Use GetContact(0) instead of contacts[0] in newer Unity versions (GC Alloc issue)
    39.                 if (hitFromRight)
    40.                 {
    41.                     Debug.Log("Puppet " + puppet.puppetMaster.name + "'s head was hit from the right side.");
    42.                     // Play head hit reaction from right animation (need to have an animation state with the same name in the Animator)
    43.                     puppet.puppetMaster.targetAnimator.CrossFadeInFixedTime("HitHeadRight", 0.2f);
    44.                 } else
    45.                 {
    46.                     Debug.Log("Puppet " + puppet.puppetMaster.name + "'s head was hit from the left side.");
    47.                     // Play head hit reaction from left animation (need to have an animation state with the same name in the Animator)
    48.                     puppet.puppetMaster.targetAnimator.CrossFadeInFixedTime("HitHeadLeft", 0.2f);
    49.                 }
    50.  
    51.                 break;
    52.         }      
    53.     }
    54.  
    55.     void OnDisable()
    56.     {
    57.         if (puppet != null) puppet.OnCollision -= OnCollision;
    58.     }
    59.  
    60. }
    BehaviourPuppet loses balance on one condition only and that is if a muscle drifts past Knock Out Distance from it's animated target, so there's no force at play there.

    Best,
    Pärtel
     
    nicknick_ and hopeful like this.
  45. nicknick_

    nicknick_

    Joined:
    Mar 31, 2017
    Posts:
    11
    Hi Pärtel,

    wow, thank you so much!!
     
  46. Daezalus

    Daezalus

    Joined:
    May 16, 2020
    Posts:
    9
    Hi Partel, you're probably aware of it, but just to let you know about a warning when importing Puppetmaster into 2022.2.5.

    - PuppetMaster(453.20) warning CS0618: 'Physics.autoSimulation' is obsolete; replaced by 'Physics.simulationMode.'
     
    Partel-Lang likes this.
  47. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    117
    Hi Partel,

    How can I make a puppet stand up no matter what?

    Because sometimes when playing multiplayer, on one PC the puppet will stand up and the other it will still be laying on the ground.

    I have increased the spring muscle by a lot when a puppet is down and it helps, but it doesn't work always, and I also trigger this code for the other players, however it doesn't always work either, and it makes the puppet sometimes get up and fall again and get up it seems.

    behaviourPuppet.SetState(BehaviourPuppet.State.GetUp);


    Many thanks,
    Partel.
     
  48. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    In multiplayer you should set behaviourPuppet.knockOutDistance to Mathf.Inifity and behaviourPuppet.canGetUp to false for all the remote instances. Control the remotes via RPC calls to SetState when the owner's state changes.

    (there's a PUN2 example included in the Integration folder)

    Best,
    Pärtel
     
  49. trzy

    trzy

    Joined:
    Jul 2, 2016
    Posts:
    128
    Hi Partel,

    Thanks for your great work! I posted in another forum but realized belatedly this is where you are :)

    I'm encountering trouble using root motion for moving characters. I have a character that walks using root motion (an OnAnimatorMove callback is used to actually move). Pretty basic stuff.

    Every now and then -- and this is almost impossible to replicate reliably -- the physics rig gets launches into the floor or elsewhere. We've narrowed this down to root motion specifically. Normally, Puppetmaster is quite tolerant to sudden collisions (e.g., switching on a box collider that envelops all or most of the character). But occasionally, just standing on a ground plane will cause this behavior, which makes the character disappear (because the physics rig has been blown clear away, with the skinned mesh following that).

    I'm not clear how to debug this problem. I used the ragdoll creator script and didn't really feel the need to adjust any of the resulting colliders (and I'm not sure exactly which interactions are causing this because the problem is so rare).

    Thanks,

    Bart
     
  50. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,542
    Hey,
    Haven't seen that one before. Maybe there's a problem in the Animator like a transition with 0 length or using Animator.Play to switch to another pose instantly that could break the physical continuity? Maybe it happens when Animator gets culled and it needs to be set to Always Animate.

    Best,
    Pärtel