Cái nhìn của người dùng về thế giới được đại diện bởi một đối tượng Camera. Bạn có thể thay đổi hành vi của camera để phù hợp với trải nghiệm của mình theo nhiều cách khác nhau. Ví dụ, camera có thể phản ứng với các sự kiện trong thế giới, chẳng hạn như rung lắc khi một con quái vật đi ngang qua, hoặc cố định ở bên cạnh nhân vật của người dùng, như trong một trò chơi cuộn bên.
Tạo camera góc nhìn thứ nhất
Camera góc nhìn thứ nhất là một chế độ xem mà camera giữ cố định với đầu nhân vật, điều này chính xác hơn so với thực tế. Nó thường thấy trong các trải nghiệm bắn súng và kể chuyện, nơi mục tiêu là khiến người dùng cảm thấy đắm chìm trong thế giới.


Trong Studio, đối tượng StarterPlayer chứa một số thuộc tính ảnh hưởng đến camera của người dùng. Thuộc tính CameraMode xác định cách camera hoạt động.
Chọn StarterPlayer.

Thay đổi CameraMode thành LockFirstPerson. Điều này đảm bảo camera của người dùng không di chuyển ra khỏi đầu họ.

Chơi thử để xem camera góc nhìn thứ nhất hoạt động.
Tạo camera cuộn bên
Một chế độ xem cuộn bên giữ camera ở một vị trí cố định so với bên cạnh nhân vật, tạo cho thế giới một cảm giác hai chiều.

Viết kịch bản cho camera
Mở rộng StarterPlayer, và trong StarterPlayerScripts thêm một LocalScript có tên là CameraManager.

Ở đầu kịch bản, sao chép và dán đoạn mã mẫu sau để lấy Players service, và sau đó trong một biến mới lấy người dùng địa phương.
local Players = game:GetService("Players")local player = Players.LocalPlayerTạo một hàm có tên là updateCamera. Điều này chứa logic cần thiết để lấy và thiết lập vị trí mới cho camera.
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal function updateCamera()endBên trong hàm, lấy mô hình nhân vật của người dùng và kiểm tra xem nó có tồn tại bằng cách sử dụng câu lệnh if.
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal function updateCamera()local character = player.Characterif character thenendend
Chỉ định camera
Tất cả các mô hình nhân vật đều chứa một phần có tên là HumanoidRootPart, có thể được sử dụng để lấy vị trí của nhân vật trong thế giới. Điều này thiết lập vị trí mà camera sẽ chỉ tới.
Sử dụng FindFirstChild để lấy HumanoidRootPart và kiểm tra nó có tồn tại bằng cách sử dụng câu lệnh if.
local Players = game:GetService("Players")local player = Players.LocalPlayerlocal function updateCamera()local character = player.Characterif character thenlocal root = character:FindFirstChild("HumanoidRootPart")if root thenendendendVị trí của HumanoidRootPart thực sự thấp hơn đầu người dùng 2 studs. Để sửa điều này, hãy thêm một Vector3 mới với chiều cao là 2 studs vào vị trí của root.
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
Thiết lập vị trí camera
Camera cũng cần một vị trí. Để tạo cho cái nhìn của người dùng một cái nhìn cuộn bên 2D, camera cần nhìn trực tiếp vào bên của nhân vật. Đặt camera ở bên cạnh người dùng bằng cách thêm chiều sâu vào chỉ trục Z của vị trí camera bằng cách sử dụng một 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
Cập nhật CurrentCamera
Bây giờ các biến cho vị trí camera và mục tiêu của camera đã sẵn sàng, đã đến lúc cập nhật vị trí của camera. Bạn có thể truy cập camera của người dùng thông qua thuộc tính CurrentCamera của Workspace. Camera có một thuộc tính CFrame để xác định vị trí của nó.
Bạn có thể sử dụng CFrame.lookAt() để cập nhật camera. Nó nhận hai vị trí và tạo một CFrame nằm ở vị trí đầu tiên chỉ về vị trí thứ hai. Sử dụng CFrame.lookAt() để tạo một CFrame được đặt ở cameraPosition và chỉ về rootPosition.
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
Đồng bộ camera
Bước cuối cùng là chạy hàm này liên tục để giữ camera đồng bộ với người dùng. Hình ảnh mà người dùng thấy đang được làm mới liên tục. Khoảng thời gian mà tất cả các phép toán cần thiết mất để thực hiện được gọi là bước render.
RunService:BindToRenderStep() giúp đơn giản hóa việc thực thi một hàm trên mỗi khung hình bằng cách chấp nhận ba tham số này:
- name - Tên của binding này, nên là duy nhất để không xung đột với các hàm khác có cùng tên.
- priority - Số càng cao thì mức độ ưu tiên càng cao. Hàm này nên chạy sau bản cập nhật camera mặc định của Roblox, vì vậy mức độ ưu tiên được đặt cao hơn 1 cấp so với RenderPriority của camera nội bộ.
- function - Hàm sẽ được liên kết với bước render.
Sử dụng RunService:BindToRenderStep() để liên kết hàm updateCamera với bước render.
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)Chơi thử đoạn mã của bạn. Sử dụng các phím A và D để di chuyển nhân vật của bạn từ bên này sang bên kia.
Tạo camera isometric
Cấu trúc cơ bản của việc lấy vị trí của người dùng và cập nhật vị trí camera mỗi khung hình có thể được điều chỉnh cho nhiều kiểu camera khác nhau, chẳng hạn như một camera isometric. Một camera isometric là một cái nhìn 3D chỉ xuống một góc cố định về phía nhân vật người dùng.

Chỉnh sửa vị trí và cái nhìn
Sử dụng mã từ ví dụ trước, chỉnh sửa cameraPosition để thêm cùng một lượng vào cả 3 chiều.
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)Thay đổi thuộc tính FieldOfView của camera mô phỏng việc phóng to và thu nhỏ, điều này có thể tạo ra một cái nhìn phẳng hơn. Hãy thử đặt giá trị thành 20 để phóng to và tăng khoảng cách của camera từ người dùng để bù lại.
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()
Bằng cách thay đổi cách camera hoạt động, bạn có thể đạt được một cái nhìn hoàn toàn mới cho trải nghiệm của mình. Hãy xem liệu bạn có thể thay đổi cameraPosition để đạt được một camera nhìn từ trên xuống với cùng một đoạn mã. Hãy thử điều chỉnh các thiết lập để có được kết quả mà bạn thích!