Camera

顯示已棄用項目

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

未複製

Camera 對象定義了 3D 世界的視圖。在運行的體驗中,每個客戶端都有自己的 Camera 對象,位於該客戶端的本地 Workspace 中,通過 Workspace.CurrentCamera 屬性可存取。

最重要的相機特性是:

  • CFrame 代表相攝影機的位置和方向。

  • CameraType 這是被體驗的攝影機腳本讀取的,並決定攝影機應該如何在每個框架更新。

  • CameraSubject 這是經體驗的攝影機腳本閱讀的,並決定攝影機應該跟追蹤的對象。

  • FieldOfView 代表可見的世界範圍。

  • Focus 代表相機正在查看的點。設定此屬性很重要,因為某些視覺效果會更詳細,並且更頻繁地更新,取決於它們與焦點點的距離有多近。

請參閱自訂相機以獲得更多關於如何調整和自訂相攝影機行為的信息。

存儲多個攝影機

請注意,當將 Workspace.CurrentCamera 變更為新的 Camera 時,所有其他 CamerasWorkspace 直接下降將被摧毀。如果您需要存儲多個攝像頭並在需要時之間交換,建議您將它們存儲在 或 下的 中,在其中它們即使在 變更時也不會變更。

概要

屬性

屬性 繼承自 PVInstance

方法

方法 繼承自 PVInstance
  • 平行寫入

    獲得 PVInstance 的軸心。

  • PivotTo(targetCFrame : CFrame):()

    將 以及所有其子孫 轉換為指定的 位置,使旋轉點現在位於指定的 位置。

屬性

CFrame

平行讀取

此屬性是 CFrameCamera ,定義其在 3D 世界中的位置和方向。請注意,某些變換,例如使用 VR 裝置時頭部的旋轉,在此屬性中未反映,因此您應該使用 GetRenderCFrame() 來獲得相攝影機的 "真實" CFrame

您可以設置此屬性來移動相機。然而,預設相機腳本也會設置此屬性,因此您應該:

  • 將相機CameraType設為Enum.CameraType.Scriptable,以便預設相機腳本不會更新相攝影機的CFrame。這個方法最簡單,在大多數情況下都被推薦。

  • 完全替換預設攝影機腳本以使用替代方案。這種方法只有在您不需要任何預設攝影機功能時才推薦。

Camera 放置和定向最直觀的方法是使用 CFrame.lookAt() 建造器。在下面的例子中,Camera 位於 Vector3.new(0, 10, 0) 並且傾向於看向 Vector3.new(10, 0, 0)


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local 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 Workspace = game:GetService("Workspace")
    local camera = Workspace.CurrentCamera
    camera.CameraType = Enum.CameraType.Scriptable
    local player = Players.LocalPlayer
    local character = player.Character
    if not character or character.Parent == nil then
    character = player.CharacterAdded:Wait()
    end
    local pos = camera.CFrame * Vector3.new(0, 20, 0)
    local lookAtPos = character.PrimaryPart.Position
    local targetCFrame = CFrame.lookAt(pos, lookAtPos)
    local tween = TweenService:Create(camera, TweenInfo.new(2), {CFrame = targetCFrame})
    tween:Play()

CameraSubject

平行讀取

CameraSubject 接受各種 Instances 。預設攝影機腳本會以不同方式回應可用設定:

CameraSubject 無法設為 nil 。嘗試這樣做會將它恢復到以前的值。

若要恢復 CameraSubject 到預設值,將其設為本地角色的 Humanoid :


local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local localPlayer = Players.LocalPlayer
local camera = Workspace.CurrentCamera
local function resetCameraSubject()
if camera and localPlayer.Character then
local humanoid = localPlayer.Character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
camera.CameraSubject = humanoid
end
end
end

CameraType

平行讀取

預設 Roblox 相機腳本具有多種內置行為。設置此屬性會在各種 Enum.CameraType 行為之間切換。請注意,某些攝影機類型需要有效的 CameraSubject 才能正確運作。

預設攝影機腳本不會移動或更新攝影機,如果 CameraType 設為 Enum.CameraType.Scriptable 。要了解有關手動配置相機的更多信息,請參閱 CFrame

對於所有 設定除了 , 屬性代表攝影機的位置設置為的對象。

DiagonalFieldOfView

未複製
平行讀取

設定相機可以在橫向方向(從視窗一角到另一角)檢視到的度數(從一個角落到另一角落)。見 FieldOfView 獲得更一般的視檢視說明。

請注意, 代表可在全螢幕區域中顯示的視野,可能會被某些裝置上的劃痕或螢幕截圖遮蓋。請參閱 ViewportSize 獲得更多資訊。

FieldOfView

平行讀取

FieldOfView (FOV) 屬性設置相機可以在垂直方向查檢視多少度。此屬性位於 1120 度之間,在 70 預設值。非常低或非常高的視野並不建議,因為它們可能會讓玩家感到困惑。

請注意,強制使用統一縮放,這意味著垂直和水平視野總是與畫面的比率相關。

建議對 FieldOfView 的使用包括:

  • 將FOV減少以獲得放大的印象,例如使用望遠鏡時。
  • 當玩家「奔跑」時增加FOV,以給人一種缺乏控制的印象。

請注意, 代表可在全螢幕區域中顯示的視野,可能會被某些裝置上的劃痕或螢幕截圖遮蓋。請參閱 ViewportSize 獲得更多資訊。

FieldOfViewMode

平行讀取

相攝影機的 FieldOfView (FOV) 必須更新以反映 ViewportSize 變更。FieldOfViewMode 的值決定哪個FOV值將保持不變。

例如,當此屬性設為 Enum.FieldOfViewMode.Vertical 時,視窗縮放時更新水平 FOV,但垂直 FOV 保持不變。如果此屬性設為 Enum.FieldOfViewMode.Diagonal,水平和垂直FOV可能都會被更改,以保持橫截面FOV不變。

Focus

平行讀取

引擎執行的某些圖形操作,例如更新照明,可能需要時間或計算努力才能完成。相攝影機的 Focus 屬性告訴引擎在執行這些操作時,應優先考慮在 3D 空間的哪個區域。例如,動態燈光從對象,例如 PointLights 可能不會在遠離焦點的距離上渲染。

預設 Roblox 相機腳本會自動將 Focus 設為跟隨 CameraSubject (通常是 Humanoid )。但是,Focus不會自動更新CameraType 設為 Enum.CameraType.Scriptable 或當預設攝影機腳本未使用時。在這些情況下,您應該在Focus中更新使用RunService:BindToRenderStep(),在Enum.RenderPriority.Camera中使用。

Focus 對相攝影機的位置或方向沒有影響;請參閱 CFrame 獲得此信息。

HeadLocked

平行讀取

切換攝影機是否會自動跟隨玩家使用 VR 裝置的頭部運動。當 true (預設) 時,引擎會將 CFrame 與使用者頭部的 Enum.UserCFrame 結合,以渲染包含頭部追蹤的玩家視圖。視圖將在下列 CFrame 中渲染:


local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local headCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
headCFrame = headCFrame.Rotation + headCFrame.Position * camera.HeadScale
-- 這將相當於相機:GetRenderCFrame()
local renderCFrame = camera.CFrame * headCFrame

建議不要 禁用此屬性 ,以下是其原因:

  • 如果沒有添加相等的頭部追蹤解決方案,玩家可能會感到運動癱瘓。
  • Roblox 引擎在 HeadLocked 真實時執行延遲最佳化。
也見「也見」

HeadScale

平行讀取

HeadScale 是使用 VR 時用戶對世界的觀點的比例。

在 VR 中的 1 個單位的大小是 0.3 meters / HeadScale , 意味著較大的 HeadScale 值等於使用 VR 裝置時世界看起來更小的用戶角度。例如,高度為 1 個單位的零件似乎對 VR 玩家有 0.6 公尺高度,而有 HeadScale0.5 對玩家有 0.6 公尺高度。

此屬性由 VRService.AutomaticScaling 自動控制,以將玩家的視角與其虛擬人偶的尺寸對齊。如果您打算控制 HeadScale 自己或使用自定义角色,切換 VRService.AutomaticScalingEnum.VRScaling.Off

此屬性不應與 Humanoid.HeadScale 混淆,這是一個 NumberValue 對一個 Humanoid 進行父級控制的子級,用於控制其縮放。

MaxAxisFieldOfView

未複製
平行讀取

MaxAxisFieldOfView 屬性設置相機可以查檢視最長視區軸的多少度。

當最長軸是垂直軸時,此屬性將與 FieldOfView 屬性相似。一般來說,當裝置處於肖像模式時,會發生這種情況。在景觀方向中,最長軸會是水平軸;在這種情況下,屬性會描述 Camera 的水平視野。

NearPlaneZ

唯讀
未複製
平行讀取

NearPlaneZ 屬性描述相攝影機的近距離剪輯平面有多遠,以磚格為單位。接近剪輯平面是一個幾何平面,坐在相攝影機的 CFrame 前面。在這個平面和相機之間的任何東西都不會成像,在非常短的距離觀看物體時創建截圖視圖。NearPlaneZ 的值在不同平台上會各不相同,目前總是在 -0.1-0.5 之間。

Diagram showing how the NearPlaneZ clips (does not render) 3D content between the plane and the camera.

VRTiltAndRollEnabled

平行讀取

此屬性會切換是否在玩家使用 VR 裝置時應用傾斜和滾動的 CFrame 屬性。

為了防止運動災難,地平線應保持平等級。使用 VR 裝置時斜坡和滾動玩家的視圖可能會導致玩家的物理空間與他們正在查看的虛擬空間之間發生斷開。改變顯然的下向方向可能會導致玩家失去平衡或感到頭暈。

因此,一般來說,除非您已經徹底測試過您的體驗對這些效果的影響,否則建議將此屬性禁用。即使啟用了傾斜和滾動,您也可能想確保玩家始終擁有穩定的參考框架,例如車輛內部或可幫助玩家在物理空間中找到自己的地板。

ViewportSize

唯讀
未複製
平行讀取

ViewportSize 返回當前畫面上裝置安全區域的尺寸。這個區域是一個長方形,包括 Roblox 上方欄位區域,但不包括任何裝置槽或螢幕截圖。ViewportSize 的單位是 Roblox 介面偏移單位,可能與原生顯示像素不同。

Mobile device screen with cutout showing device safe area.

如上所述,ViewportSize 不等於顯示器上的切割或劃痕區域的全螢幕區域尺寸。若要在所有顯示器上獲得完整螢幕區域尺寸,您可以查詢 AbsoluteSize 屬性的 ScreenGuiScreenInsets 設為 None 。查看 Enum.ScreenInsets 獲得更多關於如何定義屏幕區域的信息。

最後,請注意,ViewportSize 不是相機用於渲染的實際視窗尺寸 (相機在全螢幕區域渲染)。此外,FieldOfViewDiagonalFieldOfView 屬性是基於全螢幕區域,而不是ViewportSize

相機更新

目前只有 CameraWorkspace.CurrentCamera 引用的已更新 ViewportSize 每個框架在 PreRender 步驟期間。你體驗中所有其他攝影機的 ViewportSize 將不會更新,包括用於 ViewportFrames 的攝影機。

方法

GetPartsObscuringTarget

Instances

此方法返回一個 BaseParts 陣列,它會擋住相攝影機的 CFrameVector3 位置在 castPoints 陣列中的視線線。任何包含在 ignoreList 陣列中的 Instances 將被忽略,以及它們的後裔。

castPoints 參數作為一個數陣的 Vector3 位置提供。請注意,返回的 BaseParts 陣列是隨機排序的,並且沒有額外的射線投射資料提供。如果您需要數據,例如命中位置、命中材料或表面正常,您應該選擇 WorldRoot:Raycast() 方法。


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local castPoints = {
Vector3.new(0, 10, 0),
Vector3.new(0, 15, 0)
}
local ignoreList = {}
local partsObscuringTarget = camera:GetPartsObscuringTarget(castPoints, ignoreList)

如果 遮蓋了投射點, 遮蓋投射點之間的黑暗將不會返回。

參數

castPoints: Array

一個由 Vector3 位投射點位置組成的陣列。

預設值:""
ignoreList: Instances

一個由 Instances 組成的陣列,應忽略其子孫。

預設值:""

返回

Instances

一個由 BaseParts 組成的陣列,會擋住相攝影機的 CFramecastPoints 之間的視線。

GetRenderCFrame

此方法返回渲染時的實際 的 ,包括 VR 的影響 (VR 頭部變形不適用於 屬性,因此最好使用 來獲得玩家的檢視覺的 "真實" )。

例如,當使用 VR 時,Camera 實際上在下列 CFrame 中渲染:


local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local headCFrame = UserInputService:GetUserCFrame(Enum.UserCFrame.Head)
headCFrame = headCFrame.Rotation + headCFrame.Position * camera.HeadScale
renderCFrame = camera.CFrame * headCFrame

相攝影機的渲染 CFrame 只會在 HeadLocked 屬性是真實的情況下變更,以便計算頭部。


返回

正在渲染 CFrameCamera

GetRoll

這個方法返回, 以弧度計, 目前對 Camera 使用 SetRoll() 的滾動。滾動定義為在相攝影機的 Z 軸上旋轉。

此方法只返回使用 SetRoll() 方法應用的滾動。手動滾動應用到相攝影機的 CFrame 不會被計算。若要獲得 Camera 的實際卷,包括手動應用的卷,您可以使用以下片段:


local Workspace = game:GetService("Workspace")
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

返回

目前由 SetRoll() 應用的滾動,以 ради為單位。

範例程式碼

This example, when used in a LocalScript, will retrieve the current roll of the camera in degrees. Then, if the camera roll angle is not 20 degrees, the camera roll angle is set to 20 degrees.

Camera:GetRoll

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 插入。來自 的起源是在給定深度 (以磚格為單位) 的世界上 2D 位置的等值 (在磚格為單位) 。

因為這個方法認可 GUI 插入,因此從頂部欄中應用的偏移量 (例如對 GUI 元素) 將被計算。這意味著指定的畫面位置將在上方欄位的左上角開始。對於不考慮 GUI 偏移值的相同方法,請使用 ViewportPointToRay()

因為創建的 Ray 單位射線只有一個螺柱長度,若要創建更長的射線,您可以執行以追蹤中操作:


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local length = 500
local unitRay = camera:ScreenPointToRay(100, 100)
local extendedRay = Ray.new(unitRay.Origin, unitRay.Direction * length)

此方法僅適用於目前的 Workspace 相機。其他攝影機,例如您為 ViewportFrame 創建的攝影機,初始視區尺寸為 (1, 1) ,只有在您將它們設置為 Workspace.CurrentCamera 後才會更新。視窗尺寸不匹配會導致相機返回具有錯誤 Ray.Direction 的射線。

參數

X 軸上,以像素計算,屏幕點的位置,用於生成 Ray 。這個位置占用了 GUI 插入。

預設值:""

Y 軸上,以像素計算,屏幕點的位置,用於生成 Ray 。這個位置占用了 GUI 插入。

預設值:""
depth: number

深度來自 Camera ,以厘米為單位,用於抵消 Ray 的起源。

預設值:0

返回

單位 , 起源於給定深度遠離 給定屏幕座標位置的相等世界位置。這個射線是在 Camera 的方向上旋轉的。

SetRoll

()

此方法已過時,不再被視為最佳實踐。

這個方法設置 Camera 的目前滾動,以 ради安為單位。滾動在 CFrame 之後應用,代表相攝影機的 Z 軸周圍的旋轉。

例如,以下將反轉 Camera :


local Workspace = game:GetService("Workspace")
Workspace.CurrentCamera:SetRoll(math.pi) -- math.pi radians = 180 degrees

SetRoll對使用 CFrame 屬性應用的任何滾動沒有影響。使用「設定滾動」應用的滾動不會反映在 CFrame 屬性中,但會反映在 CFrameGetRenderCFrame() 返回的滾動中。

此方法只能在 CameraType 設為 Scriptable 時使用,無論是否使用預設相機腳本。如果與其他 CameraType 一起使用,在輸出中會提供警告。

使用此方法應用的任何滾動將在 CameraTypeScriptable 變更時丟失。

使用此方法獲得滾動集合使用 GetRoll()

由於此方法已過時,建議您使用 Camera 屬性來應用滾動到 CFrame 。例如:


local Workspace = game:GetService("Workspace")
local currentCFrame = Workspace.CurrentCamera.CFrame
local rollCFrame = CFrame.Angles(0, 0, roll)
Workspace.CurrentCamera.CFrame = currentCFrame * rollCFrame

參數

rollAngle: number

在 radians 中應用到 Camera 的滾動角度。

預設值:""

返回

()

ViewportPointToRay

平行寫入

這個方法從裝置安全視窗坐標中的 2D 位置創建單位 Ray ,定義在像素中。射線起源於 Vector3 世界上給定深度 (以磚格為單位) 的 2D 位置的等值 (Camera )。

如下圖所示,(0, 0) 對應 Roblox 上方欄的左上角。這意味著輸入的 2D 位置不會計算 在插入中的 CoreUISafeInsets,但會計算任何 DeviceSafeInsets

Diagram showing the origin of the device safe area viewport coordinate system.

請注意,使用者介面實例使用不同的坐標系統(GuiObject.AbsolutePosition 使用 CoreUISafeInsets 視窗坐標系統,而此方法使用 DeviceSafeInsets 視窗坐標系統)。如果您想在核心 UI 坐標中指定位置,請使用 ScreenPointToRay()

請注意,此方法只適用於 Workspace.CurrentCamera 攝影機。其他相機,例如您為 ViewportFrame 創建的相機,初始視區尺寸為 (1, 1) ,只有在您將它們設置為 CurrentCamera 後才會進行更新。視窗尺寸不匹配會導致相機返回具有錯誤 Ray.Direction 的射線。

這種方法可以與 ViewportSize 屬性一起使用,以從屏幕中心創建射線,例如:


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local viewportPoint = camera.ViewportSize / 2
local unitRay = camera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)

因為創建的 Ray 單位射線只有一個螺柱長度,若要創建更長的射線,您可以執行以追蹤中操作:


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local length = 500
local unitRay = camera:ScreenPointToRay(100, 100)
local extendedRay = Ray.new(unitRay.Origin, unitRay.Direction * length)

參數

X 軸上,以像素計算,視窗點的位置,在裝置安全區域協調坐標中產生 Ray , 在裝置安全區域協調坐標中產生

預設值:""

Y 軸上,以像素計算的視窗點的位置,用於產生 Ray ,在裝置安全區域協調坐標中。

預設值:""
depth: number

深度來自 Camera ,以厘米為單位,用於抵消 Ray 的起源。

預設值:0

返回

單位 Ray , 起源於等值的 Vector3 世界位置的給定視窗坐標在給定深度遠離 Camera 。這個射線是在 Camera 的方向上旋轉的。

WorldToScreenPoint

平行寫入

此方法返回 Vector3 worldPoint 屏幕位置和深度以及此點是否在屏幕範圍內。

這個方法會考慮當前的 GUI 插入,例如頂部欄的空間,因此返回的 2D 位置與 GUI 位置相同,可用於放置 GUI 元素。對於忽略 GUI 插入的相同方法,請參閱 WorldToViewportPoint()


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local 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 是否在屏幕範圍內的 boolean 將是 true 無論點是否被 BasePartsTerrain 遮蓋。

參數

worldPoint: Vector3

世界位置 Vector3

預設值:""

返回

包含順序的 tuple:

  • 一個 Vector3XY 組件代表從屏幕左上角的偏移 worldPoint ,以像素計算。 Z 組件代表從屏幕深度 (以厘米計)。

  • 一個是否指示 worldPoint 是否在畫面範圍內的 boolean。

WorldToViewportPoint

平行寫入

此方法返回 Vector3 worldPoint 屏幕位置和深度以及此點是否在屏幕範圍內。

此方法不會考慮當前的 GUI 插入,例如頂部欄的空間,因此返回的 2D 位置來自視角左上角。除非您使用 ScreenGui.IgnoreGuiInset , 這個位置不適合放置 GUI 元素。

對於其他相同的方法,負責 GUI 插入,請參閱 WorldToScreenPoint()


local Workspace = game:GetService("Workspace")
local camera = Workspace.CurrentCamera
local 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 是否在屏幕範圍內的 boolean 將是 true 無論點是否被 BasePartsTerrain 遮蓋。

參數

worldPoint: Vector3

世界位置 Vector3

預設值:""

返回

包含順序的 tuple:

  • A 其 X 和 Y 組件代表從視角左上角的偏移,以像素計算。 Z 組件代表從屏幕深度 (以厘米計)。

  • 一個是否指示 worldPoint 是否在畫面範圍內的 boolean。

ZoomToExtents

()

參數

boundingBoxCFrame: CFrame
預設值:""
boundingBoxSize: Vector3
預設值:""

返回

()

活動

InterpolationFinished

Camera 使用 Camera:Interpolate() 方法完成插入時,此事件發生。如果青少年因為 Camera:Interpolate() 再次被呼叫而中斷,它不會發射。

建議您使用 TweenService 來動畫 Camera ,因為它更可靠且提供更多緩和風格的選擇。