0
votes

The playerLife variable doesn't update visibly in the Inspector or the on-screen Health Text, but the Player still dies because the playerLife drops below zero.

I've determined that the Player prefab attached to the Zombie GameObject is solely the Player prefab rather than the in-scene active Player. How do I make it so that the zombies always reference the in-scene active Player rather than the basic Player prefab, by script? (Also, it won't allow me to manually drag the active Player into the Zombie)

Call hierarchy for playerLife

public class Player : MonoBehaviour
{
    public RaycastHit hit;
    public int gunDamage = 1;
    public Zombie zombie;

    private float hitForce = 100f;
    public float playerLife;
    private Vector3 flareLower = new Vector3(0, -0.5f, 0);

    void Start()
    {
        spawnPoints = playerSpawnPoint.GetComponentsInChildren<Transform>();
        playerLife = 200;
    }

    void Update() //T-toggle
    {
        if (Input.GetButton("Fire1"))
        {
            LazerBeam();
        }

        if (reSpawn != lastToggle)
        {
            ReSpawn();
            reSpawn = false;
        }
        else
            lastToggle = reSpawn;
    }



    public void Life (float damage)
    {
        playerLife -= damage;
        if (playerLife <=0)
        {
            playerLife = 100;
            SceneManager.LoadScene(2);
        }
    }

}

public class Zombie : MonoBehaviour
{
    public int currentHealth;
    public Player player;
    public PlayerLifeCollider playerCollider; 
    private int damage;

    public void Damage(int damageAmount)
    {
        currentHealth -= damageAmount;
        if (currentHealth <= 0)
        {
            PlayerLifeCollider.instance.ObjectsInRange.Remove(gameObject);
            DestroyZombie();
        }
    }

    public void DestroyZombie()
    {
        Destroy(gameObject);
        // gameObject.SetActive(false);
    }

    public void DamagePlayer(float damage)
    {
         player.Life(damage);
    }
}
2
How is it possible that the player dies before playerlife ever changes? If it doesn't change, it can't possibly reach zero, so the player should be invincible.M Palmer
What exactly do you mean by "doesn't update"? Do you mean the lifePlayer value never changes in the Inspector until the player dies?Isuka
If I had to guess you weren't setting the player variable inside of Zombie?Bailey Miller
It doesn't update the public variable in the Inspector but it seems to update in the background.MrHero
Ok, i figured out the problem but not sure how to fix it. I attached the Player Prefab rather then the Player GameObject and it's reducing the health of the prefab rather then the in-game Player GameObject. How do I make it so that the zombies always reference to the in-game Player GameObject?MrHero

2 Answers

0
votes
public void Damage(int damageAmount)
{
    currentHealth -= damageAmount;

    print(currentHealth);// will show in terminal if thats what you are asking


    if (currentHealth <= 0)
    {
        PlayerLifeCollider.instance.ObjectsInRange.Remove(gameObject);
        DestroyZombie();
    }
}
0
votes

As you said, the problem is that you are not referencing the Player object on your scene, but a prefab one. To avoid that, you can add a Start function to the Zombie script and ask to look for what should be the only Player instance in the scene. For this, you can use the FindObjectOfType function:

void Start()
{
    player = FindObjectOfType<Player>();
}

Considering you will only have one Player script in your entire scene, what you can also do is to save in your Player class a static reference to your Player instance.

public class Player : MonoBehaviour
{
    private static Player _instance;

    public static Player Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<Player>();
            }
           return _instance;
        }
    }

    // Reset of your class

}

You can then get this reference in your Zombie script:

public class Zombie : MonoBehaviour
{
    static Player player;

    void Start()
    {
        if(player == null)
        {
            player = Player.Instance;
        }
    }

    // Rest of your class content
}

This way, you will only have one call to the FindObjectOfType function instead of once per object using the Zombie script.