Oluşturma sadece bir deneyimde bir nesne veya karakter oluşturma işlemini içerir ve respawn bir nesneyi veya karakteri bir deneyimine eklemekten sonra bir nesneyi deneyime eklemek için önemlidir, bir karakterin sağlığının sıfıra ulaşması veya haritadan düşmesi gib
Bu nedenle, bu eğitimin referansı olarak kullanılan örnek lazer etiketi deneyimi size, yazılım hướnglendirmesi dahil, yeniden oluşturma ve yeniden oluşturma işlemlerini ele almanın yollarını gösteriyor:
- Oyuncuların sadece takımlarının oluşturma bölgesine oluşturulabilmesi için oluşturma yerlerini yapılandırıyoruz.
- Deneyime katılan yeni oyuncular ve onların karakterleri tura eklenir.
- Oyuncuların oluşturulması ve yeniden doğmasını engelleyen güç alanlarını özelleştirme.
- Oyun oynanışının uygun anda doğru şekilde çalışması için kullanıcı durumunu ele alır.
- Turun sonunda etiketlenen karakterlerin yeniden doğması.
- Oyun oynatma ve karakter özellikleri ayarları için kritik derecede önemli olan küçük, genel eylemleri yapmak.
Bu bölüm, çok sayıda kod içeriğini içerir, ancak bir deneyimi oluştururken her şeyi yazmayı yerine, mevcut bileşenleri hızlı bir şekilde itereceğinizi ve vizyonunuzu yerine getireceğiniz sistemleri bulacağınızı öğretir. Bu bölümü tamamladıktan sonra, etraftaki göstergeleri izleyen, oyuncunun durumunu izleyen
Oluşturma Konumlarını Yapılandır
Şu anda deneyimin oynanmasını test ederseniz, tüm oyuncular doğal takımın oluşturma bölgesindeki SpawnLocation nesnelerinde veya pembe takımın oluşturma bölgesindeki SpawnLocation nesnelerinde rastgele doğacaktır. Bu, oyuncuların birbirlerine etkis
Bu probleme karşı koymak için, özel bir laser etiketi deneyimi, her iki oluşma yerini de Neutral özelliğiyle spawn yerinde sınırlamak için kı
- TeamASpawn – Yeşil takımın oluşturma bölgesindeki oluşturma yeri, TeamColor özelliği setlenmiş olarak Mint .
- TeamBSpawn – Pink takımının oluşturma bölgesindeki oluşturma yeri, TeamColor özelliği setlenmiş olarak Karnasyon Pembesi olarak.
Bir oyuncu deneyime katıldığında, ServerScriptService > Gameplay > Rounds > 1> Rounds1> > 4> Rounds4> > 7> Rounds7> > 0> Rounds0> > 3> Rounds3> > 6> Rounds6> > 9> Rounds 9> > 2> Rounds2> > 5> Rounds5> > 8> R
spawnOyuncularHaritasında
local function getSmallestTeam(): Team
local teams = Teams:GetTeams()
-- Takımları en küçükten en büyüğe doğru sırala
table.sort(teams, function(teamA: Team, teamB: Team)
return #teamA:GetPlayers() < #teamB:GetPlayers()
end)
-- En küçük takımı iade et
return teams[1]
end
En az oyuncu sayısını bildiğinde, oyuncuyu o takıma sıralar, onların Player.Neutral özelliğini false olarak ayarlar, böylece oyuncu sadece takımlarının oluşturma yerine, ardından PlayerState 'yı seçer,
spawnOyuncularHaritasında
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
Eğer Çalışma Alanı > Dünya > Harita > 1> Harita1> > 4> Oluştur
Örneğin, etkinlik turu aktifse, Neutral özelliği false olarak ayarlandığından,
Göstermek için, ServerScriptService > Gameplay > Rounds > 1> SpawnPlayersInLobby1>, bir turun sonunda çalışan her oyuncuya göre, oyun kaynağını görebilirsiniz ki bu her oyuncunun 4> players: Player 4> tabelasına geçişi için, kodu
- Onların Player.Neutral özelliğini doğru ayarlar ve oyuncuyu lobide yeniden oluşturur, böylece oyun aktif değilken oyuncu lobide yeniden doğar, spawnLocation'nin Class.SpawnLocation.Neutral|Neutral özelliği de ayarlandığı için oyun
- oyuncublaster'ını ve ilk kişi UI görüntülerini kaldırmak için PlayerState 'ını InLobby 'ine değiştirir.
Neutral oluşturma bölgesinin her tur için işlevselliği hakkında daha fazla bilgi için Oluşturma Etapları bölümünün sonraki bölümünde görüntülenen bir bölüm oluşturun.
spawnOyuncularLobby
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
Yeni Oyuncuları Bağla
Stüdyo'daki Luau kodu genellikle etkinlik tabanlıdır, yani scriptler Roblox hizmetinden gelen etkinlikleri dinler ve ardından yanıt olarak bir işlev çağrılır. Örneğin, yeni oyuncular bir çok oyuncu deneyimine eklenirken, etkinlik işleyen bu eşdeğer etkinlik Players.PlayerAdded:Connect dir.
Players.PlayerAdded:Connect deneyiminin bir parçasıdır. Eğer Ctrl/Commands+Shift+F kısayolunu ve arama Players.PlayerAdded:Connect içindeyse, sonuçlar deneyimin ilk kurulumunu anlamak için iyi bir başlangıç noktası sağlar.
Göstermek için, SunucuScriptService > YüklemeHumanoid 'yı açın. Bu senaryonun Player ile 2> Class.Player.Character|Character2> arasındaki farkı anlamak için anahtar bu senaryodur:
- Bir oyuncu bir bağlantılı kliendir ve bir karakter bir Humanoid modelidir.
- Oyuncular bir blaster seçmelidir ve liderlik tablosueklenmelidir. Karakterlerin bir blaster oluşturması ve bir blaster alması gerekir.
SetupHumanoid derhal oyuncunun bir karaktere sahip olup olmadığını kontrol eder (yalnızca katıldı). Sonra birini bulduktan sonra
İnsanoidAsync'ı yapılandır
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
Bu senaryonun önemli notu, özelliklerin tamamen op션 olduğudur, yani eğer işlevin ilk altı satırını kaldırsanız deneyim hala işlevsel olarak çalışır. Tasarım hedeflerinizle uyumlu olmak için her bir özellik yapabilirsiniz. Örneğin:
- Karakter isimlerinin yakın mesafelerde görüntülenmesini istiyorsanız, Humanoid.NameDisplayDistance değerini azaltın.
- Sadece bir karakterin sağlığını gösterirse, %100'nin altındaysa, Humanoid.HealthDisplayType’yı Hasarlandığında Göster’ye ayarların.
- Karakterlerin sağlığı 0'a ulaştığında parçalanmasını istiyorsanız, Humanoid.BreakJointsOnDeath 'i Açık olarak ayarlayın.
Bu özelliklerin değerlerini değiştirirseniz, yeni ayarlarınızın etkisini görebilmek için oyun test etmek önemlidir. Clients and Servers sekmesinin Test tabındaki en az iki karakteri seçerek oyun test etmeniz, oyuncuların deneyimine katkıda bulunur.
Players.PlayerAdded:Connect etkinliğinin bir başka örneği ServerScriptService > PlayerStateHandler içindedir. Bu etkinliğin önceki örneği g
Oyuncu Durumu Değiştirici
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 ın bir özelliği, attributeChangedConnectionByPlayer ın tartışılmasını sağlar: Connections . Bu tablama tüm oyuncular
Oyuncu Durumu Değiştirici
local attributeChangedConnectionByPlayer = {}
local function onPlayerAdded(player: Player)
-- Oyuncu durumunun tüm gelecekteki güncellemelerini işleyin
attributeChangedConnectionByPlayer[player] = player
:GetAttributeChangedSignal(PlayerAttribute.playerState)
:Connect(function()
local newPlayerState = player:GetAttribute(PlayerAttribute.playerState)
onPlayerStateChanged(player, newPlayerState)
end)
end
-- Oyuncu ayrıldığında özellik değiştirilmiş bağlantıdan ayrıl
local function onPlayerRemoving(player: Player)
if attributeChangedConnectionByPlayer[player] then
attributeChangedConnectionByPlayer[player]:Disconnect()
attributeChangedConnectionByPlayer[player] = nil
end
end
You can see that both connected functions in onPlayerAdded() call onPlayerStateChanged() . During initial setup after a player sorts into a team, onPlayerAdded() sets 1> PlayerState
Oyuncu Durumu Değiştirici
local function onPlayerStateChanged(player: Player, newPlayerState: string)
-- Blaster durumu sadece oyuncu durumu 'Oynama' olduğunda "Hazır"
local newBlasterState = if newPlayerState == PlayerState.Playing then BlasterState.Ready else BlasterState.Disabled
-- Oyuncu oynamaya başladığında silme gücü algoritmasını planlayın
if newPlayerState == PlayerState.Playing then
scheduleDestroyForceField(player)
end
player:SetAttribute(PlayerAttribute.blasterStateServer, newBlasterState)
end
Eğer breakpoints'ınızı ekler veya sadece bir <
Güç Alanlarını Özelleştir
Özel bir uygulama kullanmak yerine, örnek laser etiketi deneyimi Studio'nun iç built-in ForceField klasını kullanarak oyuncuların blaster'larını seçerken hasar almalar
Benzer topları setupHumanoidAsync , ForceFieldClientVisuals ın çoğu satırı gerekli değildir. Örneğin, aşağıdaki senaryo gibi içeriği yorumlarsanız, deneyim Hexagonal Skript yerine kullanıcı arkasındaki kısa kısa kılıcı alanı kullanır. Ayr
ForceFieldClientVisuals'ta Özellikleri Değerlendirme
local function onCharacterAddedAsync(character: Model)
-- yerel forceField = karakter:WaitForChild("ForceField", 3)
-- ForceField olmadığında
-- döndür
-- bitir
-- forceField.Visible = false
-- localPlayer.PlayerGui:WaitForChild("ForceFieldGui")'i etkinleştirdi
-- forceField.Destroying:Wait()
-- localPlayer.PlayerGui.ForceFieldGui.Enabled = false
end
Özelleştirilmiş güç alanı, yeni bir ParticleEmitter değil, sadece ilk kişi görüntüleri için etkiliyiz, ForceFieldClientVisuals üçüncü kişi görüntüleri üzerinde değiştirilir. üçüncü kişi görüntüleri Rob
Güç alanları kullanışlıdır, çünkü oyuncuların yeniden doğuştan önce yeterli zamanı olurken arasında yeterli zamanı olabilirsiniz, ancak sonunda ana laser etiket oynanışiçin kaybolması gerekir. Force Field Removal'ı ele alan kod ReplicatedStorage > scheduleDestroyForceField , ve üç benzersiz koşulu test eder:
- Oyuncular bir blaster'ı seçtikten sonra, güç alanları oyuncuların çevresine alışmasını sağlayacak kadar sürecek.
- Bu aşırı yakınlaşma sırasında, güç alanları bir avantaj olmaz, bu yüzden bir oyuncu'nun blaster'ını patlattığında kaybolmalıdır.
- Güç alanları, oyuncuların karakterlerini patlatmadan önce veya güç alanı zamanlayıcısının süresi dolduğundan önce oyuncuların karakterlerini silecek şekilde görünmelidir.
Bu koşullar için scheduleDestroyForceField kripti çağrısından önce endForceField() için her bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz bir buz b
ZamanlayıcıGücü Alanı
-- Oyuncu patlarsa sona erişme alanı
local blasterStateAttribute = getBlasterStateAttribute()
attributeChangedConnection = player:GetAttributeChangedSignal(blasterStateAttribute):Connect(function()
local currentBlasterState = player:GetAttribute(blasterStateAttribute)
if currentBlasterState == BlasterState.Blasting then
endForceField()
end
end)
-- Oyuncu sıfırlarsa sona erişim alanı
characterRespawnedConnection = player.CharacterRemoving:Connect(endForceField)
-- 8 saniye sonra güç alanını sona erdir
task.delay(MAX_FORCE_FIELD_TIME, endForceField)
endForceField() includes a seemingly odd if statement around the forceFieldEnded boolean. Because the checks run sequentially, the script can call the 0> endForceField0> function two or even three times. The endForceField()3> boolean ensures that the function only tries to destroy a force field once.
ZamanlayıcıGücü Alanı
local function endForceField()
if forceFieldEnded then
return
end
forceFieldEnded = true
attributeChangedConnection:Disconnect()
characterRespawnedConnection:Disconnect()
destroyForceField(player)
end
Müşteri Durumunu Ele Al
Bu bölümün çoğu, ServerScriptService > PlayerStateHandler ,'e odaklanırken, ReplicatedStorage 'deki başka bir script aynı isimde. Ayrılma nedeni, klien-sunucu arşite:
Oyuncu durum bilgilerini anlaması gerekir, böylece oyunun gerçek zamanlı olarak yanıtlanabilmesi için, örneğin sağ kullanıcı arayüz öğelerini gösteren veya oyuncuları hareket ettiren ve patlatan gibi yanıtlayabilir.
Aynı bilgilere ihtiyacı olduğu için, tüm bu bilgileri kullanabilmek için sunucu aynıdır. Örneğin, sunucu ayrıca karakterleri oluşturup kullanmak, güç alanlarını devre dışı bırakmak ve bir liderlik tablosugöstermek için gereken oyuncu durumuna ihtiyaç duyar. Bu yüzden bu kod ReplicatedStorage içinde bulunur ve sade
Bu çekirdek mantığını görmek için, ReplicatedStorage > PlayerStateHandler > PlayerStateHandler > 1> Aktuel State1> > 4> Aktuel Aktiyonları4> 7>Kullanıcının Aktiyonları7> 9>Aktiyonları9> > 0>Aktiyonları0> > 1>Kullanıcının Aktiyonları 1> > 4>Kullanıcını
Oyuncu Durumu Değiştirici
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üm etkinlik yanıtları bu senaryoda olaylar arasında mantıksal olarak birleştirilmiştir, çünkü oyuncu denetimler, kamerayı ve hangi UI katmanını görüntüleyeceğini gerektirir. Örneğin, blaster seçimi sırasında, oyuncuların hareketini
Oyuncu Durumu Değiştirici
local function onSelectingBlaster()
togglePlayerCamera(true)
togglePlayerMovement(false)
setGuiExclusivelyEnabled(playerGui.PickABlasterGui)
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
The onPlaying() function is similarly straightforward. It enables movement, transition to the main heads-up display (HUD), enable the blaster, and calls the same force field function as the sunucu.
Oyuncu Durumu Değiştirici
local function onPlaying()
togglePlayerMovement(true)
setGuiExclusivelyEnabled(playerGui.HUDGui)
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Ready)
scheduleDestroyForceField()
end
Karakterleri Yeniden Oluştur
Örnek laser etiketi deneyimi, oyuncu durumunu onTaggedOut() devletindeki geçişle yeniden oluşturur. onPlayerStateHandler içindeki
Oyuncu Durumu Değiştirici
local function onTaggedOut()
-- Etiketlenmişken kontrolleri devre dışı bırak
togglePlayerMovement(false)
togglePlayerCamera(false)
setGuiExclusivelyEnabled(playerGui.OutStateGui)
-- Etiketlenmişken blaster'ı devre dışı bırak
localPlayer:SetAttribute(PlayerAttribute.blasterStateClient, BlasterState.Disabled)
end
Bu davranışı test etmek istiyorsanız, Esc tuşuna basabilirsiniz, Ayarlar sayfasına gidin, sonra Karakteri sıfırla düğmesine tıklayın. Fark edin ki, respawn ekranını etkinleştirdiğinizde hareket edemezsiniz, kamerayı döndüremez veya blasterınızı patlatmazsınız.
Bu kodun aslında karakterleri yeniden oluşturmadığını, sadece
Oyuncular turun yeniden oluşturulmasından sonra, SpawnLocation.TeamColor özelliğine göre takımınızın yeniden doğma konumunda yeniden doğarlar. Özelleştirme zamanını özelleştirmek için, Class.Players.RespawnTime ile aşağıdaki satırı ekleyebilir
Yüz ayarlama
local Players = game:GetService("Players")Players.RespawnTime = 10 -- new line, in seconds
Diğer Ayarlar
Başlangıç düzenlemesinin bir parçası olarak, özel laser etiketi deneyimi ayrıca bazı küçük, ancak kritik adımları yerine getirir:
Deneyim, varsayılan Roblox sağlık yenilenmesini devre dışı bırakan StarterPlayer adlı boş bir script içerir. Sağlık adının açıklaması için, Class.Humanoid.Health bakınız.
Deneyim, StarterPlayer.CameraMode.LockFirstPerson özelliğini ayarlayarak bir birinci kişi kamerası kullanır. Kullanıcıların ilk ve üçüncü kişi kameraları arasında değişmesine izin vermek istiyorsanız, özellik programını Studio'da bir kez ayarl etmek yerine, programı yeniden yazmalısınız ve kontrolleri ve UI'yi deği
Deneyim, "nokta" bir oyuncuyu başka bir oyuncuyu etiketlediğinde kazandığı puan ile iç置 Roblox lider tablosunu kullanır. SunucuScriptService > YüklemeTablosu >
Oyuncular artık oluşturulabilir ve bir blaster seçilir ve ilk kişi perspektifinden hedef alınır, bir sonraki bölümde, oyunun yuvarlak temelli oynanışının arkasındaki kodları öğretir.