控制用户的相机

*此内容使用人工智能(Beta)翻译,可能包含错误。若要查看英文页面,请点按 此处

用户对世界的视角由 Camera 对象表示。您可以通过多种方式更改相机的行为,以适应您的体验。例如,当怪物走过时,相机可以对世界中的事件做出反应而发生抖动,或者固定在用户角色的侧面,如同横版滚动游戏。

创建第一人称相机

第一人称相机是一种视角,其中相机与角色的头部保持固定,这在真实生活中更加准确。这在射击和故事体验中很常见,其目标是让用户感受到沉浸在世界中。

第一人称相机
经典 Roblox 相机

在工作室中,StarterPlayer 对象包含多个影响用户相机的属性。CameraMode 属性决定相机的行为。

  1. 选择 StarterPlayer

    alt

  2. 将 CameraMode 更改为 LockFirstPerson。这确保用户的相机不会偏离他们的头部。

    alt

  3. 测试以查看第一人称相机的效果。

创建横版滚动相机

横版滚动视图保持相机相对于角色的侧面在固定位置,使世界有一种二维的感觉。

alt

脚本化相机

  1. 展开 StarterPlayer,在 StarterPlayerScripts 中添加一个名为 CameraManagerLocalScript

    alt

  2. 在脚本顶部,复制并粘贴以下代码示例以获取 Players 服务,然后在一个新变量中获取本地用户。


    local Players = game:GetService("Players")
    local player = Players.LocalPlayer
  3. 创建一个名为 updateCamera 的函数。该函数保存获取和设置相机新位置所需的逻辑。


    local Players = game:GetService("Players")
    local player = Players.LocalPlayer
    local function updateCamera()
    end
  4. 在该函数内部,通过使用 if 语句获取用户的角色模型并检查其是否存在。


    local Players = game:GetService("Players")
    local player = Players.LocalPlayer
    local function updateCamera()
    local character = player.Character
    if character then
    end
    end

指定相机

所有角色模型都包含一个名为 HumanoidRootPart 的部件,可以用来获取角色在世界中的位置。这将设置相机指向的位置。

  1. 使用 FindFirstChild 获取 HumanoidRootPart,并使用 if 语句检查它是否存在。


    local Players = game:GetService("Players")
    local player = Players.LocalPlayer
    local function updateCamera()
    local character = player.Character
    if character then
    local root = character:FindFirstChild("HumanoidRootPart")
    if root then
    end
    end
    end
  2. HumanoidRootPart 的位置实际上在用户头部下方 2 个 studs。为了解决这个问题,向根的位置添加一个高度为 2 studs 的新 Vector3


    local Players = game:GetService("Players")
    local player = Players.LocalPlayer
    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)
    end
    end
    end

设置相机位置

相机也需要位置。为了给予用户视图一种 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 - 要被绑定到渲染步骤的函数。
  1. 使用 RunService:BindToRenderStep()updateCamera 函数绑定到渲染步骤。


    local Players = game:GetService("Players")
    local RunService = game:GetService("RunService")
    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("SidescrollingCamera", Enum.RenderPriority.Camera.Value + 1, updateCamera)
  2. 测试您的代码。使用 AD 键将您的角色从一侧移动到另一侧。

创建等距相机

获取用户位置并在每帧更新相机位置的基本结构可以适配许多其他相机样式,例如 等距相机。等距相机是一种 3D 视图,稍微向下指向用户角色,并保持固定角度。

alt

修改位置和视角

  1. 使用前一个示例中的代码,修改 cameraPosition,使三维度都增加相同的值。

    alt


    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 = rootPosition + Vector3.new(CAMERA_DEPTH, CAMERA_DEPTH, CAMERA_DEPTH)
    camera.CFrame = CFrame.lookAt(cameraPosition, rootPosition)
    end
    end
    end
    RunService:BindToRenderStep("IsometricCamera", Enum.RenderPriority.Camera.Value + 1, updateCamera)
  2. 更改相机的 FieldOfView 属性模拟放大和缩小,这可以使视图看起来更平坦。尝试将其设置为 20 以放大,并增大相机与用户之间的距离以补偿。


    local Players = game:GetService("Players")
    local RunService = game:GetService("RunService")
    local player = Players.LocalPlayer
    local camera = workspace.CurrentCamera
    local CAMERA_DEPTH = 64
    local HEIGHT_OFFSET = 2
    camera.FieldOfView = 20
    local function updateCamera()

通过改变相机的行为,您可以为您的体验带来全新的外观。看看您是否可以更改 cameraPosition,以实现使用相同脚本的俯视相机。尝试调整设置,以获得您喜欢的结果!