Adding to maximum health with consumable items

sneekyo

Member
How would I go about doing this? It could be a pick up item just like the health pack, only it adds like 5-10 to your maximum health attribute.
I have a very basic programming knowledge so any help is really appreciated.

Thank you Andrew and Justin for making my dreams come true with this awesome program and support!

-Seth
 

Andrew

Moderator
Staff member
You can just access the attribute's MaxValue directly:
C#:
var health = m_AttributeManager.GetAttribute("Health");
health.MaxValue += 10;

You could just subclass ObjectPickup and use this code in ObjectPickedUp. Something like:
C#:
protected override void ObjectPickedUp(GameObject pickedUpBy) {
    base.ObjectPickedUp(pickedUpBy);

    var attributeManager = pickedUpBy.GetComponent<AttributeManager>();
    var health = attributeManager.GetAttribute("Health");
    health.MaxValue += 10;
}
 

sneekyo

Member
Thank you for your reply Andrew,
I've tried to figure out where and how I would implement that code. Do I add it into the "ObjectPickup.cs" script? Do I need to make a separate script. I'm really sorry these questions must sound silly, but I really have no idea what I'm doing with programming. Some more information on the process would be extremely helpful. I want it to be trigger activated, like with the health pack.
 

Andrew

Moderator
Staff member
No problem - what I'm suggesting is creating a new "subclass" of ObjectPickup, i.e. a new component that inherits from ObjectPickup. So instead of inheriting from MonoBehaviour, as all new script components do, it would look something like public class MaxHealthPickup : ObjectPickup. This means your new component will be an ObjectPickup that you can further modify/add to by "overriding" different methods from the base class. E.g. if you look at ItemPickupBase.cs, you'll see that the ItemPickupBase class is a subclass of (aka inheriting from) ObjectPickup, meaning ItemPickups are just ObjectPickups with a couple of added things (mainly adding items to the character's inventory).

I would read up a bit on C# subclassing/inheritance and overriding methods, or just take a look at a couple of UCC scripts that are simple examples of this, like ItemPickupBase and Flashlight.
 

sneekyo

Member
Awesome thank you for your wisdom Andrew! I just read up on those subjects, I understand better what you are saying now. Still actually writing the code is difficult for me, I'll give it a shot tonight and study ItemPickupBase and Flashlight. I'll let you know how it goes.
 

sneekyo

Member
So Andrew, I haven't worked on the script yet. But my next question is, once I made this subclass script, and say I have a cube that represents my item that gives +10 max HP. I drop this script onto the cube, what else do I need to make it either a "f to interact" or a trigger area to pick up item?
 

sneekyo

Member
Hi Andrew,
This is what I have so far:

namespace Opsive.UltimateCharacterController.Objects.CharacterAssist
{
using Opsive.Shared.Game;
using Opsive.UltimateCharacterController.Traits;
using UnityEngine;

public class MaxHealthPickup : ObjectPickup
{


protected override void ObjectPickedUp(GameObject pickedUpBy)
{
base.ObjectPickedUp(pickedUpBy);

var attributeManager = pickedUpBy.GetComponent<AttributeManager>();
var health = attributeManager.GetAttribute("Health");
health.MaxValue += 10;
}



}




}

I am getting the error:

Assets/seths practice/MaxHealthPickup.cs(7,18): error CS0534: 'MaxHealthPickup' does not implement inherited abstract member 'ObjectPickup.TriggerEnter(GameObject)'


I take it from this I need to reference this trigger enter somehow, but I'm not sure how.
Thank you for your time,

-Seth
 

sneekyo

Member
Here is what I came up with, it doesn't have any errors, but it doesn't do anything when I run over it,
 

Attachments

  • MaxHealthPickup.cs
    892 bytes · Views: 2

Andrew

Moderator
Staff member
You'll need to call ObjectPickedUp from TriggerEnter, so that when the player enters the trigger, the pickup occurs. I.e.:
C#:
public override void TriggerEnter(GameObject other) {
    ObjectPickedUp(other);
}
 

sneekyo

Member
Hi Andrew currently I have this now:
-----------------------------

namespace Opsive.UltimateCharacterController.Objects.CharacterAssist
{
using Opsive.Shared.Game;
using Opsive.UltimateCharacterController.Traits;
using UnityEngine;

public class MaxHealthPickup : ObjectPickup
{





protected override void ObjectPickedUp(GameObject pickedUpBy)
{
base.ObjectPickedUp(pickedUpBy);

var attributeManager = pickedUpBy.GetComponent<AttributeManager>();
var health = attributeManager.GetAttribute("Health");
health.MaxValue += 10;
}


public override void TriggerEnter(GameObject other)
{
ObjectPickedUp(other);
}


}




}


-----------------------------

The object now gets picked up, but it doesn't apply the +10 health and I get an error when I pick it up:

NullReferenceException: Object reference not set to an instance of an object
Opsive.UltimateCharacterController.Objects.CharacterAssist.MaxHealthPickup.ObjectPickedUp (UnityEngine.GameObject pickedUpBy) (at Assets/seths practice/MaxHealthPickup.cs:19)
Opsive.UltimateCharacterController.Objects.CharacterAssist.MaxHealthPickup.TriggerEnter (UnityEngine.GameObject other) (at Assets/seths practice/MaxHealthPickup.cs:26)
Opsive.UltimateCharacterController.Objects.CharacterAssist.ObjectPickup.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Opsive/UltimateCharacterController/Scripts/Objects/CharacterAssist/ObjectPickup.cs:165)


What am I doing wrong?

Andrew thank you for your patience with me, I'm sure it's frustrating dealing with someone of my low level of programming skill. It's nearly no level of programing skill actually.

-Seth
 

Andrew

Moderator
Staff member
So TriggerEnter is called when another Collider object collides with the pickup object, i.e. other will reference the Collider object. A UCC character doesn't have its main CapsuleCollider on the root object, but in a child object (Nolan/Colliders/Capsule Collider), so other will refer to this child object, which doesn't have the AttributeManager component on it, hence the null reference.

You can use GetComponentInParent to find the first instance of a particular component anywhere in an object's parent hierarchy, i.e. GetComponentInParent<AttributeManager>(). I'll let you figure out where to implement that ;)
 

sneekyo

Member
Andrew you are an absolute legend. Thank you so much for all your help over the past month. I am so satisfied with the level of customer service.
 
Top