- Home /
Why does this alway return 0
Why does AddedValue always return 0, what on earth am i doing wrong?
Score.scoreValue can be 1, 2, 3 ect... and I want to add that number / 10 (to get a decimal) onto the intensity of a vignette.
Any Ideas???
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;
public class VignetteScriptLight : MonoBehaviour
{
public PostProcessVolume Volume;
public float AddedValue = Score.scoreValue / 10f;
private Vignette _Vignette;
// Start is called before the first frame update
void Start()
{
Volume.profile.TryGetSettings(out _Vignette);
_Vignette.intensity.value = 0.45f + AddedValue;
Debug.Log(AddedValue);
}
// Update is called once per frame
void Update()
{
}
}
This is where Score.scoreValue comes from.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public static int scoreValue;
public static int playerHealth;
Text score;
private void Start()
{
score = GetComponent<Text>();
}
private void Update()
{
score.text = "You Got to Floor" + " " + scoreValue;
}
}
Can some one please help???
(think you might've reversed top and bottom there :-) )
I don't understand what you are expecting. Start
is called once, when the scene loads. If the static integer scoreValue
wasn't greater than 0 when the scene where VignetteScriptLight
is located, Score.scoreValue / 10
(called in the constructor of the VignetteScriptLight
, called when the scene is loaded, even before Awake
) will return 0.
Terribly sorry missed a bit of code and info.
IEnumerator Win()
{
Fade.GetComponent<Fade>().Load();
yield return new WaitForSeconds(1);
Score.scoreValue += 1;
Speed = 4;
Scene$$anonymous$$anager.LoadScene(Scene$$anonymous$$anager.GetActiveScene().name);
Destroy(this.gameObject);
}
When the play gets past level it added one to the score, the effect only starts once they have reached level 2, but even when they do it still return 0.
The assignment is hardcoded and doesn't update. It will only ever equal what scoreValue / 10 is at compile time. You either need to use a setter or update it in a method.
When I go to level 2 the script does recognise that it has changed as I used it to try help debug, I also use it to display the score
scoreValue
is an int so Score.scoreValue / 10f
would give you 0 until scoreValue
is 11 or above.
Answer by Bunny83 · Oct 07, 2019 at 11:13 PM
Well you don't do anything wrong but it seems you have the wrong idea about how C# works ^^. C# is an imperative programming language and not a functional programming language.
A field initializer is essentially an expression that is executed once when the class is initialized (that's why they are called field initializers).
This line:
public float AddedValue = Score.scoreValue / 10f;
can be broken up into two parts. The variable declaration
public float AddedValue
and the field initializer:
= Score.scoreValue / 10f;
The variable declaration actually tells the compiler that your class should have a variable named AddedValue and to be of type float. A variable is just a place in memory where this value is stored. A variable never does something on it's own. It's just memory. The field initializer on the other hand is an expression (executable code) which runs once even before the constructor of the class runs. So the expression just provides an initial default value for that variable. This line does not create a "function".
In essence what you did is similar to this:
public class VignetteScriptLight : MonoBehaviour
{
public float AddedValue;
public VignetteScriptLight()
{
AddedValue = Score.scoreValue / 10f;
}
// [ ... ]
So your field initializer runs just once at the start and the resulting value is stored in the variable. When your scoreValue changes it has no effect on the AddedValue variable.
Note that C# has many different concepts which are meant to simplify / shorten the code to make our lives easier. In C# we can create properties. A property can be used similar to a variable but it's actually a pair of methods: a get and/or a set method. Properties on their own do not have any memory. Instead when you read a property you actually execute the get method and get back whatever the get method returns. The get method is executed every time you read a property. Likewise when you assign a value to a property its set method will be called and the value that you assigned will be passed as the special implicit parameter "value". A property does not need to define both methods, but at least one of them. Of course a property without a set method can not be assigned,only read.
So you could declare your "AddedValue" as a read only property like that:
public float AddedValue
{
get {
return Score.scoreValue / 10f;
}
}
In C# 6 there's now an even shorter form for readonly properties which should have a method body. It's essentially a combination of the lambda operator =>
and the property declaration. By changing your line to
public float AddedValue => Score.scoreValue / 10f;
AddedValue will no longer be a variable, but a property that executes this expression every time it is read. Note that this new syntax can only be used when you have C#6 support. This highly depends on your Unity version, your target platform and your actual used scripting backend and .NET version.
Your answer
Follow this Question
Related Questions
Why doesn't this shader work when using it with as a custom effect on the post processing stack 1 Answer
How do I change a game object's saturation? 0 Answers
Ignore post processing on object without using two cameras 0 Answers
Copy,Graphics.CopyTexture error with PostProcessing Effects 2 Answers
How to change URP overrides by script? 0 Answers