mirror of
https://github.com/galacean/engine.git
synced 2026-05-22 08:26:12 +08:00
151 lines
5.2 KiB
Plaintext
151 lines
5.2 KiB
Plaintext
---
|
||
order: 2
|
||
title: 场景
|
||
type: 核心概念
|
||
label: Core
|
||
---
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/cbcc9725-811d-4203-a65d-b4a430083db3/image-20250124154359477.png" />
|
||
|
||
Scene 作为场景单元,可以方便的进行实体树管理,尤其是大型游戏场景。如: **scene1** 和 **scene2** 作为两个不同的场景,可以各自独立管理其拥有的 **Entity** 树,因此场景下的光照组件、渲染组件和物理组件之间也互相隔离,互不影响。我们可以同时渲染一个或多个 Scene,也可以在特定时机下根据项目逻辑动态切换当前 Scene。
|
||
|
||
从结构上每个 Engine 下可以包含一个和多个激活的场景(目前编辑器还不支持多个)。每个 Scene 可以有多个根实体。
|
||
|
||
## 编辑器使用
|
||
|
||
### 创建和切换
|
||
|
||
在 **[资产面板](/docs/assets/interface)** 右键(或资产面板右上角 + 号)创建场景,双击场景可以切换过去:
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/eef870a7-2630-4f74-8c0e-478696a553b0/2024-03-19%25252018.04.02.gif" />
|
||
|
||
### 环境光
|
||
|
||
详情请参照[环境光教程](/docs/graphics/light/ambient/) 和 [烘焙教程](/docs/graphics/light/bake/)。
|
||
|
||
### 背景
|
||
|
||
详情请参照[背景教程](/docs/graphics/background/background/)。
|
||
|
||
### 阴影
|
||
|
||
详情请参照[阴影教程](/docs/graphics/light/shadow/)。
|
||
|
||
### 雾化
|
||
|
||
可以给整个场景增加 **线性、指数、指数平方** 3 种雾化:
|
||
|
||
<Image src="https://gw.alipayobjects.com/zos/OasisHub/224fbc16-e60c-47ca-845b-5f7c09563c83/2024-03-19%25252018.08.23.gif" />
|
||
|
||
## 脚本使用
|
||
|
||
| 属性名称 | 解释 |
|
||
| :---------------------------------------- | :------- |
|
||
| [scenes](/apis/core/#SceneManager-scenes) | 场景列表 |
|
||
|
||
| 方法名称 | 解释 |
|
||
| :-------------------------------------------------- | :------- |
|
||
| [addScene](/apis/core/#SceneManager-addScene) | 添加场景 |
|
||
| [removeScene](/apis/core/#SceneManager-removeScene) | 移除场景 |
|
||
| [mergeScenes](/apis/core/#SceneManager-mergeScenes) | 合并场景 |
|
||
| [loadScene](/apis/core/#SceneManager-loadScene) | 加载场景 |
|
||
|
||
### 加载场景
|
||
|
||
如果想要加载 **Scene** 资产作为应用中的一个场景,可以使用 `engine.resourceManager.load` 传入 url 即可。
|
||
|
||
```typescript
|
||
const sceneUrl = "...";
|
||
|
||
engine.resourceManager.load({ type: AssetType.Scene, url: "..." }).then((scene) => {
|
||
engine.sceneManager.addScene(scene);
|
||
});
|
||
```
|
||
|
||
### 获取场景对象
|
||
|
||
通过调用 `engine.sceneManager.scenes` 可以获取当前引擎运行时激活的全部场景,也可以通过 `entity.scene` 获取对应 `entity` 从属的 `scene`。
|
||
|
||
```typescript
|
||
// 获取当前所有激活的场景
|
||
const scenes = engine.sceneManager.scenes;
|
||
|
||
// 获取节点属于的场景
|
||
const scene = entity.scene;
|
||
```
|
||
|
||
### 添加/移除 Scene
|
||
|
||
`engine.sceneManager.scenes` 是只读的,若需要添加和移除 **Scene** ,需要调用 `engine.sceneManager.addScene()` 或 `engine.sceneManager.removeScene()` ,**引擎支持同时渲染多个场景**。
|
||
|
||
```typescript
|
||
// 假设已经有两个场景
|
||
const scene1, scene2;
|
||
|
||
// 添加 场景1
|
||
engine.sceneManager.addScene(scene1);
|
||
|
||
// 添加 场景2
|
||
engine.sceneManager.addScene(scene1);
|
||
|
||
// 移除 场景2
|
||
engine.sceneManager.removeScene(scene2);
|
||
```
|
||
|
||
### 合并场景
|
||
|
||
可以使用 `engine.sceneManager.mergeScenes` 将 2 个场景进行合并为 1 个场景。
|
||
|
||
```typescript
|
||
// 假设已经有两个未激活的场景
|
||
const sourceScene, destScene;
|
||
|
||
// 将 sourceScene 合并到 destScene
|
||
engine.sceneManager.mergeScenes(sourceScene, destScene);
|
||
|
||
// 激活 destScene
|
||
engine.sceneManager.addScene(destScene);
|
||
```
|
||
|
||
### 销毁场景
|
||
|
||
调用 `scene.destroy()` 即可销毁场景,被销毁的场景也会自动从激活场景列表中移除。
|
||
|
||
### 实体树管理
|
||
|
||
| 方法名称 | 解释 |
|
||
| :-- | :-- |
|
||
| [createRootEntity](/apis/core/#Scene-createRootEntity) | 新创建的 _scene_ 默认没有根实体,需要手动创建 |
|
||
| [addRootEntity](/apis/core/#Scene-addRootEntity) | 可以直接新建实体,或者添加已经存在的实体 |
|
||
| [removeRootEntity](/apis/core/#Scene-removeRootEntity) | 删除根实体 |
|
||
| [getRootEntity](/apis/core/#Scene-getRootEntity) | 查找根实体,可以拿到全部根实体,或者单独的某个实体对象。注意,全部实体是只读数组,不能改变长度和顺序 |
|
||
|
||
```typescript
|
||
const engine = await WebGLEngine.create({ canvas: "demo" });
|
||
const scene = engine.sceneManager.scenes[0];
|
||
|
||
// 创建根实体
|
||
const rootEntity = scene.createRootEntity();
|
||
|
||
// 添加实体到场景
|
||
scene.addRootEntity(rootEntity);
|
||
|
||
// 删除根实体
|
||
scene.removeRootEntity(rootEntity);
|
||
|
||
// 查找根实体
|
||
const allEntities: Readonly<Entity[]> = scene.rootEntities;
|
||
|
||
const entity2 = scene.getRootEntity(2);
|
||
```
|
||
|
||
### 其他
|
||
|
||
需要注意的是,当我们熟悉了 [Engine](/apis/core/#Engine) 和 [Scene](/apis/core/#Scene) 之后,如果想要将渲染画面输出到屏幕上或者进行离屏渲染,我们还得确保当前 _scene_ 的实体树上挂载了 [Camera](/apis/core/#Camera),挂载相机的方法如下:
|
||
|
||
```typescript
|
||
const cameraEntity = rootEntity.createChild("camera");
|
||
|
||
cameraEntity.addComponent(Camera);
|
||
```
|