RenderingServer.camera_create
最后同步日期:2026-04-15 | Godot 官方原文 — RenderingServer.camera_create
RenderingServer.camera_create
定义
RenderingServer.camera_create() 是底层渲染服务器提供的方法,用于在渲染服务器层面创建一个新的摄像机资源,并返回一个摄像机 ID(Rid)。
你可以把渲染服务器想象成"幕后舞台管理员"。普通开发中我们用的是 Camera3D 节点——它就像"演员",放在场景树上就能看到。而 RenderingServer.camera_create() 则是直接跟"舞台管理员"打交道,绕过节点系统,在最底层创建一个摄像机。这种方式性能更高、控制更精细,但代码也更复杂,通常只在需要高度自定义渲染管线时才使用。
创建出来的摄像机需要通过其他 RenderingServer 方法(如 camera_set_perspective、camera_set_transform)来配置参数,然后挂载到某个视口(viewport)上才能生效。
函数签名
public static Rid CameraCreate()func camera_create() -> RID参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| — | — | — | 此函数不接受任何参数 |
返回值
类型: Rid(资源 ID)
返回新创建的摄像机的 RID(Resource ID)。这个 RID 就像摄像机的"身份证号",后续所有对这个摄像机的操作(设置投影、设置位置、挂载视口等)都需要用到它。
代码示例
基础用法:创建并配置一个透视摄像机
using Godot;
public partial class CustomCameraDemo : Node
{
private Rid _cameraRid;
private Rid _viewportRid;
public override void _Ready()
{
// 1. 获取主视口的 RID
_viewportRid = GetViewport().GetViewportRid();
// 2. 在渲染服务器层面创建一个摄像机
_cameraRid = RenderingServer.CameraCreate();
// 3. 设置为透视投影(视场角 70 度,近裁面 0.05,远裁面 100)
RenderingServer.CameraSetPerspective(_cameraRid, fov: 70f, znear: 0.05f, zfar: 100f);
// 4. 设置摄像机的位置和朝向
var transform = new Transform3D(
basis: Basis.Identity,
origin: new Vector3(0, 5, 10)
);
// 让摄像机朝向原点
transform = transform.LookingAt(Vector3.Zero, Vector3.Up);
RenderingServer.CameraSetTransform(_cameraRid, transform);
// 5. 把摄像机挂载到视口上
RenderingServer.ViewportAttachCamera(_viewportRid, _cameraRid);
GD.Print("自定义摄像机创建完成!RID: ", _cameraRid);
// 运行结果: 自定义摄像机创建完成!RID: RID(0, 1)
}
public override void _ExitTree()
{
// 退出场景时释放摄像机资源,防止内存泄漏
RenderingServer.FreeRid(_cameraRid);
}
}extends Node
var _camera_rid: RID
var _viewport_rid: RID
func _ready():
# 1. 获取主视口的 RID
_viewport_rid = get_viewport().get_viewport_rid()
# 2. 在渲染服务器层面创建一个摄像机
_camera_rid = RenderingServer.camera_create()
# 3. 设置为透视投影(视场角 70 度,近裁面 0.05,远裁面 100)
RenderingServer.camera_set_perspective(_camera_rid, 70.0, 0.05, 100.0)
# 4. 设置摄像机的位置和朝向
var transform = Transform3D(Basis.IDENTITY, Vector3(0, 5, 10))
# 让摄像机朝向原点
transform = transform.looking_at(Vector3.ZERO, Vector3.UP)
RenderingServer.camera_set_transform(_camera_rid, transform)
# 5. 把摄像机挂载到视口上
RenderingServer.viewport_attach_camera(_viewport_rid, _camera_rid)
print("自定义摄像机创建完成!RID: ", _camera_rid)
# 运行结果: 自定义摄像机创建完成!RID: RID(0, 1)
func _exit_tree():
# 退出场景时释放摄像机资源,防止内存泄漏
RenderingServer.free_rid(_camera_rid)实际场景:小地图摄像机
using Godot;
/// <summary>
/// 使用 RenderingServer 创建一个俯视小地图摄像机,
/// 渲染到 SubViewport 上供 UI 纹理使用。
/// </summary>
public partial class MinimapCamera : Node
{
private Rid _minimapCameraRid;
[Export] public SubViewport MinimapViewport { get; set; }
public override void _Ready()
{
if (MinimapViewport == null)
{
GD.PrintErr("请在编辑器中指定 MinimapViewport!");
return;
}
var viewportRid = MinimapViewport.GetViewportRid();
// 创建小地图专用摄像机
_minimapCameraRid = RenderingServer.CameraCreate();
// 使用正交投影,适合俯视小地图(上方 50 单位高度,向下看)
RenderingServer.CameraSetOrthogonal(
_minimapCameraRid,
size: 30f,
znear: 0.05f,
zfar: 100f
);
// 设置俯视角度
var camTransform = new Transform3D(
basis: Basis.Identity,
origin: new Vector3(0, 50, 0)
);
camTransform = camTransform.LookingAt(Vector3.Zero, Vector3.Forward);
RenderingServer.CameraSetTransform(_minimapCameraRid, camTransform);
// 挂载到小地图视口
RenderingServer.ViewportAttachCamera(viewportRid, _minimapCameraRid);
GD.Print("小地图摄像机已就绪");
}
/// <summary>
/// 让小地图摄像机跟随目标位置
/// </summary>
public void FollowTarget(Vector3 targetPosition)
{
var newTransform = new Transform3D(
basis: Basis.Identity,
origin: targetPosition + new Vector3(0, 50, 0)
);
newTransform = newTransform.LookingAt(targetPosition, Vector3.Forward);
RenderingServer.CameraSetTransform(_minimapCameraRid, newTransform);
}
public override void _ExitTree()
{
RenderingServer.FreeRid(_minimapCameraRid);
}
}extends Node
## 使用 RenderingServer 创建一个俯视小地图摄像机,
## 渲染到 SubViewport 上供 UI 纹理使用。
@export var minimap_viewport: SubViewport
var _minimap_camera_rid: RID
func _ready():
if minimap_viewport == null:
push_error("请在编辑器中指定 minimap_viewport!")
return
var viewport_rid = minimap_viewport.get_viewport_rid()
# 创建小地图专用摄像机
_minimap_camera_rid = RenderingServer.camera_create()
# 使用正交投影,适合俯视小地图(上方 50 单位高度,向下看)
RenderingServer.camera_set_orthogonal(
_minimap_camera_rid,
30.0, # size
0.05, # znear
100.0 # zfar
)
# 设置俯视角度
var cam_transform = Transform3D(Basis.IDENTITY, Vector3(0, 50, 0))
cam_transform = cam_transform.looking_at(Vector3.ZERO, Vector3.FORWARD)
RenderingServer.camera_set_transform(_minimap_camera_rid, cam_transform)
# 挂载到小地图视口
RenderingServer.viewport_attach_camera(viewport_rid, _minimap_camera_rid)
print("小地图摄像机已就绪")
## 让小地图摄像机跟随目标位置
func follow_target(target_position: Vector3) -> void:
var new_transform = Transform3D(
Basis.IDENTITY,
target_position + Vector3(0, 50, 0)
)
new_transform = new_transform.looking_at(target_position, Vector3.FORWARD)
RenderingServer.camera_set_transform(_minimap_camera_rid, new_transform)
func _exit_tree():
RenderingServer.free_rid(_minimap_camera_rid)进阶用法:动态切换摄像机投影模式
using Godot;
/// <summary>
/// 演示在运行时动态切换透视投影和正交投影。
/// 比如策略游戏中的"缩放时切换到正交视角"效果。
/// </summary>
public partial class DynamicCameraProjection : Node3D
{
private Rid _cameraRid;
private Rid _viewportRid;
private bool _isPerspective = true;
[Export] public float ExPerspectiveFov = 70f;
[Export] public float ExOrthogonalSize = 20f;
[Export] public float ExNear = 0.05f;
[Export] public float ExFar = 500f;
public override void _Ready()
{
_viewportRid = GetViewport().GetViewportRid();
_cameraRid = RenderingServer.CameraCreate();
SetPerspective();
var transform = GlobalTransform;
RenderingServer.CameraSetTransform(_cameraRid, transform);
RenderingServer.ViewportAttachCamera(_viewportRid, _cameraRid);
}
public override void _UnhandledInput(InputEvent ev)
{
// 按 Tab 键切换投影模式
if (ev is InputEventKey { Pressed: true, Keycode: Key.Tab })
{
if (_isPerspective)
SetOrthogonal();
else
SetPerspective();
_isPerspective = !_isPerspective;
GD.Print("投影模式: ", _isPerspective ? "透视" : "正交");
// 运行结果: 投影模式: 透视
// 或: 投影模式: 正交
}
}
private void SetPerspective()
{
RenderingServer.CameraSetPerspective(
_cameraRid, ExPerspectiveFov, ExNear, ExFar
);
}
private void SetOrthogonal()
{
RenderingServer.CameraSetOrthogonal(
_cameraRid, ExOrthogonalSize, ExNear, ExFar
);
}
public override void _ExitTree()
{
RenderingServer.FreeRid(_cameraRid);
}
}extends Node3D
## 演示在运行时动态切换透视投影和正交投影。
## 比如策略游戏中的"缩放时切换到正交视角"效果。
var _camera_rid: RID
var _viewport_rid: RID
var _is_perspective: bool = true
@export var perspective_fov: float = 70.0
@export var orthogonal_size: float = 20.0
@export var near_distance: float = 0.05
@export var far_distance: float = 500.0
func _ready():
_viewport_rid = get_viewport().get_viewport_rid()
_camera_rid = RenderingServer.camera_create()
_set_perspective()
var t = global_transform
RenderingServer.camera_set_transform(_camera_rid, t)
RenderingServer.viewport_attach_camera(_viewport_rid, _camera_rid)
func _unhandled_input(ev: InputEvent) -> void:
# 按 Tab 键切换投影模式
if ev is InputEventKey and ev.pressed and ev.keycode == KEY_TAB:
if _is_perspective:
_set_orthogonal()
else:
_set_perspective()
_is_perspective = not _is_perspective
print("投影模式: ", "透视" if _is_perspective else "正交")
# 运行结果: 投影模式: 透视
# 或: 投影模式: 正交
func _set_perspective() -> void:
RenderingServer.camera_set_perspective(
_camera_rid, perspective_fov, near_distance, far_distance
)
func _set_orthogonal() -> void:
RenderingServer.camera_set_orthogonal(
_camera_rid, orthogonal_size, near_distance, far_distance
)
func _exit_tree():
RenderingServer.free_rid(_camera_rid)注意事项
必须手动释放资源:通过
RenderingServer.camera_create()创建的摄像机不会随节点树自动销毁。一定要在不再使用时调用RenderingServer.FreeRid(cameraRid)(GDScript:RenderingServer.free_rid(camera_rid))释放资源,否则会造成内存泄漏。建议在_ExitTree()中释放。需要挂载到视口才能生效:创建摄像机后,必须调用
RenderingServer.ViewportAttachCamera()将其绑定到某个视口上,否则它不会参与渲染。需要额外设置参数:新创建的摄像机没有默认的投影参数和变换。你需要手动调用
CameraSetPerspective/CameraSetOrthogonal设置投影,以及CameraSetTransform设置位置和朝向。大多数情况下优先使用 Camera3D 节点:如果你只是需要普通的游戏摄像机,直接在场景中添加
Camera3D节点即可,更简单且不易出错。RenderingServer底层 API 适用于需要高性能、自定义渲染管线、或同时管理大量摄像机的场景(如分屏游戏、小地图、监控画面等)。RID 是全局标识符:
Rid是渲染服务器中所有资源的统一标识类型。请妥善保管创建后返回的 RID,一旦丢失就无法再操作该摄像机。
