Home > database >  where do i call Random.Range( )
where do i call Random.Range( )

Time:11-25

The following code throws an error:

UnityException: Range is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Cube : MonoBehaviour
{
    public MeshRenderer Renderer;

    private float speed = Random.Range(10f, 30f);

    void Start()
    {
        transform.Rotate(speed* Time.deltaTime, 0.0f, 0.0f);
    }
       
    void Update()
    {
        if (Input.GetKeyDown("space"))
        {
            GetComponent<Renderer>().material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f, 0.5f, 1f); 
        }
    }
}

So I edited it by calling the Range method in start

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Cube : MonoBehaviour
{
    public MeshRenderer Renderer;

    void Start()
    {
        private float speed = Random.Range(10f, 30f);
        transform.Rotate(speed* Time.deltaTime, 0.0f, 0.0f);
    }

    void Update()
    {
        if (Input.GetKeyDown("space"))
        { 
            GetComponent<Renderer>().material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f, 0.5f, 1f); 
        }
    }
}

However, I got a bunch of errors, such as error CS1513, CS1519, CS8124 etc.

I'm sorry if this sounds really dumb, and I've been trying to fix this by calling Range in Awake() or googling for similar situations online, but nothing seems to be working.

To summarize:

  1. Where do I call Random.Range() in my code?
  2. Why does calling it in Start() result in a variety of syntax errors, such as } expected when I already typed }?

CodePudding user response:

  1. Where do I call Random.Range() in my code?

As Unity tells you within a class derived from MonoBehaviour it can't be done at field initialization time (which happens before the constructor is executed). The reason is most probably mainly because this instance created by the underlying c backend entity component system and accessing the UnityEngine.Random class from there or in general from other threads is unreliable (see UnityEngine.Random)

→ Unity already tells you exactly what to do though

call it in Awake or Start instead

you have to assign the value within one of the event message methods Awake, Start, etc.

  1. Why does calling it in Start() result in a variety of syntax errors, such as } expected when I already typed }?

Because a local variable within a method can not have any access modifiers and you have private there. So the compiler expects you to first close the Start method with a } before using the keyword private. The rest are just follow up compiler errors.


You want to keep the field declaration at class level and then assign it in Start

private float speed;

private void Start ()
{
    speed = Random.Range(10f, 30f);
}

Then you also most probably don't want to rotate only once in Start but rather move it into Update in order to get a continous rotation.

private void Update ()
{
    transform.Rotate(speed * Time.deltaTime, 0.0f, 0.0f);
    
    ...
}

Finally (this is more a general side note) you should change the field type and rather cache

// Already assign vis the Inspector if possible
public Renderer renderer;

private void Awake ()
{
    // Get ONCE as fallback
    if(!renderer) renderer = GetComponent<Renderer>();
}

and then reuse that reference

private void Update ()
{
    ...

    // it is also preferred to use KeyCode instead of strings
    if (Input.GetKeyDown(KeyCode.Space))
    {
        renderer.material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f, 0.5f, 1f);
    }
}

CodePudding user response:

Unity works weirdly on the backend. You'll need to declare private float speed; like in the first snippet. Then in the start/awake method call speed = Random.Range(10f, 30f);

public class Cube : MonoBehaviour
{
    public MeshRenderer Renderer;

    private float speed;
    void Start()
    {
        speed = Random.Range(10f, 30f);
        transform.Rotate(speed* Time.deltaTime, 0.0f, 0.0f);
    }
       
   
    void Update()
    {
    if (Input.GetKeyDown("space"))
        {GetComponent<Renderer>().material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f, 0.5f, 1f); }
        
    }
}
  • Related