Add directional force on enemy death, not sure if I'm taking the right approach

Hello. I’m trying to add a slightly cartoony level of force when an enemy dies. I’ve got it sort of working, but with a nullref error and another problem.

I added the commented lines to Ragdoll.cs.

public class Ragdoll : MonoBehaviour // Place on character's/enemy's main gameobject
{
    [SerializeField] private Animator animator;
    [SerializeField] private CharacterController controller;
    //[SerializeField] private WeaponDamage weapondamage;
    //[SerializeField] private PlayerAttackingState pattackingstate;
    private Collider[] allColliders;
    private Rigidbody[] allRigidbodies;
    //public Vector3 forceDirection;
    //public float currentForce;
    private void Start()
    {
        allColliders = GetComponentsInChildren<Collider>(true);
        allRigidbodies = GetComponentsInChildren<Rigidbody>(true);
        ToggleRagdoll(false);
    }
    public void ToggleRagdoll(bool isRagdoll)
    {
        foreach (Collider collider in allColliders)
        {
            if (collider.gameObject.CompareTag("Ragdoll"))
            {
                collider.enabled = isRagdoll;
            }
        }
        // forceDirection = -weapondamage.hitDirection;
        // currentForce = pattackingstate.currentForce;
        foreach (Rigidbody rigidbody in allRigidbodies)
        {
            if (rigidbody.gameObject.CompareTag("Ragdoll"))
            {
                rigidbody.isKinematic = !isRagdoll;
                rigidbody.useGravity = isRagdoll;
                // rigidbody.AddForce(Vector3.up * 15, ForceMode.Impulse);
                // rigidbody.AddForce(forceDirection * currentForce, ForceMode.Impulse);
            }
        }
        controller.enabled = !isRagdoll;
        animator.enabled = !isRagdoll;
    }
}

The line for rigidbody.AddForce(Vector3.up * 15, ForceMode.Impulse); works fine for the upward force.

I wanted a reference to the Vector3 direction in WeaponDamage.cs (forceDirection) and the amount of attack force from PlayerAttackingState.cs (currentForce) to create something similar to the ‘impact’ we normally have when attacking the live enemy.

When currentForce = pattackingstate.currentForce; is in the code I notice the enemy rig is really jittery glitchy in-game, so I guess this might be a conflict with the player script being referenced with the enemy or I chose the wrong place to place this line. What’s a better way to get the current attack’s force reference to Ragdoll.cs?

The nullref brings me to forceDirection = -weapondamage.hitDirection;

Does anyone have any suggestions on what to try or have an idea of what missteps I’m taking?

Thanks

1 Like

I can help you with the null ref; have you referenced the WeaponDamage in the inspector? Seems like the only reason there would be a null reference exception here.

You may also want to combine the forces and only apply it once. I don’t know if this will solve your problem, though.

var force = Vector3.up * 15 + forceDirection * currentForce;
rigidbody.AddForce(force, ForceMode.Impulse);
2 Likes

Thanks for the response.
I was indeed missing the WeaponDamage ref on my character. I remember adding it to the enemy so I must’ve wrote it off in my brain. Thanks :sweat_smile:

That also lead me to realize the enemy was using a ref to his own weapon when I needed the player’s in that case, so now I’m getting the enemy flying in the proper direction 100% of the time. :partying_face:

I think the only thing left is to get a current force reference from PlayerAttackingState.cs, but I’m not quite sure how to do that. It looks like even though I have the field in Ragdoll.cs, it’s not showing up in the inspector. That has something to do with PlayerAttackingState being part of the abstract classes?

Thanks

public class Ragdoll : MonoBehaviour
{
    [SerializeField] private Animator animator;
    [SerializeField] private CharacterController controller;
    [SerializeField] private PlayerAttackingState pattackingstate;
    [SerializeField] private WeaponDamage weapondamage;

1 Like

I would start by separating the logic of the ToggleRagdoll and the actual force application. You can remove all those extra SerializedFields, you don’t need them, and you don’t want to unnecessarily couple Ragdoll with those other classes.

        public void AddForce(Vector3 force)
        {
            if (!isRagdoll) return;
            foreach (var rigidbody in allRigidbodies)
            {
                rigidbody.AddForce(force);
            }
        }

You’ll need to maintain a global isRagdoll which would be set in ToggleRagDoll()

this.isRagdoll = isRagdoll;

Now in the WeaponDamage.OnTriggerEnter script, add this to the end:

            if (other.TryGetComponent(out Ragdoll ragDoll))
            {
                ragDoll.AddForce((other.ClosestPoint(transform.position)-transform.position).normalized * damage);
            }

If there is a Ragdoll on the enemy, it will try to add the force of the impact to the Ragdoll. The Ragdoll will only accept that force if the character is in Ragdoll… Because this line will be AFTER the call to damage the enemy, the Ragdoll code should have already triggered if the character is now dead.

3 Likes

@Brian_Trotter’s answer should help you out.

I just want to add the reason why the PlayerAttackingState is not showing up in the editor because this will happen again in the future for valid scenarios and you’d want to know how to fix it: Custom classes and structs need to be marked as Serializable for them to show up in the inspector, so in this case it would be something like

using System;
[Serializable]
public class PlayerAttackingState { /* etc. */ }
2 Likes

Thanks to both of you for your help. :partying_face:

I followed @Brian_Trotter 's help and got it to work after some stumbling a bit over my own mistakes. A good learning experience.
cap4

5 Likes

That’s some righteous knockback!

2 Likes

JAM!!! :laughing: :laughing: :laughing:

I like how she just looks away like nothing happened.

She’s like, “Wut?” :laughing: :laughing:

Gonna need a search and rescue team with a helicopter to find out where that guy landed. :rofl: :rofl: :rofl:

2 Likes

Nah, she’s posing to show that kill off on her insta.

2 Likes

@Brian_Trotter

:rofl: :rofl: :rofl: :rofl: :rofl:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms