Player Not Dying When Health <= Zero

Hello! I've set up a state on the player's Attribute Manager where the Auto Update Value Type is set to "Decreasing" and I set this state when the player collides with a certain object. All of this is working, however the player does not die when its health is less than or equal to zero. I've reviewed the documentation at the link below, and while I could write a new component that listens for the OnDeath event, I am not sure this is the best approach. Is there a simpler way to accomplish this?

Thanks!
 
Did you add the Ragdoll or Die ability? These abilities listen for the OnDeath event and will play the according animation.
 
So health is 0 and player ragdolls? Sounds like death to me. From there I think you just need to use the state/events system to figure out what to do with the body. Or am I missing something?
 
@jandd661 Apologies for the confusion - I'll clarify:
When the player collides with an object, a state is set in the Attribute Manager which causes the "Auto Update Value Type" to become enabled with a value of "Decreasing." At runtime, when the player collides with this object the state is correctly set and I can see the player's health drop all the way down to 0 over a short period of time - this works as expected. However, the player does not die when health reaches zero - I can still move around as usual. (Not sure if it's significant for this troubleshooting, but I'm also not seeing the red damage indicator on Canvas when health drops due to the Auto Update Value Type.)

Hopefully that helps clarify!
 
The "Health Attribute" is not directly responsible for triggering any events. Think of an attribute as a variable. The Player Health script is responsible for killing the player when the health attribute reaches 0. However, the player health script only checks the attribute value when it is called into service to damage, heal or immediately kill the player. It does not monitor the value. So the functionality of the Attribute Manager to periodically increase or decrease an attributes value is just a utility. You will still need the object that damages the player to do it by calling the PlayerHealth script. Once enough damage has been applied
Code:
(PlayerHealth.Damage(float amount))
, the PlayerHealth script will kill the player and send out the appropriate events.

Damage Processor:
https://opsive.com/support/documentation/ultimate-character-controller/objects/damage-processor/

Simple example, bellow attached to a trigger collider and the UCC scripts on a player in the root of the hierarchy.

C#:
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Traits;
using UnityEngine;

public class DamagePlayer : MonoBehaviour
{
    private UltimateCharacterLocomotion _ucl = null;
    private Health _playerHealth = null;
    private void OnTriggerStay(Collider other)
    {
        _ucl = other.transform.root.gameObject.GetComponent<UltimateCharacterLocomotion>();
        if(_ucl != null)
        {
            _playerHealth = _ucl.GetComponent<Health>();
            if(_playerHealth != null)
            {
                _playerHealth.Damage(0.1f);
            }

            if(_playerHealth.HealthValue <= 0f)
            {
                _playerHealth.ImmediateDeath();
            }
        }
    }
}

Currently, I have a script running on update (just for testing) checking player health and killing the player when health is 0. It's called GrimReaper.cs lol.
 
Last edited:
@jandd661 @Justin In theory I understand what you're saying, but I am failing to see why I would need to add additional calls to the Damage method. The player's health is being damaged...he just does not die. Please see gif below. The health bar runs out and I can still control the player.

gif1.gif
 
The attribute manager does not trigger anything if an attribute is reaching 0. It just manages the attributes and their values. You need another component that checks the value, and triggers some action. The CharacterHealth component checks the health value only upon damage, not because it is decreased automatically. This is why your character dies if hit by an enemy (because it causes damage), but he does not die if you reduce health using the attribute manager. In the latter case the health is not "damaged", and the CharacterHealth component does not care.
 
So, what is the use case behind the "Auto Update Value Type" for the health field? It sounds like reducing health via the attribute manager is pointless for my use case (getting poisoned) because I need to apply actual damage via another (new) component. Meaning, I should just write a new component that doles out damage at a specified internal, rather than setting a state for health in the attribute manager?

In general, seems like it would be helpful to have a toggle that allows the Auto Update Value Type decreasing health be counted as damage.
 
The attribute manager has no semantics, so it does not know that an attribute "Health" has anything to do with the character health. The semantics is set by the CharacterHealth component by evaluating the "Health" attribute. But you could also call the attribute "life points" or whatever you like. This pattern is called separation of concern, and allows to use the attribute manager for any type of attribute, not only health. So you always need a component/ability that evaluates the attribute value and triggers some reaction.
To cover your use case, you can inherit from the CharacterHealth class, and add the zero-check in Update, and not only upon damage.
 
The attribute manager can be used for many things like Heath/stamina (as in your case), ability cooldowns, shield recharge to log out timers. It's a handy, and central, place to store those values that has the boiler plate code with some useful utilities like Auto Increment already completed.

It's up to the developer to implement the functionality of those attributes. The Player Health script is an example of an implementation of managing an attribute called health.
 
Last edited:
Top