Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

PuppetMaster - Advanced Character Physics Tool [RELEASED]

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

  1. sancha-km

    sancha-km

    Joined:
    Jun 5, 2016
    Posts:
    28
    Check it, Layer Collision Matrix not changing in play mode.

    Update. Collision between puppets not working if i place them in pool on start, as child to an gameobject.
    If storing in gameobject array, all is working fine.
    Any fix to this? Because i may need to add puppet as child to gameobject in future.
     
    Last edited: May 9, 2020
  2. chrisk

    chrisk

    Joined:
    Jan 23, 2009
    Posts:
    681
    Thanks, Partel as always. I'll give it a try. ^^
     
  3. gliealonso

    gliealonso

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

    I'm still having issues with the getting up for the Puppets, I'm not sure if it's because the FBIK is getting out of the PlayArea, because there are walls where the edges of the PlayArea is, and that's causing the issues.

    Here is a gif of the issue:
    https://imgur.com/a/fPESD1f
    (It only happens sometimes)

    I even tried to set the Blend To Animation Time to 0.0001, and still the issue happens.

    puppet master.PNG puppet get up.PNG

    EDIT: Could it be related to this?
    puppeterrors.PNG


    What do you suggest I try?

    Many thanks,
    Gabriel.
     
    Last edited: May 11, 2020
  4. mutp

    mutp

    Joined:
    Oct 1, 2018
    Posts:
    18
  5. FriendNFoe

    FriendNFoe

    Joined:
    Sep 24, 2012
    Posts:
    5
    Hey Partel, awesome work on this plugin, really having a blast playing around with it :)

    I'm using UCC though, and encountering errors when combining with Puppetmaster, even just initializing things, would be great to have a basic integration in place!
     
  6. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Oh yeah, sorry, I forgot about that at first. Collisions are not solved if puppets currently share the same root gameobject. It is an optimization (lines 93, 105 and 117 in MuscleCollisionBroadcaster.cs). It is the fastest way to exclude solving internal collisions and it needs to be really fast because there can be a lot of collisions per frame. I know it is not ideal, I just can't think of a better and equally fast way.

    Hey,
    Those warnings are there to warn you that your character controller capsule might be colliding with ragdoll colliders. If you don't have a character controller capsule, ignore those or just move the ragdoll to another layer.

    About getting up, maybe it is something preventing the character from being moved by BehaviourPuppet while it is unpinned? For example if you have VRIK, need to disable that while behaviourPuppet.state != BehaviourPuppet.State.Puppet. Or maybe some other code you might have that controls the position and rotation of the character, it all needs to be disabled while unpinned.

    Hey,
    Just tried that, seems to work. Did a quick integration package with a basic demo, this is what it looks like.

    Hey, thanks!

    UCC is not currently supported, I used to have an integration to that, but it broke when they rewrote it all for their version 2. I've been trying to get it back running for a long time without success, there is some heavy jitter we can't figure out. They have thousands of lines of code and so does PuppetMaster and without knowing a lot about both it is very difficult, sorry.

    Best,
    Pärtel
     
    mutp likes this.
  7. gliealonso

    gliealonso

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

    Just wanted to let you know that I found the issue. I had an Anim.Play that whenever the opponent was hurt, he would retreat, however I forgot to disable this forceful animation when he wasn't standing.

    Thanks for the help again bro
    Gabriel.
     
    Partel-Lang likes this.
  8. mojao

    mojao

    Joined:
    Sep 2, 2013
    Posts:
    45
    hi.
    i m trying to get puppets collision via script , but i couldnt.
    how to ditect puppets collision?
    ex.i add script onentercollision to mypuppet.
    but puppets fist hit opponent body, then not fire on entercollision.
    thx.
     
  9. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    57
    I believe you should add that the collider should only react to GameObjects according to their tag or comparing the GameObject itself.

    https://docs.unity3d.com/ScriptReference/Collider.OnCollisionEnter.html

    This should help.


    Gabriel.
     
  10. sancha-km

    sancha-km

    Joined:
    Jun 5, 2016
    Posts:
    28
    Hi, When puppets sometimes collide with rigidboides, they fly apart at high speed with a lot of jitter, etc...
    So far i find only one fix - set angular limits, but in this case very strange animation(shown on gif)
    Increasing limits don't help.
     

    Attached Files:

  11. alexkarak

    alexkarak

    Joined:
    Feb 7, 2018
    Posts:
    25
    Hey Partel.. I am trying to instantiate a hit particle effect when on collision impulse gets called but i can't make it spawn in the collision place...
     
  12. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    57
    Hey man,

    You didn't give much information there, but I think you can do something like this.

    void OnCollisionEnter(Collision collision)
    {
    {
    if (collision.gameObject.CompareTag("Tag of GameObject")) //This is to compare the tag, so you can collide with only the object that you want to collide
    {
    ContactPoint contact = collision.contacts[0]; // this is to get the contact position
    contactPointCollision = contact.point; // then transfer the position of the contact to the variable contactPointCollision which is a Vector3. And now you can instantiate a particle at the contactPointCollision transform.
    }
    }
    }
     
  13. pccross

    pccross

    Joined:
    Jun 20, 2015
    Posts:
    99
    Having a strange issue where the Puppetmaster component attached to my character seems to work great when in editor mode, however when I create a build, it doesn't detect collisions from my weapon. The weapon (long pipe) just passes right through the character in the built version. I set the rigidbody collision detection to 'Continuous Speculative' on my weapon so can't imagine the colliders aren't detected.
    For reference, I attached the 'Puppet (with Fall)' behavior from demo scenes and set collision layer to match my weapon.
    Any clues as to what I may have missed?
     
  14. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Hey,
    If you are using BehaviourPuppet, that already reads collision events. You can use BehaviourPuppet.OnCollision delegate:

    Code (CSharp):
    1. public BehaviourPuppet behaviourPuppet;
    2.  
    3. void Start() {
    4. behaviourPuppet.OnCollision += OnCollision;
    5. }
    6.  
    7. void OnCollision(MuscleCollision m) {
    8. // m.collision.GetContact(0).point...
    9. }
    Or you could just add your own collision processing script to all the rigidbodies of all the puppetMaster.muscles.

    Hey,
    That is not PuppetMaster, but just general PhysX joint stability issue. Check out this page, see if there's anything there you can try. Also Unity 2019.3 has much more stable joints due to upgrade to PhysX 4.1. Also has a new Temporal Gauss-Seidel joint solver type, which you can enable in the Physics Settings. But as always in Unity new things come with new bugs so try to use version 2019.3.7 or later because stuff can just fall through MeshColliders in earlier 2019.3 versions when you make a build lol.

    Hey,
    in OnCollisionImpulse, when you spawn it at m.collision.GetContact(0).point, it should work.

    Hey,
    Thanks for the help! Just wanted to point out that you should use collision.GetContact(0). Collision.contacts[0] still allocates to GC even if you have "Reuse Collision Callbacks" enabled in Physics Settings.

    Hey,
    Which Unity version were you using. I have noticed in Unity2019.3 versions earlier than 2019.3.7 MeshColliders sometimes don't work in builds so it could be that.

    Best,
    Pärtel
     
  15. pccross

    pccross

    Joined:
    Jun 20, 2015
    Posts:
    99
    I'm actually using 2019.2.15. Any issues with that version?

    Hey,
    Which Unity version were you using. I have noticed in Unity2019.3 versions earlier than 2019.3.7 MeshColliders sometimes don't work in builds so it could be that.

    Best,
    Pärtel[/QUOTE]
     
  16. sancha-km

    sancha-km

    Joined:
    Jun 5, 2016
    Posts:
    28
    Use latest version of Unity 2019.3.13(later than 3.7), same problem,
    1. Temporal Gauss-Seidel is On
    2. PhysX 4.1 as i understand is On by default

    Also in Joint settings i set Projection mode to Position and Rotation, it helps me with standart ragdoll without Puppet master in past.
    But in Runtime it switch back to None, can i fix it without additional scripting?
     
  17. gliealonso

    gliealonso

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

    I have been checking the Unet NetworkPuppet example and trying to change it to Photon(only for opponents), I'm not really good at this and now I'm getting stack overflow exception error at line 147, could you please check what I did wrong?

    And this is the setup I'm using:
    photonpuppetmaster.PNG


    (Also, thanks for the Collision Point tip!)


    Many thanks,
    Gabriel.
     

    Attached Files:

  18. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    [/QUOTE]

    Hey,
    Not that I know of.
    Did you try ContinuousDynamic CCD? ContinuousSpeculative is a piece of junk.
    Other than that, looks like a Unity bug, could try another Unity version. There is no #if_UNITY_Editor code in PuppetMaster runtime to make it behave dirfferent in build.

    Hey,
    Can you check the line number? 147 is just "}" in the NetworkPuppet you attached.
    Stack overflow happens for example when you call a method that re-calls itself, like adding FixedUpdate(); inside a FixedUpdate, but I can't spot anything like that in the script. Maybe you have rigidbodySynInterval set to 0 so there is a division by 0 on line 146?

    Cheers,
    Pärtel
     
  19. alexkarak

    alexkarak

    Joined:
    Feb 7, 2018
    Posts:
    25
    Hey Partel ...I am still trying to figure out how to add a second action animation in character meele demo script!

    Code (CSharp):
    1. namespace RootMotion.Demos {
    2.    
    3.     /// <summary>
    4.     /// User input for a third person melee character controller.
    5.     /// </summary>
    6.     public class UserControlMelee : UserControlThirdPerson {
    7.  
    8.         public KeyCode hitKey;
    9.         public KeyCode KickKey;
    10.      
    11.        
    12.  
    13.         protected override void Update () {
    14.             base.Update();
    15.  
    16.             state.actionIndex = Input.GetKey(hitKey)? 1: 0;
    17.            
    18.             state.actionIndex = Input.GetKey(KickKey)? 2 : 0;
    19.  
    20.         }
    21.     }
    22. }
    23.  
    I did this

    and then i added this to my character controller inspector (in the picture)
    I added an animation to my animator with the same parameters as Hit action but with action index=2
    But now the kick animation plays but the hit animation stoped playing (the keycode for hit is e and the keycode for kick is q but e doesnt work now)
     

    Attached Files:

    • 111.png
      111.png
      File size:
      46.2 KB
      Views:
      6
  20. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    57
    Hey,
    Can you check the line number? 147 is just "}" in the NetworkPuppet you attached.
    Stack overflow happens for example when you call a method that re-calls itself, like adding FixedUpdate(); inside a FixedUpdate, but I can't spot anything like that in the script. Maybe you have rigidbodySynInterval set to 0 so there is a division by 0 on line 146?

    Cheers,
    Pärtel[/QUOTE]


    Hi Partel,

    Yes, I find it strange as well, the only thing that I think I removed from the FixedUpdate was the Unet command (isServer), do you think this could be the issue? I searched it and "isServer" means it will only run the function if the object is active, correct? Then I also tried replacing it with "if (PhotonNetwork.IsMasterClient)", but had the same issue.

    The rigidbodySynInterval was 0.1, and then this is the error that appears: error line 147.PNG

    Then I set the rigidbodySynInterval to 1, this is what appeared:
    line 169 error.PNG


    But then when I managed to double click the error on the line 147, the script BehaviourPuppetStateSwitching opened up on line 214:
    upload_2020-5-18_11-51-48.png

    What do you suggest I do?

    Many thanks,
    Gabriel.
     
  21. Redux

    Redux

    Joined:
    Nov 10, 2011
    Posts:
    133
    Has anyone set up aim IK for third person and had to deal with the what happens when the spine is isolated by the overriding aim pose animations (left/right/up/down) that you get unnatural run/walk as a result? The aim poses are static more than less but there's a lot of motion in the spine during run/walk which ends up being lost while aiming and it looks terrible.

    Any idea on how to better set this up are appreciated. Eliminating rotation on the pelvis doesn't sound very plausible solution as it can make the animations look stiff, but I don't know the best solution. Any advice appreciated.

    Tl;DR; Set up aim pose animations like shown in tutorial, aim pose animations don't work nicely while character running. What's proper way to handle this.
     
    Last edited: May 18, 2020
  22. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Hey,
    It is because the second line state.actionIndex = Input.GetKey(KickKey)? 2 : 0; just overwrites what the previous line does. Add this method:

    Code (CSharp):
    1. private int GetActionIndex() {
    2. if (Input.GetKey(hitKey)) return 1;
    3. if (Input.GetKey(KickKey)) return 2;
    4. return 0;
    5. }
    Then use it like this:
    Code (CSharp):
    1. state.actionIndex = GetActionIndex();

    Hi Partel,

    Yes, I find it strange as well, the only thing that I think I removed from the FixedUpdate was the Unet command (isServer), do you think this could be the issue? I searched it and "isServer" means it will only run the function if the object is active, correct? Then I also tried replacing it with "if (PhotonNetwork.IsMasterClient)", but had the same issue.

    The rigidbodySynInterval was 0.1, and then this is the error that appears: View attachment 624016

    Then I set the rigidbodySynInterval to 1, this is what appeared:
    View attachment 624019


    But then when I managed to double click the error on the line 147, the script BehaviourPuppetStateSwitching opened up on line 214:
    View attachment 624028

    What do you suggest I do?

    Many thanks,
    Gabriel.[/QUOTE]

    Hey,
    Still not sure, sorry. Could you click on the first error you see and send me a screenshot of the entire trace from the Console?

    Hey, what does your AimIK bone setup look like, do you use arm bones for aiming too?
    If you get too much IK on the spine, try reducing bone weights for the lower spine bones.

    Cheers,
    Pärtel
     
  23. gliealonso

    gliealonso

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

    This is the first error that appears:
    upload_2020-5-20_11-38-55.png

    And when I double click it, this is the line that highlights.
    upload_2020-5-20_12-2-52.png



    Many thanks,
    Gabriel.
     
    Last edited: May 20, 2020
  24. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    23
    How would I approach mantaining(trying to) a certain pose while my puppet is in the staggering behaviour? for example staggering while holding something
     
  25. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Hey,
    Here, made a Photon version of that UNet demo package.
    Still not sure where you got that stack overflow from though.

    Hey,
    You'd have to set "Windmill Weight" to 0 in BehaviourBipedStagger (click on the "Curve" button on the right side of it to change it to Float), then you can just play an animation of holding something.

    Cheers,
    Pärtel
     
  26. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    23
    Thanks for your answer.

    Do you know how to make any character with staggering behaviour act just like the Pilot from your demo? Its staggering is perfect for my needs but I can't replicate in any other character even using the same settings and same masses for the muscles rigidbodies, I think it's something to do with how the ragdoll is set up, its completely different from when I use the ragdoll creator on a character, it looks "simpler".

    I've tried copying the puppetmaster setup from the "Pilot (Stagger)" and reassigning the references of the muscles but the colliders twist around when I do that and are positioned completely wrong...

    Also sometimes the ragdoll creator will position some parts rotated a little bit off, how to fix that without trigger errors in puppetmaster on runtime?
     
    Last edited: May 23, 2020
  27. gliealonso

    gliealonso

    Joined:
    Oct 21, 2018
    Posts:
    57

    Brooo!

    Thank you so much! I think that my code had "something MasterClient" instead of "isMine"....

    Anyway, it's working great! Thanks again Partel!

    Gabriel.
     
    Partel-Lang likes this.
  28. NewMagic-Studio

    NewMagic-Studio

    Joined:
    Feb 25, 2015
    Posts:
    145
    EDIT : got to solve it

    Hello,
    I have puppetmaster and vrik inside a parent object which i deactivate, then activate and then change scene but puppetmaster is not destroyed. Then when i try to grab a weapon with
    Manager.SINGLETON.avatarHandLeftOneHand.GetComponent<PropRoot>().currentProp = prop.GetComponent<PropTemplate>(); it sends me an error saying "PuppetMaster has not been initiated yet.", but it is active, dont understand why it is not working
     
    Last edited: May 23, 2020
  29. NewMagic-Studio

    NewMagic-Studio

    Joined:
    Feb 25, 2015
    Posts:
    145
    I still have the problem character doesnt match camera sometimes, it stays away some metres from camera at start, most times work fine but other dont and just stays away from camera jittering
     
  30. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Hey,
    Not sure, can you please package up that puppet you have and export as unitypackage (save entire puppet rig as a prefab, select the prefab, scene and fbx, do Assets/Export, deselect "Include Dependencies"). Also please let me know which Unity version you used to export the package with.

    Hey, just replied to you email.

    Cheers,
    Pärtel
     
  31. Milionario

    Milionario

    Joined:
    Feb 21, 2014
    Posts:
    23
    How to use puppetmaster with characters that have LODs and a LOD group? Because they will have a few different models with less polys, but only one of the models will have the colliders, or do i have to setup puppetmaster in all of the lods?

    Also some colliders need adjustment but everytime I try to adjust them I need to "Fix muscles positions and rotations" for puppetmaster to work, and that resets its orientation, example:



    How can I adjust them?
     
    Last edited: May 26, 2020
  32. NewMagic-Studio

    NewMagic-Studio

    Joined:
    Feb 25, 2015
    Posts:
    145
    Didnt get any reply
     
  33. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    410
    Partel,

    Can you explain what you are doing with PuppetMaster.Teleport(). I've reviewed the code and played with the Respawning Demo but I don't understand the sequence of events you are going through in code. You don't comment any of your code.

    Is there a reason why you do not realign the root of the character with the Controller gameobject and the PuppetMaster gameobject when using Teleport? It seems to me that Teleport would be the perfect opportunity to zero out all child objects (Behaviors, PuppetMaster, Controller) under the root just as when you start the game. Instead Teleport just creates further distance between the root of the character and the Controller.

    Thanks
    Allan
     
  34. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Hey, this is the mail I sent on 25th, maybe it ended up in the spam folder?
    .../
    I think the problem is that when Animator starts playing or IK starts updating for the first frame, it will snap the pose very violently within a single frame.

    Please try changing PM mode to Kinematic in Editor and set Blend time to 0.

    When you start the game, wait a frame or 2, then set puppetMaster.blendTime to what you normally use and puppetMaster.mode = PuppetMaster.Mode.Active; That should activate it smoothly.
    /...

    Hey,
    The root of the character is considered just a folder for the rig, to contain the puppet and the animated hierarchy in the same place. It's position and rotation is never supposed to be used/changed or have any meaning, that's why I am ignoring it in teleport. If you don't like having that root around, you can get rid of it. Unparent both the ragdoll and the animated target, parent the Behaviours to PuppetMaster. As long as you have Target Root assigned in PuppetMaster, they will remain connected. But then you'd have your ragdoll and animated target separately under the scene. Can't parent the ragdoll to animated target, because it would inherit motion from it, it is supposed to be moved by physical forces only.

    Cheers,
    Pärtel
     
  35. chaneya

    chaneya

    Joined:
    Jan 12, 2010
    Posts:
    410
    Thanks for the explanation.

    Keeping a root folder for the whole setup is useful in case you need to find something on one of it's children, you can use GetcomponentInChildren. I just didn't know if it made a difference if the parent objects/folders for Behaviors, PuppetMaster, Root and Animator/Controller all had different position values over the course of a long game play session. That's what happens if you use Teleport.

    I would still like to request that you help us out by commenting your code. I know documentation is a huge pain because it's hard to maintain as you make changes and improvements. Some helpful commenting in your code would help all of us....including yourself. :) The added Teleport method is the perfect example. It is an excellent and essential update to your product. And you have to use it if you pool or spawn characters but I'm left trying to understand your code to figure out exactly what it does.

    Thanks
    Allan
     
  36. alexkarak

    alexkarak

    Joined:
    Feb 7, 2018
    Posts:
    25
    Hey Again Partel
    Thanks for your help so far!
    I have one more question! I am trying to make my enemy being able to throw the enemy when he grabs him!
    Code (CSharp):
    1.  void Update()
    2.         {
    3.             if (!grabbed) return;
    4.  
    5.             // Releasing the other puppet, restoring the initial state
    6.             if (Input.GetKeyDown(KeyCode.X))
    7.             {
    8.                 Destroy(joint);
    9.  
    10.                 r.mass /= massMlp;
    11.                 puppetMaster.solverIterationCount /= solverIterationMlp;
    12.                 //otherCollider.GetComponent<Rigidbody>().AddForce(transform.forward * 100);
    13.                 userControl.walkByDefault = false;
    14.                 Physics.IgnoreCollision(c, otherCollider, false);
    15.                 otherPuppet.canGetUp = true;
    16.                 otherPuppet = null;
    17.                 otherCollider = null;
    18.                 grabbed = false;
    19.                 nextGrabTime = Time.time + 1f;
    20.             }
    tried to add this but its obviously wrong! (the commented out line)

    also when my player is down or trying to get up is still able to grab the other puppets ...that breaks both the player and the grabbed puppet making them fly in the air and strech!

    and lastly is it possible to make the grabbed puppet animate a little (like making hime a little pinned) so he is not completely still? or this will break the physics?
     
  37. Partel-Lang

    Partel-Lang

    Joined:
    Jan 2, 2013
    Posts:
    2,062
    Hey,
    Teleport basically just teleports the entire rig so that position and rotation of the Target Root (the gameobject with the Animator) matches the values you call with Teleport(). It does not affect BehaviourPuppet, I mean it doesn't matter if you call it while the puppet is unpinned or getting up or running around, it will just snap to that new position/rotation and everything else should continue the same. As for respawning, the code in Respawn first sets state to Alive (just in case the puppet was pooled dead), plays the idle animation (in case some other animation was playing when pooled), sets BehaviourPuppet to Puppet state (so it starts standing up) and then teleports the puppet to the spawn position and unparents from the deactivated pool object.

    Thanks for the feedback about commenting more, noted!

    Hey,

    When you add force to the puppet, add some to other muscles too (foreach (Muscle m in puppetMaster.muscles)) otherwise if you grab from the forearm for example, and just add force to that, it will require a lot of it to make the ragdoll actually move.

    To prevent grabbing while unpinned or getting up, add this condition:
    if (behaviourPuppet.state == BehaviourPuppet.State.Puppet) {}
    so it could only grab while pinned.

    To make the grabbed puppet animate, just play some animation. Normally, when the puppet is unpinned by the grabbing, BehaviourPuppet will switch to whatever animation you have set in BehaviourPuppet's "On Lose Balance" event. The animation used by default is just static so that's why it appeares still. So you can change the value of behaviourPuppet.onLoseBalance.animations[0].animationState right before you grab to use another animation.

    Best,
    Pärtel
     
unityunity