Unity3D 在Update中不要过多地修改Transform 信息
2017-07-06 01:13
393 查看
前文说到碰撞检测时候,不要在Update内部尝试移动GameObject 来检查碰撞检测,这样是徒劳无功。但是 说到
因为你移动的过程中其实并没有将实际的移动位置更新到物理引擎,只是做了个缓存而已,
只有在调用FixedUpdate的内部函数(物理引擎处理)时,才会将最新的位置设置到物理引擎上,甚至是渲染引擎也使用最新的位置。
其实是有问题的,因为我发现每次移动都会导致 碰撞器不断更新
View Code
这里顺便测试了到底 在Update中修改Transform(.Position)而更新 BoxCollider 是否会激发OnTriggerEnter2D、OnTriggerExit2D。如果 此两个函数输出时 TEST 的值不为0,则是在Update中会导致物理引擎的更新。这里输出的结果为0,所以我的猜测是对的。物理引擎并不是和脚本逻辑并行的(不是多线程)
但是更新了Transform 而立即导致物理碰撞器的更新,而不是暂时将Transform做缓存,等到物理引擎更新时才读取最新的Transform来更新碰撞器,为什么Unity3D这样做呢?
实际原因我当然是不得而知了,但是我猜测吧,应该是 物理引擎提供了一些基本的函数给脚本逻辑使用,例如
因为你移动的过程中其实并没有将实际的移动位置更新到物理引擎,只是做了个缓存而已,
只有在调用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。
相关文章推荐
- sql update 触发器 获得被update的行的信息(某行的某字段被修改后,自动修改该行的另外一个字段)
- 11周2-2项目 - 存储班长信息的学生类,将Stu类的数据成员的访问权限改为private,你的程序是否能完成要求的功能?如果不行,请修改程序。请不要修改给出的代码,只能修改自己写的代码。
- [Unity3D]使用OnGUI函数显示状态栏并且使用触发器修改玩家当前信息
- 存储班长信息的学生类,将Stu类的数据成员的访问权限改为private,你的程序是否能完成要求的功能?如果不行,请修改程序。请不要修改给出的代码,只能修改自己写的代码。
- Oracle EBS PO API po_change_api1_s.update_po修改PO行信息
- 动态修改UI的RectTransform的位置和宽高信息
- 求助 这是我的mfc下一个修改数据库信息的一段代码,里面执行到m_Ado.m_pRecordset->Update(); 这句话的时候就会出现异常,而且修改不了数据库内的信息。
- 微信卡券开发,代金券修改卡券信息返回40145错误码: invalid update! Can not both set PayCell and CenterCellInfo(include: center_title, center_sub_title, center_url). hint: [DZ9rna0637ent1]
- Classical-Music 目录 (2005.03.22/ 整理和使用ShitMp3 修改MP3信息)
- Occident & Sweden & Switzerland 目录 (2005.03.22/ 整理和使用ShitMp3 修改MP3信息)
- Japan-Korea 目录 (2005.03.22/ 整理和使用ShitMp3 修改MP3信息)
- 修改創世紀工作站注册信息和网吧欢迎信息的方法
- C# 向数据库中添加 修改数据库的两种方法Sql语句和update(dataSet)
- Chantress 目录 (2005.03.22/ 整理和使用ShitMp3 修改MP3信息)
- 修改Apache的返回头部信息,让人误认为是IIS的..
- Jazz 目录 (2005.03.22/ 整理和使用ShitMp3 修改MP3信息)
- Rock And Roll & Goth 目录 (2005.03.22/ 整理和使用ShitMp3 修改MP3信息)
- 用户控件(显示用户信息,修改用户名密码)的WebPart预览版
- 简析修改Exchange Server各协议版本信息(Banner)