Search Unity

PuppetMaster - Advanced Character Physics Tool [RELEASED]

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

  1. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    504
    Hey!
    I started to write a AStar Pathfinding Character Controller extension for Puppetmaster.
    looks like this at the moment:
    puppetmaster_astar2.gif

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. using RootMotion;
    5. using RootMotion.Demos;
    6.  
    7. using Pathfinding;
    8.  
    9. /*
    10. * Instructions:
    11. *
    12. * This script needs to be outside Plugins folder. Assets/Scripts for example is a good place.
    13. *
    14. * Attach this script to the Character Controller object. It needs to have a Seeker component attached (Unity should attach it automatically,
    15. * but that doesn't seem to always work).
    16. *
    17. */
    18.  
    19. [RequireComponent(typeof(Seeker))]
    20. public class ThirdPersonControllerWithPathfinding : UserControlThirdPerson
    21. {
    22.     public Transform moveTarget;
    23.  
    24.     public float stoppingDistance = 0.5f;
    25.     public float stoppingThreshold = 1.5f;
    26.  
    27.     // The path the character is currently following
    28.     private Path currentPath;
    29.  
    30.     // The seeker component actually performs the pathfinding
    31.     private Seeker seeker;
    32.  
    33.     // For only recalculating the path if the target has moved.
    34.     private Vector3 lastMoveTargetPosition;
    35.  
    36.     // Store the current waypoint
    37.     private int currentWaypoint = 0;
    38.  
    39.     private float sqrStoppingDistance;
    40.  
    41.     protected virtual void Awake()
    42.     {
    43.         // Cache the seeker for faster access
    44.  
    45.         seeker = GetComponent<Seeker>();
    46.  
    47.         sqrStoppingDistance = stoppingDistance * stoppingDistance;
    48.     }
    49.  
    50.     public override void Update ()
    51.     {
    52.         // If there's no target, we'll not be moving
    53.         if(moveTarget == null)
    54.         {
    55.             state.move = Vector3.zero;
    56.  
    57.             return;
    58.         }
    59.  
    60.         // If we don't have a path or the target has move, find a new path
    61.         if(currentPath == null || lastMoveTargetPosition != moveTarget.position)
    62.         {
    63.             // Remember to reset the current waypoint
    64.             currentWaypoint = 0;
    65.  
    66.             // Get the next path
    67.             seeker.StartPath (transform.position, moveTarget.position, OnPathComplete);
    68.  
    69.             // Remember the last position the path was sought to
    70.             lastMoveTargetPosition = moveTarget.position;
    71.         }
    72.         else
    73.         {
    74.             // The path is complete, so we'll just wait here.
    75.             if (currentWaypoint >= currentPath.vectorPath.Count)
    76.             {
    77.                 state.move = Vector3.zero;
    78.  
    79.                 return;
    80.             }
    81.  
    82.             float moveSpeed = walkByDefault? 0.5f: 1f;
    83.  
    84.             // Get the direction to the next node.
    85.             Vector3 direction = (currentPath.vectorPath[currentWaypoint]-transform.position).normalized;
    86.  
    87.             // Reset the y so we won't fly.
    88.             direction.y = 0f;
    89.  
    90.             float sD = state.move != Vector3.zero? stoppingDistance: stoppingDistance * stoppingThreshold;
    91.  
    92.             state.move = direction.magnitude > sD? direction.normalized * moveSpeed: Vector3.zero;
    93.  
    94.             // If we've reached the waypoint, move on to the next waypoint
    95.             // We're using the sqrMagnitude to avoid a costly square root calculation
    96.             if ((transform.position - currentPath.vectorPath[currentWaypoint]).sqrMagnitude < sqrStoppingDistance) {
    97.                 currentWaypoint++;
    98.             }
    99.         }
    100.     }
    101.  
    102.     // OnPathComplete is called when the Seeker component finds the path
    103.     private void OnPathComplete(Path path)
    104.     {
    105.         // Store the current path
    106.  
    107.         currentPath = path;
    108.     }
    109.  
    110. }
    111.  
    i also attached a unitypackage with script+demo scene to this post

    it works pretty fine at the moment but its not perfect.
    especially running curves lookes weird sometimes.
    so if anybody want to contribute, just go ahead :)
     

    Attached Files:

  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,453
    Hi - bug!

    In 5.5b7, when I use the ragdoll editor on an already-existing rig (I leave it on for changes throughout development, tweaks etc).

    What happens is I click Convert To Box Collider on the hand collider and it vanishes. Same happens with Convert To Sphere Collider. The collider is a capsule for the hand, but I now want to change it to something else. There is no error and this functionality worked fine before.

    I'm using the very latest from asset store, any thoughts are appreciated :)

    I do have a child collider I added to the head (for his nose, so it doesn't go through geometry) but this hasn't affected my tinkering of hands and feet in the past.

    I can probably change this manually but it's a pain without the nice symmetry tools etc ;)
     
  3. Alfonso_CJ

    Alfonso_CJ

    Joined:
    Nov 19, 2015
    Posts:
    35
    So how's the Stagger doing, Pärtel? ;)
     
  4. TommiH

    TommiH

    Joined:
    Jan 14, 2008
    Posts:
    252
    Hello,

    I'm really enjoying PuppetMaster and FinalIK, getting some really cool ragdoll effects done using the combo!

    But one thing bugs me about the way it seems to be set up: In the examples with ragdolls (such as the Grab example with the teddy bear) it seems the top root object of the ragdoll character's hierarchy never moves as the ragdoll is moved around via PuppetMaster (the animated target sometimes moves with the ragdoll). Which I would like to avoid in my game - I'd like the root object of my characters to always be where the character "is" - probably at or near the character's hips at all times. Is there any nice and clean way to achieve this without compromising the workings of PM?

    I have two reasons to want this: One is a matter of cleanliness of the scenes. The other is that if I make a character into a ragdoll by reducing their master pin to 0, let the physics move them somewhere, and then want them to get up again by increasing pin again, the character is dragged back to where the root is (or more precisely, where the animated bones are).

    I understand that often / most of the time it's good to let the animated bones and the main root object stay in one place and do any PM effects relative to those. It certainly makes sense with high-pinning setups where PM is used to respond to colliders etc. But is there a golden middle, maybe?
     
    Last edited: Oct 30, 2016
  5. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,453
    I had a similar question to partel a few pages back:

    From Unity:
    from http://blogs.unity3d.com/2016/04/13/unleashing-animation-and-audio-2/

    Partel's response was:
    I don't know if this would help your situation though, but worth bearing in mind!
     
  6. TommiH

    TommiH

    Joined:
    Jan 14, 2008
    Posts:
    252
    Thanks, hippocoder, but I'm afraid I don't understand what that has to do with my question.
     
  7. RickyX

    RickyX

    Joined:
    Jan 16, 2013
    Posts:
    280
    @PicturesInDark @Partel-Lang
    Hey. What happened to the problem you've had? When i play the "Falling" demo scene the character just falls through the floor. I don't want to touch anything, i expect the demo scenes to work without me editing anything. So any ideas why this is happening? Same happens to almost all scenes.
     
  8. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,453
    This is usually because your project's layers are all different or such. To try out the demos I would recommend you open a new project just for those and learn from that instead (that's what I do).
     
    Partel-Lang likes this.
  9. RickyX

    RickyX

    Joined:
    Jan 16, 2013
    Posts:
    280
    Okay well it works on a fresh project. But how exactly do i learn what's up from this? I still can't think of what could be going wrong in the original project. Well, a lot of things probably, which exactly is a problem.
     
  10. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hey, nicely done and thanks for sharing the script!

    Hi!

    I haven't been able to reproduce this issue. Downloaded 5.5.0b9, tried to convert colliders of all types, seems to work.
    I haven't changed anything with RagdollEditor for a couple of updates either.

    It's still where it was, there has been so much interest in VRIK, it has taken most of my time.

    Hi!

    The root is basically just a folder for the puppet character. It should not be moved, because doing so would also move the ragdoll, but it is supposed to be governed only by physical forces. So you should just move the target root (the one with the Animator) instead. Also when you start getting up, just move the target root to where the ragdoll hips are.

    It is so because of the dual rig setup. Technically, I could make it work without it, but it would make PM a lot slower.

    Hey,
    It is just the Layer Collision Matrix, thats all.
    Basically just make sure your character controller collides with the world, but doesn't collide with the ragdoll colliders.
    If using BehaviourPuppet, take a look at the "Ground Layers" and "Collision Layers" in there, the first is what your character walks on, the latter is what damages or unbalances it.

    I could make PM a full project import, but that would just override too many things in people's project settings and make it even more confusing probably to merge into existing projects.

    Cheers,
    Pärtel
     
  11. RickyX

    RickyX

    Joined:
    Jan 16, 2013
    Posts:
    280
    Oh wow, yeah that was it. Thank you i really wasn't sure. But why did you mark your ground's layer in the demo scene as the water? Just curious.
     
  12. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Just had to use the 4 or 5 default layers they have, otherwise layer masks would appear to be empty when imported to a new project where all the other layers are unnamed.
     
  13. TommiH

    TommiH

    Joined:
    Jan 14, 2008
    Posts:
    252
    Thanks for the response. Seems I'll need to adapt to this. There are fortunately some other upsides to keeping some things unmoved. I just think it'll be frustrating to have to open this top level folder every time I want to select the actual character in order to press F on it to find it in the scene. I know it's just one extra click and definitely PuppetMaster is worth it but...
     
  14. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    You could actually get rid of the root. Just make sure to assign the "Target Root" in PuppetMaster.
    But then you'll have the target and the ragdoll separate among other stuff and you'll be wondering which belongs to which.
     
  15. RickyX

    RickyX

    Joined:
    Jan 16, 2013
    Posts:
    280
    Okay i see.
    I have some questions now, it could be a bit hard to answer them. My time is really limited now, but so is yours and if you don't answer i won't judge. So I chose PM for handling my ragdolling as it seemed very nice and probably the best solution ever made for unity. What i'm planning to power up with it is my falling system and all of the humanoid characters that will be inside the game so i can handle deaths, and i'd also like to prevent body parts to clip through walls and maybe stop using capsule collider if possible?

    So what i currently have in my falling system is of course the "grounded detection". I also have 3 different landings (soft, medium/roll and hard landings).
    The question about that is how can PM make it better/improve it since it's raw animations now, and the falling animation looks a bit unnatural, and is there a better, more efficient and correct way to detect "grounding" using PM in a difference from mine which is just 4 raycasts with a capsule collider.

    And another question, how good is PM for performance? What if we for example had 100 bodies with PM effected by an explosion, or they all got into the "dead mode", would that even be possible to handle by an average PC, or at all? And also, does your "freeze" mode decrease the memory usage or anything at all? So would it increase performance if we used freeze for dead bodies that are not moving anymore in the game?

    Thanks in advance!
     
  16. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    480
    Hi there.

    I'm looking for some guidence on the ImmunityBooster. What I have is the following;

    Code (csharp):
    1.  
    2. //Add the RB's immunity so that, based on his endurance, can break a tackle or two.
    3. const float DEFAULTHITENDURANCE = 75.0f;
    4. {
    5. ... //other code
    6. }
    7. // mParent.Data.R_HitEndurance = 80.0f and ONEHUNDRED = 0.01f so we get a total of of 60.0f for this character.
    8. mParent.BehaviourPuppet.BoostImmunity(DEFAULTHITENDURANCE * (mParent.Data.R_HitEndurance * Globals.ONEHUNDRED));
    9.  
    10. //The boost falloff for this character will be 0.8f
    11. mParent.BehaviourPuppet.boostFalloff = (mParent.Data.R_HitEndurance * Globals.ONEHUNDRED);
    12.  
    The documentation isn't very clear on how this should work. It just says lower numbers. But what is the range? 0-1? 0 to 100? I'm really not seeing much of a difference to this characters ability to withstand a collision regardless of how I set these. Each character also has their own collision resistance value set, but again, I don't really see much difference.

    thanks
     
  17. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,

    I'm working on damage particle effects during combat between Puppet Master characters. When I instantiate the particle effects during runtime, I parent them to the character controller gameobject transform so they exist in the same localspace as the character. When I destroy those particle effects during runtime, I get MissingReferenceException errors. It appears that StoreTargetMappedState() is checking the entire child hierarchy of the Controller gameobject instead of just the skeleton Armature. Is this a bug? Or should I be using some other gameobject in the character hierarchy for attaching a detaching objects?

    MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Transform.get_localPosition () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineTransformBindings.gen.cs:40)
    RootMotion.Dynamics.PuppetMaster.StoreTargetMappedState () (at Assets/Plugins/RootMotion/PuppetMaster/Scripts/PuppetMasterTargetMappedState.cs:83)
    RootMotion.Dynamics.PuppetMaster.OnLateUpdate () (at Assets/Plugins/RootMotion/PuppetMaster/Scripts/PuppetMaster.cs:643)
    RootMotion.Dynamics.PuppetMaster.LateUpdate () (at Assets/Plugins/RootMotion/PuppetMaster/Scripts/PuppetMaster.cs:590)

    Any help would be appreciated.
    Thanks
    Allan
     
  18. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Well I found it to be more accurate to attach my damage particle effects to the PuppetMaster muscle objects upon collision using behaviorPuppet.puppetMaster.muscles[m.muscleIndex].transform.

    That way the particle effect is attached to the actual muscle object that was hit.

    However I still would like to know why deleting an object from the controller object during runtime results in a MissingReferenceException from StoreTargetMappedState().

    Thanks
    Allan
     
    recon0303 likes this.
  19. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hey,
    Thank you, you are absolutely right, it is a bug. Please download this patch.
    It should also speed things up a bit. :)

    Best,
    Pärtel
     
  20. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    254
    Hello, Partel! Is it possible to make additional collider(for neck) for ragdoll at runtime ?
     
  21. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hi!
    Not by any tools that I have. But you could just add Rigidbodies, Colliders and Joints to the neck, then reassign head joint's connectedBody to the neck.
     
    justtime likes this.
  22. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    390
    I'm having trouble getting the puppetmaster extended demo to work properly. I have it almost all working but when I collide with objects with my character replacement the offset gets messed up somehow. So instead of turning normally the character turns around a further away point which screws up the control rotation and makes the joins jittery. I'll send you a pm with the package as well.
     
  23. TommiH

    TommiH

    Joined:
    Jan 14, 2008
    Posts:
    252
    Any tips incorporating PuppetMaster with multiplayer? Should we try to synch the bones between the clients at all times, or should we just let the ragdoll physics play out on all clients separately? The latter would obviously suffer less from lag effects, but the problem is the ragdoll can end up in quite different positions and locations based on small differences in initial conditions. And we need the ragdoll then to get repinned and be in a consistent location between clients afterwards.
     
  24. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,

    I just upgraded to Puppet Master .5 and noticed that none of my Props were causing collisions with opposing ragdolls. After digging through my previous posts I found my post about PuppetMasterHierarchyAPI.cs changing the layer of props upon pickup. I had commented out the lines that did this but it appears .5 overrode my changes.

    Looking at that class in .5 in a clean project just to be sure it wasn't my upgrade, it looks like it's still changing the prop layer.

    Code (CSharp):
    1.     joint.gameObject.layer = gameObject.layer; //@todo what if collider is on a child gameobject?
    2.             target.gameObject.layer = targetRoot.gameObject.layer;
    Just wanted to give you a head up.
     
  25. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,

    I've run into another problem with Puppet Master .5. For some reason when I pickup a prop for the first time, everything works fine. However when I drop the prop and then pick it up again, the prop freaks out shaking and jittering in the character's hand. At first I thought it was a layer issue but I fixed the 2 areas where you change the prop layers in PuppetMasterHierarchyAPI.cs and in Prop.cs. And the layers appear to be correct.

    It looks like it has something to do with Additional Pins. This problem only occurs on props where I am using Additional Pins such as swords. The Additional Pin is positioned correctly on the first pickup but after dropping and subsequent pickups, the Additional Pin is offset from the prop. As a matter of fact it looks like every time I drop and pick the prop back up the Additional Pin position is increasing by 1.0 on the Y axis so the Additional Pin keeps getting further and further from the prop causing instability to increase with each drop and pickup.

    Just so you know I am using my own copies of your Prop.cs, PropRoot.cs, MeleeProp.cs and PropPickupTrigger.cs because I made enough changes to them, I didn't want upgrades to destroy my work.

    Are there any changes you have made in .5 that would cause the displacement of the Additional Pin as you drop and pickup.

    Thanks
    Allan
     
  26. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,

    I think I fixed the problem.

    I just had to compare all of your prop classes to the copies which I have made and modified for my own purposes.

    It was in PropRoot.cs in the AttachProp method when you call puppetMaster.AddMuscle(). At the end is a new option to ForceTreeHierarchy and it is set to set to true in your class. In my copy of PropRoot.cs, I wasn't using that option. I set it to true like yours and my props are working again.

    If you don't use that option and set it to true, the Additional Pin not only remains outside of the Prop hierarchy on PuppetMaster but becomes more offset each time you drop and pickup.

    Thanks
    Allan
     
  27. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    515
    Hi again,

    Here is a little cinematic I'm working on for my game series. It uses puppet master and final ik.

    Thanks pärtel!

     
  28. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,

    I guess this question is more about ragdolls than Puppet Master but I'm hoping you have an answer. Is there a good way to determine when a ragdoll has settled down. I'm working on applying particle effects to my character after he has lost balance and gone into Dead State but of course in melee combat those can occur well before the ragdoll finally settles to the ground. Would the best method be to check the rigidbody velocity of one of the PuppetMaster muscles?

    Thanks
    Allan
     
  29. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Once again I found a good solution for determining when the ragdoll comes to rest and answered my own question. I'll go ahead and post it in case it helps anyone else.

    I just used the method BehaviorPuppet.cs uses to determine when to enable GetUp.

    behaviorPuppet.puppetMaster.muscles[0].rigidbody.velocity.magnitude < minHipVelForEffects

    I can set minHipVelForEffects to whatever value I want, say .2f and fire off my effects at that point. Works very well.

    Allan
     
    Partel-Lang likes this.
  30. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hi! Just replied to your PM.

    Hi!
    Please check out the UNet integration package under Plugins/RootMotion/PuppetMaster/_Integration.

    Hi!
    Please download this patch to avoid this problem in the future. It will give you a "Force Layers" checkbox, which you should uncheck for each of your Props.
    Looks like you already found answers to all your other questions :)

    Exellent work there! Thanks for sharing the video, stuff like that keeps up my spirits ;)

    Cheers,
    Pärtel
     
    Danirey likes this.
  31. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,,

    As always thanks a ton for the patch and the great service to your product. :)

    Allan
     
    Partel-Lang likes this.
  32. internethip

    internethip

    Joined:
    Oct 21, 2013
    Posts:
    20
    @Partel-Lang

    In your Melee examples, you update your animator in a way which is very different from what Unity's documentation tells you to do.

    The way you do it is by running animator.CrossFadeInFixedTime instead of setting floats and bools.

    Why do you do it that way?

    I am asking because I wrote my code based upon the unity standard assets where they do a blendtree and setting floats with damptime and deltatime. This results in some very small, but still noticable, jittering and I am looking at your example and you do not have that issue.

    Do you believe using a solution similar to yours will solve my issue as well?

    Edit:
    I applied your changes to the turn function:
    Code (CSharp):
    1.             // Calculate the angular delta in character rotation
    2.             float angle = -GetAngleFromForward(lastForward);
    3.             lastForward = transform.forward;
    4.             angle *= turnSensitivity * 0.01f;
    5.             angle = Mathf.Clamp(angle / Time.deltaTime, -1f, 1f);
    6.            
    7.             // Update Animator params
    8.             animator.SetFloat("Turn", Mathf.Lerp(animator.GetFloat("Turn"), angle, Time.deltaTime * turnSpeed));
    9.             animator.SetFloat("Forward", characterController.animState.moveDirection.z);
    10.             animator.SetFloat("Right", characterController.animState.moveDirection.x);
    11.             animator.SetBool("Crouch", characterController.animState.crouch);
    12.             animator.SetBool("OnGround", characterController.animState.onGround);
    13.             animator.SetBool("IsStrafing", characterController.animState.isStrafing);
    And I dont know if its placebo or not but it looks better now. Thanks.
     
    Last edited: Nov 10, 2016
  33. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hi,

    I'm just an oldschool guy, still prefer to do some stuff the Legacy way, thats all :)
    Anyway, glad you got it fixed.

    Pärtel
     
    recon0303 likes this.
  34. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Partel,

    I was wondering if you would take a moment and provide some clarification on exactly how you are applying BoostImmunity and BoostImpulseMlp in your code and where in your code the application is taking place. I'm having a lot of trouble following your code trying to figure out what adjustments you are making when these methods are called. I would like to know because instead of calling these methods and relying upon boostFalloff to lerp out of their effects, I want to apply the same effects using StateMachineBehaviors so the effects can last only as long as certain animation states. In order to do that, I need to be able to store current values before applying a new Boost, apply the Boost for the duration of the animation state and then refer back to the stored value. So I'm trying to track down what muscle values these methods are changing.

    My best guess is that you are applying the these effects in BehaviourPuppetDamage.cs but for the life of I can't figure out how impulseMlp is being used or what changes it's making to the muscles. It looks like you use it in the OnMuscleCollisionBehavior method but I'm not sure what it's doing.

    In line 109 in the UnPinMuscle method it appears that you simply say If immunity is >= 1 then return, meaning don't unpin anything. Does this mean setting Immunity to anything greater than 1 is meaningless? You also clamp immunity to a max of 1 so it's incorrect to say you can set immunity to a specified value. Actually as far as I can tell you can only set it to 0 - 1. What changes to the muscles are occuring within the range of 0 - 1 immunity values. I see in line 124 where you adjust pinWeightMlp by a damage value that is created using the immunity value. What exactly is that doing?

    I have no idea what the range of ImpusleMlp is because I can't figure out what it's doing in the code.

    Thanks
    Allan
     
  35. TommiH

    TommiH

    Joined:
    Jan 14, 2008
    Posts:
    252
    Hello, and thanks for the reply! I hadn't noticed that integration.

    So it looks like it synchronizes all the bones over the network frame by frame when unpinned but otherwise relies on each client to do their own physics. Makes sense, though I still worry somewhat about latency making it stuttery on poor networks.

    Also, I noticed that while the ragdolls look pretty well synchronized, sometimes the puppets in the demo end up facing in different directions once they stand up. See screenshot. The one at the back just fell down and got up and is now out of synch.
     

    Attached Files:

  36. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hey,
    The code that handles boosting can be found in BehaviourPuppetBoosting.cs.
    If you wish to bypass boostFalloff and manage it via a StateMachineBehaviour, you actually only need to consider 2 variables in Muscle:
    muscle.state.immunity and muscle.state.impulseMlp.
    Meaningful values for immunity are 0-1 as you already found out. 0 is no immunity, 1 is total immunity. impulseMlp is a multiplier and can be a value from 0, which makes the muscle apply no damage to other puppet's muscles, to infinity basically, so 1 means normal damage.

    In short, in your StateMachineBehaviour, set immunity and impulseMlp for the muscles you wish to boost in each update, then reset them to default values (0 immunity, 1 impulseMlp) when the state exits.

    Hi,
    That rotation issue must be a problem with the Network Transform I guess, because NetworkPuppet does not handle that. Perhaps it fails to sync the rotation of the rigidbody if rotational rigidbody constraints are all locked. I'll have to look into that, thanks!
     
  37. Ragoo

    Ragoo

    Joined:
    Feb 15, 2014
    Posts:
    64
    Hi Partel,

    I'm trying to get the external forces on an active puppet to affect the controller velocity and torque, without using a capsule collider on the controller.

    So this would mean calculating the external force (e.g. running into a wall) applied to all the muscles, and applying the combined forces to the controller.

    I'm having some trouble wrapping my head around calculating external force since PM itself also applies force to the muscles. Could you please check if my reasoning in the approach below would be the best way to go about this:

    • OnRead -> get the positions (this should be the finished position of the previous frame and cached as a reference)
    • OnWrite -> get the positions again, the differences between onread/onwrite is how much external force was applied (muscle didn't reach the target fully)
    • OnLateUpdate -> apply that cumulative difference * relative rigidbody mass as force back onto the controller
    • At least one problem with this is lack of muscle strength and inaccuracies would affect the controller

    Second method I see would be using the collision broadcasters to get the collisions and apply those back onto the controller, but I think this would be quite a bit less efficient performance wise.

    Cheers
     
  38. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hi!

    I don't think it would be even possible to calculate all that, there are waaaay too many variables to consider and it would probably end up being a show stopper in terms of performance anyway.
    In short, I have no idea, sorry.

    You can find the force that PM applies through pinning in Muscle.cs, in the end of private void Pin(), but there are also accelerations from joint target rotations and stuff like that would be extremely difficult to calculate.

    Pärtel
     
    Ragoo likes this.
  39. Ragoo

    Ragoo

    Joined:
    Feb 15, 2014
    Posts:
    64
    okay! Thanks for the answer
     
  40. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    401
    Thank you for this explanation Partel.

    Can you please explain what changes you are making to the Puppet when muscle.state.immunity and muscle.state.impulseMlp are changed. I'm having trouble with immunity not doing what I expect and the problem is I don't know what to look for on the Puppet to see if anything has changed.

    Thanks
    Allan
     
  41. Danirey

    Danirey

    Joined:
    Apr 3, 2013
    Posts:
    515
    Hi @Partel-Lang,

    I'm fighting with the prop system with my puppet characters, but i can't get it working like the demo. I've the same set up in my character like the pilot demo. The problem is that the mesh of the prop is displaced outside the original position. Colliders still right placed, but the mesh not, and is like bouncing up and down... If i use my custom prop with the pilot, works perfect. The only difference i found is that pilot doesn't have hand colliders, and my char does. Also the hand of the blue animation rreference is twisted????

    Here is a picture:




    And here with puppet weight 0:



    You can see the prop is correct, but the colliders are wrong and the left hand collider is falling....

    Any idea or clue to look at?

    Cheers!
     
    Last edited: Nov 19, 2016
  42. wightwhale

    wightwhale

    Joined:
    Jul 28, 2011
    Posts:
    390
    How do I make it so puppetmaster can ride an object? Currently if I turn off behaviours and puppetmaster game objects I can get on and ride the bike which works fine. Idealy I would be able to keep puppetmaster enabled so my character could run into trees ect and fall off the bike.
     
  43. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hi,
    No changes at all. Search for "immunity" in BehaviourPuppetDamage.cs, you'll see that in void UnPinMuscle, that gets called on the muscle that collided, if immunity is >= 1f nothing happens and in other cases (1f - immunity) * damage will be applied to the muscle. Its the same with impulseMlp, it will just multiply the damage by the other muscle's impulseMlp in OnMuscleCollisionBehaviour.

    Hey,
    Have you tried disabling "Internal Collisions" and "Angular Limits" in PuppetMaster? It might be that the colliders block each other or the limits are in the way.

    Hi,
    Did you try parenting the root to the bike?

    Best,
    Pärtel
     
  44. Der_Kevin

    Der_Kevin

    Joined:
    Jan 2, 2013
    Posts:
    504
    Howdy!
    Short question: what is the actual workflow to create a puppet from a generic rig?
    A dog for example
    I assume using the biped ragdoll creator is wrong? Since its not biped
    Any tips how i can create a ragdoll from a generic model?
     
  45. internethip

    internethip

    Joined:
    Oct 21, 2013
    Posts:
    20
    Hello,

    When a puppet is unpinned the character controller is synced to the location of the ragdoll. Is there a way to have the ragdoll be in total ragdoll mode (No animation playing) and still have the character controller sync its location to the ragdoll?

    In otherwords, I would like to unpin a puppet and have it ragdoll with no animation while still syncing the charactercontroller rigidbody to the ragdolls position.

    Is this possible?
     
  46. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    It will take some editing, but its doable.

    Hi,

    Code (CSharp):
    1. puppetMaster.targetRoot.position += puppetMaster.muscles[0].target.position - puppetMaster.muscles[0].rigidbody.position;
     
    Der_Kevin likes this.
  47. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,453
    Hi,

    If I make a brand new project and import 0.5 puppet master, then load up "Melee Spherical.unity" I experience problems with smoothness. Basically, if Animation Controller is set to default of "Animate Physics" it is smooth, but if I set it to "Normal", the character does indeed jerk as you run around.

    This was to reproduce the problem I was having my end. I expected Normal to be smoother, only it isn't. This means I need a pretty high fixed update rate or facial anims, other anims I am using and crossfades can look bad at times since they're tied to fixed update.

    But "Animate Physics" is the only thing that *transforms* smoother. Bug?

    Been trying for a couple of days to make it smoother, but it comes down to a rock and a hard place since I either have smooth anim transitions and nice facial anims (we use bones) or I have smooth ragdoll movement. I can't have both.

    This is in Unity 5.5, haven't checked earlier...
     
    internethip likes this.
  48. internethip

    internethip

    Joined:
    Oct 21, 2013
    Posts:
    20
    This is the same issue I had with the character jittering slightly. +1 on a solution here.
     
  49. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    1,922
    Hey,

    In order for everything to be smooth, everything needs to be in sync with the motion and update rate of the camera.
    So in "Melee Spherical" you should:

    1. Set Animator update mode to Normal
    2. Enable "Smooth Physics" in CharacterMeleeDemo on the "Character Controller" gameobject
    3. Make sure the Rigidbody on the character controller is set to interpolate
    4. Enable interpolation on all the muscles
    5. Set camera controller's target to the Pelvis bone, not the pelvis muscle
    6. Set camera controller's update mode to LateUpdate
    7. Uncheck "Smooth Follow" on the camera controller
    Cheers,
    Pärtel
     
  50. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,453
    Hi, this does not resolve it for me, my end. I have followed those steps. To clarify, it's the ragdoll jerking, not the controller, and this mostly happens in my game during jumps or falling (whenever the speed picks up). In my game my controller is set to interpolate and I have witnessed the phenomenon by debug drawing the ragdoll. It happens with a *static* camera as well. Everything in sight is set to interpolation...

    ie. ignore camera, still happens.

    Also another set of issues with using Physics update: if you do anim calls in code you can't actually check if an animation is playing or transitioning in the same frame, you have to wait (obviously) for a fixed update, which is making my code somewhat spaghetti. I definitely need to be using Normal update...

    It's become a real issue, it looks as though the ragdoll itself is trying to keep up with the physics position of my controller instead of the current interpolated transform position.

    Not sure what to do about it, please suggest anything more I can try. I can confirm it's got nothing to do with cameras though (in my case, and probably in your demo too, although that's one way to make it smoother - it still occurs).

    Edit: I have emailed you two videos :)
     
    Last edited: Nov 29, 2016