C# Can';t神秘地跟踪变量的变化
我有一个带有网格布局的面板,我在其中放置预制文本对象的实例化克隆 可视计时器表示的每个实例都有一个附加的计时器脚本 以及将这些文本对象添加到列表(面板)的按钮: 按下按钮后,我从新计时器调用C# Can';t神秘地跟踪变量的变化,c#,unity3d,C#,Unity3d,我有一个带有网格布局的面板,我在其中放置预制文本对象的实例化克隆 可视计时器表示的每个实例都有一个附加的计时器脚本 以及将这些文本对象添加到列表(面板)的按钮: 按下按钮后,我从新计时器调用StartTimer函数(我省略了所有用于实例化研究名称文本的类似代码): 已启动未在代码中的任何其他位置设置。为什么会这样 另一方面,我了解到我似乎不需要变量,但我仍然很好奇它为什么会发生。在ResearchTimer类中,将isStarted=false放在Awake方法中 当实例化newTimerO
StartTimer
函数(我省略了所有用于实例化研究名称文本的类似代码):
已启动
未在代码中的任何其他位置设置。为什么会这样
另一方面,我了解到我似乎不需要变量,但我仍然很好奇它为什么会发生。在
ResearchTimer
类中,将isStarted=false
放在Awake
方法中
当实例化newTimerObject
时,会调用该对象上每个组件的Awake
方法,但在执行第一次更新之前不会调用Start
因此,在您的情况下,将调用Awake
方法(如果有),然后调用StartTimer
,该方法将isStarted
设置为true
,但在执行下一次更新时,将调用Start
方法,然后将其设置为false
如果在Awake
中初始化isStarted
,而不是Start
,则应在实例化newTimerObject
之后和调用“StartTime”之前调用它
void Awake () {
visualText = GetComponent<Text> ();
//I initiate it to false here because
//I don't need updates before the timer starts.
isStarted = false;
}
您可以利用这一点,因为
Start
仅在您自己的代码之后运行。您不知道代码的运行顺序,但是,您知道开始
总是“在所有代码之后,到处”运行。假设你正在制造一艘宇宙飞船、一艘敌舰和一艘货船。一旦Start
运行,您就知道所有三个都在那里。您知道吗,默认情况下,isStarted开始时将为false
?这就是你要问的吗?我实际上要问的是,为什么调用StartTimer()
后,isstart
仍然为false。我知道Start()
在我调用StartTimer()
之前就被调用了,所以我不明白为什么/如何在调用之后再次将其设置为false。这有用吗?很好。这是我的错误,也是一个相当尴尬的错误。我一定是糊涂了。对不起,这种问题很容易解决。确保你包括>>>>>ALLI我不知道你为什么在这里滥发评论。我知道如何使用Debug.Log()
。正如您所指出的,isStarted是一个私有变量,那么为什么其他文件很重要呢?这是我在上面的问题中已经向你们展示的。讨论+
与+=1
或v=v+1
似乎都与讨论无关。请在别处谈谈这个问题。完全正确。正如我在OP中提到的,如果他们只是添加一个调试行,人们会清楚地看到“isStarted=false”是在StartTimer调用之后调用的。事实上,正如第一条评论中提到的,“你知道吗,isStarted
在默认情况下首先将是false
”,这听起来更合理,不必麻烦了“重新初始化它”为默认值。但无论如何,MotoSV已经完全解释了问题。关键是要知道away
在对象实例化时运行,而Start仅在“runloop启动时”(稍后)运行.这正是我在问题中加入第一段的原因,@JoeBlow将其删除。我认为这可能与事件生命周期有关。我想我应该解释一下我从一开始是如何看待事件周期的,以便有人更容易纠正我。老实说,我仍然不完全理解它,我现在无法测试它,因为se我有一个不同的错误,使我现在无法运行该程序。我想这是因为我重命名了预置,从而破坏了一些元数据。我将恢复到上次保存的时间,并在我可以测试它时通知你。你可以随时恢复编辑,我删除了这个我希望我知道如何更具体,但我很有信心JoeBlow:请不要修改已经被接受的答案。如果你觉得答案不正确或者可以改进,那么请发布你自己的解决方案,如果这被认为是一个更精确的答案,那么Aske B可以选择接受这个答案我不明白这个答案。
public class ResearchTimer : MonoBehaviour {
public float timeRemaining;
private Text visualText;
private bool isStarted; //This is the variable I don't understand
void Start () {
visualText = GetComponent<Text> ();
//I initiate it to false here because
//I don't want update called before the timer starts.
isStarted = false;
}
void Update () {
//Here, isStarted is always false after setting it to true "StartTimer"
if (!isStarted) return;
//code to update text representation of the timer
...
}
public void StartTimer(float timeInSeconds) {
timeRemaining = timeInSeconds;
isStarted = true;
//When I set a breakpoint here, the "isStarted" variable is changed to true,
//but the next time the Update function runs, it's false again.
//That is the part I don't understand
InvokeRepeating ("decreaseTimeRemaining", 1.0f, 1.0f);
}
void decreaseTimeRemaining()
{
//If I set isStarted here, it shows correctly (as per screenshot),
//but then it won't be set before the first second has passed
isStarted = true;
timeRemaining--;
}
...
}
void Awake () {
visualText = GetComponent<Text> ();
//I initiate it to false here because
//I don't need updates before the timer starts.
isStarted = false;
}
_ _ _ _ _
|
|
|
| all your various code runs here
| you instantiate something .. Awake runs
| all your various code runs here
| you instantiate something .. Awake runs
| you instantiate something .. Awake runs
| all your various code runs here
|
| unity does many things here, drawing, physics, etc etc
| unity does many things here, drawing, physics, etc etc
| unity does many things here, drawing, physics, etc etc
|
|_ _ _ _ _ _
| all of the Starts are run at once here
|_ _ _ _ _
|
| next frame begins...