using UnityEngine;
using System.Collections;
public class PlayerStats : MonoBehaviour {
public float health = 100;
public float Health
{
get {
return health;
}
set {
health = value;
}
}
void Update()
{
Debug.Log (health + ", " + Health);
}
}
and this script attached to the enemy
using System.Collections;
public class DamagePlayer : MonoBehaviour {
private PlayerStats Player = new PlayerStats();
private bool playerDetected = false;
public float EnemyAttackTime;
public float Damage;
void Start()
{
InvokeRepeating ("DealDamageToPlayer", EnemyAttackTime, EnemyAttackTime);
}
void OnTriggerEnter(Collider collidingObject)
{
if (collidingObject.gameObject.tag == "Player") {
playerDetected = true;
}
}
void OnTriggerExit(Collider collidingObject)
{
if (collidingObject.gameObject.tag == "Player") {
playerDetected = false;
}
}
void DealDamageToPlayer()
{
if (playerDetected) {
Player.health -= Damage;
Debug.Log ("Health decreased: " + Player.health);
}
}
}
When the 2nd script prints to the console it says the value of “health” is changing, but when it prints from the 1st script the value doesn’t change, it’s stuck at 100.
Isn’t the 1st script also suppose to print the new value?
You’re creating two different instances of the PlayerStats class. One is implicitly created by attaching it to the Player GameObject in your scene, and the other you’re creating explicitly using “new PlayerStats()” in DamagePlayer.
By definition, these are two distinct objects with their own set of private variables. So changing Health in one has no bearing on the other.
Two different instances of the same class do not share data by default. Think of it like buying a dozen oranges and peeling just one. You wouldn’t expect the remaining eleven to spontaneously peel themselves in response. (Although I think that was the premise of the Attack of the Killer Tomatoes.)
looks like your on the right track now, by using GetComponent<> to get the player stats, but as a rule of thumb you should never create anything that inherits from MonoBehaviour using “new” and must either get it with GetComponent or create it with AddComponent
Getters and Setters never display in the Inspector, if you want it in the inspector you have to use either the [SerializeField] attribute, or define the field as public.
public float health = 100;
public float Health
{
get {
return health;
}
set {
health = value;
}
}
Is exactly the same as just writing:
public float Health = 100;
Unless you are implementing custom access instructions for your values you shouldn’t use properties. C# properties are compiled into methods which adds extra overhead for the method call.
Example:
public float get_Health()
{
return health;
}
public float set_Health(float value)
{
health = value;
}