How to keep health from going over 100% when heath pickup is used and why does the item effect stop working after I instantiate it from the vendor.

link:here is a video of what is happening

Hello, the problem I am having is that when I use a health pick it makes the health go over 100%, I would like for 100% to be the max health. Also when I buy the same health pick up from the vendor and after I put into my inventory the item is having no effect on my health.

I am using 4 scripts: PlayerHealth script, Vendor script are both in C-sharp then the Inventory script and the Itemeffect script are both Java (yeah I know).

here are the four scripts:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class PlayerHealth : MonoBehaviour
{
//[SerializeField]
public Slider healthBar;
[SerializeField]
Text healthText;
[SerializeField]
GameObject DeathUI;

[SerializeField]
private string sceneNameToLoad;

public float maxHealth = 100;
public float curHealth;

void Start()
{
	healthBar.value = maxHealth;
	curHealth = healthBar.value;

}

void  OnTriggerStay ( Collider other  )
{
	if (other .gameObject.tag == "Damage")
	{
		healthBar.value -= 1f;
		curHealth = healthBar.value;

	}

	if (other .gameObject.tag == "Heal")
	{
		healthBar.value += 1f;
		curHealth = healthBar.value;

	}

	//if (other .gameObject.tag == "HPickUp")
	//{
		//healthBar.value += 25f;
		//curHealth = healthBar.value;
	//}

}

void Update()
{
	healthText.text = curHealth.ToString () + " %";
	maxHealth = Mathf.Clamp(maxHealth, 1, 100);

	if (curHealth >= 51)
		DeathUI.gameObject.SetActive (false);
	else
		DeathUI.gameObject.SetActive (true);

	if (curHealth <= 0)
		SceneManager.LoadScene (sceneNameToLoad);

}

}

Here is the Vendor script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Vendor : MonoBehaviour {

Currency script;
//Inventory invScript;

public GameObject vendorUI;
public GameObject objToCreate;
public Transform posToCreate;

public int cost;

void Start()
{
	vendorUI.SetActive(false);
	script = GameObject.FindWithTag("GameController").GetComponent<Currency>();
	//invScript = GameObject.FindWithTag("GameController").GetComponent<Inventory>();
}
void OnTriggerEnter()
{
	vendorUI.SetActive(true);
	Cursor.visible = true;
}

// Update is called once per frame
void OnTriggerExit ()
{
	vendorUI.SetActive(false);
	Cursor.visible = false;
}
public void BuyItem()
{
	if (script.gold >= cost)
	{
		script.gold -= cost;

		Instantiate (objToCreate, posToCreate.position, posToCreate.rotation);
		//i.transform.SetParent(invScript.invTab.transform);
	}
}

}

Here is the Inventory script:
//This is the central piece of the Inventory System.

var Contents : Transform; //The content of the Inventory
var MaxContent : int = 12; //The maximum number of items the Player can carry.

var DebugMode = false; //If this is turned on the Inventory script will output the base of what it’s doing to the Console window.

private var playersInvDisplay : InventoryDisplay; //Keep track of the InventoryDisplay script.

static var itemHolderObject : Transform; //The object the unactive items are going to be parented to. In most cases this is going to be the Inventory object itself.

@script AddComponentMenu (“Inventory/Inventory”)

//Handle components and assign the itemHolderObject.
function Awake ()
{
itemHolderObject = gameObject.transform;

playersInvDisplay = GetComponent(InventoryDisplay);
if (playersInvDisplay == null)
{
	Debug.LogError("No Inventory Display script was found on " + transform.name + " but an Inventory script was.");
	Debug.LogError("Unless a Inventory Display script is added the Inventory won't show. Add it to the same gameobject as the Inventory for maximum performance");
}

}

//Add an item to the inventory.
function AddItem(Item:Transform)
{
var newContents = new Array(Contents);
newContents.Add(Item);
Contents=newContents.ToBuiltin(Transform); //Array to unity builtin array

if (DebugMode)
{
	Debug.Log(Item.name+" has been added to inventroy");
}

//Tell the InventoryDisplay to update the list.
if (playersInvDisplay != null)
{
	playersInvDisplay.UpdateInventoryList();
}

}

//Removed an item from the inventory (IT DOESN’T DROP IT).
function RemoveItem(Item:Transform)
{
var newContents=new Array(Contents);
var index=0;
var shouldend=false;
for(var i:Transform in newContents) //Loop through the Items in the Inventory:
{
if(i == Item) //When a match is found, remove the Item.
{
newContents.RemoveAt(index);
shouldend=true;
//No need to continue running through the loop since we found our item.
}
index++;

	if(shouldend) //Exit the loop
	{
		Contents=newContents.ToBuiltin(Transform);
		if (DebugMode)
		{
			Debug.Log(Item.name+" has been removed from inventroy");
		}
		if (playersInvDisplay != null)
		{
			playersInvDisplay.UpdateInventoryList();
		}
		return;
	}
}

}

//Dropping an Item from the Inventory
function DropItem(item)
{
gameObject.SendMessage (“PlayDropItemSound”, SendMessageOptions.DontRequireReceiver); //Play sound

var makeDuplicate = false;
if (item.stack == 1) //Drop item
{
	RemoveItem(item.transform);
}
else //Drop from stack
{
	item.stack -= 1;
	makeDuplicate = true;
}

item.DropMeFromThePlayer(makeDuplicate); //Calling the drop function + telling it if the object is stacked or not.

if (DebugMode)
{
	Debug.Log(item.name + " has been dropped");
}

}

//This will tell you everything that is in the inventory.
function DebugInfo()
{
Debug.Log(“Inventory Debug - Contents”);
items=0;
for(var i:Transform in Contents){
items++;
Debug.Log(i.name);
}
Debug.Log(“Inventory contains “+items+” Item(s)”);
}

//Drawing an ‘S’ in the scene view on top of the object the Inventory is attached to stay organized.
function OnDrawGizmos ()
{
Gizmos.DrawIcon (Vector3(transform.position.x, transform.position.y + 2.3, transform.position.z), “InventoryGizmo.png”, true);
}
Here is the ItemEffect script:
#pragma strict

//This script allows you to insert code when the Item is used (clicked on in the inventory).

var deleteOnUse = true;

private var playersInv : Inventory;
private var item : Item;
public var playerHealth : PlayerHealth; //c# script

@script AddComponentMenu (“Inventory/Items/Item Effect”)
@script RequireComponent(Item)

//This is where we find the components we need
function Awake ()
{
playersInv = FindObjectOfType(Inventory); //finding the players inv.
if (playersInv == null)
{
Debug.LogWarning(“No ‘Inventory’ found in game. The Item " + transform.name + " has been disabled for pickup (canGet = false).”);
}
item = GetComponent(Item);
}

//This is called when the object should be used.
function UseEffect ()
{

if(item.name == "HPickUp")     playerHealth.curHealth += 50f;
if(item.name == "HPickUp")     playerHealth.healthBar.value += 50f;




//Play a sound
playersInv.gameObject.SendMessage("PlayDropItemSound", SendMessageOptions.DontRequireReceiver);

//This will delete the item on use or remove 1 from the stack (if stackable).
if (deleteOnUse == true)
{
	DeleteUsedItem();
}

}

//This will delete the item on use or remove 1 from the stack (if stackable).
if (deleteOnUse == true)
{
DeleteUsedItem();
}

//This takes care of deletion
function DeleteUsedItem()
{
if (item.stack == 1) //Remove item
{
playersInv.RemoveItem(this.gameObject.transform);
}
else //Remove from stack
{
item.stack -= 1;
}
Debug.Log(item.name + " has been deleted on use");
}
There you are if anyone can help me make sense of this it would be greatly appreciated.

Have you tried to do so?

if (curHealth > maxHealth)
{
curHealth = 100;
}

And the problem with the prefabricated, the script that adds 50 in life is attached to the prefab, or to the GameObject in Scene?

Because if it is only on the object in the scene, it will only work for that object, and when you instantiate a prefab it does not come with the script.

I believe that to solve this problem, you have to transform the object that has the script into a new prefab and replace it with the original.

Hey, first off, may I suggest you implemt an addhealth function to your playerhealth script?

Because it would allow you to:

  • add and subtract from player health via other classes.
  • clamp the health, without doing it every frame in update, which is really unnecessary, since you’re not going ot change player health every frame, only the moment he gets the damage or the heal

something like this. by inserting a negative value you can “do damage” without having to check whether the Pickup is a heal or does damage.

public class PlayerHealth{
    [SerializeField] int maxhealth;
    private int health;
    
    public int get_health() {return health}
    public void add_to_health(int mod){
       health += mod;
       Mathf.Clamp(currenthealth, 0, maxhealth);
    }
    
}
public class HealthPickup { //this is in another unity c# script, which you put on the health object or trap itself
    ontriggerenter (Collider other) {
    var ph = other.GetComponent<PlayerHealth>(); 
    if (ph != null){ //check if playerscript is actually there
         ph.add_to_health(25); //if you wanna do damage type -25 for example
    }