【Unity脚本】使用脚本修改游戏对象静态属性

news2024/11/15 16:23:56
【知识链】Unity -> -> 脚本系统 -> 访问游戏对象 -> 静态属性

【摘要】本文介绍了Unity中游戏对象的静态和动态类型,并说明了如何修改静态属性。
在这里插入图片描述

文章目录

  • 第一章 Unity中的静与动
  • 第二章 静态和动态对象
    • 1. 静态对象(Static Objects)
    • 2. 动态对象(Dynamic Objects)
    • 3. 对比总结
    • 4. 实际应用
  • 第三章 如何修改对象的静态属性
    • 1. 在编辑器中手动设置
    • 2. 在脚本中动态设置(运行时修改)
    • 3. 使用 GameObjectUtility.SetStaticEditorFlags(在编辑器脚本中)
    • 总结
  • 第四章 StaticEditorFlags
    • 1. BatchingStatic
    • 2. NavigationStatic
    • 3. OccludeeStatic
    • 4. OccluderStatic
    • 5. ReflectionProbeStatic
    • 6. OffMeshLinkGeneration
    • 7. LightmapStatic
    • 8. ContributeGI
    • 9. Everything
    • 小结
  • 第五章 运行时修改静态属性
    • 1. 运行时修改 GameObject.isStatic
    • 2. 运行时修改的影响
    • 3. 编辑器中的静态优化
    • 4. 小结
  • 第六章 本文总结
  • 第七章 学以致用
    • 练习题 1:理论题
    • 练习题 2:实践题
  • 第八章 参考资料

第一章 Unity中的静与动

在Unity中,静态(Static)对象和动态(Dynamic)对象有着不同的属性和用途,它们的主要区别在于它们是否能够在运行时移动或变化,以及Unity对它们应用的优化策略。

静态对象是指那些在游戏中不会动的东西,比如地面、建筑物,它们永远固定在那里。Unity可以对这些静态对象进行优化,以提高游戏性能,因为这些东西不会变动。

动态对象则是会动的东西,比如玩家角色、敌人或者会滚动的球。这些对象在游戏运行时会改变位置、大小或方向,Unity需要实时计算它们的变化,所以不能对它们进行像静态对象那样的优化。

简单来说,静态对象是固定不动的,性能更好;动态对象是会动的,但需要更多计算

需要特别说明的是,在构建应用时Unity会对静态对象进行优化。Unity提供了相应的方法来改变对象的静态属性,但这种改变只是在编辑状态时有效,而对于运行时即使设置了静态属性也不会进行相应的优化。当然运行时静态属性的改变也有其他一些用途,将在本文中一一说明。

第二章 静态和动态对象

1. 静态对象(Static Objects)

定义:
静态对象是指在运行时不会移动、缩放或旋转的对象。它们的变换(Transform)属性在游戏运行期间保持不变。

主要特点:

  • 性能优化:

    • 静态批处理(Static Batching):Unity可以对静态对象进行静态批处理,这样可以大大减少绘制调用(Draw Calls),提高渲染性能。静态批处理通过将多个静态对象合并为一个网格(Mesh)来减少渲染开销。
    • 光照贴图(Lightmapping):静态对象可以在编辑器中进行光照贴图烘焙,这意味着光照信息在构建时就被预先计算并存储在贴图中,减少了运行时的光照计算开销。
    • 剔除优化(Occlusion Culling):静态对象可以参与剔除优化,Unity可以预先计算哪些对象在视野之外,从而减少不必要的渲染。
  • 物理计算:

    • 静态对象通常不会参与物理模拟(如刚体、重力等),因为它们的状态不会发生变化。Unity可以对这些对象应用简化的物理计算,从而提高性能。
      场景构建:
    • 静态对象通常用作场景的不可移动部分,例如地形、建筑物、固定障碍物等。它们为游戏世界提供了稳定的背景。

设置方式:

  • 在Unity编辑器中,选择对象后,可以在Inspector面板中勾选 “Static” 复选框,或选择具体的静态类型(如光照静态、导航静态等)。

2. 动态对象(Dynamic Objects)

定义:
动态对象是指在运行时会发生移动、缩放、旋转或其他变化的对象。它们的变换属性在游戏运行期间是可变的。

主要特点:

  • 没有静态优化:

  • 动态对象不会参与静态批处理或光照贴图烘焙,因为它们的状态是动态变化的,无法预先计算和优化。渲染这些对象时需要单独进行处理,可能会增加绘制调用。

  • 物理计算:

    • 动态对象通常是物理模拟的一部分,它们可能受到重力、碰撞、力等影响。例如,玩家角色、敌人、可移动的道具等都属于动态对象。
  • 实时光照:

    • 动态对象通常使用实时光照,这意味着光照计算在运行时进行,适应对象的实时位置和状态变化。
  • 交互性:

    • 动态对象通常是游戏中可交互的部分,它们响应玩家输入或环境变化,如推拉门、移动平台、掉落的物体等。

常见用途:

  • 动态对象用于所有需要在运行时发生变化的场景中,例如玩家角色、NPC、可移动的道具、环境变化的物体等。

3. 对比总结

特性静态对象动态对象
移动/旋转/缩放在运行时不变在运行时会变化
性能优化静态批处理、光照贴图、剔除优化等无静态优化,渲染和物理计算开销较高
物理计算通常不参与物理模拟或使用简化的计算参与物理模拟,响应力、重力和碰撞等
光照光照贴图烘焙(静态)实时光照(动态)
场景用途固定不变的场景元素,如建筑、地形可移动的游戏元素,如角色、道具

4. 实际应用

  • 选择静态对象:如果你确定某个对象在游戏运行时绝不会移动、旋转或缩放,建议将其标记为静态对象,以便Unity应用各种性能优化。
  • 选择动态对象:对于需要在运行时发生变化或与玩家互动的对象,应该保持它们为动态对象。

第三章 如何修改对象的静态属性

在Unity中,可以通过以下几种方法来改变对象的static属性:

1. 在编辑器中手动设置

操作方法:

  1. 在Unity编辑器中,选中需要设置为静态的对象。
  2. 在Inspector面板的顶部,有一个名为"Static"的复选框。
  3. 勾选此复选框后,弹出下拉菜单,你可以选择应用哪些静态标志(例如BatchingStatic、NavigationStatic等)。如果选择了Everything,对象将会被标记为所有类型的静态对象。
    用途:适用于手动设置场景中的对象为静态。

2. 在脚本中动态设置(运行时修改)

操作方法:

  • 通过C#脚本,在运行时修改对象的静态属性。虽然在运行时可以修改,但实际上在运行时修改对象的静态属性并不会触发Unity的静态优化,静态标志的实际作用在编辑器中设置并在构建时生效。

示例代码

GameObject myObject = GameObject.Find("MyObject");
// 设置对象为静态
myObject.isStatic = true;
// 取消对象的静态设置
myObject.isStatic = false;

用途:适用于在特殊情况下根据游戏逻辑临时改变对象的静态状态,但不推荐用于期望的性能优化场景,因为运行时设置isStatic并不会应用静态优化。

3. 使用 GameObjectUtility.SetStaticEditorFlags(在编辑器脚本中)

操作方法:

  • GameObjectUtility.SetStaticEditorFlags方法通常用于编辑器扩展或批量设置多个对象的静态标志。这在你需要创建自定义工具或编辑器脚本时非常有用。

示例代码:

using UnityEditor;
using UnityEngine;

public class SetStaticFlagsExample : MonoBehaviour
{
    [MenuItem("Tools/Set Static Flags")]
    static void SetStaticFlags()
    {
        GameObject myObject = GameObject.Find("MyObject");

        // 设置对象的静态标志
        GameObjectUtility.SetStaticEditorFlags(myObject, StaticEditorFlags.BatchingStatic | StaticEditorFlags.NavigationStatic);

        // 取消所有静态标志
        GameObjectUtility.SetStaticEditorFlags(myObject, 0);
    }
}

用途:适用于在编辑器中批量或程序化地设置对象的静态属性,通常在构建场景或优化时使用。
还有一种比较简便的方法
参考:https://discussions.unity.com/t/how-to-set-use-staticeditorflags-cant-seem-to-set-them-from-script/476886/13

public static void SetStaticEditorFlag(GameObject obj, StaticEditorFlags flag,  bool shouldEnable)
        {
            var currentFlags = GameObjectUtility.GetStaticEditorFlags(obj);
            if (shouldEnable)
            {
                currentFlags |= flag;
            }
            else
            {
                currentFlags &= ~flag;
            }
           
            GameObjectUtility.SetStaticEditorFlags(obj, currentFlags);
        }

使用方法:
SetStaticEditorFlag(gameObject, StaticEditorFlags.LightmapStatic, true)

总结

  • 在编辑器中手动设置:最常用的方式,适合单独设置或通过Inspector面板批量设置对象为静态。
  • 在脚本中动态设置:可以在运行时修改对象的isStatic属性,但无法利用静态优化。
  • 使用 GameObjectUtility.SetStaticEditorFlags:适合在编辑器脚本中批量设置对象的静态属性,特别适用于需要开发自定义工具或进行批量操作时。

第四章 StaticEditorFlags

StaticEditorFlags 是 Unity 中用来标记一个对象在编辑器中静态属性的枚举类型。通过设置这些标志,你可以决定 Unity 如何在构建时优化这些对象。以下是 StaticEditorFlags 的各个类型及其含义:

1. BatchingStatic

  • 描述:用于静态批处理优化。将对象标记为 BatchingStatic 后,Unity 会在构建时将多个静态对象合并为一个网格,以减少绘制调用(Draw Calls)。
  • 用途:适用于大量的、小而重复的几何体,如建筑物的墙体、柱子等。

2. NavigationStatic

  • 描述:用于导航网格优化。将对象标记为 NavigationStatic 后,Unity 会在导航网格烘焙时将其视为不可移动的障碍物或路径的一部分。
  • 用途:适用于需要在AI路径规划中被视为不可穿越的静态对象,如建筑物、固定的障碍物。

3. OccludeeStatic

  • 描述:用于遮挡剔除优化。标记为 OccludeeStatic 的对象可以被遮挡剔除系统考虑,用于决定哪些对象可以被视野外的其他对象遮挡,从而不进行渲染。
  • 用途:适用于较大的、可能会遮挡其他对象的静态物体,如建筑物或大型场景物体。

4. OccluderStatic

  • 描述:用于遮挡物优化。标记为 OccluderStatic 的对象可以作为遮挡物使用,用于遮挡视野中的其他对象。
  • 用途:适用于可以充当遮挡物的静态对象,如建筑物的墙体、山体等。

5. ReflectionProbeStatic

  • 描述:用于反射探针优化。标记为 ReflectionProbeStatic 的对象会在烘焙反射探针时被认为是静态的,因此反射效果更加精确。
  • 用途:适用于需要高质量反射效果的静态对象,如水面、玻璃、光滑的金属表面等。

6. OffMeshLinkGeneration

  • 描述:用于生成离线网格链接。标记为 OffMeshLinkGeneration 的对象会被用来生成离线网格链接,这些链接可以用作AI路径规划的跳跃、攀爬等动态动作。
  • 用途:适用于场景中需要AI做特殊移动的静态对象,如悬崖边缘、楼梯等。

7. LightmapStatic

  • 描述:用于光照贴图优化。将对象标记为 LightmapStatic 后,Unity 会在光照贴图烘焙时将其纳入考虑,使其接收并投射阴影、反射光等。
  • 用途:适用于需要烘焙光照贴图的静态对象,如地形、建筑物、室内装饰等。

8. ContributeGI

  • 描述:用于全局光照贡献。标记为 ContributeGI 的对象会被全局光照系统纳入计算,从而影响整个场景的全局光照。
  • 用途:适用于希望在全局光照中起作用的静态对象,如地形、建筑物、大型场景物体等。

9. Everything

  • 描述:将对象标记为所有类型的静态对象,即它将同时启用所有上述优化选项。
  • 用途:适用于希望对某个对象应用所有可能的静态优化的情况。

小结

  • StaticEditorFlags 提供了针对不同优化需求的标志,可以根据对象在场景中的角色和用途选择合适的标志进行设置。通过合理使用这些标志,可以显著提高游戏的性能,特别是在涉及大量静态几何体的场景中。

第五章 运行时修改静态属性

你可以在运行时修改GameObject.isStatic属性。不过需要理解的是,虽然这个属性在运行时是可修改的,但它的用途和效果与编辑器中的静态优化不同。

1. 运行时修改 GameObject.isStatic

在运行时,你可以通过脚本来动态改变一个游戏对象的静态状态,例如:

void Start()
{
    // 将该GameObject设置为静态
    gameObject.isStatic = true;
    
    // 也可以在运行时将其设置为非静态
    gameObject.isStatic = false;
}

2. 运行时修改的影响

虽然你可以在运行时更改 isStatic 属性,但这不会触发编辑器中的静态优化(如静态批处理、全局光照预计算等),因为这些优化操作通常是在构建或预处理阶段完成的,并且在运行时不再重新计算。
运行时的效果:

  • 碰撞检测:Unity可以基于该属性来优化物理系统的处理。将对象设置为静态后,Unity可以假设该对象不会在运行时移动,从而减少碰撞检测的开销。
  • 渲染优化:在某些情况下,渲染系统可能会基于该属性做出不同的优化决策,比如剔除(Culling)或灯光照射计算。
    然而,这些优化在运行时动态修改 isStatic 属性后,不一定会立刻重新计算或应用。例如,静态批处理通常不会因为在运行时改变 isStatic 而重新触发。

3. 编辑器中的静态优化

在编辑器中使用 StaticEditorFlags 来设置对象为静态时,Unity会在场景加载或构建时应用一系列静态优化,例如:

  • 静态批处理:减少绘制调用。
  • 光照贴图:预计算光照并烘焙到贴图中。
  • 导航网格:计算路径时不考虑静态对象的变化。
    这些优化通常在运行时不会因为修改 isStatic 而重新计算。

4. 小结

运行时修改 isStatic:可以改变对象的静态状态,可能会影响物理引擎和渲染系统的某些优化,但不会触发静态批处理或光照贴图等复杂的静态优化重新计算。
编辑器中的静态优化:通过 StaticEditorFlags 设置,在构建或场景加载时应用广泛的静态优化,但这些设置通常在运行时不再动态改变。
如果你希望在编辑器中批量设置对象为静态,以便在构建时获得最大化的性能优化,建议使用 GameObjectUtility.SetStaticEditorFlags 或在Inspector中手动设置静态标志。

第六章 本文总结

在Unity中将对象设置为静态,主要目的是为了提高性能。我们可以通过GameObject.isStatic和GameObjectUtility.SetStaticEditorFlags方法在编辑器中设置对象的静态属性。当然在运行时通过GameObject.isStatic修改静态属性,虽然不会触发静态优化,但可以在碰撞检测等场景中减少一部分开销。

第七章 学以致用

练习题 1:理论题

问题: 在Unity中,如何使用脚本动态设置一个对象的StaticEditorFlags?简要描述你需要完成的步骤,并编写一个脚本,使得名为"Environment"的GameObject对象被标记为静态物体,并且只开启光照贴图(LightmapStatic)和遮挡物(OccluderStatic)的静态标志。

目标:

  • 测试你对如何在脚本中使用GameObjectUtility.SetStaticEditorFlags的理解。
  • 测试你对静态标志的设置及其用途的掌握程度。

练习题 2:实践题

问题: 创建一个Unity场景,场景中包含两个GameObject对象,分别是House和Tree。使用Unity编辑器手动设置它们的静态属性:

  • House应该被设置为BatchingStatic和LightmapStatic。
  • Tree应该被设置为OccludeeStatic和NavigationStatic。
    接着,编写一个编辑器脚本,通过脚本验证这些对象的静态属性是否被正确设置。如果设置正确,在控制台输出相应的消息。

目标:

  • 测试你对在Unity编辑器中手动设置静态属性的熟悉程度。
  • 测试你对如何在脚本中获取和验证对象静态属性的理解与实践能力。

第八章 参考资料

  1. https://docs.unity3d.com/Manual/StaticObjects.html
  2. https://docs.unity3d.com/ScriptReference/GameObject-isStatic.html
  3. https://docs.unity3d.com/ScriptReference/GameObjectUtility.GetStaticEditorFlags.html
  4. https://discussions.unity.com/t/how-to-set-use-staticeditorflags-cant-seem-to-set-them-from-script/476886/13

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2057659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web服务器——————nginx篇

一.What is Web服务器 Web服务器介绍 Web服务器(Web Server)是指驻留于因特网上某种类型计算机的程序,该程序可以向Web浏览器(如Chrome、Firefox、Safari等)等客户端提供文档,也可以放置网站文件&#…

4-1-3 arduino驱动直流电机(电机专项教程)

4-1-3 arduino驱动直流电机(电机专项教程) 4-1-3 arduino驱动直流电机XY-2.5AD电机控制模块家用直流电源改装成项目制作电源示例程序效果演示 4-1-3 arduino驱动直流电机 Arduino控制直流有刷电机的话,通过H桥电路实现转向控制,以…

C语言——预处理

C语言编译步骤 预处理 编译 汇编 链接 预处理 概念: 预处理就是在源文件(如.c文件)编译之前,所进行的一部分预备操作,这部分操作是由预处理程序自动来完成;当源文件在编译时,编译器会自动调用预处理程序来…

ESP32神经网络初步使用

摘要 本文档描述了如何使用Python和TensorFlow训练一个简单的神经网络模型来预测正弦函数,并将其部署到ESP32微控制器上。 参考文章 使用Python和Arduino在ESP32上预测正弦函数 - Dapenson - 博客园 (cnblogs.com) 最简单体验TinyML、TensorFlow Lite——ESP32跑…

Android Studio修改默认.m2与Gradle user home缓存位置

Android Studio修改默认.m2与Gradle user home缓存位置 1、修改Gradle user home的方法: android studio配置默认.gradle路径_android studio gradle在哪-CSDN博客文章浏览阅读2k次。当android studio新建一个项目时候,默认的.gradle路径均认为是在c盘的…

若依搭建实践

若依要求版本 JDK>1.8 MySQL>5.7 Maven>3.0 Node >12 Redis >3 一、环境下载及安装 我本地JDK1.8 MySQL9.0.1 Maven3.5.4 Node 20.12.2 Redis 5.0.14.1 在若依官网下载需要的版本,目前若依支持版本有四个,我们根据需要选择对应的版本…

集合及数据结构第五节————ArrayList的介绍和应用

系列文章目录 集合及数据结构第五节————ArrayList的介绍和应用 ArrayList的介绍和应用 什么是ArrayLisArrayList使用简单的洗牌算法杨辉三角 文章目录 系列文章目录集合及数据结构第五节————ArrayList的介绍和应用 ArrayList的介绍和应用 一、ArrayList1.什么是Arra…

鸿蒙 使用 expandSafeArea 实现顶部沉浸式导航

1, 先看效果; // 设置顶部绘制延伸到状态栏.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP]) 2, 直接cv 粘贴代码 // xxx.ets Entry Component struct Example {build() {Column() {Row() {Text().fontSize(40).textAlign(Text…

2_foc转速环_电磁转矩方程与运动方程的传递函数

转速环里面包含有电流环在内,当外面给定转速时,系统通过控制iq来控制电磁转矩,从而电机开始转动。电机在转动的过程,传感器检测到机械角度会改变,也就是说电角度也会改变,由电角度在单位时间的变化&#xf…

【C++ 第十五章】map 和 set 的封装(封装红黑树)

1. map 和 set 的介绍 ⭐map 与 set 分别是STL中的两种序列式容器; 它们是一种树形数据结构的容器,且其的底层构造为一棵红黑树; 而在上一篇文章中提到,其实红黑树本身就是一棵二叉搜索树,是基于二叉搜索树的性质对其增加了平衡的属性来提高其综合性能 ⭐当然也…

ip地址冲突的原因及其解决方法是什么

在当今的信息化时代,网络已成为我们生活和工作中不可或缺的一部分。然而,随着网络设备数量的不断增加,网络管理中的问题也日益凸显,其中IP地址冲突便是常见问题之一。IP地址冲突不仅会导致网络通信不稳定,甚至可能使设…

详解栈和队列

目录: 1.栈 2.队列 一、 栈(Stack) 1.1 概念: 栈是一种特殊的线性表,只允许在固定的一端进行插入和删除元素的操作。进行插入元素的一端叫做栈顶,另一端叫做栈底。从数据结构的角度出发,栈中…

k8s-deployment控制器

k8s-deployment控制器 1、yaml文件标签学习-指定pod在哪台节点上创建 强制指定pod在指定节点上创建: --- apiVersion: apps/v1 kind: Deployment metadata:name: my-deployment spec:replicas: 3selector:matchLabels:app: web1template:metadata:labels:app: web1…

流媒体服务器二 3学习 librtmp 库的配置使用

librtmp 库是个啥? librtmp是一个开源的基于C语言的库,提供了一个连接RTMP服务器,发送和接收RTMP流的API。 它可以用来开发流媒体播放器,网络直播等应用。它的主要特点是快速、稳定和低延迟。 librtmp支持RTMP,RTMPS…

超越 RAG 基础:AI 应用的高级策略

作者:来自 Elastic Platform Team 我们最近与 Cohere 举办的线上活动深入探讨了检索增强生成 (Retrieval Augmented Genereation - RAG) 的世界,重点讨论了在概念验证阶段之后构建 RAG 应用程序的关键注意事项。我们的演讲者是 Elastic 的首席解决方案架…

使用 Python和 FFmpeg 批量截图视频到各自文件夹中

在这篇博客中,我们将创建一个简单的图形用户界面 (GUI) 工具,利用 wxPython 和 FFmpeg 来从视频文件中批量生成截图。这个工具能够让用户选择一个文件夹,遍历其中的所有视频文件,按照视频长度将其分为四等分,然后为每个…

鸿蒙HarmonyOS之使用ArkTs语言实现自定义Tab菜单栏分页主页面UI

一、效果 显示为3个Tab菜单栏,中间可以滑动 二、实现步骤 1、Index.ets 示例代码中用到的颜色、文字、图片等资源可以自行替换 import { Tab_1 } from ./Tab_1; import { Tab_2 } from ./Tab_2; import { Tab_3 } from ./Tab_3;//主页面 Entry Component stru…

Excel数字中间指定位置插入符号——以120120加*为例

设置单元格格式——自定义 更多阅读Excel数字中间指定位置插入符号_哔哩哔哩_bilibili

B码对时案例分享,基于RK3568J+Logos-2,让电力设备轻松实现“高精度授时”!

本文主要介绍瑞芯微RK3568J紫光同创Logos-2的B码对时案例,开发环境如下: Windows开发环境:Windows 7 64bit、Windows 10 64bit Pango Design Suite(PDS):PDS_2022.2-SP3 IRIG-B码对时典型应用 IRIG-B码对时可应用于继电保护装…

台球厅自动控制无人台球之智能开关-SAAS本地化及未来之窗行业应用跨平台架构

一、无人台球厅优点 1. 降低人力成本:无需雇佣大量员工,如收银员、服务员等,节省了工资、福利和管理成本。 2. 24 小时营业:不受人工营业时间限制,可以随时满足顾客的需求,增加营业时长和收入。 3. 便捷高…