- Home /
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.
Answer by Pokedlg3 · Jan 16, 2021 at 01:55 AM
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.
Hello, where exactly would I put that, and on which script? I have put it in the Itemeffect script java and it gave me errors.
in the PlayerHealth Script:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Scene$$anonymous$$anagement;
public class PlayerHealth : $$anonymous$$onoBehaviour
{
[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 = $$anonymous$$athf.Clamp(maxHealth, 1, 100);
if (curHealth > maxHealth)
{
curHealth = 100;
}
if (curHealth >= 51)
DeathUI.gameObject.SetActive (false);
else
DeathUI.gameObject.SetActive (true);
if (curHealth <= 0)
Scene$$anonymous$$anager.LoadScene (sceneNameToLoad);
}
THANK YOU VERY $$anonymous$$UCH!!!! Sorry for yelling, I had been struggling with that for so long. Also the answer for the instantiate health, I just had to create a function that had the "clone" name space added to it and with your help everything works great now.
Answer by BennyXUNITY · Jan 16, 2021 at 04:19 AM
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
}
Your answer
Follow this Question
Related Questions
Do not pick item when item full 2 Answers
Instantiate a prefab and follow player position in runtime? 0 Answers
How to add an inventory to the Player 2 Answers
Needs help to instantiate camera as child of player 0 Answers
Player prefab instantiation 1 Answer