101 lines
3.1 KiB
C#
101 lines
3.1 KiB
C#
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
public class EnemyRagdoll : MonoBehaviour
|
||
|
|
{
|
||
|
|
private Rigidbody[] allRigidbodies;
|
||
|
|
private Collider[] allColliders;
|
||
|
|
private Animator animator;
|
||
|
|
|
||
|
|
// The root components we use while alive (so we don't turn them off)
|
||
|
|
private Collider mainCollider;
|
||
|
|
private Rigidbody mainRigidbody;
|
||
|
|
|
||
|
|
void Awake()
|
||
|
|
{
|
||
|
|
animator = GetComponent<Animator>();
|
||
|
|
mainCollider = GetComponent<Collider>();
|
||
|
|
mainRigidbody = GetComponent<Rigidbody>();
|
||
|
|
|
||
|
|
// Grab every bone physics component in the children
|
||
|
|
allRigidbodies = GetComponentsInChildren<Rigidbody>();
|
||
|
|
allColliders = GetComponentsInChildren<Collider>();
|
||
|
|
|
||
|
|
DeactivateRagdoll();
|
||
|
|
}
|
||
|
|
|
||
|
|
public void DeactivateRagdoll()
|
||
|
|
{
|
||
|
|
// Turn off bone physics so the Animator can control the model
|
||
|
|
foreach (Rigidbody rb in allRigidbodies)
|
||
|
|
{
|
||
|
|
if (rb != mainRigidbody)
|
||
|
|
{
|
||
|
|
rb.isKinematic = true;
|
||
|
|
rb.useGravity = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (Collider col in allColliders)
|
||
|
|
{
|
||
|
|
if (col != mainCollider)
|
||
|
|
{
|
||
|
|
col.enabled = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public void ActivateRagdoll(Vector3 hitSource, float knockbackForce)
|
||
|
|
{
|
||
|
|
// 1. Turn off the main capsule collider so it doesn't interfere
|
||
|
|
if (mainCollider != null) mainCollider.enabled = false;
|
||
|
|
if (mainRigidbody != null) mainRigidbody.isKinematic = true;
|
||
|
|
|
||
|
|
// 2. Turn on all bone physics
|
||
|
|
foreach (Collider col in allColliders)
|
||
|
|
{
|
||
|
|
if (col != mainCollider) col.enabled = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach (Rigidbody rb in allRigidbodies)
|
||
|
|
{
|
||
|
|
if (rb != mainRigidbody)
|
||
|
|
{
|
||
|
|
rb.isKinematic = false;
|
||
|
|
rb.useGravity = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. Apply the Sauron Force directly to the Hips
|
||
|
|
ApplyForceToHips(hitSource, knockbackForce);
|
||
|
|
|
||
|
|
// 4. Turn off the Animator LAST to let physics seamlessly take over
|
||
|
|
animator.enabled = false;
|
||
|
|
}
|
||
|
|
private void ApplyForceToHips(Vector3 hitSource, float knockbackForce)
|
||
|
|
{
|
||
|
|
// Synty uses Humanoid rigs, so we can reliably find the Hips bone
|
||
|
|
Transform hipsTransform = animator.GetBoneTransform(HumanBodyBones.Hips);
|
||
|
|
|
||
|
|
if (hipsTransform != null)
|
||
|
|
{
|
||
|
|
Rigidbody hipsRb = hipsTransform.GetComponent<Rigidbody>();
|
||
|
|
if (hipsRb != null)
|
||
|
|
{
|
||
|
|
// Calculate trajectory: away from player + up in the air
|
||
|
|
Vector3 launchDirection = (hipsTransform.position - hitSource).normalized;
|
||
|
|
launchDirection.y = 1.2f;
|
||
|
|
|
||
|
|
// THE FIX: Use VelocityChange so the heavy Ragdoll mass is ignored!
|
||
|
|
hipsRb.AddForce(launchDirection * knockbackForce, ForceMode.VelocityChange);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Debug.LogWarning("<color=red>Hips found, but it has no Rigidbody attached!</color>");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Debug.LogWarning("<color=red>Animator could not find the Hips bone!</color>");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|