Why does this not work?

The player in my game has 2000 health, I have a red vignette that appears when your health is low but I cannot get it to work.
I want it to be reliable so I’m trying to make it the vignette intensity scale up when the health goes down.

    private void OnTriggerEnter(Collider other)
    {
        if ( other.GetComponent<Damage>() )
        {
            health -= other.GetComponent<Damage>().damage;

            Debug.Log(65 / health); // Returns 0
            vg.intensity.value = 1 / health * vignetteMultiplier;
            Debug.Log(vg.intensity.value); // Also returns 0
        }
    }
    }

And I know I do change the vignette intensity because if I set it to be 1 in the script it does change.
(Full script, in case anyone wants it)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using DG.Tweening;
using UnityEngine.SceneManagement;

public class Player : MonoBehaviour
{
    public int health = 2000;
    public MeshRenderer whiteScreen;
    public Volume v;
    public float vignetteMultiplier = 65f;

    private Vignette vg;

    private void Start()
    {
        v.profile.TryGet(out vg);

        whiteScreen.material.DOFade(0, 3);
    }

    private void Update()
    {
        if ( Inputs.aButtonPressed )
        {
            Time.timeScale = 0.05f;
            Time.fixedDeltaTime = 0.002f;

            foreach ( AudioSource audio in FindObjectsOfType<AudioSource>() )
            {
                audio.pitch = 0.5f;
            }
        }

        else
        {
            Time.timeScale = 1f;
            Time.fixedDeltaTime = 0.02f;

            foreach ( AudioSource audio in FindObjectsOfType<AudioSource>() )
            {
                audio.pitch = 1;
            }
        }

        if ( health < 1 )
        {
            StartCoroutine(LoadMainMenu());
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if ( other.GetComponent<Damage>() )
        {
            health -= other.GetComponent<Damage>().damage;

            Debug.Log(65 / health); // Returns 0
            vg.intensity.value = 1 / health * vignetteMultiplier;
            Debug.Log(vg.intensity.value); // Also returns 0
        }
    }

    IEnumerator LoadMainMenu()
    {
        whiteScreen.material.DOFade(255, 5);

        yield return new WaitForSeconds(6);

        SceneManager.LoadScene("Main Menu");
    }
}

Cast your health to a float. vg.intensity.value = 1 / (float)health * vignetteMultiplier;

Currently you’re getting an int as the value from dividing and int by and int, which lops off the remainder.

2 Likes

Instead of casting health to a float, you can simply use 1f / health * vignetteMultiplier; or simplified vignetteMultiplier / health; since vignetteMultiplier is a float as well. You only need one of the two operands to be a float in order to get a floating point division / multiplication. Multiplication and division have the same precedence and are therefore carried out from left to right.

So your original code reads like this:

vg.intensity.value = (1 / health) * vignetteMultiplier;

So it means you’ll get an integer division (which would be 0 for any health value greater than 1, 65 if health is 1 and a divide by zero exception in case health is 0). If the first operand is a float you get an actual floating point division and most of the problems would be gone. Though you get positive infinity if health would be 0.

1 Like