用户对世界的视角由 Camera 对象表示。您可以通过多种方式更改相机的行为,以适应您的体验。例如,当怪物走过时,相机可以对世界中的事件做出反应而发生抖动,或者固定在用户角色的侧面,如同横版滚动游戏。
创建第一人称相机
第一人称相机是一种视角,其中相机与角色的头部保持固定,这在真实生活中更加准确。这在射击和故事体验中很常见,其目标是让用户感受到沉浸在世界中。


在工作室中,StarterPlayer 对象包含多个影响用户相机的属性。CameraMode 属性决定相机的行为。
选择 StarterPlayer。
将 CameraMode 更改为 LockFirstPerson。这确保用户的相机不会偏离他们的头部。
测试以查看第一人称相机的效果。
创建横版滚动相机
横版滚动视图保持相机相对于角色的侧面在固定位置,使世界有一种二维的感觉。
脚本化相机
展开 StarterPlayer,在 StarterPlayerScripts 中添加一个名为 CameraManager 的 LocalScript。
在脚本顶部,复制并粘贴以下代码示例以获取 Players 服务,然后在一个新变量中获取本地用户。
local Players = game:GetService("Players")local player = Players.LocalPlayer创建一个名为 updateCamera 的函数。该函数保存获取和设置相机新位置所需的逻辑。
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal function updateCamera()end在该函数内部,通过使用 if 语句获取用户的角色模型并检查其是否存在。
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal function updateCamera()local character = player.Characterif character thenendend
指定相机
所有角色模型都包含一个名为 HumanoidRootPart 的部件,可以用来获取角色在世界中的位置。这将设置相机指向的位置。
使用 FindFirstChild 获取 HumanoidRootPart,并使用 if 语句检查它是否存在。
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal function updateCamera()local character = player.Characterif character thenlocal root = character:FindFirstChild("HumanoidRootPart")if root thenendendendHumanoidRootPart 的位置实际上在用户头部下方 2 个 studs。为了解决这个问题,向根的位置添加一个高度为 2 studs 的新 Vector3。
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal HEIGHT_OFFSET = 2local function updateCamera()local character = player.Characterif character thenlocal root = character:FindFirstChild("HumanoidRootPart")if root thenlocal rootPosition = root.Position + Vector3.new(0, HEIGHT_OFFSET, 0)endendend
设置相机位置
相机也需要位置。为了给予用户视图一种 2D 横版滚动的外观,相机需要直视角色的侧面。通过在相机的位置的 Z 轴 上添加深度,来将相机置于用户的旁边,使用一个 Vector3。
local player = Players.LocalPlayer
local CAMERA_DEPTH = 24
local HEIGHT_OFFSET = 2
local function updateCamera()
local character = player.Character
if character then
local root = character:FindFirstChild("HumanoidRootPart")
if root then
local rootPosition = root.Position + Vector3.new(0, HEIGHT_OFFSET, 0)
local cameraPosition = Vector3.new(rootPosition.X, rootPosition.Y, CAMERA_DEPTH)
end
end
end
更新 CurrentCamera
现在,相机位置和相机目标的变量已经准备就绪,接下来是更新相机的位置。您可以通过工作区的 CurrentCamera 属性访问用户的相机。相机有一个 CFrame 属性来确定其位置。
您可以使用 CFrame.lookAt() 更新相机。它需要两个位置,并创建一个位于第一个位置指向第二个的 CFrame。使用 CFrame.lookAt() 创建一个位于 cameraPosition 并指向 rootPosition 的 CFrame。
local player = Players.LocalPlayer
local camera = workspace.CurrentCamera
local CAMERA_DEPTH = 24
local HEIGHT_OFFSET = 2
local function updateCamera()
local character = player.Character
if character then
local root = character:FindFirstChild("HumanoidRootPart")
if root then
local rootPosition = root.Position + Vector3.new(0, HEIGHT_OFFSET, 0)
local cameraPosition = Vector3.new(rootPosition.X, rootPosition.Y, CAMERA_DEPTH)
camera.CFrame = CFrame.lookAt(cameraPosition, rootPosition)
end
end
end
同步相机
最后一步是重复运行此函数,以保持相机与用户同步。用户看到的图像是不断刷新的。进行所有必要计算所需的时间被称为 渲染步骤。
RunService:BindToRenderStep() 使得在每一帧上执行函数变得简单,通过接受这三个参数:
- name - 此绑定的名称,应是唯一的,以免与其他同名函数冲突。
- priority - 数字越高,优先级越高。此函数应在 Roblox 的默认相机更新之后运行,因此优先级设置为比内部相机的 RenderPriority 高 1 级。
- function - 要被绑定到渲染步骤的函数。
使用 RunService:BindToRenderStep() 将 updateCamera 函数绑定到渲染步骤。
local Players = game:GetService("Players")local RunService = game:GetService("RunService")local player = Players.LocalPlayerlocal camera = workspace.CurrentCameralocal CAMERA_DEPTH = 24local HEIGHT_OFFSET = 2local function updateCamera()local character = player.Characterif character thenlocal root = character:FindFirstChild("HumanoidRootPart")if root thenlocal rootPosition = root.Position + Vector3.new(0, HEIGHT_OFFSET, 0)local cameraPosition = Vector3.new(rootPosition.X, rootPosition.Y, CAMERA_DEPTH)camera.CFrame = CFrame.lookAt(cameraPosition, rootPosition)endendendRunService:BindToRenderStep("SidescrollingCamera", Enum.RenderPriority.Camera.Value + 1, updateCamera)测试您的代码。使用 A 和 D 键将您的角色从一侧移动到另一侧。
创建等距相机
获取用户位置并在每帧更新相机位置的基本结构可以适配许多其他相机样式,例如 等距相机。等距相机是一种 3D 视图,稍微向下指向用户角色,并保持固定角度。
修改位置和视角
使用前一个示例中的代码,修改 cameraPosition,使三维度都增加相同的值。
local function updateCamera()local character = player.Characterif character thenlocal root = character:FindFirstChild("HumanoidRootPart")if root thenlocal rootPosition = root.Position + Vector3.new(0, HEIGHT_OFFSET, 0)local cameraPosition = rootPosition + Vector3.new(CAMERA_DEPTH, CAMERA_DEPTH, CAMERA_DEPTH)camera.CFrame = CFrame.lookAt(cameraPosition, rootPosition)endendendRunService:BindToRenderStep("IsometricCamera", Enum.RenderPriority.Camera.Value + 1, updateCamera)更改相机的 FieldOfView 属性模拟放大和缩小,这可以使视图看起来更平坦。尝试将其设置为 20 以放大,并增大相机与用户之间的距离以补偿。
local Players = game:GetService("Players")local RunService = game:GetService("RunService")local player = Players.LocalPlayerlocal camera = workspace.CurrentCameralocal CAMERA_DEPTH = 64local HEIGHT_OFFSET = 2camera.FieldOfView = 20local function updateCamera()
通过改变相机的行为,您可以为您的体验带来全新的外观。看看您是否可以更改 cameraPosition,以实现使用相同脚本的俯视相机。尝试调整设置,以获得您喜欢的结果!