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

前文说到碰撞检测时候,不要在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);
    }

这里顺便测试了到底 在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。

时间: 2024-12-26 16:59:01

Unity3D 在Update中不要过多地修改Transform 信息的相关文章

银行管理系统 实现用户注册 登录 存、取款 交易记录查询和修改用户信息等功能

========= 项    目   介   绍======== 银行账户管理系统 本项目主要实现用户注册 登录 存.取钱和修改用户信息功能. 用户信息的存储和获取通过集合和IO输入输出流实现. 存钱 取钱功能通过修改用户信息中的余额实现 修改用户信息 要先获取用户信息 ,再把修改后的信息保存到List中,同时必须删除原有的用户信息. ========项目功能需求============= 该银行管理系统可以实现 以下主要几个功能 用户注册   注册成功才能进行用户登录 用户登录  登录成功后

Unity3D引擎扩展中的编辑器定制方法

http://gamerboom.com/archives/36432 作者:Richard Fine Unity3D的方便之处在于,它很容易地扩展编辑器套件.每款游戏都对加工有着不同的需求,可以快速地以完全集成的方法来构建这些内容并极大地提升开发速度. 目前有大量复杂的软件包提供以基本Unity功能套件为基础的复杂工具,从视觉脚本编辑器到编辑器内导航网格生成.但是,有关如何自行构建此类事物的程序说明却很少.我将在下文列举某些在自己的工作中总结的编辑器定制相关信息. Unity-Window(f

update 中exists使用

update 中使用exists和不适用exists区别,为更客观的发现问题,执行以下2个SQL. SQL1: update NET_S_SUBSTATION a   set DEV_NAME =       (SELECT name1  FROM ff b where b.id1 = a.dev_id); 执行结果:更新了DEV_NAME的所有数据,符合条件的更新为ff表中的数据,不符合条件的更新为NULL. SQL2: update NET_S_SUBSTATION a   set DEV_

centos linux中怎么查看和修改计算机名/etc/sysconfig/network

centos linux中怎么查看和修改计算机名 查看计算机名:在终端输入hostname 修改的话 hostname +计算机名(重启后失效)要永久修改的话要修改配置文件/etc/sysconfig/network修改hostname=你要改的名字

DSP中cmd文件(修改1)

DSP中cmd文件(修改1) 看TMS320C6000 Optimizing Compiler v7.6 User's Guide和TMS320C6000 Assembly Language Tools User's Guide ? CMD 的专业名称叫链接器配置文件,是存放链接器的配置信息的,其中比较关键的就是MEMORY和SECTIONS两个伪指令的使用. ? DSP工程文件夹中有两个cmd文件,其中一个为linker.cmd;另一个为c6455.cmd.c6455.cmd文件在工程中.工程

easydialog中对js的修改

easydialog-v2.0,对初学者来说,就是练习修改js的最好文件.将这个压缩包打开后,通过修改js可改变index.html中的弹出框的变化. 打开压缩包,点击index.html,同时用自己的编辑器,打开easydialog.js进行编译. 可在easydialog.js中修改在index.html中弹出框的宽高,边距,图片显示时间等 当修改后的easydialog.js,因文件太大,无法上传,所以可百度上下载"Beyond_Compare"这个软件包,将下面上传的单个eas

Jquery实现表格中的查看删除修改

首先我们在学习js的时候就有接触到表格中的一些操作,那么Jquery是一个兼容多浏览器的轻量级的javascript库,它的核心理念是写的更少,做的更多. 现在就用学到的Jquery来做一个表格中的查看删除修改感受一下Jquery的强大. 第一步:我们编写html页 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-

Unity3D在NGUI中使用mask

过程是这样的:最近一直想做一个头像的mask效果,后来发现原来unity的mask需要用shader来写,网上找了不少资料,也能实现,不过大多数都是用render texture作为相机投影的texture.然后把这个相机的图像作为一个material,然后在ngui中创建一个texture,把这个material赋给texture.怎么说呢,这种方式虽然也能实现,但是必须要创建一个相机,对于一个大型项目来说有点不切实际.一个头像加个mask多简单的一件事,肯定有更好的办法. 最终还是找到了一种

如何限制Exchange用户在OWA中修改个人信息

一.为什么要限制或禁用呢? 最近在做一个Exchange的项目,客户那老是有用户在用户的ECP上随意修改自己的个人信息,懂Exchange与AD的童鞋们知道,用户自行修改后的这些信息会同步到AD,并且在地址簿中显示,基于安全原因和管理原因需要禁用ECP这个自助功能. 二.要限制哪一些功能? 以Exchange 2013为例在OWA中,我们先来看看,有哪几类功能,可供用户修改个人信息,主要包括以下几类: 1.自定义邮件签名.外出自动答复等邮件相关信息,如下图: 2. 修改密码.照片.帐号常规信息等