您的位置:首页 > 移动开发 > Unity3D

Unity3D 在Update中不要过多地修改Transform 信息

2017-07-06 01:13 393 查看
前文说到碰撞检测时候,不要在Update内部尝试移动GameObject 来检查碰撞检测,这样是徒劳无功。但是 说到


因为你移动的过程中其实并没有将实际的移动位置更新到物理引擎,只是做了个缓存而已,

只有在调用FixedUpdate的内部函数(物理引擎处理)时,才会将最新的位置设置到物理引擎上,甚至是渲染引擎也使用最新的位置。


其实是有问题的,因为我发现每次移动都会导致 碰撞器不断更新

int TEST = 0;

// Returns true if you were able to move, false if you collided.
// 人物不断尝试往'下'走到 Y+amount
//  如果 中途碰撞到物体 则 人物站在 物体上 并return false
//  否则返回true,代表人物已成功移动到yVel 的位置
bool TryMoveY(float amount)
{
//optimize

var sign = Mathf.Sign(amount);
var increment = 0.001f;
var progress = 0f;

//var DEBUG = 0;
TEST = 0;
while (true)
{
//DEBUG++;
++TEST;
var rest = Mathf.Abs(amount) - Mathf.Abs(progress);
if (rest <= 0)
break;
increment = Mathf.Min(increment, rest);

Y += increment * sign;
progress += increment * sign;
if (Colliding())
{
Y -= increment * sign;
//print(DEBUG);
return false;
}

}
//print(TEST);
TEST = 0;

//print(DEBUG);
return true;

//var increment = amount > 0 ? 0.01f : -0.01f;
//var progress = 0f;

//while(Mathf.Abs(progress) < Mathf.Abs(amount))
//{
//    // progress 远远 小于 amount - increment
//    // 步伐依然为 increment = 0.01
//    if (Mathf.Abs(progress) < Mathf.Abs(amount) - Mathf.Abs(increment))
//    {
// NOTHING
//    }
//    else // 缩小步伐(最后一步了)
//    {
//        increment = amount - progress;
//    }

//    Y += increment;
//    progress += increment;

//    if (Colliding())
//    {
//        Y -= increment;
//        return false;
//    }
//}

//return true;

}

private void OnTriggerEnter2D(Collider2D collision)
{
print("ENTER: " + collision + " " + name + "  " + TEST);

}

private void OnTriggerExit2D(Collider2D collision)
{
print("EXIT: " + collision + " " + name + "  " + TEST);
}


View Code
这里顺便测试了到底 在Update中修改Transform(.Position)而更新 BoxCollider 是否会激发OnTriggerEnter2D、OnTriggerExit2D。如果 此两个函数输出时 TEST 的值不为0,则是在Update中会导致物理引擎的更新。这里输出的结果为0,所以我的猜测是对的。物理引擎并不是和脚本逻辑并行的(不是多线程)



但是更新了Transform 而立即导致物理碰撞器的更新,而不是暂时将Transform做缓存,等到物理引擎更新时才读取最新的Transform来更新碰撞器,为什么Unity3D这样做呢?

实际原因我当然是不得而知了,但是我猜测吧,应该是 物理引擎提供了一些基本的函数给脚本逻辑使用,例如
Physics.Raycast / RaycastHit2D Linecast(Vector2 start, Vector2 end);等,如果没有及时更新 BoxCollider2D的信息,有可能会导致使用碰撞检测等API时会出现BUG。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐