2.3 Unity API 常用类


文档摘要

2.3 Unity API 常用类 (GameObject, Transform, Component, Time) 二、C# 脚本编程 2.3 Unity API 常用类 (GameObject, Transform, Component, Time) 在 Unity3D 游戏开发中,C# 脚本扮演着至关重要的角色,它是连接游戏逻辑与 Unity 引擎的桥梁。而要高效地进行 C# 脚本编程,深入理解 Unity 提供的应用程序编程接口 (API) 是必不可少的。本章节将聚焦于 Unity API 中最常用且核心的四个类: 、 、 和 。掌握这四个类,你将能够构建出复杂的游戏世界,控制游戏对象的行为,并实现各种游戏机制。 2.3.

2.3 Unity API 常用类 (GameObject, Transform, Component, Time)

二、C# 脚本编程

2.3 Unity API 常用类 (GameObject, Transform, Component, Time)

在 Unity3D 游戏开发中,C# 脚本扮演着至关重要的角色,它是连接游戏逻辑与 Unity 引擎的桥梁。而要高效地进行 C# 脚本编程,深入理解 Unity 提供的应用程序编程接口 (API) 是必不可少的。本章节将聚焦于 Unity API 中最常用且核心的四个类:GameObjectTransformComponentTime。掌握这四个类,你将能够构建出复杂的游戏世界,控制游戏对象的行为,并实现各种游戏机制。

2.3.1 GameObject:游戏世界的基石

GameObject 是 Unity 场景中最基础、也是最重要的类之一。你可以将它视为游戏世界中的实体对象。无论是角色、道具、场景物件,甚至是空物体,都是 GameObject 的实例。理解 GameObject 的概念,是理解 Unity 场景结构和对象组织方式的关键。

2.3.1.1 GameObject 的作用和特性
  • 场景中的实体: GameObject 代表着场景中存在的任何物体,它可以是看得见的模型、听得见的声音源,也可以是仅仅用于逻辑控制的空对象。

  • 容器: GameObject 本身并不具备特定的功能,它的强大之处在于它可以作为 组件 (Component) 的容器。通过附加不同的组件,GameObject 可以拥有各种各样的行为和属性。

  • 层级结构: GameObject 可以通过父子关系构建场景的层级结构。这种层级结构对于组织和管理场景中的对象,以及实现对象间的相对运动至关重要。

  • 标识符: 每个 GameObject 都有一个名称 (Name)、标签 (Tag) 和层 (Layer),用于在脚本中识别和管理不同的游戏对象。

  • 生命周期管理: GameObject 的创建、激活、禁用和销毁都受到 Unity 引擎的管理,了解其生命周期对于编写高效且健壮的游戏逻辑至关重要。

2.3.1.2 GameObject 的常用 API

在 C# 脚本中,我们可以通过 GameObject 类提供的 API 来操作和管理游戏对象。以下是一些常用的 API 及其详细说明和代码示例:

1. 名称 (Name)

  • name 属性 (string): 获取或设置 GameObject 的名称。名称主要用于在编辑器和脚本中识别对象,不会影响游戏运行逻辑。
// 获取当前 GameObject 的名称 string objectName = gameObject.name; Debug.Log("当前游戏对象的名称是: " + objectName); // 设置当前 GameObject 的名称 gameObject.name = "PlayerCharacter"; Debug.Log("游戏对象名称已更改为: " + gameObject.name);

2. 标签 (Tag)

  • tag 属性 (string): 获取或设置 GameObject 的标签。标签是一种轻量级的标识符,用于在运行时快速识别一类游戏对象。Unity 预定义了一些常用标签,你也可以自定义标签。
// 获取当前 GameObject 的标签 string objectTag = gameObject.tag; Debug.Log("当前游戏对象的标签是: " + objectTag); // 设置当前 GameObject 的标签为 "Enemy" gameObject.tag = "Enemy"; // 检查 GameObject 是否拥有特定标签 if (gameObject.CompareTag("Player")) { Debug.Log("这是一个玩家对象"); } else if (gameObject.CompareTag("Enemy")) { Debug.Log("这是一个敌人对象"); }

3. 层 (Layer)

  • layer 属性 (int): 获取或设置 GameObject 所属的层。层主要用于控制渲染顺序、碰撞检测以及光照效果。Unity 提供了 32 个层,可以根据项目需求进行配置。
// 获取当前 GameObject 的层级索引 int objectLayerIndex = gameObject.layer; Debug.Log("当前游戏对象的层级索引是: " + objectLayerIndex); // 获取当前 GameObject 的层级名称 string objectLayerName = LayerMask.LayerToName(gameObject.layer); Debug.Log("当前游戏对象的层级名称是: " + objectLayerName); // 设置当前 GameObject 的层级为 "Ignore Raycast" 层 (假设该层索引为 2) gameObject.layer = LayerMask.NameToLayer("Ignore Raycast"); // 使用 LayerMask 进行层级检测 int layerMask = 1 << LayerMask.NameToLayer("Ground"); // 创建一个只包含 "Ground" 层的 LayerMask if ((layerMask & gameObject.layer) != 0) { Debug.Log("游戏对象在 Ground 层"); }

4. 激活状态 (Active State)

  • activeSelf 属性 (bool): 获取或设置 GameObject 自身是否激活。即使父对象未激活,activeSelf 为 true 的对象也可能不显示或不参与游戏逻辑。

  • activeInHierarchy 属性 (bool): 获取 GameObject 在层级结构中是否处于激活状态。只有当自身和所有父对象都激活时,activeInHierarchy 才为 true。

// 检查 GameObject 自身是否激活 if (gameObject.activeSelf) { Debug.Log("GameObject 自身处于激活状态"); } else { Debug.Log("GameObject 自身处于禁用状态"); } // 检查 GameObject 在层级结构中是否激活 if (gameObject.activeInHierarchy) { Debug.Log("GameObject 在层级结构中处于激活状态"); } else { Debug.Log("GameObject 在层级结构中处于禁用状态"); } // 激活 GameObject gameObject.SetActive(true); // 禁用 GameObject gameObject.SetActive(false);

5. 组件操作

  • GetComponent<T>() 方法: 获取附加到 GameObject 的指定类型的组件。如果不存在该组件,则返回 null
// 获取 Rigidbody 组件 Rigidbody rb = GetComponent<Rigidbody>(); if (rb != null) { Debug.Log("找到了 Rigidbody 组件"); // 可以通过 rb 对象访问 Rigidbody 组件的属性和方法 rb.useGravity = false; // 关闭重力 } else { Debug.Log("未找到 Rigidbody 组件"); } // 获取 Renderer 组件 Renderer renderer = GetComponent<Renderer>(); if (renderer != null) { Debug.Log("找到了 Renderer 组件"); renderer.material.color = Color.red; // 将材质颜色设置为红色 }
  • AddComponent<T>() 方法: 动态地为 GameObject 添加指定类型的组件。返回新添加的组件实例。
// 添加 Rigidbody 组件 Rigidbody newRigidbody = gameObject.AddComponent<Rigidbody>(); Debug.Log("成功添加 Rigidbody 组件"); newRigidbody.mass = 10f; // 设置刚体的质量 // 添加 自定义脚本组件 (假设脚本名为 "MyScript") MyScript myScript = gameObject.AddComponent<MyScript>(); Debug.Log("成功添加 MyScript 组件"); myScript.speed = 5f; // 设置 MyScript 组件中的 speed 变量
  • GetComponents<T>() 方法: 获取附加到 GameObject 的所有指定类型的组件,返回一个组件数组。
// 获取所有 Renderer 组件 Renderer[] renderers = GetComponents<Renderer>(); Debug.Log("找到 " + renderers.Length + " 个 Renderer 组件"); foreach (Renderer r in renderers) { r.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; // 关闭所有 Renderer 组件的阴影投射 }
  • Destroy(Component component)Destroy(GameObject targetObject) 方法: 销毁指定的组件或 GameObject。需要注意的是,Destroy 方法只是标记对象为销毁,实际销毁会延迟到帧末尾。可以使用 DestroyImmediate 方法立即销毁,但通常不推荐,因为它可能导致性能问题。
// 获取 Rigidbody 组件 Rigidbody rbToDestroy = GetComponent<Rigidbody>(); if (rbToDestroy != null) { Destroy(rbToDestroy); // 销毁 Rigidbody 组件 Debug.Log("Rigidbody 组件已被标记为销毁"); } // 销毁当前 GameObject Destroy(gameObject); Debug.Log("GameObject 已被标记为销毁");

6. 查找 GameObject

  • FindGameObjectWithTag(string tag) 静态方法: 在场景中查找第一个拥有指定标签的 GameObject。如果找到,返回该 GameObject;否则返回 null
// 查找标签为 "Player" 的 GameObject GameObject playerObject = GameObject.FindGameObjectWithTag("Player"); if (playerObject != null) { Debug.Log("找到了玩家对象: " + playerObject.name); // 可以对 playerObject 进行操作 } else { Debug.LogError("未找到标签为 'Player' 的游戏对象"); }
  • Find(string name) 静态方法: 在场景中按名称查找 GameObject (包括层级结构中的子对象)。 搜索是广度优先的,效率可能较低,不推荐频繁使用,尤其是在性能敏感的代码中。
// 查找名为 "Enemy_01" 的 GameObject GameObject enemyObject = GameObject.Find("Enemy_01"); if (enemyObject != null) { Debug.Log("找到了敌人对象: " + enemyObject.name); } else { Debug.LogError("未找到名为 'Enemy_01' 的游戏对象"); }
2.3.1.3 GameObject 的代码实践示例
using UnityEngine; public class GameObjectExample : MonoBehaviour { void Start() { // 创建一个新的空 GameObject GameObject newGameObject = new GameObject("MyNewObject"); // 设置新 GameObject 的标签和层级 newGameObject.tag = "InteractiveObject"; newGameObject.layer = LayerMask.NameToLayer("Default"); // 获取新 GameObject 的 Transform 组件 Transform newTransform = newGameObject.transform; // 设置新 GameObject 的位置 newTransform.position = new Vector3(0, 1, 0); // 为新 GameObject 添加一个 MeshRenderer 组件,使其可见 (需要手动设置 Mesh 和 Material) MeshRenderer meshRenderer = newGameObject.AddComponent<MeshRenderer>(); // 为新 GameObject 添加一个自定义脚本组件 (假设脚本名为 "ObjectBehavior") ObjectBehavior behaviorScript = newGameObject.AddComponent<ObjectBehavior>(); behaviorScript.speed = 2.5f; // 设置脚本组件中的 speed 变量 Debug.Log("成功创建并配置新的 GameObject: " + newGameObject.name); } } // 假设的自定义脚本组件 public class ObjectBehavior : MonoBehaviour { public float speed = 1f; void Update() { // 在每一帧中移动 GameObject transform.Translate(Vector3.forward * speed * Time.deltaTime); } }
2.3.1.4 GameObject 与其他类的关系
  • GameObject 与 Transform: 每个 GameObject 都有一个关联的 Transform 组件,用于控制其在场景中的位置、旋转和缩放。TransformGameObject 的核心组成部分,负责空间变换。

  • GameObject 与 Component: GameObject 可以包含多个 Component 组件。组件赋予 GameObject 各种功能和行为。Transform 本身也是一种组件。

  • Component 与 MonoBehaviour: MonoBehaviour 是 Unity 中所有脚本组件的基类。我们自定义的脚本通常都继承自 MonoBehaviour。因此,自定义脚本也是一种 Component

2.3.2 Transform:掌控空间变换

Transform 组件是 Unity 中用于控制 GameObject 在 3D 空间中位置、旋转和缩放的关键组件。每个 GameObject 都有且只有一个 Transform 组件。理解 Transform 的工作原理和 API,是实现对象移动、旋转、缩放以及构建层级结构的基础。

2.3.2.1 Transform 的作用和特性
  • 位置 (Position): 定义 GameObject 在世界坐标系中的位置。

  • 旋转 (Rotation): 定义 GameObject 在世界坐标系中的旋转角度。可以使用欧拉角 (Euler angles) 或四元数 (Quaternion) 表示。

  • 缩放 (Scale): 定义 GameObject 在局部坐标系中的缩放比例。

  • 父子关系 (Parent-Child Hierarchy): 通过 Transform 组件可以建立 GameObject 之间的父子关系,子对象的变换会受到父对象的影响。

  • 局部坐标系和世界坐标系: Transform 组件提供了局部坐标系和世界坐标系的概念,理解两者之间的区别对于精确控制对象变换至关重要。

2.3.2.2 Transform 的常用 API

1. 位置 (Position)

  • position 属性 (Vector3): 获取或设置 GameObject世界坐标系 中的位置。
// 获取当前 GameObject 的世界坐标位置 Vector3 worldPosition = transform.position; Debug.Log("世界坐标位置: " + worldPosition); // 设置当前 GameObject 的世界坐标位置 transform.position = new Vector3(5, 0, 5);
  • localPosition 属性 (Vector3): 获取或设置 GameObject局部坐标系 (相对于父对象) 中的位置。如果没有父对象,则局部坐标系与世界坐标系重合。
// 获取当前 GameObject 的局部坐标位置 Vector3 localPosition = transform.localPosition; Debug.Log("局部坐标位置: " + localPosition); // 设置当前 GameObject 的局部坐标位置 transform.localPosition = new Vector3(1, 2, 0);

2. 旋转 (Rotation)

  • rotation 属性 (Quaternion): 获取或设置 GameObject世界坐标系 中的旋转,使用 四元数 (Quaternion) 表示。 四元数是一种更高效且避免万向节锁的旋转表示方法。
// 获取当前 GameObject 的世界坐标旋转 (四元数) Quaternion worldRotationQuaternion = transform.rotation; Debug.Log("世界坐标旋转 (四元数): " + worldRotationQuaternion); // 设置当前 GameObject 的世界坐标旋转 (四元数) transform.rotation = Quaternion.Euler(0, 45, 0); // 使用欧拉角转换为四元数
  • localRotation 属性 (Quaternion): 获取或设置 GameObject局部坐标系 (相对于父对象) 中的旋转,使用 四元数 (Quaternion) 表示。
// 获取当前 GameObject 的局部坐标旋转 (四元数) Quaternion localRotationQuaternion = transform.localRotation; Debug.Log("局部坐标旋转 (四元数): " + localRotationQuaternion); // 设置当前 GameObject 的局部坐标旋转 (四元数) transform.localRotation = Quaternion.Euler(30, 0, 0);
  • eulerAngles 属性 (Vector3): 获取或设置 GameObject世界坐标系 中的旋转,使用 欧拉角 (Euler angles - X, Y, Z 轴旋转角度) 表示。 欧拉角更容易理解,但在进行复杂旋转时可能出现万向节锁问题。
// 获取当前 GameObject 的世界坐标旋转 (欧拉角) Vector3 worldRotationEuler = transform.eulerAngles; Debug.Log("世界坐标旋转 (欧拉角): " + worldRotationEuler); // 设置当前 GameObject 的世界坐标旋转 (欧拉角) transform.eulerAngles = new Vector3(0, 90, 0); // 绕 Y 轴旋转 90 度
  • localEulerAngles 属性 (Vector3): 获取或设置 GameObject局部坐标系 中的旋转,使用 欧拉角 (Euler angles) 表示。
// 获取当前 GameObject 的局部坐标旋转 (欧拉角) Vector3 localRotationEuler = transform.localEulerAngles; Debug.Log("局部坐标旋转 (欧拉角): " + localRotationEuler); // 设置当前 GameObject 的局部坐标旋转 (欧拉角) transform.localEulerAngles = new Vector3(0, 0, 45); // 绕 Z 轴旋转 45 度

3. 缩放 (Scale)

  • localScale 属性 (Vector3): 获取或设置 GameObject局部坐标系 中的缩放比例。
// 获取当前 GameObject 的局部缩放 Vector3 localScale = transform.localScale; Debug.Log("局部缩放: " + localScale); // 设置当前 GameObject 的局部缩放 transform.localScale = new Vector3(2, 2, 2); // 放大两倍

4. 父子关系 (Parenting)

  • parent 属性 (Transform): 获取或设置 GameObject 的父 Transform 组件。设置为 null 表示取消父对象。
// 获取当前 GameObject 的父 Transform Transform parentTransform = transform.parent; if (parentTransform != null) { Debug.Log("父对象名称: " + parentTransform.gameObject.name); } else { Debug.Log("没有父对象"); } // 设置当前 GameObject 的父对象 (假设 parentObject 是一个 GameObject) Transform newParentTransform = parentObject.transform; transform.parent = newParentTransform; Debug.Log("已设置父对象为: " + parentObject.name); // 取消父对象 transform.parent = null; Debug.Log("已取消父对象");
  • SetParent(Transform parent) 方法: 设置 GameObject 的父 Transform 组件。可以选择是否保持世界坐标。
// 设置父对象,保持世界坐标 transform.SetParent(newParentTransform, true); // 第二个参数为 true 表示保持世界坐标 // 设置父对象,不保持世界坐标 (默认行为) transform.SetParent(newParentTransform); // 等同于 transform.SetParent(newParentTransform, false);

5. 移动、旋转和缩放方法

  • Translate(Vector3 translation, Space relativeTo = Space.Self) 方法: 在指定的坐标空间中移动 GameObjectSpace.Self 表示局部坐标系,Space.World 表示世界坐标系。
// 在局部坐标系中向前移动 1 个单位 transform.Translate(Vector3.forward * Time.deltaTime); // 帧率独立移动 // 在世界坐标系中向右移动 0.5 个单位 transform.Translate(Vector3.right * 0.5f, Space.World);
  • Rotate(Vector3 eulerAngles, Space relativeTo = Space.Self) 方法: 在指定的坐标空间中旋转 GameObject,使用欧拉角表示旋转角度。
// 在局部坐标系中绕 Y 轴旋转 1 度 transform.Rotate(Vector3.up * 1f * Time.deltaTime); // 在世界坐标系中绕 Z 轴旋转 45 度 transform.Rotate(Vector3.forward * 45f, Space.World);
  • LookAt(Transform target, Vector3? worldUp = null) 方法: 使 GameObject 的 Z 轴指向目标对象。可以指定世界坐标系中的 Up 向量。
// 使当前 GameObject 指向目标对象 (targetTransform) transform.LookAt(targetTransform); // 使当前 GameObject 指向目标位置 (targetPosition),并指定世界 Up 向量为 Vector3.up transform.LookAt(targetPosition, Vector3.up);
2.3.2.3 Transform 的代码实践示例
using UnityEngine; public class TransformExample : MonoBehaviour { public Transform targetObject; // 在 Inspector 面板中拖拽目标对象 public float moveSpeed = 5f; public float rotateSpeed = 100f; void Update() { // 移动到目标对象 float step = moveSpeed * Time.deltaTime; transform.position = Vector3.MoveTowards(transform.position, targetObject.position, step); // 旋转朝向目标对象 Vector3 targetDirection = targetObject.position - transform.position; Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, rotateSpeed * Time.deltaTime, 0.0f); transform.rotation = Quaternion.LookRotation(newDirection); // 缩放 (每秒放大 0.1 倍) transform.localScale += Vector3.one * 0.1f * Time.deltaTime; } }
2.3.2.4 Transform 与其他类的关系
  • Transform 与 GameObject: Transform 组件依附于 GameObject 存在,是 GameObject 的一部分,负责其空间变换。

  • Transform 与 Transform (Parenting): Transform 可以拥有一个父 Transform,形成层级结构。子 Transform 的变换会受到父 Transform 的影响。

  • Transform 与 Vector3/Quaternion: Transform 使用 Vector3 结构体存储位置、欧拉角和缩放信息,使用 Quaternion 结构体存储旋转信息。

2.3.3 Component:赋予行为和功能

Component 是 Unity 中实现 组件化 编程的核心概念。它是所有附加到 GameObject 的功能模块的基类。通过组合不同的组件,我们可以赋予 GameObject 各种各样的行为和属性,例如渲染、物理、动画、音频以及自定义逻辑等。

2.3.3.1 Component 的作用和特性
  • 功能模块化: Component 将复杂的游戏对象分解为多个独立的、可重用的功能模块。

  • 组合性: 通过添加和移除组件,可以灵活地组合和修改 GameObject 的功能。

  • 继承性: Unity 提供的各种内置组件 (如 Renderer, Collider, Rigidbody) 以及我们自定义的脚本组件都继承自 Component 类。

  • 依附于 GameObject: Component 必须依附于 GameObject 才能存在和工作。一个 GameObject 可以拥有多个 Component

  • 消息传递: Component 可以通过 Unity 的消息系统 (例如 SendMessage, BroadcastMessage) 与其他组件或脚本进行通信。

2.3.3.2 Component 的常用 API (基于 MonoBehaviour)

由于我们自定义的脚本组件通常继承自 MonoBehaviour (而 MonoBehaviour 又继承自 Component),所以这里主要介绍 MonoBehaviour 中常用的 API,这些 API 实际上也是 Component 类提供的 (或扩展的)。

1. GameObject 访问

  • gameObject 属性 (GameObject): 获取当前组件所依附的 GameObject 实例。
// 在组件脚本中获取依附的 GameObject GameObject currentGameObject = gameObject; Debug.Log("当前组件依附的 GameObject 名称: " + currentGameObject.name);

2. Transform 访问

  • transform 属性 (Transform): 获取当前组件所依附的 GameObjectTransform 组件。这是一个常用的快捷方式,因为大多数组件都需要访问 Transform 来进行位置、旋转和缩放操作。
// 在组件脚本中获取依附 GameObject 的 Transform 组件 Transform currentTransform = transform; Debug.Log("当前组件依附 GameObject 的 Transform 组件位置: " + currentTransform.position);

3. 组件启用/禁用

  • enabled 属性 (bool): 获取或设置组件是否启用。禁用组件会使其停止执行 Update, FixedUpdate, LateUpdate 等生命周期函数,但组件仍然存在于 GameObject 上。
// 检查组件是否启用 if (enabled) { Debug.Log("组件已启用"); } else { Debug.Log("组件已禁用"); } // 禁用当前组件 enabled = false; // 启用当前组件 enabled = true;

4. 获取其他组件

  • GetComponent<T>(), GetComponents<T>(), GetComponentInChildren<T>(), GetComponentInParent<T>() 方法: 这些方法与 GameObject 类中同名的方法功能相同,用于在当前组件所依附的 GameObject 或其子对象/父对象上查找其他组件。
// 在当前 GameObject 上获取 Rigidbody 组件 Rigidbody rb = GetComponent<Rigidbody>(); // 在当前 GameObject 的所有子对象中获取 Renderer 组件 Renderer[] childRenderers = GetComponentsInChildren<Renderer>(); // 在当前 GameObject 的父对象中获取 AudioSource 组件 AudioSource parentAudioSource = GetComponentInParent<AudioSource>();

5. 组件类型信息

  • GetType() 方法: 获取当前组件的运行时类型。
// 获取当前组件的类型 System.Type componentType = GetType(); Debug.Log("当前组件的类型是: " + componentType.FullName); // 输出完整的类型名称 (包括命名空间) Debug.Log("当前组件的类型名称是: " + componentType.Name); // 输出类型名称 (不包括命名空间)
2.3.3.3 Component 的代码实践示例
using UnityEngine; public class ComponentExample : MonoBehaviour { void Start() { // 获取当前 GameObject 的 Renderer 组件 Renderer renderer = GetComponent<Renderer>(); if (renderer != null) { // 禁用 Renderer 组件 renderer.enabled = false; Debug.Log("Renderer 组件已禁用"); } // 获取当前 GameObject 的 Transform 组件 Transform currentTransform = transform; Debug.Log("当前 GameObject 的位置: " + currentTransform.position); // 添加一个新的 Light 组件 Light newLight = gameObject.AddComponent<Light>(); newLight.type = LightType.Point; newLight.color = Color.yellow; Debug.Log("成功添加 Point Light 组件"); } void Update() { // 每帧旋转当前 GameObject transform.Rotate(Vector3.up * 30f * Time.deltaTime); } }
2.3.3.4 Component 与其他类的关系
  • Component 与 GameObject: Component 必须依附于 GameObject,通过 gameObject 属性可以访问到依附的 GameObject

  • Component 与 MonoBehaviour: 自定义脚本组件通常继承自 MonoBehaviourMonoBehaviour 本身也是一种 Component

  • Component 与其他内置组件: Unity 提供了各种内置组件,例如 Renderer (用于渲染),Collider (用于碰撞检测),Rigidbody (用于物理模拟),AudioSource (用于音频播放),Light (用于灯光) 等,它们都继承自 Component

  • Component 与 Transform: Component 可以通过 gameObject.transform 访问到依附 GameObjectTransform 组件。

2.3.4 Time:掌控时间流逝

Time 类是一个静态类,提供了访问时间相关信息的接口,用于实现帧率独立的游戏逻辑、控制游戏时间流速以及进行各种时间相关的操作。理解 Time 类对于编写流畅且稳定的游戏至关重要。

2.3.4.1 Time 的作用和特性
  • 帧率独立性: Time 类提供的 deltaTime 属性可以帮助我们实现帧率独立的游戏逻辑,确保游戏在不同帧率下运行速度一致。

  • 游戏时间控制: Time 类可以获取游戏运行时间、帧数等信息,也可以控制游戏时间缩放,实现慢动作、快进等效果。

  • 物理更新控制: Time 类提供了与物理引擎更新相关的属性,例如 fixedDeltaTime,用于控制物理模拟的步长。

  • 性能优化: 合理使用 Time 类可以帮助我们优化游戏性能,例如避免在每一帧中进行不必要的时间计算。

2.3.4.2 Time 的常用 API

1. 帧率相关

  • deltaTime 属性 (float): 自上一帧完成到现在所用的时间 (以秒为单位)。这是实现帧率独立运动和动画的关键。
// 帧率独立移动示例 float speed = 5f; transform.Translate(Vector3.forward * speed * Time.deltaTime); // 无论帧率高低,每秒移动速度都接近 5 个单位 // 帧率独立旋转示例 float rotationSpeed = 90f; // 每秒旋转 90 度 transform.Rotate(Vector3.up * rotationSpeed * Time.deltaTime);

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U