Unity中Random.Range()调用位置及Start内调用报错问题咨询
Unity Random.Range()调用报错问题解答
1. Random.Range()的正确调用位置
- 继承自
MonoBehaviour的脚本,不允许在字段初始化器(也就是定义类字段时直接赋值的位置)、类构造函数中调用Random.Range(),这是Unity生命周期限制导致的,这类Unity内置API需要在引擎初始化完脚本实例后才能调用。 - 合法调用位置包括:
- 生命周期初始化方法
Awake()、Start(),适合给全局类字段赋初始随机值 - 运行时方法
Update()、FixedUpdate()、OnTriggerXXX()等所有脚本生命周期回调方法 - 普通自定义方法,只要调用时机不是在脚本构造/字段初始化阶段即可
- 生命周期初始化方法
- 如果是非
MonoBehaviour的普通C#类,没有调用位置限制。
2. Start方法内调用仍报错的原因
你遇到的} expected类报错是语法解析错误,和Random.Range本身无关,问题出在你在方法内部的局部变量前加了访问修饰符private:
C#中
private/protected/public这类访问修饰符只能用来修饰类成员(字段、属性、方法等),方法内部的局部变量天生仅属于当前方法作用域,不允许加任何访问修饰符。
编译器遇到方法内的private关键字时无法正常解析语法,才会误报缺少大括号的错误,并非你真的漏写了闭合括号。
修正后的完整代码
如果你的speed仅需要在Start方法内使用,直接去掉private即可:
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); } } }
如果需要让Cube持续旋转,在Update中也要使用speed变量,则需要把speed声明为类字段:
using UnityEngine; public class Cube : MonoBehaviour { public MeshRenderer Renderer; // 把speed声明为类字段,可加private修饰符 private float speed; void Start() { // 仅在Start中赋值,不用加修饰符 speed = Random.Range(10f, 30f); } void Update() { // Update中可正常使用speed变量实现持续旋转 transform.Rotate(speed * Time.deltaTime, 0.0f, 0.0f); if (Input.GetKeyDown("space")) { GetComponent<Renderer>().material.color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f, 0.5f, 1f); } } }
内容的提问来源于stack exchange,提问作者Sophie Lee
相关产品推荐
相关产品推荐

