销毁物体和ExecuteInEditMode

本文探讨了Unity中[ExecuteInEditMode]属性的作用及其对脚本执行的影响,特别是在编辑器模式下对物体实例化和销毁行为的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在使用Destroy函数销毁物体的时候,出现了一些状况。


首先来看一下这样一段简单的代码:


    [ExecuteInEditMode]
    public class Test : MonoBehaviour
    {

        public GameObject TestGameobject;

        public void Start()
        {
            Instantiate(TestGameobject);
        }

按照Unity 场景的序列化和反序列化的机制(也就是常说的在Play模式下所有修改都不会生效)。

在点击Play按钮之后,执行脚本后会创建一个物体,然后再次点击Play退出游戏后,原先场景的数据会执行反序列化恢复到原状,也就是说物体会被销毁。


但是,运行这一段脚本会发现,实例化之后的TestGameobject并没有随着游戏的退出而自动销毁,而是随着游戏的每次运行退出之后都不断增加。


经过研究发现问题出现在[ExecuteInEditMode]这个属性上。

官方文档上的解释是:

Makes a script execute in edit mode.

By default, script components are only executed in play mode. By adding this attribute, each script component will also have its callback functions executed while the Editor is not in playmode.

让脚本在编辑器模式下也能运行。


实际上,这个属性的对Awake和Start这样的函数会有下面的影响:

    当该MonoBehavior在编辑器中被赋于给GameObject的时候,Awake, Start 将被执行。
    当Play按钮被按下游戏开始以后,Awake, Start 将被执行。
    当Play按钮停止后,Awake, Start将再次被执行。
    当在编辑器中打开包含有该MonoBehavior的场景的时候,Awake, Start将被执行。


编辑器在每次更新的时候,都会执行一次Awake和Start。


这样就能解释上面的情况。

开始游戏的时候,Start被执行创建了一个物体,退出游戏后场景反序列化该物体被删除,但是这时候编辑器的视图也更新了,又触发了一次Start创建了一个物体。所以每次开始和退出游戏之后,都会多出一个物体。

也就是说,退出游戏之后多出来的那个物体和进入游戏时创建的那个物体不是同一个。

通过在Start函数里面输出日志的办法证实了我的想法。


参考资料:

http://www.cnblogs.com/xpvincent/p/3178042.html

http://docs.unity3d.com/ScriptReference/ExecuteInEditMode.html

### 关于Unity中实现物体水面效果的Shader教程 在创建逼真的水面效果时,通常会涉及到多个方面的技术组合来达到理想的结果。对于Unity中的水面效果而言,可以采用Shader Graph工具简化开发过程并提高效率。 #### 使用Shader Graph制作基础水波纹效果 通过Shader Graph能够直观地构建节点网络以定义材质属性。为了生成基本的水波动画,可引入时间变量控制纹理坐标偏移,从而制造出动态变化的感觉[^1]: ```hlsl float timeOffset = _Time.y * speed; float2 uvOffset = float2(sin(timeOffset), cos(timeOffset)) * waveStrength; fixed4 col = tex2D(_MainTex, i.uv + uvOffset); ``` 这段HLSL代码片段展示了如何基于当前帧的时间戳调整UV坐标的位移量,进而影响最终颜色输出`col`。其中`_Time.y`代表自游戏启动以来经过秒数;`speed``waveStrength`则是用于调节动画频率与振幅大小的参数。 #### 结合摄像机深度信息增强视觉表现力 为了让水面看起来更加真实可信,在着色器内部获取场景内其他对象距离摄像头远近的数据是一项重要优化措施。这可以通过访问Camera组件上的depth texture完成设置工作[^2]: ```csharp using UnityEngine; [ExecuteInEditMode] public class WaterEffectController : MonoBehaviour { private Camera mainCam; void Start() { mainCam = GetComponent<Camera>(); if (mainCam != null) { mainCam.depthTextureMode |= DepthTextureMode.Depth; } } } ``` 上述C#脚本负责确保所挂载的游戏对象(通常是主摄像机)开启了深度贴图功能,以便后续能够在Shader层面读取这些数据参与计算。 #### 应用高级光学现象提升沉浸感 除了简单的几何形变外,还可以进一步探索物理仿真领域内的知识点——比如菲涅尔效应、全内反射以及色散特性等,它们共同作用使得液体表面呈现出丰富多彩的变化形态[^3]。 - **菲涅尔项**:描述光线入射角同观察者视线夹角之间的关系,决定了不同视角下的高光强度分布情况; - **色散现象**:由于白光穿过介质时各单色成分传播速度存在差异而导致的颜色分离状况; 综上所述,借助Unity强大的图形编程接口配合恰当的艺术风格设计思路,完全可以打造出令人惊叹不已的虚拟水域景观!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值