相机 对象定义了 3D 世界的视图。在运行体验中,每个客户端都有自己的 相机 对象,该客工作间端的本地 Workspace 中,通过 1> Class.Workspace.CurrentCamera1> 属性访问。
最重要的相机属性是:
Camera.CFrame ,代表相镜头的位置和方向。
Camera.CameraType ,这是体验的相机脚本所读取的,并确定相机在每个帧上更新如何。
Camera.CameraSubject ,其中经体验的相机脚本读取,并确定相机应该跟关注哪个对象。
Camera.FieldOfView ,代表可观察世界的可见范围。
Camera.Focus ,代表相机正在查看的点。重要的是,此属性必须设置,因为某些视觉效果将更加详细,并且更频繁更新,取决于它们是否靠近焦点。
有关调整和自定义相镜头行为的更多信息,请参阅自定义相机。
概要
属性
Class.Camera 的 Camera,定义其在 3D 世界中的位置和方向。
指定 Enum.CameraType 以便被相机脚本读取。
设置相镜头的垂直查看野角度。
设置相镜头的垂直视野角。
确定 Camera 在视窗尺寸变更下的 FOV 值。
将区域在 Roblox 图形系统的优先级下设置在 3D 空间。
切换是否使用 VR 设备自动跟踪玩家的头部运动。
设置使用 VR 时用户的世界视角的缩放。
设置相镜头的视野角以沿长视窗轴方向。
描述 Z 偏移量,用钉子表示,在镜头附近的相机。
切换是否在玩家使用 VR 设备时从 Camera.CFrame 属性应用斜倾和滚动。
Roblox 客户端上的设备安全区的尺寸。
方法
返回一个 BaseParts 阵列,它掩盖了摄像镜头之间的视线,在 Camera.CFrame 和投射点之间。
返回在 radians 当前卷轴,或在 Camera 使用 Camera:SetRoll() 应用。
从镜头幕上的位置(以像素计)创建一个单元 Ray ,在设置深度从 Camera 对齐的相机的方向。 计算图形用户界面的位置。
设置当前旋转在相镜头的 Z 轴上应用的旋转。
从视镜头位置(以像素计)上的位置创建一个单位 Ray 从Camera,在CoreUISafeInsets的方向上。不考虑1> 枚。屏幕设置|核心UISafeInsets1> 在设置。
返回屏幕位置和深度的一个 Vector3 worldPoint 和是否该点位在屏幕边界内。 计算屏幕插入。
返回Vector3的屏幕位置和深度,以及worldPoint和是否该点位位于屏幕边界。不会计算屏幕内置。
属性
CFrame
这个属性是 CFrame 的 Camera,定义其位置和方向在 3D 世界中。注意一些变形,例如使用 VR 设备时头部的旋转,不会反映在此属性中,因此您应该使用 Class.Camera:GetRenderCFrame()|GetRenderCFrame()</
您可以通过设置此属性来移动相机。 但默认相机脚本也会设置它,因此您应该:
将相机设置为 Camera.CameraType ,使默认相机脚本不会更新相镜头的 Enum.CameraType.Scriptable 。 此方法最简单,并且在大多数情况下都推荐。
完全替换默认的摄像头脚本以替换替换方案。此方法仅适用于不需要任何默认摄像头功能的情况。
最直观的方法来将 Camera 放置和定向是使用 CFrame.lookAt() 构建器。在以下示例中, Camera 位于 2>Datatype.Vector3.new(0, 10, 0)2> 并向向 5>
local camera = workspace.CurrentCameracamera.CameraType = Enum.CameraType.Scriptablelocal pos = Vector3.new(0, 10, 0)local lookAtPos = Vector3.new(10, 0, 0)workspace.CurrentCamera.CFrame = CFrame.lookAt(pos, lookAtPos)
虽然相机可以放置在上面显示的方式,但您可能会想要将其动画为从一个 CFrame 到另一个。为此,您可以使用以下方法:
使用 RunService:BindToRenderStep() 和 CFrame:Lerp() 方法设置相镜头的位置/方向。
创建并播放一个 Tween,该操作会动画相镜头的位置/方向:
local Players = game:GetService("Players")local TweenService = game:GetService("TweenService")local camera = workspace.CurrentCameracamera.CameraType = Enum.CameraType.Scriptablelocal player = Players.LocalPlayerlocal character = player.Characterif not character or character.Parent == nil thencharacter = player.CharacterAdded:Wait()endlocal pos = camera.CFrame * Vector3.new(0, 20, 0)local lookAtPos = character.PrimaryPart.Positionlocal targetCFrame = CFrame.lookAt(pos, lookAtPos)local tween = TweenService:Create(camera, TweenInfo.new(2), {CFrame = targetCFrame})tween:Play()
CameraSubject
CameraSubject 接受各种 Instances 。默认的摄像头脚本根据可用设置不同地响应:
默认情况下,相机脚本跟随本地角色的 Humanoid,并且考虑到人形的当前状态和 Humanoid.CameraOffset。
设置为 BasePart 时,相机脚本跟随其位置,并且在 VehicleSeats 的情况下有垂直 Offset。
相机对象 无法设置为 nil 。尝试这样做将会将其重设为其以前的值。
要恢复 CameraSubject 到其默认值,将其设置为本地角色的 Humanoid :
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local function resetCameraSubject()
if workspace.CurrentCamera and localPlayer.Character then
local humanoid = localPlayer.Character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
workspace.CurrentCamera.CameraSubject = humanoid
end
end
end
CameraType
默认 Roblox 相机脚本有几个内置行为。 设置此属性会在各种 Enum.CameraType 行为之间切换。 请注意,一些相机类型需要一个有效的 Camera.CameraSubject 才能正常工作。
如果 CameraType 设置为 Enum.CameraType.Scriptable ,默认相机脚本将不会移动或更新相机。 For more information on positioning and orienting the camera manually, see Camera.CFrame 。
对于所有 CameraType 设置,除了 Class.Camera.CameraSubject|CameraSubject 外, Enum.CameraType.Scriptable 是设置的对象。
DiagonalFieldOfView
设置相机在垂直方向(从视窗角落到视窗另一角落)上可以查看的度数。请参阅 FieldOfView 以了解更多关于视野的解释。
注意,DiagonalFieldOfView 代表 Camera 渲染到全屏区域,可能受到某些设备上的迹子或屏幕切割来阻塞视野。请参阅Class. Camera.ViewportSize|ViewportSize获取更多信息。
FieldOfView
FieldOfView 属性设置相机在垂直方向上可以查看的度数。 此属性是在 1 和 120 之间的调整,默认为 70。 非常低或非常高的度数视野对玩家造成困惑,因此不建议。
注意,强制使用单位调整,意味着垂直和横向视野总是由屏幕的方面比例关系。
FieldOfView (FOV) 的建议用途包括:
- 减少 FOV 以减少放大的印象,例如使用 binoculars 时。
- 增加玩家“冲刺”时的 FOV 以增加错觉的控制。
注意 FieldOfView 代表 Camera 渲染到全屏区域,可能受到某些设备上的迹子或屏幕切割来阻塞或切割屏幕。请参阅 Class.Camera. ViewportSize|ViewportSize 获取更多信息。
FieldOfViewMode
相镜头的视野(FOV)必须更新,反映ViewportSize 的更改。 视野模式 的值决定了哪个 FOV 值将被保持不变。
例如,当此属性设置为 Enum.FieldOfViewMode.Vertical 时,当视窗调整大小时,横向 FOV 会更新,但垂直 FOV 将保持不变。如果此属性设置为 Enum.FieldOfViewMode.Diagonal ,视窗的横向和垂直向 FOV 都可能会变更,以保持直角 FOV 的不变性。
Focus
某些图形操作,例如更新照明,可能需要时间或计算资源来完成。 相镜头的 聚焦 属性告诉引擎在执行此类操作时要优先考虑哪个区域在 3D 空间中。 例如,从对象 PointLights 的动态照明可能无法在遥远地点渲染。
默认 Roblox 相机脚本会自动将 焦点 设置为跟
焦点 对相镜头的位置或方向没有影响;请参阅 Camera.CFrame 了解此信息。
HeadLocked
切换是否使用 VR 设备自动跟踪玩家的头部运动。 true (默认) 将引擎与玩家头部的 Camera.CFrame 结合,以便在头部跟踪因素中考虑头部。视图将在 следующем Enum.UserCFrame 中渲染:
local UserInputService = game:GetService("UserInputService")local camera = workspace.CurrentCameralocal headCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)headCFrame = headCFrame.Rotation + headCFrame.Position * camera.HeadScale-- 这将相当于 Camera:GetRenderCFrame()local renderCFrame = camera.CFrame * headCFrame
建议您不要禁用此属性的原因如下:
- 如果没有添加相应的头跟踪解决方案,玩家可能会感到运动不舒服。
- 当 头锁定 是真的时候,Roblox 引擎会优化延迟。
还见
- VRService:GetUserCFrame() 可用于获得头部的 CFrame 。
- VRService:RecenterUserHeadCFrame() 用于将头重新定位到 VR 设备的当前位置和方向。
- 返回用户头的 Class.Camera.CFrame 和用户头的 Camera.CFrame 的组合。
HeadScale
头部比例 是使用虚拟现实时,用户的世界视角的缩放。
在 VR 中 1 格的大小是 0.3 meters / HeadScale ,这意味着大于 5 格的头部可以从用户的视角看到更小的世界。例如,高 1 格的零件看起来高 0.6 米,当使用 VR 设备时,用户的头部瞄准到 0.5 格的世界。
此属性由 VRService.AutomaticScaling 自动控制,以将玩家的视虚拟形象与他们的头像大小对齐。如果您打算控制 头部 自己或使用自定义角色,切换 VRService.AutomaticScaling 为 2>Class.VRService.Off2>。
这个属性不应与 Humanoid.HeadScale ,它是一个 NumberValue 父级于一个 Humanoid 来控制其缩放。
MaxAxisFieldOfView
MaxAxisFieldOfView 属性设置相机可以在最长视窗轴上查看的度数。
当最长轴是垂直轴时,此属性会与 FieldOfView 属性相似。 此是一般在设备处于肖像方向时的情况。 在地图方向中,最长轴将是横向;在此情况下,属性描述 Camera 的横向视野。
NearPlaneZ
靠近飞机 Z 属性描述相镜头的近接飞机在锥体上的位置,在 studs 。 靠近飞机是一个几何平面,坐落在镜头机的 Camera.CFrame 前。 在视角很短的距离上,任何东西都不会渲染,创建一个切割视图
VRTiltAndRollEnabled
此属性切换是否在玩家使用 VR 设备时从 Camera.CFrame 属性应用斜倾和滚动。
为了防止运动伤害,地平线应保持平等级。 使用 VR 设备时,倾斜和滚动玩家的视图可以导致玩家之间的物理空间和虚拟空间之间的连接中断。 改变显然向下的方向可能会导致玩家失去平衡或体验头疼。
因此,有以下理由,通常不建议启用此属性,除非您有充分测试您的体验以为这些效果提供长期测试。即使启用了倾斜和滚动,您也可能想要确保玩家总是有一个稳定的引用框,例如车辆内部或可以帮助玩家在他们的物理空间上自己找到位置的地板。
ViewportSize
ViewportSize 返回当前屏幕上的设备安全区的尺寸。此区域是一个长方体,包括 Roblox 顶部栏区,但不包括任何设备的不平移或屏幕切割。 Class.Camera.ViewportSize|ViewportSize 的单位是 Roblox UI 偏移单位,可能与 native 显示像素不同。
您注意到上述,ViewportSize 不等于切开或鼓孔显示器的全屏显示区域的大小。要获得所有显
最后,请注意,ViewportSize 不是相机在渲染时使用的实际视窗大小。 另外,Camera.FieldOfView 和 Camera.DiagonalFieldOfView 属性基于全屏幕区域,不是1> Class.Camera.ViewportSize1>
相机更新
只有 Camera 当前由 Class.Workspace. CurrentCamera 参照时,其 ViewportSize 每个框架在 1>Class.RunService.PreRender|PreRender1> 步骤中
方法
GetPartsObscuringTarget
此方法返回一个 BaseParts 数组列,该阵列正在 Camera 的 Camera.CFrame 和 Vector3 位置之间遮蔽视线,以及其子。任何包含在 2>castPoints2> 阵列中的 <
castPoints 参数作为 Vector3 位置的阵列提供。 注意,返回的 BaseParts 阵列的顺序是任意排列的,并且不提供额外的射线投射数据。 如果您需要击位、材质或表面正常,您应该选择 1>Class.WorldRoot:Raycast()
local camera = workspace.CurrentCameralocal castPoints = {Vector3.new(0, 10, 0),Vector3.new(0, 15, 0)}local ignoreList = {}local partsObscuringTarget = camera:GetPartsObscuringTarget(castPoints, ignoreList)
如果 Terrain 遮蔽了一个投射点, BaseParts 遮蔽了投射点之间的投射点 Terrain 和投射点之间的投射点不会返回。
参数
返回
一阵 BaseParts 将遮蔽视线在相镜头的 Camera.CFrame 和 castPoints 之间的线路。
代码示例
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local function XRay(castPoints, ignoreList)
ignoreList = ignoreList or {}
local parts = camera:GetPartsObscuringTarget(castPoints, ignoreList)
for _, part in parts do
part.LocalTransparencyModifier = 0.75
for _, child in pairs(part:GetChildren()) do
if child:IsA("Decal") or child:IsA("Texture") then
child.LocalTransparencyModifier = 0.75
end
end
end
end
XRay({ Vector3.new() })
GetRenderCFrame
此函数将 CFrame 的实际 Camera 返回,包括 VR 的影响 (VR 头部变形不适用于 Camera.CFrame 属性,因此是最佳实践使用 2>Class.Camera:GetRenderCFrame()2> 来获得
例如,使用 VR 时,Camera 实际上会在以下 CFrame 中渲染:
local UserInputService = game:GetService("UserInputService")local camera = workspace.CurrentCameralocal headCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)headCFrame = headCFrame.Rotation + headCFrame.Position * camera.HeadScalerenderCFrame = camera.CFrame * headCFrame
只有在 CFrame 属性是真的时,才会更改相镜头的渲染 Camera.HeadLocked。
返回
Datatype.CFrame 正在渲染。
GetRoll
此函数将以 ради为返回,在 Camera 上使用 Camera:SetRoll() 应用。滚动是围绕相镜头 Z 轴的旋转。
此函数只返回使用 Camera:SetRoll() 函数应用的滚动。 手动应用于相镜头的 Camera.CFrame 不被计算。 要获得实际滚动的 Camera,包括手动应用的滚动,您可以使用以下代码:
local function getActualRoll()
local camera = workspace.CurrentCamera
local trueUp = Vector3.new(0, 1, 0)
local cameraUp = camera:GetRenderCFrame().upVector
return math.acos(trueUp:Dot(cameraUp))
end
返回
当前滚动由 Camera:SetRoll() 应用,以 radian 计。
代码示例
local currentRoll = math.deg(workspace.CurrentCamera:GetRoll()) -- Gets the current roll of the camera in degrees.
if currentRoll ~= 20 then
workspace.CurrentCamera:SetRoll(math.rad(20)) -- If the camera isn't at 20 degrees roll, the roll is set to 20 degrees.
end
ScreenPointToRay
此函数从屏幕上的 2D 位置(定义在像素)创建一个单元 Ray,为 GUI 插入计算。 Ray 的起源来自于世界上给定的 Vector3 的 2D 位置在给定深度 (in studs) 远离 2>Class.Camera2> 。
由于此函数承认图形用户界面插入,应用程序对图形用户界面元素(例如从顶部栏)的 Offset (应用程序对顶部栏的 Offset )已被计算。这意味着屏幕位置指定将在顶部栏下的左上角开始。为了其他相同的功偏移值,不计算 GUI Offset 的话,请使用 Camera:ViewportPointToRay() 。
作为 Ray 创建的是一个单位射线,它只是一英尺长。要创建更长的射线,您可以执行以关注中/正在关注操作:
local camera = workspace.CurrentCameralocal length = 500local unitRay = camera:ScreenPointToRay(100, 100)local extendedRay = Ray.new(unitRay.Origin, unitRay.Direction * length)
此功能仅适用于当前工作区相镜头。 其他相机,例如您创建的 ViewportFrame ,具有初始视窗大小为 (1, 1) ,并且只有在您将其设置为 Workspace.CurrentCamera 后才会更新。 视窗大小不匹配会导致相机返回
参数
返回
SetRoll
此功能已过期且不再被视为最佳实践。
此函数设置 Camera 的当前卷轴,以 ради数设置。卷轴在 Camera.CFrame 后应用,代表在相镜头的 Z 轴上旋转。
例如,以下将扭曲 Camera:
workspace.CurrentCamera:SetRoll(math.pi) -- math.pi radians = 180 degrees
SetRoll 对使用 Camera.CFrame 属性的任何卷轴没有效果。 卷轴使用 SetRoll 不会反映在 Camera.CFrame 属性,但会反映在 CFrame 返回的 1> Class.Camera:GetRenderCFrame()1> 中。
此函数仅限于 Camera.CameraType 设置为 'Scriptable' ,无论是否使用默认摄像头脚本。如果它与任何其他 Camera.CameraType 使用,警告将在输出中显示。
使用此函数应用的任何卷轴将在 Camera.CameraType 中从 “可滚动” 更改为失效。
使用此函数获取卷轴使用 Camera:GetRoll() .
由于此功能已过期,您建议使用 Camera 属性将滚动应用到 Camera.CFrame 。例如:
local currentCFrame = workspace.CurrentCamera.CFramelocal rollCFrame = CFrame.Angles(0, 0, roll)workspace.CurrentCamera.CFrame = currentCFrame * rollCFrame
参数
返回
ViewportPointToRay
此函数从 2D 位置在设备安全视窗坐标中创建一个单元 Ray 从射线源在世界的 Class.Camera 远离 8 。
如下所示,(0, 0) 对应 Roblox 顶部栏的左上角。这意味着输入 2D 位置不会为 Enums.ScreenInsets|CoreUISafeInsets 设置造成帐户,但会为任何CoreUISafeInsets 设置造成帐户。
注意,UI 实例使用不同的坐标系统 (GuiObject.AbsolutePosition 使用 CoreUISafeInsets 视窗坐标系统,而此功能使用 DeviceSafeInsets 视窗坐标系统)。如果您想在核心 UI 坐标指定位置,请使用
还注意,此功能仅适用于 Class.Workspace. CurrentCamera 相镜头。 其他相机,例如您创建的 ViewportFrame ,有一个初始视窗大小为 (1, 1) 的视窗大小,并且只有在您将其设置为
此功能可以与 ViewportSize 属性一起使用,以从屏幕中心创建射线,例如:
local Workspace = game:GetService("Workspace")local camera = Workspace.CurrentCameralocal viewportPoint = camera.ViewportSize / 2local unitRay = camera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)
作为 Ray 创建的是一个单位射线,它只是一英尺长。要创建更长的射线,您可以执行以关注中/正在关注操作:
local Workspace = game:GetService("Workspace")local camera = Workspace.CurrentCameralocal length = 500local unitRay = camera:ScreenPointToRay(100, 100)local extendedRay = Ray.new(unitRay.Origin, unitRay.Direction * length)
参数
在 X 轴上的位置,以像素计表示,用于设备安全区域的协调坐标。
返回
WorldToScreenPoint
此函数返回屏幕位置和深度以及Vector3 worldPoint 以及该点是否位于屏幕边界。
此函数考虑到当前 GUI 的插入,例如顶部栏占位,意味着返回的 2D 位置与 GUI 位置相同,可以用于放置 GUI 元素。对于其他与 GUI 无关的函数,请参阅 Camera:WorldToViewportPoint()。
local camera = workspace.CurrentCameralocal worldPoint = Vector3.new(0, 10, 0)local vector, onScreen = camera:WorldToScreenPoint(worldPoint)local screenPoint = Vector2.new(vector.X, vector.Y)local depth = vector.Z
注意,此函数不会执行任何射线投射,且指示屏幕是否包含在worldPoint 内的屏幕边界会是true 无论是否遮蔽BaseParts 或1> Class.Terrain1> 。
参数
Datatype.Vector3 世界位置。
返回
WorldToViewportPoint
此函数返回屏幕位置和深度以及Vector3 worldPoint 以及该点是否位于屏幕边界。
此函数不考虑当前图形用户界面的插入,例如顶部栏占用空间,意味着返回的2D位置是从视图左上角的顶部角落取得的。除非您使用 ScreenGui.IgnoreGuiInset,这个位置不适合放置图形元素。
对于其他与图形用户界面插入相同的功能,请参阅 Camera:WorldToScreenPoint() 。
local camera = workspace.CurrentCameralocal worldPoint = Vector3.new(0, 10, 0)local vector, onScreen = camera:WorldToViewportPoint(worldPoint)local viewportPoint = Vector2.new(vector.X, vector.Y)local depth = vector.Z
注意,此函数不会执行任何射线投射,且指示屏幕是否包含在worldPoint 内的屏幕边界会是true 无论是否遮蔽BaseParts 或1> Class.Terrain1> 。
参数
Datatype.Vector3 世界位置。
返回
活动
InterpolationFinished
此事件发生,当 Camera 使用 Camera:Interpolate() 函数完成交换。
如果 Camera:Interpolate() 被重新调用,该事件不会发生。
您建议使用 TweenService 来动画 Camera ,因为它更可靠,并提供更多选择来减轻风格。