การเรียกวิธีการสร้างวัตถุหรือตัวละครในประสบการณ์ คือกระบวนการสร้างวัตถุหรือตัวละครในประสบการณ์ และ การเรียกคืน คือกระบวนการเพ
โดยใช้ประสบการณ์ เลเซอร์เวทย์ตัวอย่าง เป็นตัวอ้างอิง ส่วนนี้ของการกวดวิชาสอนคุณวิธีการใช้และปรับแต่งคุณสมบัติที่ติดตั้งของ Roblox เพื่อจัดการการเกิดและการเกิดใหม่รวมถึงการสคริ
- การกำหนดตำแหน่งการเรียกให้ผู้เล่นสามารถเรียกในพื้นที่เรียกของทีมของพวกเขาเท่านั้น
- เพิ่มผู้เล่นใหม่และตัวละครของพวกเขาในรอบเมื่อพวกเขาเข้าร่วมประสบการณ์
- กําหนดขีดจํากัดแรงที่ป้องกันความเสียหายเมื่อผู้เล่นเกิดและรีสปาวน์
- การจัดการสถานะของลูกค้าเพื่อให้การเล่นเกมทำงานได้อย่างถูกต้องในเวลาที่เหมาะสม
- การเรียกตัวละครใหม่หลังจากที่พวกเขาถูกแท็กออกจากรอบ
- การทำงานเล็กน้อยที่ไม่มีประโยชน์ที่จำเป็นสำหรับการตั้งค่าตัวละครและตัวละคร
ส่วนนี้รวมถึงเนื้อหาสคริปต์จำนวนมาก แต่แทนที่จะเขียนทุกอย่างจากเริ่มต้นเมื่อสร้างประสบการณ์ มันจะเปิดเผยให้คุณเห็นว่าส่วนประกอบใดที่ต้องการการปรับแต่งแบ
จัดเค้าโครงสถานที่เรียกร้อง
หากคุณจะทดสอบประสบการณ์ในขณะนี้, ผู้เล่นทั้งหมดจะปรากฏขึ้นสุ่มที่ SpawnLocation วัตถุในเขตพื้นที่เริ่มต้นของทีมสีเขียวหรือ Class.SpawnLocation
เพื่อต่อสู้กับปัญหานี้ ตัวอย่างเลเซอร์แท็งก์ประสบการณ์การกำหนดสถานที่เกิดขึ้นทั้งหมดด้วยค่า
เมื่อผู้เล่นเข้าร่วมประสบการณ์ ServerScriptService > Gameplay > Rounds > 1> Rounds1> > 4> สร้างผู้เล่นในแผนที่4> ตรวจสอบว่าจำนวนผู้เล่นในแต่ละทีมน้อยที่สุด แล้วกลั
เรียกผู้เล่นในแผนที่
local function getSmallestTeam(): Team
local teams = Teams:GetTeams()
-- เรียงทีมตามลำดับจากเล็กที่สุดไปยังใหญ่ที่สุด
table.sort(teams, function(teamA: Team, teamB: Team)
return #teamA:GetPlayers() < #teamB:GetPlayers()
end)
-- กลับทีมเล็กที่สุด
return teams[1]
end
เมื่อมันรู้ทีมที่มีจำนวนผู้เล่นน้อยที่สุดมันจะเรียงผู้เล่นในทีมนั้น, ตั้งค่าคุณสมบัติของพวกเขา Player.Neutral ให้เป็น
เรียกผู้เล่นในแผนที่
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
หากคุณตรวจสอบ Workspace > World > Map > 1> Spawns1> คุณสามารถดู
เช่นเดียวกับการเปิดใช้งานในรอบนี้ค่า Neutral จะตั้
เพื่อแสดงให้เห็นว่า, ถ้าคุณตรวจสอบ ServerScriptService > Gameplay > Rounds > 1> SpawnPlayersInLobby1> , ซึ่งเปิดในตอนท้ายของรอบ, คุณสามารถเห็นได้ว่าสำหรับผู
- ตำแหน่งของการเกิดใหม่Player.Neutral ให้เป็นค่า true เพื่อรีเซ็ต Player.Team ให้เป็น nil โดยอนุญาตให้ผู้เล่น respawn ในล็อบบี้เมื่อไม่ม
- เปลี่ยน PlayerState ของพวกเขาเป็น InLobby เพื่อลบวิดีโอ UI ของผู้เล่นและประสิทธิภาพของ blaster ของผู้เล่น
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเขตออกมาในที่สมบูรณ์ประกายเงาและความสามารถของมันสำหรับแต่ละรอบดูใน เพิ่มรอบ ในส่วนต่อไปของการกวดวิชา
เรียกผู้เล่นในล็อบบี้
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
เชื่อมต่อผู้เล่นใหม่
รหัส Luau ใน Studio มักจะเป็นรหัสที่ขับเคลื่อนโดยอีเว้นท์ ซึ่งหมายความว่าสคริปต์จะฟังอีเว้นท์จากบริการ Roblox แล้วจากนั้นจะโทรหาฟังก์ชันในการตอบกลับ ตัวอย่าง
Players.PlayerAdded:Connect เป็นส่วนหนึ่งของสคริปต์หลายอันในประสบการณ์ หากคุณใช้สั้นลัด Ctrl/Commands+Shift+F และค้นหาสำหรับ Players.PlayerAdded:Connect ผลลัพธ์จะให้เป็นจุดเริ่มต้นที่ดีสำ
เพื่อแสดงให้เห็น เปิด ServerScriptService > การตั้งค่า Humanoid ความแตกต่างระหว่าง Player และ 1> Class.Player.Character|Character1> สำคัญในการเข้าใจสคริปนี้:
- ตารางอันดับblaster และได้รับการเพิ่มในกระดานผู้นํา ตัวละครจะต้องเกิดและได้รับ blaster
SetupHumanoid ตรวจสอบทันทีว่าผู้เล่นมีตัวละคร (เพิ่งเข้าร่วม) หรือไม
ตั้งค่า HumanoidAsync
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
โน้ตสำคัญกับสคริปต์นี้คือคุณสมบัติเป็นสิ่งเลือกอย่างสมบูรณ์ หมายถึงหากคุณลบหกบรรทัดแรกของฟังก์ชัน ประสบการณ์ก็ยังทำงานได้อย่างสมบูรณ์ แทนที่จะเป็นตัวตัดสินการออกแบบที่ตรงไปต
- หากคุณต้องการให้ชื่อตัวละครปรากฏในระยะไกล ลดค่าของ Humanoid.NameDisplayDistance
- หากคุณต้องการแสดงสุขภาพของตัวละครเท่านั้นหากมันอยู่ภายใต้ 100% ตั้งค่า Humanoid.HealthDisplayType เป็น แสดงเมื่อเสียหาย * หากคุณต้องการให้ตัวละครพังทลายลงเมื่อพลังชีวิตของพวกเขาถึง 0 ตั้ง Humanoid.BreakJointsOnDeath เป็น จริง หากคุณเปลี่ยนค่าของสมมติทั้งหมดนี้ สิ่งสำคัญคือต้องทดสอบเพื่อให้คุณสามารถดูผลกระทบของการตั้งค่าใหม่ของคุณได้ คุณสามารถสร้างสถานการณ์ที่ผู้เล่นประสบในสภาพแวด
ตัวอย่างอื่นของกิจกรรม Players.PlayerAdded:Connect คือใน ServerScriptService > PlayerStateHandler โดยทันทีตรว
PlayerStateHandler
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)
ตัวแปรหนึ่งใน PlayerStateHandler รับรองการพูดคุย: attributeChangedConnectionByPlayer รับรองการเชื่อมต่อทั้งหม
PlayerStateHandler
local attributeChangedConnectionByPlayer = {}
local function onPlayerAdded(player: Player)
-- จัดการกับการปรับปรุงสถานะผู้เล่นในอนาคตทั้งหมด
attributeChangedConnectionByPlayer[player] = player
:GetAttributeChangedSignal(PlayerAttribute.playerState)
:Connect(function()
local newPlayerState = player:GetAttribute(PlayerAttribute.playerState)
onPlayerStateChanged(player, newPlayerState)
end)
end
-- ตัดการเชื่อมต่อจากค่าตัวละครที่เปลี่ยนแปลงเมื่อผู้เล่นออก
local function onPlayerRemoving(player: Player)
if attributeChangedConnectionByPlayer[player] then
attributeChangedConnectionByPlayer[player]:Disconnect()
attributeChangedConnectionByPlayer[player] = nil
end
end
คุณสามารถดูได้ว่าทั้งสองฟังก์ชันที่เชื่อมต่อใน onPlayerAdded() เรียก on
PlayerStateHandler
local function onPlayerStateChanged(player: Player, newPlayerState: string)
-- สถานะของเครื่องยิงนัดจะเป็น 'พร้อม' เฉพาะถ้าสถานะของผู้เล่นคือ 'เล่น'
local newBlasterState = if newPlayerState == PlayerState.Playing then BlasterState.Ready else BlasterState.Disabled
-- กำหนดเวลาการทำลายล็อกฟิกต์ฟอร์ซเมิลเมื่อผู้เล่นเริ่มเล่น
if newPlayerState == PlayerState.Playing then
scheduleDestroyForceField(player)
end
player:SetAttribute(PlayerAttribute.blasterStateServer, newBlasterState)
end
หากคุณเพิ่ม breakpoints หรือ even just a
ปรับแต่งฟิลด์
แทนที่จะใช้การปรับแต่งการใช้งานเฉพาะในตัวอย่างเลเซอร์แท็กประสบการณ์ใช้งานจาก Studio ในกา
คล้ายกับ setupHumanoidAsync ส่วนใหญ่ของเส้นใน ForceFieldClientVisuals เป็นไปตามความต้องการ เช่นหากคุณควบคุมเนื้อหาของฟังก์ชันเช่นสคริปต์ต่อไปนี้ใน
การแสดงความคิดเห็นของสมบัติใน ForceFieldClientVisuals
local function onCharacterAddedAsync(character: Model)
-- ล็อคอินฟิลด์ = ตัวละคร:WaitForChild("ForceField", 3)
-- ถ้าไม่ forceField แล้ว
-- กลับ
-- ปิด
-- forceField.Visible = ปิด
-- localPlayer.PlayerGui:WaitForChild("ForceFieldGui") เปิดใช้งานแล้ว
-- forceField.Destroying: รอ()
-- localPlayer.PlayerGui.ForceFieldGui.Enabled = ปิด
end
เนื่องจากสนามลựcที่กําหนดเองไม่ใช่ GUI ใหม่ ParticleEmitter สกริปต์ ForceFieldClientVisuals เฉพาะสําหรับผู้เล่นคนแรกเท่านั้น
ฟิลด์อำนาจมีประโยชน์เพราะพวกเขาให้เวลาผู้เล่นเพียงพอในการระหว่างการเกิดขึ้นและการเกิดใหม่โดยไม่จำเป็นต้องกังวลเกี่ยวกับผู้เล่นศัตรู แต่ในที่สุดพวกเขาต
- หลังจากที่ผู้เล่นเลือกบลาสเตอร์ผู้เล่นจะต้องอยู่ในระยะเวลาที่ยาวนานเพียงพอจะให้ผู้เล่นปรับตัวให้เข้ากับสภาพแวดล้อม
- ในระยะเวลาการอุดตันนี้ ฟิลด์อำนาจไม่สามารถเป็นข้อได้เปรียบ ดังนั้นพวกเขาจึงจำเป็นต้องหายไปในขณะที่ผู้เล่นระเบิดนักเล่น
- ต้องมีการเปลี่ยนแปลงอะไรบางอย่างในตัวผู้เล่นก่อนที่จะทำให้ฟิลด์ดันเหลี่ยมจากตัวผู้เล่นหายไปหรือฟิลด์ดันเหลี่ยมจากตัวผู้เล่นจะหมดอายุ
แต่ละของเหล่านี้ตรวจสอบใน scheduleDestroyForceField สคริปต์โทร endForceField() สำหรับเหล่านี้
กำหนดการทำลายล้างของ forcefield
-- ปิดการใช้งานฟิลด์ต่อสู้หากผู้เล่นระเบิด
local blasterStateAttribute = getBlasterStateAttribute()
attributeChangedConnection = player:GetAttributeChangedSignal(blasterStateAttribute):Connect(function()
local currentBlasterState = player:GetAttribute(blasterStateAttribute)
if currentBlasterState == BlasterState.Blasting then
endForceField()
end
end)
-- ปิดการใช้งานฟิลด์ดันหนีถ้าผู้เล่นรีเซ็ต
characterRespawnedConnection = player.CharacterRemoving:Connect(endForceField)
-- สิ้นสุดแรงผลักหลังจาก 8 วินาที
task.delay(MAX_FORCE_FIELD_TIME, endForceField)
endForceField() รวมถึงข้อความที่ดูแปลก ๆ รอบ ๆ ตัวอักษร if ในบรรทัด forceFieldEnded บรรทัดที่สคริปต์สามารถเรียกได้สองหรื
กำหนดการทำลายล้างของ forcefield
local function endForceField()
if forceFieldEnded then
return
end
forceFieldEnded = true
attributeChangedConnection:Disconnect()
characterRespawnedConnection:Disconnect()
destroyForceField(player)
end
จัดการสถานะของลูกค้า
ในขณะที่ส่วนใหญ่ของส่วนนี้เน้นที่ ServerScriptService > PlayerStateHandler มีสคริปต์อื่นของชื่อเดียวกันใน ReplicatedStorage เหตุผลสำหรับการแบ่งนั้นคือการออกแบบของเซิร์ฟเวอร์:
ลูกค้าต้องเข้าใจข้อมูลสถานะของผู้เล่นเพื่อให้สามารถตอบสนองได้อย่างเหมาะสมในเวลาจริง, เช่น การแสดงผลตัวอักษรผู้ใช้ที่เหมาะสมหรือการเปิดใช้งานปุ่มเปิดและปิด
เซิร์ฟเวอร์ต้องการข้อมูลเหมือนกันทั้งหมดนี้เพื่อให้สามารถป้องกันการโจมตีที่น่ารังเกียจได้ เช่น เซิร์ฟเวอร์ยังต้องการสถานะผู้เล่นเพื่อให้สามารถทำสิ่งเช่นการเร
เพื่อดูเหตุผลการทำงานหลักนี้ให้ดูสคริปต์ต่อไปใน ReplicatedStorage > PlayerStateHandler ซึ่งตรวจสอบสถานะของผู้ใช้แล้วจากนั้นเรียกใช้ฟังก์ชันที่เหมาะสมที่จัดการกับการกระทำสำหรับสถานะนั้น
PlayerStateHandler
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
การตอบสนองของทุกอีเวนต์ถูกรวมอยู่ในสคริปต์นี้เนื่องจากพวกเขาต้องการพฤติกรรมที่คล้ายกันเมื่อเปิดหรือปิดการควบคุมผ
PlayerStateHandler
local function onSelectingBlaster()
togglePlayerCamera(true)
togglePlayerMovement(false)
setGuiExclusivelyEnabled(playerGui.PickABlasterGui)
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
การใช้งาน onPlaying() เช่นกันง่ายแสนง่าย มันเปิดใช้งานการเคลื่อนที่, เปิดใช้งานการเปลี่ยนเป็นหน้าหลักของหน้าจอ (HUD) เปิดใช้งานบลาสเตอร์, และโทรออกฟีเจอร์ฟิลด์เดียวกับเซิร์ฟเวอร์
PlayerStateHandler
local function onPlaying()
togglePlayerMovement(true)
setGuiExclusivelyEnabled(playerGui.HUDGui)
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Ready)
scheduleDestroyForceField()
end
เรียกตัวละครใหม่
ประสบการณ์เลเซอร์แท็กตัวอย่างจัดการการเกิดใหม่ของตัวละครกลับเป็นรอบผ่านสถาน
PlayerStateHandler
local function onTaggedOut()
-- ปิดการใช้งานปุ่มในขณะที่ป้อน
togglePlayerMovement(false)
togglePlayerCamera(false)
setGuiExclusivelyEnabled(playerGui.OutStateGui)
-- ปิดการทำงาน blaster ในขณะที่ป้องกันตัวออก
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
หากคุณต้องการทดสอบพฤติกรรมนี้คุณสามารถกด Esc ไปที่ การตั้งค่า แท็บแล้วคลิกปุ่ม รีเซ็ตตัวละคร ตระหนักว่าเมื่อคุณเรียกใช้หน้าจอเรเสี่นคุณจะไม
สำคัญที่จะทราบว่าสคริปต์นี้ไม่ได
เมื่อผู้เล่นเกิดใหม่ในรอบนั้นพวกเขาจะเกิดใหม่ที่สถานที่เกิดของทีมตามค่า SpawnLocation.TeamColor ของพวกเขา เพื่อปรับเวลาการเกิดใหม่ คุณสามาร
ตั้งค่าHumanoid
local Players = game:GetService("Players")Players.RespawnTime = 10 -- new line, in seconds
การตั้งค่าทั่วไป
ในส่วนของการตั้งค่าเริ่มต้นนั้น ประสบการณ์เลเซอร์เต็มขนาดสามารถทำสิ่งเล็ก แต่สำคัญได้บางอย่างต่อไปนี้:
ประสบการณ์นี้รวมถึงสคริปต์ที่ว่างเปล่าที่มีชื่อว่า StarterPlayer > StarterCharacterScripts > Health ซึ่งปิดการเรียกร้องการฟื้นฟูพลังชีวิตของ Roblox โดยการอธิบายว่าพฤติกร
ประสบการณ์ใช้กล้องมุมมองบุคคลแรกโดยการตั้งค่าสมบัติของ StarterPlayer.CameraMode.LockFirstPerson โปรดทราบว่าหากคุณต้องการให้ผู้ใช้เปลี่ยนระหว่างกล้องมุมบุคคลแรกและกล้องมุมบุ
ประสบการณ์ใช้ตารางจัดอันดับ Roblox ของตัวเองพร้อมด้วยหน่วย "คะแนน" ซึ่งผู้เล่นจะได้รับแต้มทุกค
ตอนนี้ผู้เล่นสามารถเรียกใช้ได้แล้วเลือกบลาสเตอร์และเล็งมันจากมุมมองของผู้ชมคนแรก ๆ การเล่นเกม