Help with GetComponent (93700)

This is using the Unity Engine.
I have 3 scripts related to this problem. One is attached to a temporary game object that when the player collides with it, sends a message to the player Damage Controller. The player Damage Controller updates the health inside of the player’s Damage Controller script. Using Debug.Log, I can see that the player health updates as expected.

The third script is a component of a GUI Texture. From inside of the GUITexture script, I try to GetComponent of the Damage Controller.health. But running a Debug inside of the GUITexture script, for some reason the GetComponent.health is not updating as expected and is why my health status GUI Texture is not changing inside the game scene. Any help will be great.

using UnityEngine;
using System.Collections;
public class Trap: MonoBehaviour 
{
	//Trap intrinsic properties
	public int damage = 1;

	void OnTriggerEnter(Collider other) 
	{
		if(other.tag == "Player" || other.tag == "Enemy")
		{	
			//Debug.Log("Collision with Player Object!");
			other.collider.SendMessage("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
			//this.SendMessage("SetGUITexture");
			Destroy(gameObject);
		}
	}
} 

using UnityEngine;
using System.Collections;
public class DamageController : MonoBehaviour 
{
	public int         health = 4;

	public void ApplyDamage(int damage)
	{
		health -= damage;
		Debug.Log("Updated Health is: "+health);

		if(health == 0)
		{
			Destroy(gameObject);
		}
	}
}

using UnityEngine;
using System.Collections;
public class HealthGUI : DamageController
//public class HealthGUI : MonoBehaviour 
{

	public int healthGUI = 4;
	public DamageController damageController;
	private GameObject playerGameObject;

	// Use this for initialization
	void Start () 
	{
		playerGameObject = GameObject.FindGameObjectWithTag("Player");
	}
	
	// Update is called once per frame
	void Update () 
	{
		DamageController damageController = playerGameObject.GetComponent<DamageController>();
		healthGUI = damageController.health;
		Debug.Log("Health is  : "+healthGUI);
	}
}

Firstly I don't see a reason for that many / and you saying when a script ends... I think that's pretty clear just from the formatting... Secondly, do you get any errors? If so you should post them.

No, no errors. Runs fine in game mode. But as I mentioned in the top of the question, the Debug.Log for the healthGUI = damageController.health only returns the initialized value of 4 without reflecting changes to changes in health when damage is applied. But I know for a fact that the health variable in DamageController IS being updated when the trap object sends the message to "ApplyDamage" function inside of DamageController.

Definitely worth removing all the Start() and Update()s that are blank just cluttering. In the last script you already declared public DamageController damageController so you should remove type "DamageController" from the call in Update(). You could also combine the damageController call to damageConroller = GameObject.FindGameObjectWithTag("Player").GetComponent<DamageController>(); Finally, that shouldn't be in Update() move it to Start(). Not sure this will solve the issues, but a little clean-up shouldn't hurt.

Please remove those empty update and start calls in the code you've posted here to make it easier to read.

No problem Shrandis. I've taken out unused Start and Update calls. Thank you.

1 Answer

1

Ok, figured it out. The root of the problem stems from your double use of the tag “Player”. Throughout your code, you are thinking of the parent, “PFB_PlayerCar”, and the child/collider, “PlayerMesh”, as the same thing, and mixing them up. You need to have only one object tagged “Player”.

The specific bug here is because both “PFB_PlayerCar” and “PlayerMesh” have a “DamageController” component. In your OnTriggerEnter, you are calling SendMessage on the collider object, “PlayerMesh”, and modifying that health. So, remove “DamageController” from “PlayerMesh”, and then change trigger line to be:

other.collider.transform.parent.SendMessage("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);

Good luck :slight_smile:

Sorry, that return line in ApplyDamage function is not necessary. I was wanting to try something when debugging so I made that function public int ApplyDamage() but I've rewritten so that it is a public void that does not return anything, as originally written.

Are you sure there isn't more than one object with the tag "Player"? Maybe you are finding the wrong one because you've mistagged something. Try using GameObject.Find("Player") instead. Also, trying debugging, putting a breakpoint on line 80, and look at damageController in the inspector, you can make sure you have the right object that way.

Hi Jinxology I went back and did a Debug.Log(" "+damageController) at line 80 of HealthGUI.cs and returns "PrefabPlayer(DamageController)" which tells me that it's identifying the DamageController script of the player object in the hierarchy. So far seems right. But when accessing damageController.health, still giving the initialized value of 4 every frame even after damage. I double checked all objects in the scene and player is the only one tagged "Player."

I think you're going to have a much better chance debugging this using the debugger instead of Debug.Log commands. Other than that, I wish I could help, but it's so hard to debug this just by looking at the code. Sorry =/

That's ok, thanks for checking anyway.