Unity3D 在Update中不要过多地修改Transform 信息
前文说到碰撞检测时候,不要在Update内部尝试移动GameObject 来检查碰撞检测,这样是徒劳无功。但是 说到
因为你移动的过程中其实并没有将实际的移动位置更新到物理引擎,只是做了个缓存而已,
只有在调用FixedUpdate的内部函数(物理引擎处理)时,才会将最新的位置设置到物理引擎上,甚至是渲染引擎也使用最新的位置。
其实是有问题的,因为我发现每次移动都会导致 碰撞器不断更新

下面是测试代码:
int TEST = ;
// 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 = ;
while (true)
{
//DEBUG++;
++TEST;
var rest = Mathf.Abs(amount) - Mathf.Abs(progress);
if (rest <= )
break;
increment = Mathf.Min(increment, rest);
Y += increment * sign;
progress += increment * sign;
if (Colliding())
{
Y -= increment * sign;
//print(DEBUG);
return false;
}
}
//print(TEST);
TEST = ;
//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);
}
这里顺便测试了到底 在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。
Unity3D 在Update中不要过多地修改Transform 信息的更多相关文章
- svn修改log信息
在linux下安装了SVN服务器来做版本控制. 有天提交文件忘记了填写SVN提交日志,于是在项目中使用右键,show log,找到我提交的无日志的那条记录,点击右健,选择了“Edit log mess ...
- Properties集合_修改配置信息
集合中的数据来自于一个文件 注意:必须要保证该文件中的数据是键值对. 需要使用到读取流 使用load()方法读取已有文件中的数据,存储到Properties集合中 public class Pro ...
- C# json反序列化 对象中嵌套数组 (转载) 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
C# json反序列化 对象中嵌套数组 (转载) 看图: 这里可以看到是二层嵌套!!使用C#如何实现?? 思路:使用list集合实现 → 建立类 → list集合 → 微软的 Newtonso ...
- Thinking in Unity3D:渲染管线中的Rendering Path
关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的 ...
- Unity3D引擎扩展中的编辑器定制方法
http://gamerboom.com/archives/36432 作者:Richard Fine Unity3D的方便之处在于,它很容易地扩展编辑器套件.每款游戏都对加工有着不同的需求,可以快速 ...
- ListView与.FindControl()方法的简单练习 #2 -- ItemUpdting事件中抓取「修改后」的值
原文出處 http://www.dotblogs.com.tw/mis2000lab/archive/2013/06/24/listview_itemupdating_findcontrol_201 ...
- 可能会导致循环或多重级联路径。请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
错误提示:可能会导致循环或多重级联路径.请指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束. 原因:自表连接(同一张表 ...
- 聊聊 Vue 中 title 的动态修改
由于之前的 Vue 项目打包成果物一直是嵌入集成平台中,所以一直没有关注过项目的 title.直到最近,突然有个需求,要求点击按钮在集成平台外新开一个页面,此时我才发现,原来我的项目的 title 一 ...
- TDD在Unity3D游戏项目开发中的实践
0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...
随机推荐
- django开发网站 让局域网中的电脑访问你的主机
1. 关闭主机电脑上的防火墙(不用关闭,加一个端口号就行) 2.在你的settings.py文件中,找到ALLOWED_HOSTS=[ ],在中括号中加入你在局域网中的IP.如我在局域网中的IP为19 ...
- c++堆和栈(转)
想要学好C++的C++堆栈,那么就要了解什么是C++堆栈,所为C++堆栈就是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除,分为堆和栈两部分. 在C++中,内存分 ...
- SpringCloud系列六:Feign接口转换调用服务(Feign 基本使用、Feign 相关配置)
1.概念:Feign 接口服务 2.具体内容 现在为止所进行的所有的 Rest 服务调用实际上都会出现一个非常尴尬的局面,例如:以如下代码为例: Dept dept = this.restTempla ...
- django之缓存的用法, 文件形式与 redis的基本使用
django的缓存的用法讲解 1. django缓存: 缓存的机制出现主要是缓解了数据库的压力而存在的 2. 动态网站中,用户的请求都会去数据库中进行相应的操作,缓存的出现是提高了网站的并发量 3. ...
- 学习python 检测字符串的方法
检测字符串长度的方法:len() 检测字符串是否含有字母的方法:str.isalpha() 检测字符串是否含有数字的方法:str.isnumeric() 检测字符串是否有大写字母:str.upper( ...
- Sql Server数据库之存储过程
阅读目录 一:存储过程概述 二:存储过程分类 三:创建存储过程 1.创建无参存储过程 2.修改存储过程 3.删除存储过程 4.重命名存储过程 5.创建带参数的存储过程 简单来说,存储过程就是一条或 ...
- SQL Server中与IO相关的等待类型:IO_COMPLETION和PAGEIOLATCH_*
一个大的SQL语句操作,执行计划中包含了一个merge join操作,观察到SQL长时间处于IO_COMPLETION等待状态,如果是读取相关的表的数据,服务器应该全力为其服务,但是服务器的物理IO又 ...
- ARTS打卡计划第一周-Review
本周分享的文章来自于medium的 Testing Best Practices for Java + Spring Apps 这个文章主要讲的是java测试的一些最佳实践 1.避免函数返回void, ...
- tornado 基于MongoDB存储 session组件开发
1.开发伊始 根据源码中RequestHandler类中发现__init__函数中会调用自身initialize函数,此函数中为pass,即可以围绕initialize开发一系列的组件 2.开发实现 ...
- Arthas的基础学习
下载与安装 wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 启动 查看启动的帮助信息: ...