Tạo và Respawn

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Spawning là quá trình tạo một đối tượng hoặc nhân vật trong một trải nghiệm, và respawning là quá trình thêm một đối tượng hoặc nhân vật vào trải nghiệm sau khi họ đạt được một điều kiện loại bỏ, ch

Sử dụng kinh nghiệm sample laser tag experience như một tham khảo, bài này của hướng dẫn cho bạn cách sử dụng và tùy chỉnh các tính năng tích hợp của Roblox để xử lý việc tạo và tái tạo, bao gồm hướng dẫn scripting trên:

  • Tùy chỉnh vị trí đẻ trứng để người chơi chỉ có thể đẻ trứng trong khu vực đẻ trứng của đội họ.
  • Thêm những người chơi mới và nhân vật của họ vào trò chơi khi họ tham gia trải nghiệm.
  • Tùy chỉnh các trường lực ngăn chặn sát thương khi người chơi xuất hiện và tái sinh.
  • Xử lý tình trạng client để gameplay hoạt động đúng lúc.
  • Tái sinh những nhân vật sau khi chúng bị thẻ ra khỏi vòng.
  • Thực hiện các hành động nhỏ, phức tạp khác nhau mà rất quan trọng để cài đặt các tham số trò chơi và nhân vật.

Phần này bao gồm rất nhiều nội dung script, nhưng thay vì viết mọi thứ từ đầu khi tạo một trải nghiệm, nó khuyến khích bạn tận dụng các thành phần hiện có, nhanh chóng iteate và tìm ra các hệ thống cần một giải pháp tùy chỉnh để phù hợp với

Tùy chỉnh vị trí phát

Nếu bạn chơi thử trải nghiệm ngay bây giờ, tất cả các người chơi sẽ ngẫu nhiên xuất hiện ở SpawnLocation đối tượng trong khu vực phát triển của đội xanh lá cây hoặc SpawnLocation đố

Để combat this problem, the sample laser tag experience configures both spawn locations with a Neutral property set to false to restrict the opposing team's players from spawning in the wrong spawn zone, and a Class.SpawnLocation.TeamColor|TeamColor</

  • TeamASpawn – Địa điểm spawn trong khu vực spawn của đội xanh với một TeamColor property set to Mint .
  • TeamBSpawn – Địa điểm spawn trong khu vực spawn của đội hồng với một TeamColor thuộc tính được đặt thành Hoa hồng Pink .
TeamASpawn
TeamBSpawn

Khi một người chơi tham gia trải nghiệm, ServerScriptService > Gameplay > Rounds > 1> Rounds1> > 4> spawntPlayersInMap4> kiểm tra để xem có bao nhiêu người chơi trong mỗi đội, sau đó trả lại đội với số lượng người chơi ít nhất.

gọiNgười chơi trong map

local function getSmallestTeam(): Team
local teams = Teams:GetTeams()
-- Sắp xếp các đội theo thứ tự từ nhỏ nhất đến lớn nhất
table.sort(teams, function(teamA: Team, teamB: Team)
return #teamA:GetPlayers() < #teamB:GetPlayers()
end)
-- Quay trở lại đội nhỏ nhất
return teams[1]
end

Một khi nó biết đội với số lượng người chơi ít nhất, nó sắp xếp người chơi vào đó, đặt độ đồ Player.Neutral của họ đến false để người chơi chỉ có thể xu

gọiNgười chơi trong map

local function spawnPlayersInMap(players: { Player })
for _, player in players do
player.Team = getSmallestTeam()
player.Neutral = false
player:SetAttribute(PlayerAttribute.playerState, PlayerState.SelectingBlaster)
task.spawn(function()
player:LoadCharacter()
end)
end
end

Nếu bạn xem Workspace > World > Map > 1>Spawns1> , bạn có thể thấy rằng có mộ

Ví dụ, nếu hiệp đấu đang diễn ra, thì Neutral tính năng đặt giá trị trên

Neutral

Để minh họa, nếu bạn xem ServerScriptService > Gameplay > Rounds > 1> SpawnPlayersInLobby1>, mà chạy ở cuối của một vòng, bạn có thể thấy rằng cho mỗi người chơi được truyền vào bảng 4>players: player

  • Đặt định hướng của họ Player.Neutral để true để tự động thiết lập họ Player.Team đến nil, cho phép người chơi respawn trong lobby khi một vòng không đang diễn ra, vì định hướng của sp
  • Đổi PlayerState của họ thành InLobby để loại bỏ hình ảnh người chơi và UI người chơi thứ nhất.

Để biết thêm thông tin về khu vực sinh sản trung tín và các chức năng của nó cho mỗi vòng, xem Thêm vòng trong một phần tiếp theo của hướng dẫn.

chơiNgười chơiTrongLobby

local function spawnPlayersInLobby(players: { Player })
for _, player in players do
player.Neutral = true
player:SetAttribute(PlayerAttribute.playerState, PlayerState.InLobby)
task.spawn(function()
player:LoadCharacter()
end)
end
end

Kết Nối Người Chơi Mới

Mã Luau trong Studio thường được lái xe bởi các sự kiện, có nghĩa là các script lắng nghe các sự kiện từ một dịch vụ Roblox, sau đó gọi một hàm để phản hồi. Ví dụ, khi thêm các người chơi mới vào một trải nghiệm nhiều người chơi, có

Players.PlayerAdded:Connect là một phần của nhiều script trong trải nghiệm. Nếu bạn sử dụng các tổ hợp phím Ctrl/Commands+Shift+F và tìm kiếm Players.PlayerAdded:Connect , kết quả cung cấp một điểm xuất phát tốt để hiểu cấu hình ban đầu của

Studio's Find All window with the Players.PlayerAdded results highlighted.

Để minh họa, mở ServerScriptService > SetupHumanoid . Sự khác biệt giữa Player và 1> Class.Player.Character|Character1> là chìa khóa để hiểu những kịch bản này:

  • Một player là một khách hàng kết nối, và một nhân vật là một mô hình Humanoid.
  • Người chơi cần phải chọn một kẻ cướp và được thêm vào bảng xếp hạng. Người chơi cần phải sinh sản và nhận một kẻ cướp.

SetupHumanoid ngay lập tức kiểm tra xem người chơi có một nhân vật (chỉ vừa tham gia) hay không (đang t

setupHumanoidAsync

local function setupHumanoidAsync(player: Player, humanoid: Humanoid)
humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.Subject
humanoid.NameDisplayDistance = 1000
humanoid.HealthDisplayDistance = 1000
humanoid.NameOcclusion = Enum.NameOcclusion.OccludeAll
humanoid.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOn
humanoid.BreakJointsOnDeath = false
humanoid.Died:Wait()
onHumanoidDied(player, humanoid)
end

Ghi chú quan trọng với脚本 này là các thuộc tính hoàn toàn tùy chọn, có nghĩa là nếu bạn xóa sáu dòng đầu tiên của chức năng, trải nghiệm vẫn hoạt động đúng cách. Thay vì là các yêu cầu chức năng, mỗi thuộc tính cho phép bạn đưa ra các quyết định thiết kế phù hợp vớ

  • Nếu bạn muốn tên nhân vật được hiển thị ở khoảng cách gần hơn, giảm giá trị của Humanoid.NameDisplayDistance .
  • Nếu bạn chỉ muốn hiển thị sức khỏe của một nhân vật nếu nó dưới 100%, hãy đặt Humanoid.HealthDisplayType để hiển thị khi bị hư hỏng .
  • Nếu bạn muốn nhân vật phá hủy khi sức khỏe của họ đạt đến 0, hãy đặt Humanoid.BreakJointsOnDeath lên True .

Nếu bạn thay đổi giá trị của các thuộc tính này, quan trọng là bạn có thể chơi thử để xem ảnh hưởng của các cài đặt mới của bạn. Bạn có thể tái tạo những gì người chơi trải nghiệm trong một môi trường nhiều người chơi bằng cách chọn ít nh

Studio's Test tab with the the players dropdown highlighted. This setting needs to be at least two players to see the impact of your new settings.

Một ví dụ khác của sự kiện Players.PlayerAdded:Connect là trong ServerScriptService > PlayerStateHandler . Tương tự như trong ví dụ trư

Người Lập Trạng Thái

local function onPlayerAdded(player: Player)
player.CharacterAdded:Connect(function()
if not player.Neutral then
player:SetAttribute(PlayerAttribute.playerState, PlayerState.SelectingBlaster)
onPlayerStateChanged(player, PlayerState.SelectingBlaster)
end
end)

Một biến cụ thể trong PlayerStateHandler khiến cuộc thảo luận này xứng đáng thảo luận: attributeChangedConnectionByPlayer . Bảng này lư

Người Lập Trạng Thái

local attributeChangedConnectionByPlayer = {}
local function onPlayerAdded(player: Player)
-- Xử lý tất cả các cập nhật tương lai đến trạng thái người chơi
attributeChangedConnectionByPlayer[player] = player
:GetAttributeChangedSignal(PlayerAttribute.playerState)
:Connect(function()
local newPlayerState = player:GetAttribute(PlayerAttribute.playerState)
onPlayerStateChanged(player, newPlayerState)
end)
end
-- Ruột kết nối từ thuộc tính thay đổi kết nối khi người chơi rời đi
local function onPlayerRemoving(player: Player)
if attributeChangedConnectionByPlayer[player] then
attributeChangedConnectionByPlayer[player]:Disconnect()
attributeChangedConnectionByPlayer[player] = nil
end
end

Bạn có thể thấy rằng cả hai chức năng kết nối trong onPlayerAdded() gọi onPlayerStateChanged() . Khi cài đặt

Người Lập Trạng Thái

local function onPlayerStateChanged(player: Player, newPlayerState: string)
-- Tình trạng Blaster chỉ là 'Sẵn sàng' nếu tình trạng người chơi là 'Chơi'
local newBlasterState = if newPlayerState == PlayerState.Playing then BlasterState.Ready else BlasterState.Disabled
-- Lập trình độ hủy diệt trường lực khi người chơi bắt đầu chơi
if newPlayerState == PlayerState.Playing then
scheduleDestroyForceField(player)
end
player:SetAttribute(PlayerAttribute.blasterStateServer, newBlasterState)
end

Nếu bạn thêm các điểm dừ

Tùy chỉnh trường lực

Thay vì sử dụng một giải pháp tùy chỉnh, trải nghiệm laser tag mẫu ForceField của Studio sử dụng SpawnLocation.Duration tính nă

Tương tự như setupHumanoidAsync , hầu hết các dòng trong ForceFieldClientVisuals là tùy chọn. Ví dụ, nếu bạn bình luận nội dung của chức năng như trong StarterGui > 1>ForceFieldGui1> , trải nghiệm sử dụ

Bình luận các thuộc tính trong ForceFieldClientVisuals

local function onCharacterAddedAsync(character: Model)
-- ForceField = character:WaitForChild("ForceField", 3)
-- nếu không forceField thì
-- quay lại
-- kết thúc
-- forceField.Visible = false
-- localPlayer.PlayerGui:WaitForChild("ForceFieldGui") Đã bật
-- forceField.Destroying:Chờ đợi
-- localPlayer.PlayerGui.ForceFieldGui.Enabled = false
end

Vì các lực lượng tùy chỉnh không phải là một GUI mà là một new ParticleEmitter , script ForceFieldClientVisuals chỉ ảnh hưởng đến các visuals người chơi thứ nhất, không phải là visual

First-person force field visuals include a futuristic hexagonal grid on the perimeter of the screen.
Các hình ảnh trường lực thứ nhất
Third-person force field visuals include a blue sparkling orb around the player spawning into the experience.
Các hình ảnh của trường lực thứ ba

Các trường lực hữu ích vì chúng cung cấp cho người chơi đủ thời gian để giữa sinh sản và respawn mà không cần phải lo lắng về những người chơi khác, nhưng cuối cùng chúng cần phải biến mất cho các trò trải nghiệm trò chơilaser chính. Script xử lý việc xóa trường lực

  • Sau khi người chơi chọn một blaster, các trường lực lượng phải tồn tại đủ lâu để cho phép người chơi thích nghi với môi trường xung quanh.
  • Trong thời gian đó, trường lực không thể là một lợi thế, vì vậy chúng cần phải biến mất khi một người chơi thổi hơi cường độ của họ.
  • Các trường lực cần phải biến mất khi người chơi thiết lập lại nhân vật của họ trước khi phát nổ hoặc trước khi trường lực lên mức hết hạn.

Mỗi trong số những kiểm tra này trong scheduleDestroyForceField script call endForceField() cho các điều kiện này.

ScheduleForceField

-- Kết thúc trường lực nếu người chơi phá vỡ
local blasterStateAttribute = getBlasterStateAttribute()
attributeChangedConnection = player:GetAttributeChangedSignal(blasterStateAttribute):Connect(function()
local currentBlasterState = player:GetAttribute(blasterStateAttribute)
if currentBlasterState == BlasterState.Blasting then
endForceField()
end
end)
-- Kết thúc trường lực nếu người chơi thiết lập lại
characterRespawnedConnection = player.CharacterRemoving:Connect(endForceField)
-- Kết thúc trường lực sau 8 giây
task.delay(MAX_FORCE_FIELD_TIME, endForceField)

endForceField() bao gồm một tuyên bố if kỳ lạ ở khu vực forceFieldEnded của hàm 0> endForceField0>. Vì các hàm chạy theo thứ tự, script có thể gọi hàm endForceField()3> một ho

ScheduleForceField

local function endForceField()
if forceFieldEnded then
return
end
forceFieldEnded = true
attributeChangedConnection:Disconnect()
characterRespawnedConnection:Disconnect()
destroyForceField(player)
end

Xử lý tình trạng khách hàng

Trong khi phần lớn của bài này tập trung vào ServerScriptService > PlayerStateHandler , thì có một script khác cùng tên trong ReplicatedStorage . Lý do cho sự chia là kiến ​​trúc client-server:

  • Client cần phải hiểu thông tin tình trạng người chơi để có thể phản hồi phù hợp trong thời gian thực, chẳng hạn như hiển thị các thành phần người dùng phù hợp hoặc cho phép người chơi di chuyển và phát nổ.

  • Máy chủ cần tất cả thông tin này để ngăn chặn các cuộc tấn công. Ví dụ, máy chủ cũng cần tình trạng người chơi để thực hiện các hành động như tạo và trang bị nhân vật, tắt các trường lực và hiển thị bảng xếp hạng. Đây là lý do tại sao script này

Để xem những hợp lý này, hãy xem những mảnh script sau đây trong ReplicatedStorage > PlayerStateHandler để xác minh trạng thái hiện tại của người dùng, sau đó gọi các chức năng tương ứng cho trạng thái đó.

Người Lập Trạng Thái

local function onPlayerStateChanged(newPlayerState: string)
if newPlayerState == PlayerState.SelectingBlaster then
onSelectingBlaster()
elseif newPlayerState == PlayerState.Playing then
onPlaying()
elseif newPlayerState == PlayerState.TaggedOut then
onTaggedOut()
elseif newPlayerState == PlayerState.InLobby then
onInLobby()
else
warn(`Invalid player state ({newPlayerState})`)
end
end

Tất cả các phản hồi của sự kiện được liên kết hợp trong những câu này vì chúng yêu cầu hành vi tương tự để bật hoặc vô hiệu hóa các điều khiển người chơi, di chuyển máy

Người Lập Trạng Thái

local function onSelectingBlaster()
togglePlayerCamera(true)
togglePlayerMovement(false)
setGuiExclusivelyEnabled(playerGui.PickABlasterGui)
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end

Hàm onPlaying() tương tự như vậy. Nó bật chuyển động, mở đầu vào màn hình chính (HUD), kích hoạt blaster và gọi cùng một hàm trường lực như máy chủ.

Người Lập Trạng Thái

local function onPlaying()
togglePlayerMovement(true)
setGuiExclusivelyEnabled(playerGui.HUDGui)
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Ready)
scheduleDestroyForceField()
end

Tái tạo nhân vật

Trải nghiệm laser tag mẫu xử lý lại nhân vật về một vòng thông qua trạng thái onTaggedOut() trong ReplicatedStorage > <

Người Lập Trạng Thái

local function onTaggedOut()
-- Vô hiệu hóa điều khiển khi bị nhãn
togglePlayerMovement(false)
togglePlayerCamera(false)
setGuiExclusivelyEnabled(playerGui.OutStateGui)
-- Vô hiệu hóa blaster khi bị thẻ ra
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end

Nếu bạn muốn kiểm tra hành vi này, bạn có thể nhấn Esc, chuyển đến tab Cài đặt , sau đó nhấp vào nút Thiết lập lại nhân vật . Lưu ý rằng khi bạn kích hoạt màn hình respawn, bạn không thể di chuyển, quay camera hoặc thổi báo súng.

Roblox's settings menu with the Reset Character button highlighted.
Nút Đặt lại Nhân vật
The respawn screen displays as a player respawns back into the round.
Màn Hình Respawn

Làm điều đó để lưu cho bạn và những ng

Khi người chơi được thả trở lại vào trò chơi, họ sẽ được thả lại tại vị trí đẻ trứng của đội họ theo định dạng SpawnLocation.TeamColor . Để tùy chỉnh thời gian thả, bạn có thể thêm dòng sau đến đ

Cấu hình người

local Players = game:GetService("Players")
Players.RespawnTime = 10 -- new line, in seconds

Cài đặt khác

Là một phần của quá trình khởi tạo ban đầu, trải nghiệm laser thử nghiệm cũng thực hiện một vài bước nhỏ nhưng quan trọng:

  • Trải nghiệm bao gồm một script trống có tên StarterPlayer > StarterCharacterScripts > Health > 1> Roblox health regen disabled1> để tắt sự tái tạo sức khỏe mặc định của Roblox. Để hiểu biết hành vi của thuộc tính này, xem 4>Class.Humanoid.Health

  • Trải nghiệm sử dụng một máy quay thứ nhất bằng cách cài đặt StarterPlayer.CameraMode.LockFirstPerson tính năng. Lưu ý rằng nếu bạn muốn cho phép người dùng thay đổi giữa các máy quay thứ nhất và thứ ba, bạn phải thay đổi chương trình cài đặt thay v

  • Trải nghiệm sử dụng bảng xếp hạng Roblox tích hợp với đơn vị "điểm", mà người chơi kiếm được mỗi lần họ thẻ một người chơi khá

Bây giờ khi người chơi có thể xuất hiện, chọn một blaster, và mục tiêu nó từ một góc nhìn thứ nhất, bài đăng tiếp theo dạy bạn về những script đằng sau việc tạo ra trải nghiệm trò chơidựa trên vòng.