Ragdoll Animator 2
Last updated
Last updated
SETTING UP
no ragdoll
config.ragdSetUp : other
config.use.ragdoll : false
collision matrix: capsule - ragdoll : false
RagdollAnimator
set up ragdoll and use pre-generated
set ragdoll dummy layer to ragdoll in SetUp
use kinematic feet helper in Extras
wip controller for ragdoll animator
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FIMSpace.FProceduralAnimation;
public class ragdAnmCX : MonoBehaviour
{
public RagdollAnimator2 ragdAnim2;
public Animator animator;
public float delay = 1f;
public bool isOn;
[System.Serializable]
public class CNF
{
[System.Serializable]
public class LM
{
public LayerMask hit;
}
public LM layerMask = new LM();
[System.Serializable]
public class PWR
{
public float minImpulse = 40;
public float impact = 2;
public float fall = 10;
public float bodyPush = 10;
public float pushForce = 40;
public float punch = 10;
public float gripEnd = 10;
}
public PWR power = new PWR();
[System.Serializable]
public class AUD
{
public AudioSource hit;
}
public AUD audio = new AUD();
}
public CNF config = new CNF();
[System.Serializable]
public class ST
{
public bool attached;
}
public ST status = new ST();
[System.Serializable]
public class ACX
{
[System.Serializable]
public class A
{
[System.Serializable]
public class OH
{
public bool fall;
}
public OH onHit = new OH();
[System.Serializable]
public class OT
{
public bool trap;
}
public OT onTrigger = new OT();
}
public A activ = new A();
}
public ACX action = new ACX();
public enum mx {off, standin, fallin, sleep};
public mx mode;
public Vector3 worldP;
public Transform nearestBone;
[System.Serializable]
public class HIT
{ //hit registered
public bool isOn;
public int layer;
public float velocity;
public float impulse;
public Rigidbody rigidb;
public float startT;
}
public HIT hit = new HIT();
public RA2MagnetPoint magnetPoint;
[System.Serializable]
public class MP
{
public bool isOn;
public enum sx {none, actor, other};
public sx set4;
[System.Serializable]
public class A
{
public bool fallOnHit;
}
public A activ = new A();
public Vector3 P;
[HideInInspector] public Quaternion Q;
[System.Serializable]
public class BN
{
public bool hip;
public bool spine;
public bool chest;
public bool head;
public bool forearmL;
public bool forearmR;
public bool elbowL;
public bool elbowR;
public bool handL;
public bool handR;
public bool thighL;
public bool thighR;
public bool kneeL;
public bool kneeR;
public bool footL;
public bool footR;
public bool other;
}
public BN bone = new BN();
public bool max;
public float motionInfluence = 1;
[System.Serializable]
public class PWR
{
public float drag = 1;
public float rotate = 1;
}
public PWR power = new PWR();
[System.Serializable]
public class OFF
{
public Vector3 origin;
public Vector3 rotate;
}
public OFF offset = new OFF();
}
public MP magnPoint = new MP();
public RA2AttachableObject attachable;
//var chain;
//var anchor;
//private ParentChain chain;
//public ERagdollChainType chain;
[System.Serializable]
public class XTR
{
public RagdollAnimator2BoneIndicator boneInd;
public RagdollAnimatorFeatureHelper blendOnCollision;
[Space(10)]
public RagdollHandler ragd = null;
}
public XTR extra = new XTR();
Vector3 dir;
[System.Serializable]
public class ACT
{
public RagdollHandler ragd = null;
public enum sx {none, off, standin, fallin, sleep};
public sx setTo;
public RagdollAnimator2BoneIndicator boneInd;
public Rigidbody rigidb;
public Vector3 dir;
[System.Serializable]
public class BN
{
public RagdollChainBone hip;
public RagdollChainBone spine;
public RagdollChainBone chest;
public RagdollChainBone head;
public RagdollChainBone handR;
public RagdollChainBone handL;
public RagdollChainBone footR;
public RagdollChainBone footL;
}
public BN bones = new BN();
[System.Serializable]
public class MSC
{
public bool isOn;
[Range (0f, 1f)] public float power;
}
public MSC muscles = new MSC();
[System.Serializable]
public class NST
{
public enum tx {physBoneT, animBoneT, boneColl, ragdColl, ragdRigidb, boneControl};
public tx typ;
public enum cx {core, armL, armR, legL, legR};
public cx chain;
public Vector3 P;
[Header("F O U N D")]
public Transform boneT;
public Rigidbody rigidb;
public Collider coll;
public Vector3 dir;
//public RagdollBoneController boneControl;
}
public NST nearest = new NST();
[System.Serializable]
public class IMP
{ //impact adding by script
public bool isOn;
public Vector3 dir;
public float coef;
public enum tx {bone, rigidb, chain};
public tx typ;
public enum ex {one, all};
public ex effectOn;
public bool nearest;
[System.Serializable]
public class AO
{
[System.Serializable]
public class BN
{
public bool hip;
public bool spine;
public bool chest;
public bool forearmL;
public bool forearmR;
public bool elbowL;
public bool elbowR;
public bool handL;
public bool handR;
public bool thighL;
public bool thighR;
public bool kneeL;
public bool kneeR;
public bool footL;
public bool footR;
public bool other;
}
public BN bone = new BN();
[System.Serializable]
public class CH
{
public bool core;
public bool armL;
public bool armR;
public bool legL;
public bool legR;
public bool other;
}
public CH chain = new CH();
}
public AO addOn = new AO();
[Header("F O U N D")]
//public Vector3 P;
public RagdollChainBone bone;
public Rigidbody rigidb;
}
public IMP impact = new IMP();
}
public ACT actor = new ACT();
//the other actor w ragd animator
[System.Serializable]
public class OTH
{
public List<RagdollHandler> detectedRagdolls = new List<RagdollHandler> ();
public RagdollHandler ragd = null;
public RagdollAnimator2 ragdAnim2;
public enum sx {none, off, standin, fallin, sleep};
public sx setTo;
public RagdollAnimator2BoneIndicator boneInd;
public Rigidbody rigidb;
public Vector3 dir;
[System.Serializable]
public class BN
{
public RagdollChainBone head;
public RagdollChainBone handR;
public RagdollChainBone handL;
public RagdollChainBone footR;
public RagdollChainBone footL;
}
public BN bones = new BN();
[System.Serializable]
public class NST
{
public Rigidbody rigidb;
public Vector3 dir;
}
public NST nearest = new NST();
[System.Serializable]
public class IMP
{ //impact adding by script
public bool isOn;
public Vector3 dir;
public float coef;
public enum tx {bone, rigidb, chain};
public tx typ;
public enum ex {one, all};
public ex effectOn;
public bool nearest;
[System.Serializable]
public class AO
{
[System.Serializable]
public class BN
{
public bool hip;
public bool spine;
public bool chest;
public bool forearmL;
public bool forearmR;
public bool elbowL;
public bool elbowR;
public bool handL;
public bool handR;
public bool thighL;
public bool thighR;
public bool kneeL;
public bool kneeR;
public bool footL;
public bool footR;
public bool other;
}
public BN bone = new BN();
[System.Serializable]
public class CH
{
public bool core;
public bool armL;
public bool armR;
public bool legL;
public bool legR;
public bool other;
}
public CH chain = new CH();
}
public AO addOn = new AO();
[Header("F O U N D")]
//public Vector3 P;
public RagdollChainBone bone;
public Rigidbody rigidb;
}
public IMP impact = new IMP();
}
public OTH other = new OTH();
private List<Collider> toIgnore = new List<Collider>();
public class HandControll
{
public RagdollChainBone ragdollBone;
public bool isAttached = false;
public Collider attachedTo = null;
public Vector3 attachLocalPos = Vector3.zero;
public Quaternion attachLocalRot = Quaternion.identity;
//public List<Collider> IgnoredCollisionsWith = new List<Collider>();
public void Detach()
{
ragdollBone.GameRigidbody.isKinematic = false;
isAttached = false;
attachedTo = null;
ragdollBone.MainBoneCollider.enabled = true;
//foreach( var coll in IgnoredCollisionsWith )
//{
// ragdollBone.IgnoreCollisionsWith( coll, false );
//}
//IgnoredCollisionsWith.Clear();
}
}
public bool doDebug;
int i;
private Collider[] surround = new Collider[64];
private int surroundCount = 0;
private Collider[] far = new Collider[32];
private int farCount = 0;
private Collider[] mid = new Collider[32];
private int midCount = 0;
private Collider[] close = new Collider[16];
private int closeCount = 0;
private void CastSurroundSphere( float forwardDistance = 6f, float radius = 8f )
{
Vector3 maxRange = transform.TransformPoint( new Vector3( 0f, 1f, forwardDistance ) );
surroundCount = Mathf.Min (surround.Length - 1, Physics.OverlapSphereNonAlloc (maxRange, radius, surround, config.layerMask.hit));
}
private void CastFarSphere( float distance = 3f, float radius = 1f )
{
Vector3 maxRange = transform.TransformPoint( new Vector3( 0f, 1f, distance ) );
farCount = Mathf.Min (far.Length - 1, Physics.OverlapSphereNonAlloc( maxRange, radius, far, config.layerMask.hit));
}
private void CastMidBox( float y = 1f, float width = 1.5f, float height = 1f, float zScale = 2f )
{
Vector3 midRange = transform.TransformPoint( new Vector3( 0f, y, 0.5f + zScale * 0.5f ) );
midCount = Mathf.Min (mid.Length - 1, Physics.OverlapBoxNonAlloc (midRange, new Vector3(width, height, zScale), mid, transform.rotation, config.layerMask.hit));
}
private void CastCloseBox( float y = 1f, float width = 0.05f, float height = 0.25f, float zScale = 1f )
{
Vector3 closeRange = transform.TransformPoint( new Vector3( 0f, y, 0.5f * zScale ) );
closeCount = Mathf.Min (close.Length - 1, Physics.OverlapBoxNonAlloc (closeRange, new Vector3(width, height, zScale), close, transform.rotation, config.layerMask.hit) );
}
void Start()
{
Collider[] myCol = ragdAnim2.transform.GetComponentsInChildren<Collider>();
foreach (var col in myCol) toIgnore.Add (col);
if (ragdAnim2) foreach(var col in ragdAnim2.Settings.User_GetAllDummyColliders()) toIgnore.Add(col);
extra.blendOnCollision = ragdAnim2.Handler.GetExtraFeatureHelper<RAF_BlendOnCollisions>();
//var chain = ragdAnim2.Handler.GetChain (ERagdollChainType.Core);
//var anchor = ragdAnim2.Handler.GetAnchorBoneController;
}
void Update()
{
if (!isOn && Time.time > delay) {
isOn = true;
actor.bones.hip = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.Hips);
actor.bones.spine = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.Spine);
actor.bones.chest = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.Chest);
actor.bones.head = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.Head);
actor.bones.handR = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.RightHand);
actor.bones.handL = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.LeftHand);
actor.bones.footR = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.RightFoot);
actor.bones.footL = ragdAnim2.User_GetBoneSetupByHumanoidBone (HumanBodyBones.LeftFoot);
}
if (!isOn) return;
//if (ragdAnim2.IsInFallingOrSleepMode) mode = mx.fallin;
nearestBone = ragdAnim2.User_GetNearestPhysicalTransformBoneToPosition (worldP);
if (magnPoint.isOn) addMagnetP ();
if (actor.muscles.isOn) setMusclesPower4Actor ();
if (actor.impact.isOn) addImpact4Actor ();
if (other.impact.isOn) addImpact4Other ();
if (actor.setTo != ACT.sx.none) switchMode4Actor ();
}
private void getChain (int ix) {
var chain = ragdAnim2.Handler.GetChain (ERagdollChainType.Core);
//if (ix == 0) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.Core);
if (ix == 1) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.LeftArm);
if (ix == 2) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.RightArm);
if (ix == 3) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.LeftLeg);
if (ix == 4) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.RightLeg);
}
public void setMusclesPower4Actor () {
actor.muscles.isOn = false;
ragdAnim2.Settings.MusclesPower = actor.muscles.power;
//ragdAnim2.User_FadeMusclesPower ();
//ragdAnim2.UpdateAllAfterManualChanges ();
ragdAnim2.Handler.User_UpdateJointsPlayParameters(true);
}
public void addMagnetP (){
magnPoint.isOn = false;
if(!magnetPoint) magnetPoint = new GameObject().AddComponent<RA2MagnetPoint>();
magnetPoint.transform.position = magnPoint.P;
magnetPoint.transform.rotation = magnPoint.Q;
if (magnPoint.set4 == MP.sx.actor) {
magnetPoint.ObjectWithRagdollAnimator = ragdAnim2.gameObject;
if (magnPoint.bone.hip) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.Hips);
if (magnPoint.bone.spine) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.Spine);
if (magnPoint.bone.chest) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.Chest);
if (magnPoint.bone.head) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.Head);
if (magnPoint.bone.handL) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.LeftHand);
if (magnPoint.bone.handR) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.RightHand);
if (magnPoint.bone.footL) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.LeftFoot);
if (magnPoint.bone.footR) magnetPoint.ToMove = animator.GetBoneTransform(HumanBodyBones.RightFoot);
}
if (magnPoint.max) magnetPoint.KinematicOnMax = true;
magnetPoint.OriginOffset = magnPoint.offset.origin;
magnetPoint.DragPower = magnPoint.power.drag;
magnetPoint.RotatePower = magnPoint.power.rotate;
magnetPoint.enabled = true;
status.attached = true;
actor.setTo = ACT.sx.fallin;
switchMode4Actor ();
}
public void addImpact4Actor () {
actor.impact.isOn = false;
//BONE
if (actor.impact.typ == ACT.IMP.tx.bone) {
dir = actor.impact.dir * actor.impact.coef;
if (actor.impact.nearest) {
findNearest4Actor ();
actor.impact.rigidb = actor.nearest.rigidb;
}
if (actor.impact.effectOn == ACT.IMP.ex.one) ragdAnim2.User_AddBoneImpact (actor.impact.bone, dir, 0f);
if (actor.impact.effectOn == ACT.IMP.ex.all) {
var chain = ragdAnim2.Handler.GetChain (ERagdollChainType.Core);
for (i = 0; i < 2; i++)
{
actor.impact.bone = chain.BoneSetups[i];
ragdAnim2.User_AddBoneImpact (actor.impact.bone, dir, 0f);
}
}
}
//RIGIDB
if (actor.impact.typ == ACT.IMP.tx.rigidb) {
if (actor.impact.nearest) {
findNearest4Actor ();
actor.impact.rigidb = actor.nearest.rigidb;
}
ragdAnim2.User_AddRigidbodyImpact (actor.impact.rigidb, (actor.impact.dir + new Vector3 (0f, .4f, 0f)) * config.power.pushForce, 0.14f, ForceMode.Impulse, 0.06f);
}
}
public void addImpact4Other () {
other.impact.isOn = false;
if (other.impact.typ == OTH.IMP.tx.rigidb) ragdAnim2.User_AddRigidbodyImpact (other.nearest.rigidb, (other.nearest.dir + new Vector3(0f, .4f, 0f)) * config.power.pushForce, 0.14f, ForceMode.Impulse, 0.06f);
}
public void dropAttachable (){
ragdAnim2.Handler.UnwearAttachable( attachable );
}
public void switchMode4Actor () {
if (actor.setTo == ACT.sx.off) {
//ragdAnim2.RA2Event_SwitchToOff ();
}
if (actor.setTo == ACT.sx.standin) {
ragdAnim2.User_TransitionToStandingMode (0.4f, 0f);
ragdAnim2.RA2Event_SwitchToStand ();
//ragdAnim2.User_SwitchStandState();
}
if (actor.setTo == ACT.sx.fallin) {
ragdAnim2.RA2Event_SwitchToFall ();
//ragdAnim2.User_SwitchFallState();
}
if (actor.setTo == ACT.sx.sleep) {
ragdAnim2.RA2Event_SwitchToSleep ();
//ragdAnim2.User_SwitchSleepState();
}
actor.setTo = ACT.sx.none;
}
public void switchMode4Other () {
if (other.setTo == OTH.sx.off) {
}
if (other.setTo == OTH.sx.standin) {
other.ragdAnim2.User_TransitionToStandingMode (0.4f, 0f);
other.ragdAnim2.RA2Event_SwitchToStand ();
}
if (other.setTo == OTH.sx.fallin) {
other.ragdAnim2.RA2Event_SwitchToFall ();
}
if (other.setTo == OTH.sx.sleep) {
other.ragdAnim2.RA2Event_SwitchToSleep ();
}
other.setTo = OTH.sx.none;
}
public void RagdollAnimator2BoneCollision (RA2BoneCollisionHandler hitted)
{
var lastimpact = hitted.LatestEnterCollision;
hit.velocity = lastimpact.relativeVelocity.magnitude;
hit.impulse = lastimpact.impulse.magnitude;
hit.layer = hitted.LatestEnterCollision.collider.gameObject.layer;
// Play audio only on ball layer hits, when helocity is big enough and with some culldown to avoid duplicated sounds
if (config.audio.hit) if (hit.layer == 4) if (hit.velocity >= config.power.fall || hit.impulse > config.power.minImpulse)
{
if (Time.unscaledTime - hit.startT > 0.1f)
{
hit.startT = Time.unscaledTime;
config.audio.hit.Play();
}
}
if (action.activ.onHit.fall) {
if (ragdAnim2.IsInFallingOrSleepMode) return;
if (hit.velocity < config.power.fall) return;
hit.rigidb = hitted.DummyBoneRigidbody;
// Fall impact is calling few methods inside, like switch FallState and AddImpact
ragdAnim2.User_FallImpact (lastimpact.relativeVelocity.normalized, config.power.impact, 0.0f, config.power.bodyPush, hit.rigidb);
ragdAnim2.Handler.Mecanim.CrossFadeInFixedTime( "Fall", 0.2f );
if (doDebug) Debug.Log ("action: fall on hit");
}
}
private List<RagdollHandler> detectedRagdolls = new List<RagdollHandler>();
private List<RagdollHandler> FindRagdollsIn (Collider[] c, int length, bool clear = true)
{
if (clear) detectedRagdolls.Clear();
for (int i = 0; i < length; i++)
{
if (c[i] == null) continue;
if (toIgnore.Contains(c[i])) continue;
other.boneInd = c[i].gameObject.GetComponent<RagdollAnimator2BoneIndicator>();
if (other.boneInd)
{
if (ragdAnim2) if (other.boneInd.ParentHandler == ragdAnim2.Settings ) continue; // Dont add self
if (detectedRagdolls.Contains (other.boneInd.ParentHandler) == false)
detectedRagdolls.Add (other.boneInd.ParentHandler);
}
}
return detectedRagdolls;
}
public void findOtherRagdolls() {
other.detectedRagdolls = FindRagdollsIn (surround, surroundCount);
}
public void findNearest4Actor() {
/*
var chain = ragdAnim2.Handler.GetChain (ERagdollChainType.Core);
if (actor.nearest.chain == ACT.NST.cx.legL) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.LeftLeg);
if (actor.nearest.chain == ACT.NST.cx.legR) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.RightLeg);
if (actor.nearest.chain == ACT.NST.cx.armL) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.LeftArm);
if (actor.nearest.chain == ACT.NST.cx.armR) chain = ragdAnim2.Handler.GetChain (ERagdollChainType.RightArm);
*/
var chain = ERagdollChainType.Core;
actor.nearest.P = ragdAnim2.transform.TransformPoint (Vector3.up * 1.5f);
if (actor.nearest.typ == ACT.NST.tx.physBoneT) actor.nearest.boneT = ragdAnim2.User_GetNearestPhysicalTransformBoneToPosition (actor.nearest.P, true);
if (actor.nearest.typ == ACT.NST.tx.animBoneT) actor.nearest.boneT = ragdAnim2.User_GetNearestAnimatorTransformBoneToPosition (actor.nearest.P, true);
if (actor.nearest.typ == ACT.NST.tx.ragdRigidb) actor.nearest.rigidb = ragdAnim2.User_GetNearestRagdollRigidbodyToPosition (actor.nearest.P, true, chain);
}
public void findNearest4Other() {
other.nearest.rigidb = other.ragdAnim2.User_GetNearestRagdollRigidbodyToPosition (other.ragdAnim2.transform.TransformPoint(Vector3.up * 1.5f), true, ERagdollChainType.Core);
}
private HandControll leftHand;
private HandControll rightHand;
private HandControll GetHand (int ix)
{ if (ix <= 0) return leftHand; else return rightHand; }
public void magnPointBones () {
magnPoint.bone.hip = false;
magnPoint.bone.spine = false;
magnPoint.bone.chest = false;
//magnPoint.bone.forearmL = false;
//magnPoint.bone.forearmR = false;
//magnPoint.bone.elbowL = false;
//magnPoint.bone.elbowR = false;
magnPoint.bone.handL = false;
magnPoint.bone.handR = false;
//magnPoint.bone.thighL = false;
//magnPoint.bone.thighR = false;
//magnPoint.bone.kneeL = false;
//magnPoint.bone.kneeR = false;
magnPoint.bone.footL = false;
magnPoint.bone.footR = false;
magnPoint.bone.other = false;
}
public void clearImpactBones4Actor () {
actor.impact.addOn.bone.hip = false;
actor.impact.addOn.bone.spine = false;
actor.impact.addOn.bone.chest = false;
actor.impact.addOn.bone.forearmL = false;
actor.impact.addOn.bone.forearmR = false;
actor.impact.addOn.bone.elbowL = false;
actor.impact.addOn.bone.elbowR = false;
actor.impact.addOn.bone.handL = false;
actor.impact.addOn.bone.handR = false;
actor.impact.addOn.bone.thighL = false;
actor.impact.addOn.bone.thighR = false;
actor.impact.addOn.bone.kneeL = false;
actor.impact.addOn.bone.kneeR = false;
actor.impact.addOn.bone.footL = false;
actor.impact.addOn.bone.footR = false;
actor.impact.addOn.bone.other = false;
}
public void clearImpactBones4Other () {
other.impact.addOn.bone.hip = false;
other.impact.addOn.bone.spine = false;
other.impact.addOn.bone.chest = false;
other.impact.addOn.bone.forearmL = false;
other.impact.addOn.bone.forearmR = false;
other.impact.addOn.bone.elbowL = false;
other.impact.addOn.bone.elbowR = false;
other.impact.addOn.bone.handL = false;
other.impact.addOn.bone.handR = false;
other.impact.addOn.bone.thighL = false;
other.impact.addOn.bone.thighR = false;
other.impact.addOn.bone.kneeL = false;
other.impact.addOn.bone.kneeR = false;
other.impact.addOn.bone.footL = false;
other.impact.addOn.bone.footR = false;
other.impact.addOn.bone.other = false;
}
public void clearImpactChain4Actor () {
actor.impact.addOn.chain.core = false;
actor.impact.addOn.chain.armL = false;
actor.impact.addOn.chain.armR = false;
actor.impact.addOn.chain.legL = false;
actor.impact.addOn.chain.legR = false;
actor.impact.addOn.chain.other = false;
}
public void clearImpactChain4Other () {
other.impact.addOn.chain.core = false;
other.impact.addOn.chain.armL = false;
other.impact.addOn.chain.armR = false;
other.impact.addOn.chain.legL = false;
other.impact.addOn.chain.legR = false;
other.impact.addOn.chain.other = false;
}
}