一直以为Execute下的三个枚举 OnUpdate, OnStart,OnEnable的意思分别是 在Update,Start,OnEnable执行的时候适配尺寸(相对于Target的自适应),原来一直是我理解错了。
今天项目需求需要在Anchor适应完了之后 执行一个计算操作,我把这个操作放在了Start里,也就是需要让Start在Anchor适应完了之后执行,结果无论怎么调整Execute都达不到效果,照理说即使OnEnable应该是会在Start之前执行的 结果Execute选择OnEnable也不行。 于是去看NGUI实现Anchors适配的代码,这一步操作是继承自UIRect的.
protected virtual void OnEnable ()
{
#if UNITY_EDITOR
mEnabled = true;
#endif
mUpdateFrame = -1;
if (updateAnchors == AnchorUpdate.OnEnable)
{
mAnchorsCached = false;
mUpdateAnchors = true;
}
if (mStarted) OnInit();
mUpdateFrame = -1;
}
protected void Start ()
{
mStarted = true;
OnInit();
OnStart();
}
public void Update ()
{
if (!mAnchorsCached) ResetAnchors();
int frame = Time.frameCount;
#if UNITY_EDITOR
if (mUpdateFrame != frame || !Application.isPlaying)
#else
if (mUpdateFrame != frame)
#endif
{
#if UNITY_EDITOR
if (updateAnchors == AnchorUpdate.OnUpdate || mUpdateAnchors || !Application.isPlaying)
#else
if (updateAnchors == AnchorUpdate.OnUpdate || mUpdateAnchors)
#endif
{
mUpdateFrame = frame;
mUpdateAnchors = false;
bool anchored = false;
if (leftAnchor.target)
{
anchored = true;
if (leftAnchor.rect != null && leftAnchor.rect.mUpdateFrame != frame)
leftAnchor.rect.Update();
}
if (bottomAnchor.target)
{
anchored = true;
if (bottomAnchor.rect != null && bottomAnchor.rect.mUpdateFrame != frame)
bottomAnchor.rect.Update();
}
if (rightAnchor.target)
{
anchored = true;
if (rightAnchor.rect != null && rightAnchor.rect.mUpdateFrame != frame)
rightAnchor.rect.Update();
}
if (topAnchor.target)
{
anchored = true;
if (topAnchor.rect != null && topAnchor.rect.mUpdateFrame != frame)
topAnchor.rect.Update();
}
// Update the dimensions using anchors
if (anchored) OnAnchor();
}
// Continue with the update
OnUpdate();
}
}
可以看到只有在Update中有执行Anchor的适应操作,难怪不管Execute中不管选择哪个Anchors的适配都要比Start晚执行了,Update确实是比Start要晚执行啊。
<pre name="code" class="csharp">if (updateAnchors == AnchorUpdate.OnUpdate || mUpdateAnchors)
Update中控制执行Anchor的条件 可以看出若Execute类型选择了OnUpdate 那么每次Update的时候都会自适应一次。另一个mUpdateAnchors 变量在初始化的时候是为True的,也就是说如果选择了OnStart 那么在游戏开始的时候会执行一次自适应,但是也是在Update中执行的,只是这个模式 只在开始的时候执行一次。
而如果选择了OnEnable则在每次Enable的时候都将mUpdateAnchors都置为true一次,然后就能进到Update中进行自适应了,但是这个操作还是在Update中执行的。
所以这三个选择并不是分别在Start Update 和OnEnable的时候 自适应一次的意思。而是只适配一次(Stasrt),每次Update都适配,和每次Enable都适配 的意思。
那么想要达到 分别在Start Update 和OnEnable的时候 自适应一次的效果 只需要在Start 和 OnEnable的时候调用一次Update 就可以了、
更改Start和OnEnable中的代码
protected virtual void OnEnable ()
{
#if UNITY_EDITOR
mEnabled = true;
#endif
mUpdateFrame = -1;
if (updateAnchors == AnchorUpdate.OnEnable)
{
mAnchorsCached = false;
mUpdateAnchors = true;
Update();
}
if (mStarted) OnInit();
mUpdateFrame = -1;
}
protected void Start ()
{
mStarted = true;
OnInit();
OnStart();
if (updateAnchors == AnchorUpdate.OnStart)
{
Update();
}
}
这样也没有改变代码原来的意思,选择OnStart还是只在开始的时候 适应一次,只是变成了 在Start中立即执行,OnEnable也是一样。这样就能满足一些更适应顺序相关的需求了。