- Home /
I'm trying to make a potion for my health system but I don't know how to access public properties from another code. When I though I had it, the game stop updating my Health.
My Health code using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;
public class HeartSystemNolimit : MonoBehaviour { public GameObject[] hearts; private int life; private int maxLife; private bool dead;
private void Start() { life = hearts.Length; maxLife = life; }
void Update()
{
if (dead == true)
{
// set gameover scene or reload level
SceneManager.LoadScene(SceneManager.GetActiveScene().name); //reload level code
}
}
public void TakeDamage(int d)
{
life -= d;
//Destroy (hearts[life].gameObject);
hearts[life].gameObject.SetActive(false);
if(life < 1)
{
dead = true;
}
}
public void AddLife()
{
if(life < maxLife)
{
hearts[life].gameObject.SetActive(true);
life += 1;
}
}
void OnTriggerEnter2D(Collider2D other)
{
Bullet bullet = other.GetComponent<Bullet>();
if (bullet != null)
{
TakeDamage(1);
}
// Destroy(gameObject);
}
}
My failed potion code using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events;
public class Health : MonoBehaviour { public UnityEvent interact; private void OnTriggerEnter2D(Collider2D other)
{
interact.Invoke();
Destroy(gameObject);
}
//Destroy(gameObject);
}
I can't see any glaring issues with your code. Just a few sanity checks: - Can you confirm that you have no compiler errors before you press play (errors that won't clear when you press clear in the console window) - You have definitely assigned your unity event in the inspector - the gameobject is your player object and the function name is AddLife - You only have 1 player object and 1 HeartSystemNolimit component on it
If all of these checks pass then the next debugging step would be to confirm that your OnTriggerEnter2D in your potion code is definitely firing - I'd advise you use breakpoints for this. 90% of debugging is saying to yourself "I expect the data to have this certain value at this time" then figuring out where that is wrong. When you stop your code execution via a breakpoint you can see what values all your variables are at that time which is far better than having a stream of logs saying "here 6" "asjndasd a=2" and "this thing happens"!
If the potion's OnTriggerEnter2D function is not firing when you expect then you need to have a look at whether your colliders are intersecting and whether at least 1 of the two objects has a rigidbody. If it is then step through the code expecting to see your invoke call take you to your HeartSystemNolimit component and then add a life.
If you're still stuck then let me know at which point this sequence stops working and we can go from there. :)
https://youtu.be/yLkfKtZpOrg this is the video that shows my problem.
The error on the video is
IndexOutOfRangeException: Index was outside the bounds of the array. HeartSystemNolimit.AddLife () (at Assets/Code/Player/HeartSystemNolimit.cs:43) UnityEngine.Events.InvokableCall.Invoke () (at :0) UnityEngine.Events.UnityEvent.Invoke () (at :0) Health.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Code/Enemy/Health.cs:13)
Since you're getting an IndexOutOfRangeException this means that your code is trying to access an element of an array outside its bounds.
For example if you define an array with 3 elements, you can access the first with myArray[0]
, the second with myArray[1]
and the third with myArray[2]
. If you try to call myArray[3]
then you'll get an IndexOutOfRangeException because the index 3 is outside the array's range. The same thing will happen if you call myArray[-1]
.
The exception is happening on line 43 which you should be able to see in your code editor although since the only place that you access an array within your AddLife function is the line hearts[life].gameObject.SetActive(true);
we can tell that this is the problem line. Since you're setting maxLife to be the length of your hearts array, I can't see why this is happening so the rest will have to be investigated at your end.
Do any other scripts alter your hearts array? Might be worth printing out the length of your hearts array and the value of 'life' just before you're trying to access it.
Debug.Log($"There are {hearts.Length} hearts in the array. We are accessing element {life}");
Answer by Sacaitha · Apr 27 at 09:08 PM
Check if "other" contains the component first; if(other.GetComponent()) { //code }
For the health system it has Bullet bullet = other.GetComponent();
if (bullet != null)
{
TakeDamage(1);
}
and the potion only have void OnTriggerEnter2D(Collider2D other)
I don't really understand your question.
Answer by Caeser_21 · Apr 28 at 12:30 PM
Why can you just call AddLife
in the collision event? Something like :
public void OnTriggerEnter2D(Collider2D other)
{
if (other.transform.tag == "Player")
{
HeartSystemNolimit Health = other.GetComponent<HeartSystemNolimit>();
Health.AddLife();
}
}
NOTE : Your player tag has to be "Player" for this to work...
Now I'm getting this error
Assets\Code\Enemy\Health.cs(9,5): error CS1520: Method must have a return type
This is the code now. public class Health : MonoBehaviour { OnTriggerEnter2D(Collider2D other) { if (other.tag == "Player") { other.GetComponent().AddLife(); } } }