private void SpawnBlood(DamageInfo info) { if (AI.IsTurtle(this.m_AI.m_ID) || this.m_AI.m_ID == AI.AIID.ArmadilloThreeBanded) { return; } AIManager.BloodFXType key = info.m_DamageItem ? info.m_DamageItem.m_Info.m_BloodFXType : AIManager.BloodFXType.Blunt; List <string> list = AIManager.Get().m_BloodFXNames[(int)key]; if (list.Count == 0) { DebugUtils.Assert("Missing blood fxes!", true, DebugUtils.AssertType.Info); return; } string text = list[UnityEngine.Random.Range(0, list.Count)]; text += ((this.m_AI.m_Params.m_Human || this.m_AI.m_Params.m_BigAnimal) ? "_M" : "_S"); Vector3 vector = Vector3.zero; RagdollBone closestRagdollBone = this.m_AI.GetClosestRagdollBone(info.m_Position); if (closestRagdollBone) { vector = closestRagdollBone.transform.position; } else { vector = base.transform.position; } Vector3 forward = (info.m_Damager && info.m_Damager.IsPlayer()) ? (Camera.main.transform.position - Camera.main.transform.right - vector).normalized : (-info.m_HitDir); ParticlesManager.Get().Spawn(text, vector, Quaternion.LookRotation(forward), Vector3.zero, null, -1f, false); }
RagdollBoneTargetBonePair[] CreateBonePairs(RagdollDefinitionBindings bindings, Transform targetParent) { List <RagdollBoneTargetBonePair> pairs = new List <RagdollBoneTargetBonePair>(); CreateBonePairsRecursively(FindCorrespondingBone(bindings.Root.Transform, targetParent), pairs, bindings.transform); return(pairs.ToArray()); void CreateBonePairsRecursively(Transform targetBoneTransform, List <RagdollBoneTargetBonePair> ragdollPairs, Transform ragdollParentTransform) { Transform ragdollBoneTransform = FindCorrespondingBone(targetBoneTransform, ragdollParentTransform); RagdollBone ragdollBone = null; if (ragdollBoneTransform) { ragdollBone = GetRagdollBoneForRagdollBoneTransform(ragdollBoneTransform, bindings); } if (ragdollBone != null) { ragdollPairs.Add(new RagdollBoneTargetBonePair(ragdollBone, targetBoneTransform)); } //Recursively call all of its children for (int i = 0; i < targetBoneTransform.childCount; i++) { CreateBonePairsRecursively(targetBoneTransform.GetChild(i), ragdollPairs, ragdollParentTransform); } } }
private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight, bool translationEnabled) { if ((this.Ragdoll != null) && (this.m_inicialized && this.IsActive)) { int index = this.m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex][0]; MyCharacterBone bone = this.m_bones[index]; Matrix matrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity; Matrix matrix3 = (this.m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * this.Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex)) * Matrix.Invert(bone.BindTransform * matrix); if (!this.m_animationBlendingHelper.Initialized) { this.m_animationBlendingHelper.Init(this.m_bones, this.m_character.AnimationController.Controller); } this.m_animationBlendingHelper.BlendWeight(ref weight, bone, this.m_character.AnimationController.Variables); weight *= MyFakes.RAGDOLL_ANIMATION_WEIGHTING; float single1 = MathHelper.Clamp(weight, 0f, 1f); weight = single1; if (matrix3.IsValid() && (matrix3 != Matrix.Zero)) { if (weight == 1f) { bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize(matrix3.GetOrientation())); if (translationEnabled) { bone.Translation = matrix3.Translation; } } else { bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize(matrix3.GetOrientation())), weight); if (translationEnabled) { bone.Translation = Vector3.Lerp(bone.Translation, matrix3.Translation, weight); } } } bone.ComputeAbsoluteTransform(true); foreach (RagdollBone bone2 in ragdollBone.m_children) { float num2 = dynamicChildrenWeight; if (this.m_keyframedBodies.Contains(bone2.m_rigidBodyIndex)) { num2 = keyframedChildrenWeight; } if (this.IsPartiallySimulated) { this.SetBoneTo(bone2, num2, dynamicChildrenWeight, keyframedChildrenWeight, false); } else { this.SetBoneTo(bone2, num2, dynamicChildrenWeight, keyframedChildrenWeight, !this.Ragdoll.IsRigidBodyPalmOrFoot(bone2.m_rigidBodyIndex) && MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION); } } } }
void DoPoweredRotationMatching(AnimatedPair pair, BoneProfile boneProfile, float dt) { RagdollBone bone = pair.RagdollBone; Rigidbody rigidbody = bone.Rigidbody; float alpha = boneProfile.rotationAlpha; float dampingRatio = boneProfile.rotationDampingRatio; SetTargetRotation(pair); SetTargetAngularVelocityLocal(bone.Joint, pair.poseAngularVelocity, pair.RagdollBone.StartingJointRotation); bone.Joint.slerpDrive = AnimationMatching.GetRotationMatchingJointDrive(alpha, dampingRatio, rigidbody.mass, dt, boneProfile.maxAngularAcceleration); }
private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight) { int firstBoneIndex = m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex].First(); MyCharacterBone bone = m_bones[firstBoneIndex]; //Matrix localTransform = m_ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex); Matrix localTransform = m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * m_ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex); Matrix parentMatrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity; Matrix absoluteMatrixInverted = Matrix.Invert(bone.BindTransform * parentMatrix); Matrix finalTransform = localTransform * absoluteMatrixInverted; //finalTransform = rigidBodyToBoneTransform * finalTransform; if (weight == 1.0f) { bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())); // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled on all bodies except the firs one if (MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION) { bone.Translation = finalTransform.Translation; } } else { bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())), weight); // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled if (MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION) { bone.Translation = Vector3.Lerp(bone.Translation, finalTransform.Translation, weight); } } bone.ComputeAbsoluteTransform(); foreach (var childBone in ragdollBone.m_children) { float childWeight = dynamicChildrenWeight; if (m_keyframedBodies.Contains(childBone.m_rigidBodyIndex)) { childWeight = keyframedChildrenWeight; } SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight); } }
private void SetupRagdollBones() { List <Rigidbody> componentsDeepChild = General.GetComponentsDeepChild <Rigidbody>(base.gameObject); for (int i = 0; i < componentsDeepChild.Count; i++) { componentsDeepChild[i].isKinematic = true; Collider component = componentsDeepChild[i].GetComponent <Collider>(); RagdollBone ragdollBone = component.gameObject.AddComponent <RagdollBone>(); ragdollBone.m_Parent = base.gameObject; component.enabled = false; component.isTrigger = true; this.m_RagdollBones.Add(component, componentsDeepChild[i]); } }
public override bool TakeDamage(DamageInfo info) { RagdollBone closestRagdollBone = this.GetClosestRagdollBone(info.m_Position); if (closestRagdollBone) { info.m_Damage *= closestRagdollBone.GetDamageMultiplier(false); } this.m_LastDamageInfo = info; bool flag = base.TakeDamage(info); if (flag && info.m_Damager && info.m_Damager.GetComponent <ReplicatedLogicalPlayer>()) { PlayerStateModule.Get().OnGiveDamageToAI(this, info); } return(flag); }
void HandleBoneDecayOnCollision(float collisionMagnitude2, RagdollBone bone, bool isCrushed, Collision collision) { if (isCrushed) { //Debug.LogWarning(bone + " / " + collision.transform.name + " CrUSHED"); ragdollController.SetBoneDecay(bone.bone, 1, neighborDecayMultiplier); } // if the magnitude is above the minimum threshold for adding decay else if (collisionMagnitude2 >= decayMagnitudeRange.x * decayMagnitudeRange.x) { float magnitude = Mathf.Sqrt(collisionMagnitude2); //linearly interpolate decay between 0 and 1 base on collision magnitude float linearDecay = (magnitude - decayMagnitudeRange.x) / (decayMagnitudeRange.y - decayMagnitudeRange.x); //Debug.Log(bone + " / " + collision.transform.name + " mag: " + magnitude + " decay " + linearDecay); ragdollController.SetBoneDecay(bone.bone, linearDecay, neighborDecayMultiplier); } }
public RagdollBone GetClosestRagdollBone(Vector3 point) { float num = float.MaxValue; RagdollBone result = null; foreach (RagdollBone ragdollBone in this.m_RagdollBones) { bool enabled = ragdollBone.m_Collider.enabled; ragdollBone.m_Collider.enabled = true; float sqrMagnitude = (ragdollBone.m_Collider.ClosestPoint(point) - point).sqrMagnitude; if (sqrMagnitude < num) { result = ragdollBone; num = sqrMagnitude; } ragdollBone.m_Collider.enabled = enabled; } return(result); }
IEnumerator CheckForCharacter(Ray ray) { yield return(new WaitForFixedUpdate()); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f, shooting.shootMask, QueryTriggerInteraction.Ignore)) { //check if we hit a ragdoll bone RagdollBone ragdollBone = hit.transform.GetComponent <RagdollBone>(); if (ragdollBone) { // check if the ragdoll has a controller if (ragdollBone.ragdoll.hasController) { AttachToCharacter(ragdollBone.ragdoll.controller.GetComponent <Character>()); } } } }
IEnumerator ShootBullet(Ray ray) { yield return(new WaitForFixedUpdate()); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f, shootMask, QueryTriggerInteraction.Ignore)) { //check if we hit a ragdoll bone RagdollBone ragdollBone = hit.transform.GetComponent <RagdollBone>(); if (ragdollBone) { // check if the ragdoll has a controller if (ragdollBone.ragdoll.hasController) { RagdollController controller = ragdollBone.ragdoll.controller; // set bone decay for the hit bone, so the physics will affect it // slightly lower for neighbor bones float mainDecay = 1; float neighborMultiplier = .75f; controller.SetBoneDecay(ragdollBone.bone, mainDecay, neighborMultiplier); //make it go ragdoll controller.GoRagdoll(); } } // shoot normally Rigidbody rb = hit.transform.GetComponent <Rigidbody>(); if (rb) { rb.AddForceAtPosition(ray.direction.normalized * modifiedBulletForce, hit.point, ForceMode.VelocityChange); } } }
IEnumerator CheckForRagdollGrab(Ray ray) { if (grabbedBone) { RagdollPhysics.DetachRigidbody(grabbedBone.GetComponent <Rigidbody>(), hangJoint, false); grabbedBone = null; } else { yield return(new WaitForFixedUpdate()); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f, shootMask, QueryTriggerInteraction.Ignore)) { grabbedBone = hit.transform.GetComponent <RagdollBone>(); if (grabbedBone) { ragdollGrabberAnchor.transform.position = hit.point; hangJoint = RagdollPhysics.GrabRigidbody(grabbedBone.rb, ragdollGrabberAnchor.childRigidbody, true); } } } }
private void Hit(CJObject cj_object, Collider coll, Vector3 hit_pos, Vector3 hit_dir) { Item currentItem = this.m_Player.GetCurrentItem(Hand.Right); if (cj_object) { HumanAI component = cj_object.GetComponent <HumanAI>(); if (component) { if (component.m_Hallucination && component.m_HallucinationDisappearing) { return; } this.HitHumanAI(component, hit_pos, hit_dir); this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID); this.m_AlreadyHit = true; return; } else { this.HitObject(cj_object, hit_pos, hit_dir); } } else { RagdollBone component2 = coll.gameObject.GetComponent <RagdollBone>(); if (component2 && component2.m_Parent) { DeadBody component3 = component2.m_Parent.GetComponent <DeadBody>(); if (component3) { component3.OnTakeDamage(new DamageInfo { m_DamageItem = currentItem, m_Damager = base.gameObject, m_Position = hit_pos, m_HitDir = hit_dir, m_Normal = -hit_dir }); return; } } } DamageInfo damageInfo = new DamageInfo(); ObjectMaterial component4; if (cj_object != null) { component4 = cj_object.gameObject.GetComponent <ObjectMaterial>(); } else { component4 = coll.gameObject.GetComponent <ObjectMaterial>(); } EObjectMaterial mat = (!(component4 == null)) ? component4.m_ObjectMaterial : EObjectMaterial.Unknown; damageInfo.m_Damage = currentItem.m_Info.m_DamageSelf * ObjectMaterial.GetDamageSelfMul(mat); damageInfo.m_DamageItem = currentItem; this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID); currentItem.TakeDamage(damageInfo); this.OnHit(); }
private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight, bool translationEnabled) { if (Ragdoll == null) { return; } if (!m_inicialized || !IsActive) { return; } int firstBoneIndex = m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex].First(); MyCharacterBone bone = m_bones[firstBoneIndex]; //Matrix localTransform = Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex); Matrix localTransform = m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex); Matrix parentMatrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity; Matrix absoluteMatrixInverted = Matrix.Invert(bone.BindTransform * parentMatrix); Matrix finalTransform = localTransform * absoluteMatrixInverted; //finalTransform = rigidBodyToBoneTransform * finalTransform; Debug.Assert(finalTransform.IsValid() && finalTransform != Matrix.Zero, "Ragdoll - final bone transform is invalid!"); if (finalTransform.IsValid() && finalTransform != Matrix.Zero) { if (weight == 1.0f) { bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())); // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled on all bodies except the firs one if (translationEnabled)// || m_character.IsDead) { bone.Translation = finalTransform.Translation; } } else { bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())), weight); // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled if (translationEnabled)// || m_character.IsDead) { bone.Translation = Vector3.Lerp(bone.Translation, finalTransform.Translation, weight); } } } bone.ComputeAbsoluteTransform(); foreach (var childBone in ragdollBone.m_children) { float childWeight = dynamicChildrenWeight; if (m_keyframedBodies.Contains(childBone.m_rigidBodyIndex)) { childWeight = keyframedChildrenWeight; } //SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION); if (IsPartiallySimulated) { SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, false); } else { SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, (Ragdoll.IsRigidBodyPalmOrFoot(childBone.m_rigidBodyIndex)) ? false : MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION); } } }
private void Hit(CJObject cj_object, Collider coll, Vector3 hit_pos, Vector3 hit_dir) { Item currentItem = this.m_Player.GetCurrentItem(Hand.Right); if (cj_object) { HumanAI humanAI = null; AI component = cj_object.GetComponent <AI>(); if (component && component.IsHuman()) { humanAI = (HumanAI)component; } if (humanAI) { if (humanAI.m_Hallucination && humanAI.m_HallucinationDisappearing) { return; } this.HitHumanAI(humanAI, hit_pos, hit_dir); this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID); this.m_AlreadyHit = true; } else { Fish component2 = cj_object.GetComponent <Fish>(); if (component2 && component2.m_ID != AI.AIID.AngelFish && component2.m_ID != AI.AIID.DiscusFish && UnityEngine.Random.Range(0f, 1f) < 0.5f) { this.m_AlreadyHit = true; } else if (base.m_ControllerType == PlayerControllerType.WeaponMelee && component2 && component2.m_ID != AI.AIID.AngelFish && component2.m_ID != AI.AIID.DiscusFish) { component2.OnHitByItem(null, hit_pos); this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID); this.m_AlreadyHit = true; } } if (component) { PlayerConditionModule.Get().GetDirtinessAdd(GetDirtyReason.Combat, null); } if (!this.m_AlreadyHit) { this.HitObject(cj_object, hit_pos, hit_dir); } } else { RagdollBone component3 = coll.gameObject.GetComponent <RagdollBone>(); if (component3 && component3.m_ParentObject) { DeadBody component4 = component3.m_ParentObject.GetComponent <DeadBody>(); if (component4) { component4.OnTakeDamage(new DamageInfo { m_DamageItem = currentItem, m_Damager = base.gameObject, m_Position = hit_pos, m_HitDir = hit_dir, m_Normal = -hit_dir }); this.m_AlreadyHit = true; } } } DamageInfo damageInfo = new DamageInfo(); ObjectMaterial component5; if (cj_object != null) { component5 = cj_object.gameObject.GetComponent <ObjectMaterial>(); } else { component5 = coll.gameObject.GetComponent <ObjectMaterial>(); } EObjectMaterial mat = (component5 == null) ? EObjectMaterial.Unknown : component5.m_ObjectMaterial; damageInfo.m_Damage = currentItem.m_Info.m_DamageSelf * ObjectMaterial.GetDamageSelfMul(mat); damageInfo.m_DamageItem = currentItem; this.MakeHitSound(coll.gameObject, currentItem.m_Info.m_ID); currentItem.TakeDamage(damageInfo); this.OnHit(); }
private void SetBoneTo(RagdollBone ragdollBone, float weight, float dynamicChildrenWeight, float keyframedChildrenWeight, bool translationEnabled) { if (Ragdoll == null) return; if (!m_inicialized || !IsActive) return; int firstBoneIndex = m_rigidBodiesToBonesIndices[ragdollBone.m_rigidBodyIndex].First(); MyCharacterBone bone = m_bones[firstBoneIndex]; //Matrix localTransform = Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex); Matrix localTransform = m_bodyToBoneRigTransforms[ragdollBone.m_rigidBodyIndex] * Ragdoll.GetRigidBodyLocalTransform(ragdollBone.m_rigidBodyIndex); Matrix parentMatrix = (bone.Parent != null) ? bone.Parent.AbsoluteTransform : Matrix.Identity; Matrix absoluteMatrixInverted = Matrix.Invert(bone.BindTransform * parentMatrix); Matrix finalTransform = localTransform * absoluteMatrixInverted; //finalTransform = rigidBodyToBoneTransform * finalTransform; Debug.Assert(finalTransform.IsValid() && finalTransform != Matrix.Zero, "Ragdoll - final bone transform is invalid!"); if (finalTransform.IsValid() && finalTransform != Matrix.Zero) { if (weight == 1.0f) { bone.Rotation = Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())); // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled on all bodies except the firs one if (translationEnabled)// || m_character.IsDead) { bone.Translation = finalTransform.Translation; } } else { bone.Rotation = Quaternion.Slerp(bone.Rotation, Quaternion.CreateFromRotationMatrix(Matrix.Normalize((Matrix)finalTransform.GetOrientation())), weight); // NOTE: If enabled, sometimes ragdoll bodies got extra translation which leads to disproporced transfomations on limbs, therefore disabled if (translationEnabled)// || m_character.IsDead) { bone.Translation = Vector3.Lerp(bone.Translation, finalTransform.Translation, weight); } } } bone.ComputeAbsoluteTransform(); foreach (var childBone in ragdollBone.m_children) { float childWeight = dynamicChildrenWeight; if (m_keyframedBodies.Contains(childBone.m_rigidBodyIndex)) { childWeight = keyframedChildrenWeight; } SetBoneTo(childBone, childWeight, dynamicChildrenWeight, keyframedChildrenWeight, MyFakes.ENABLE_RAGDOLL_BONES_TRANSLATION); } }
/* * callback called when ragdoll bone gets a collision * then apply bone decay to those bones */ void OnRagdollCollisionEnter(RagdollBone bone, Collision collision) { float stepOffset = characterController.stepOffset; float charHeight = characterController.height; //maybe add warp to master state for ragdoll check bool checkForRagdoll = ragdollController.state == RagdollControllerState.Animated || ragdollController.state == RagdollControllerState.BlendToAnimated; bool isFalling = ragdollController.state == RagdollControllerState.Falling; if (!isFalling && !checkForRagdoll) { return; } //check for and ignore self ragdoll collsion (only happens when falling) if (ragdollController.ragdoll.ColliderIsPartOfRagdoll(collision.collider)) { return; } if (checkForRagdoll) { //if we're getting up, knock us out regardless of where the collision takes place if (!ragdollController.isGettingUp) { // if it's below our step offset (plus a buffer) // ignore it... we can just step on top of it if (!CollisionIsAboveStepOffset(collision, stepOffset, .1f)) { return; } } } bool isCrushed = CollisionHasCrushMass(collision) && CollisionIsAboveCrushOffset(collision, charHeight); float collisionMagnitude2 = collision.relativeVelocity.sqrMagnitude; if (checkForRagdoll) { // string message = "crush"; // check if we're being crushed bool goRagdoll = isCrushed; // else check if the collision is above our incoming threhsold, (something being thrown at us) if (!goRagdoll) { // message = "incoming"; goRagdoll = collisionMagnitude2 >= incomingMagnitudeThreshold * incomingMagnitudeThreshold; } // else check if we're travelling fast enough to go ragdoll (we ran into a wall or something...) if (!goRagdoll) { // message = "outgoing"; collisionMagnitude2 = controllerVelocity.sqrMagnitude; goRagdoll = collisionMagnitude2 >= outgoingMagnitudeThreshold * outgoingMagnitudeThreshold; } if (!goRagdoll) { return; } //Debug.Log( message + "/" + bone.name + " went ragdoll cuae of " + collision.collider.name + "/" + Mathf.Sqrt(collisionMagnitude2)); ragdollController.GoRagdoll(); } HandleBoneDecayOnCollision(collisionMagnitude2, bone, isCrushed, collision); }
internal RagdollBoneTargetBonePair(RagdollBone ragdollBone, Transform targetBone) { RagdollBone = ragdollBone; TargetBone = targetBone; }