PuppetMaster includes a helpful tool for attaching, detatching and managing physical props - the PropMuscle and PuppetMasterProp classes. PropMuscle is a special type of muscle that the PuppetMasterProp objects can be attached to. For an example of prop usage, please see the "Prop" and "Melee" demo scenes.
Getting Started:
Prop Setup:
Because of the dual rig structure, the prop needs to be set up so that its root GameObject is the Muscle with the Rigidbody and ConfigurableJoint components and parented to it the Target along with its mesh and renderer(s). When the prop is picked up, the prop will be split up so that the "Mesh Root" will be parented to the Target root hierarchy and the rest of the prop with colliders to the Prop Muscle. When the prop is dropped, original hierarchy will be restored.
When the prop is picked up, the Rigidbody component on it will be destroyed as the PropMuscle already has a Rigidbody. The colliders of the prop will act as compound colliders for the PropMuscle Rigidbody. When the prop is dropped, the original Rigidbody will be restored.
PropMuscle component:
PropMuscle is a special type of muscle, which all prop objects can be attached to. You can create a PropMuscle in the Editor by selecting the PuppetMaster GameObject and clicking on "Add Prop Muscle" on the bottom of the PuppetMaster component. Click on the blue button in the scene representing the PropMuscle and move/rotate it to where you need it to be. If your puppet does not have hand muscles and the PropMuscle was attached to the forearm muscle, find the Prop Muscle Target GameObject in the Target Root hierarchy and parent it to the hand bone.
Remove This Prop Muscle - destroy this PropMuscle object.
currentProp - the PuppetMasterProp currently held by this Prop Muscle. To pick up a prop, just assign it as propMuscle.currentProp. To drop, set propMuscle.currentProp to null. Replacing this value with another prop drops any previously held props.
additionalPinOffset - offset of the additional pin from this Prop Muscle in local space.
Add/Remove Additional Pin - adds or removes the additional pin object. Additional Pins help to pin this prop muscle to animation from another point. Without it, the prop muscle would be actuated by Muscle Spring only, which is likely not enough to follow fast swinging animations. Move the additional pin by 'Additional Pin Offset' towards the end of the prop (tip of the sword).
Picking up, dropping and switching props with the PropMuscle is done by simply changing the propMuscle.currentProp value. When you assign a prop to it by propMuscle.currentProp = myProp, any props held by the PropMuscle will be dropped and the new myProp will be attached instead. If you set currentProp to null, any props held by the PropMuscle will be dropped and the PropMuscle itself deactivated.
// Dropping props
propMuscle.currentProp = null;
// Dropping any props held, picking up myProp
propMuscle.currentProp = myProp;
When a prop is attached to the PropMuscle, its localPosition and localRotation are set to zero/identity, so the best practice to adjust prop holding pivot would be to parent the prop to the PropMuscle, set localPosition/Rotation to zero and adjust the positions of the mesh and colliders until they fit perfectly at hand.
PuppetMasterProp component:
meshRoot - Mesh Root will be parented to Prop Muscle's target when this prop is picked up. To make sure the mesh and the colliders match up, Mesh Root's localPosition/Rotation must be zero.
muscleProps - the muscle properties that will be applied to the Prop Muscle when this prop is picked up.
internalCollisionIgnores - defines which muscles or muscle groups internal collisions will always be ignored with regardless of PuppetMaster.internalCollisions state.
animatedTargetChildren - list of animated bones parented to this muscle's Target, except for the bones that are targets or target children of any child muscles. This is used for stopping animation on those bones when the muscle has been disconnected using PuppetMaster.DisconnectMuscleRecursive(). For example if you disconnected the spine02 muscle, you would want to have spine03 and clavicles in this list to stop them from animating.
forceLayers - if true, this prop's layer will be forced to PuppetMaster layer and target's layer forced to PuppetMaster's Target Root's layer when the prop is picked up.
mass - mass of the prop while picked up. When dropped, mass of the original Rigidbody will be used.
propType - this has no other purpose but helping you distinguish props by PropRoot.currentProp.propType.
pickedUpMaterial - if assigned, sets prop colliders to this PhysicMaterial when picked up. If no materials assigned here, will maintain the original PhysicMaterial.
additionalPinOffsetAdd - adds this to Prop Muscle's 'Additional Pin Offset' when this prop is picked up.
additionalPinWeight - the pin weight of the additional pin. Increasing this weight will make the prop follow animation better, but will increase jitter when colliding with objects.
additionalPinMass - multiplies the mass of the additional pin by this value when this prop is picked up. The Rigidbody on this prop will be destroyed on pick-up and reattached on drop, so its mass is not used while picked up.
Melee Props:
Lengthy melee props are a huge challenge to the PuppetMaster. Swinging them rapidly requires a lot of muscle force and solver iterations to fight the inertia and keep the ragdoll chain intact. The longer the chain of Joints linked together, the more inaccurate/unstable the simulation and unfortunatelly those melee props tend to be exactly at the ends of very long Joint chains (pelvis/spine/chest/upper arm/forearm/hand/sword). Besides that, as the props are swinged, they have a lot of linear and angular velocity, a very thin collider and therefore can easily skip the victim when its collider happens to be at the position between two fixed frames. It usually takes quite a lot of tweaking and some tricks to get the melee props working right. PropMuscles have the "Additional Pin" functionality which can be used to add another pinning point to the prop, helping to better pin it to high angular velocity animation.
make the collider thicker when hitting to decrease collider skipping.
use Continuous/Continuous Dynamic collision detection modes to reduce skipping, this however has a big performance cost.
reduce the fixed timestep.
use the "Additional Pin" (Prop.cs).
adjust the position of the "Additional Pin" and "Additional Pin Target" along the prop.
reduce PuppetMaster.pinDistanceFalloff.
increase PuppetMaster.muscleSpring and solverIterationCount.
disable PuppetMaster.internalCollisions to prevent the big prop collider from colliding with the Puppet.
get rid of the hand Muscle to make the joint chain shorter.
PropMelee Component: (this component will be made more generic in PuppetMaster 0.4).
capsuleCollider - switches the collider to a Capsule when the prop is picked up. Capsules collide more smoothly and with less jitter.
boxCollider - switches back to this BoxCollider when dropped.
actionColliderRadiusMlp - multiplies the radius of the Capsule when PropMelee.StartAction(float duration) is called.
actionAdditionalPinWeight - temporarily set (increase) the pin weight of the additional pin when PropMelee.StartAction(float duration) is called.
actionMassMlp - temporarily increase the mass of the Rigidbody when PropMelee.StartAction(float duration) is called.
COMOffset - offset to the default center of mass of the Rigidbody (might improve prop handling).