Üst Öğe: learn-game-mechanics-in-unreal-editor-for-fortnite Order: Type: tutorial Tags: Verse Tags: Çok oyunculu Tags: Takım Tags: Seçenek Tags: Oyun alanı Hero-image: BannerImage.png Topic-image: TopicImage.png Social-image: SocialMedia.png Prereq:
Çok oyunculu oyunlarda oyuncu takımları bir hedefe ulaşmak için rekabet eder ya da işbirliği yapar. Her takımdaki oyuncu sayısı, oynanışı çarpıcı biçimde etkileyebilir ve birçok geliştirici, eğlenceli deneyimler yaratmak için belirli oyuncu oranlarını seçer.
Takım dengeleme, belirli bir orana uyarak oyuncuları takımlara ayırır. Çoğu çok oyunculu oyun, hiçbir takımın avantajlı olmaması için takımları eşit olacak şekilde dengeler. Bazı oyunlar, aşırı güçlü bir oyuncunun karşısına dört oyuncu koymak gibi dengesiz senaryoları kasıtlı olarak oluşturur. Kurulumdan bağımsız olarak takım dengesi, birden fazla oyuncu takımı için ilgi çekici deneyimler yaratmanın ayrılmaz bir parçasıdır.

Bu kılavuzu tamamlayarak çalışma zamanında ve oyuna yeni bir oyuncunun katıldığı her durumda oyuncu takımlarını dinamik olarak dengelemeyi öğreneceksin. Tam kod, referans olması için bu kılavuzun sonuna eklenmiştir.
Kullanılan Verse Dili Özellikleri
-
array
: Bu cihaz her takımın bir referansını depolamak için dizileri kullanır. -
option
: Bu cihaz, oyuncunun bulunduğu takımdan daha az oyuncuya sahip bir takım olup olmadığını belirlemek için seçenekleri kullanır. -
for
:for
ifadesi ile cihazın kullandığı dizileri yineleyebilirsin. -
if
:if
ifadesi, oyuncuların takım boyutlarına göre yeni bir takıma geçmesinin gerekli olup olmadığını kontrol etmek için kullanılır. -
failure
: Hata bağlamları, dizilere erişmek ve programın akışını kontrol etmek için kullanılır.
Kullanılan Verse API’ları
-
Abone Olunabilir: Sürmekte olan bir oyuna yeni bir oyuncu katıldığında takımları dinamik olarak yeniden dengelemek için
PlayerAddedEvent()
olayına abone olursun. -
Takımlar: Takım sınıfı takımlara oyuncu ekler, takımlardan oyuncu kaldırır ve alır.7 Bu eğitimde oyuncuları ve takım görevlerini doğrudan yönlendirmek için takım sınıfını kullanacaksın.
-
Oyun Alanı: Oyun alanı, oyuna katılan ve oyundan ayrılan oyuncularla ilgili abone olunabilir olayları takip eder. Aynı zamanda oyuncu ve takımların listelerini alır ve belirli bir oyuncunun takımını bulur. Bu eğitimde birden fazla oyun alanı olayına abone olacak, doğrudan yönetebilmek için oyuncuları ve takımları oyun alanı yöntemlerini kullanarak alacaksın.
Bölümü Ayarlama
Bu örnekte aşağıdaki cihaz kullanılıyor.
4 adet Oyuncu Doğma Karesi cihazı: Bu cihaz, oyuncunun oyun başlangıcında nerede doğacağını belirler.
Bölümünü ayarlamak için şu adımları izle:
-
Seviyeye bir oyuncu doğma karesi ekle.
-
Anahat düzenleyiciden doğma karesini seç ve ayrıntılar panelini aç.
-
Ayrıntılar panelindeki Kullanıcı Seçenekleri altında:
-
Oyuncu Takımı’nı 1 değerine sahip Takım Dizini olarak ayarla
-
Oyunda Görünür seçeneğini etkinleştir
Büyütmek için görsele tıkla.
-
-
Doğma karesini kopyala ve ilk doğma karesinin yanına yerleştir.
-
Her iki doğma karesini de çoğalt ve ilk doğma kareleri grubundan uzakta bir yere yerleştir. 2. takımın oyuncularının burada doğar.
-
Çoğaltılan doğma karelerini seç ve ayrıntılar panelindeki kullanıcı seçenekleri bölümünün altından her iki doğma karesinin takım dizini değerini 2 olarak değiştir.
-
Anahat Düzenleyici'de Ada Ayarları Cihazını seçerek Ayrıntılar panelini aç. Kullanıcı Seçenekleri - Oyun Kuralları altında:
-
Takımlar'ı, değeri 2 olan Takım Dizini olarak ayarla. Bu örnekte iki takım kullanılıyor ancak dilediğin sayıda takımın olabilir.
-
Takım Boyutu'nu Dinamik olarak ayarla. Bu ayarla Verse kodun takım dengeleme işini devralabilir.
-
Oyun devam ederken yeni oyuncuların oyuna katılabilmesi için Sürmekte Olan Oyuna Katılma değerini Doğma olarak ayarla.
Büyütmek için görsele tıkla.
-
-
Verse Gezgini kullanarak team_multiplayer_balancing adlı yeni bir Verse cihazı oluştur ve bunu bölüme sürükle. (Verse’te yeni bir cihazın nasıl oluşturulacağını öğrenmek için Verse Kullanarak Kendi Cihazını Yarat bölümüne bakabilirsin.)
Bölümün şu kuruluma benzer şekilde görünmelidir:

Takımları Eşit Olarak Ayırma
Oyun Başlangıcında Takımları Dengeleme
Bu adımda oyun başlangıcında ve oyuna yeni bir oyuncu katıldığında oyuncuların takımlara nasıl eşit olarak ayrılacağı gösteriliyor.
-
Verse Gezgini menüsünü aç ve team_multiplayer_balancing.verse bölümüne çift tıklayarak kodu Visual Studio Code ile aç.
-
team_multiplayer_balancing
sınıf tanımında oyuncuların bulunduğu her bir takımda referansları depolayacakTeams
adlı bir değişkenteam
dizisi ekle.team_multiplayer_balance := class(creative_device): # GetTeams() ile bulunan takımları barındırır var Teams : []team = array{}
-
OnBegin()
fonksiyonundaTeams
dizisini daha önce ada ayarları menüsünde ayarlanan takımlarla eşleşecek şekilde güncelle. Oyun alanındaki tüm takımları almak içinfort_team_collection
API’ındanGetTeams()
fonksiyonunu çağır.OnBegin<override>()<suspends>:void= Print("Verse Device Started!") set Teams = Self.GetPlayspace().GetTeamCollection().GetTeams()
-
GetPlayers()
fonksiyonunu çağırarak oyundaki tüm oyuncuları bul veAllPlayers
adlı bir oyuncu dizisine kaydet.OnBegin<override>()<suspends>:void= Print("Verse Device Started!") set Teams = Self.GetPlayspace().GetTeamCollection().GetTeams() AllPlayers := GetPlayspace().GetPlayers()
-
Tüm oyuncuların listesini yinele ve aynı sayıda oyuncuya sahip takımlar oluştur. Bir oyuncunun o anda bulunduğu takımı başka bir takımla karşılaştırıp oyuncu için en uygun takım olup olmadığını belirleyebilirsin. Bu durumda
GetTeam[]
fonksiyonunu kullanarak oyun başladığında oyuncunun otomatik olarak atandığı takımı kullanabilirsin (çünkü oyuncular birden fazla takımın olduğu oyun modlarında bir takıma dahil olmak zorundadır).GetTeam[]
fonksiyonu, aracı türünde bir parametre gerektirir fakat oyuncu bir aracı alt sınıfı olduğundan bir oyuncuyu tür dönüştürme yapmadan geçirebilirsin.AllPlayers := GetPlayspace().GetPlayers() for (TeamPlayer : AllPlayers, CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]): # Takımlar dengeli değilse Oyuncuları yeni bir takıma ata
Takım bir iç sınıf olduğundan başlatılamaz ve yalnızca var olan bir takım objesinin referansı olarak kullanılabilir.
-
Tüm takımlar dengelenene kadar oyuncuları en az sayıda oyuncuya sahip takıma ataman gerekir. Bunu yapmak için her bir oyuncuyu ve sonra her bir takımı bir
for
döngüsü kullanarak kontrol etmen gerekir. Biri oyuncuları yinelemek ve diğeri takımları yinelemek üzere iki for döngüsü kullanabilirsin ancak bu örnekte takım for döngüsünü kendi yöntemi içine çıkaracaksın. Her bir oyuncunun referansını ve sonra oyuncuların bulunduğu her bir takımın referansınıCurrentTeam
adlı bir sabite alarak oyuncu for döngüsünü ayarla.-
TeamSize
adlı yeni bir değişken tamsayı oluştur ve0
ile başlat, ardından bu oyuncunun o anda bulunduğu takımın boyutuna eşit olacak şekilde ayarla.GetAgents[]
başarısız olabilir ifade olduğundan bu kümeyi bir if ifadesi içine almalısın.for (TeamPlayer : AllPlayers, CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]): # Takımlar dengeli değilse Oyuncuları yeni bir takıma ata var TeamSize : int = 0 if(set TeamSize = GetPlayspace().GetTeamCollection().GetAgents[CurrentTeam].Length): Print("Size of this player's starting team is {TeamSize}")
FindSmallestTeam()
adlı bir metot oluştur. Bu metot,TeamSize
ı bir bağımsız değişken olarak geçirdiğinde isteğe bağlı bir takım (?team
) döndürür ve en az sayıda oyuncuya sahip takımı bulma ve döndürme işlemlerini üstlenir.FindSmallestTeam()
içindeSmallestTeam
adlı yeni bir takım seçeneği başlat.FindSmallestTeam()
işlevini çağırdığında oyuncu zaten en küçük takımda olabileceğinden burada bir seçenek kullanacaksın.-
SmallestTeam
seçeneğin varsayılan olarak false olduğundan daha küçük bir takım bulunmazsafalse
olarak kalır.FindSmallestTeam()
işlevifalse
değerini döndürürse belirtilen oyuncunun zaten en küçük takımda olduğunu kesin olarak bilirsin. AyrıcaCurrentTeamSize
değişken tamsayısınıTeamSize
değeri ile başlatman gerekir. Daha az oyuncuya sahip başka bir takımın boyutuna güncellenebilmesi içinCurrentTeamSize
değerinin değişken olması gerekir.FindSmallestTeam(CurrentTeamSize : int) : ?team= var SmallestTeam : ?team = false var TeamSize : int = CurrentTeamSize
-
TeamSize
değeriSmallestTeam
boyutunu takip ettiğinden bu değeri her takımın boyutuyla karşılaştırman gerekir. Her bir takımı yinele ve takımların boyutunuCandidateTeamSize
adlı yerel tamsayı olarak al.CandidateTeamSize
değeriTeamSize
değerinden küçükseSmallestTeam
değerini bu takıma,TeamSize
değerini ise bu takımın boyutuna ayarla.TeamSize > CandidateTeamSize
koşulu for döngüsünün parantezi içinde kontrol edildiğinden bir filtre koşuludur. Filtre koşulu kullanmak, döngünün içindeki kodun yalnızca filtre koşulu başarılı olursa çalışmasını garanti eder. Bu daSmallestTeam
değerinin, bulunması halinde en az oyuncuya sahip takıma ayarlanmasını garanti eder. Daha az oyuncuya sahip bir takım bulunamazsaSmallestTeam
değeri false olarak kalır.Son olarak tüm takımlar kontrol edildikten sonra
SmallestTeam
değeri döndürülür.for(Team : Teams, CandidateTeamSize := GetPlayspace().GetTeamCollection().GetAgents[Team].Length, TeamSize > CandidateTeamSize): set SmallestTeam = option{Team} set TeamSize = CandidateTeamSize Print("Found a team with less players: {CandidateTeamSize}") return SmallestTeam
-
OnBegin()
yöntemindefor
döngüsünün içindeSmallestTeam
adlı yeni bir takım seçeneği oluştur ve bağımsız değişken olarakTeamSize
geçirildiğindeFindSmallestTeam()
değeriyle başlat.SmallestTeam : ?team = FindSmallestTeam(TeamSize)
-
Ardından
SmallestTeam
isteğe bağlı değişkenindeki değere erişmeyi dene. Değer false ise oyuncu zaten en küçük takımdadır ve bir atama gerekli değildir. Aksi takdirde oyuncuyu yeni takımına ataman gerekir. Birçok yöntem bir seçeneği bağımsız değişken olarak doğrudan geçirmemize izin vermediğinden değeriTeamToAssign
yerel değişkenine çıkarmak zorundasın.AddToTeam[player, team]
kullanarak bir oyuncuyu bu takıma atamayı deneyebilirsin. Bir oyuncuyu zaten ait olduğu takıma atamayı denersen bu atamanın başarısız olacağını unutma. Bunun herhangi bir negatif etkisi olmaz ancakfor
döngüsü yalnızca bir sonraki oyuncuya yinelenir ve birinci oyuncuyu ilk takımında bırakır.if (TeamToAssign := SmallestTeam?, GetPlayspace().GetTeamCollection().AddToTeam[TeamPlayer, TeamToAssign]): Print("Attempting to assign player to a new team")
-
-
OnBegin()
aşağıdaki kod bloğu gibi görünmelidir.OnBegin<override>()<suspends> : void = Print("Verse Device Started!") set Teams = Self.GetPlayspace().GetTeamCollection().GetTeams() Print("Beginning to Assign Players") Playspace := GetPlayspace() AllPlayers := Playspace.GetPlayers() for (TeamPlayer : AllPlayers, CurrentTeam := Playspace.GetTeamCollection().GetTeam[TeamPlayer]): var TeamSize : int = 0 if(set TeamSize = Playspace.GetTeamCollection().GetAgents[CurrentTeam].Length): Print("Size of this player's starting team is {TeamSize}") SmallestTeam : ?team = FindSmallestTeam(TeamSize) if (TeamToAssign := SmallestTeam?, Playspace.GetTeamCollection().AddToTeam[TeamPlayer, TeamToAssign]): Print("Attempting to assign player to a new team")
Oyun Sırasında Katılan Oyuncu
Takımları sürmekte olan bir oyun için de otomatik dengeleyebilmek istediğinden yeni bir oyuncu katıldığında başlatılan olaya abone olman gerekir. Yeni yazdığın tüm kodları tekrarlamak istemeyeceğinden bir ortak yönteme yeniden düzenleyebilirsin.
-
BalanceTeams()
adlı bir metot oluştur veGetTeams()
metodunu kullanıpTeams
değişkenini ayarladıktan sonraki tüm kodu taşı. Bu metot,OnBegin()
metodu içinde çağrılır, böylece oyun başladığında takımların dengeli olması sağlanır.BalanceTeams()
aşağıdaki gibi görünmelidir.BalanceTeams() : void = AllPlayers := GetPlayspace().GetPlayers() for (TeamPlayer : AllPlayers, CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]): var TeamSize : int = 0 if(set TeamSize = GetPlayspace().GetTeamCollection().GetAgents[CurrentTeam].Length): Print("Size of this player's starting team is {TeamSize}") SmallestTeam : ?team = FindSmallestTeam(TeamSize) if (TeamToAssign := SmallestTeam?, GetPlayspace().GetTeamCollection().AddToTeam[TeamPlayer, TeamToAssign]): Print("Attempting to assign player to a new team")
-
BalanceTeams()
metoduna bir çağrı içerenOnPlayerAdded()
adlı başka bir metot oluştur.player
değişkenini kullanmayacak olsan da bu değişken, metot tanımı için gereklidir çünküPlayerAddedEvent()
olayına bu yöntemi kullanarak abone olursun. Abone olunabilir olaylar hakkında daha ayrıntılı bilgi için cihaz etkileşimlerinin kodlanması sayfasına bakabilirsin.OnPlayerAdded(InPlayer : player) : void = Print("A new Player joined, assigning them to a team!") BalanceTeams()
-
OnBegin()
yöntemindeOnPlayerAdded
kullanarakPlayerAddedEvent()
olayına abone ol. Şimdi oyuna bir oyuncu katıldığındaOnPlayerAdded
işlevi, takımları otomatik olarak dengelemek içinBalanceTeams()
yöntemini çağırır.OnBegin<override>()<suspends> : void = GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded) Print("Beginning to balance teams") BalanceTeams()
-
Kodu Visual Studio Code’a kaydet ve Verse Kodu Oluştur butonuna tıklayarak kodunu derle.
-
Bölümün oynanış testini yapmak için UEFN araç çubuğunda Oturumu Başlata tıkla.
Bölümüne oynanış testi uygulamak için her bir takımın boyutunu ve kodun yazdırılan çıktı günlüğünde bulduğu daha küçük takımları görebilmen gerekir. Oyuncular takımlar arasında eşit olarak dağıtılmış olmalı ve oyuna katılan her yeni oyuncu bu eşitlenmiş dengeyi korumalıdır.

Tam Kod
Aşağıdaki kod, oyuncu takımlarını otomatik olarak dengeleyen bir cihazın tam kodudur.
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
team_multiplayer_balance := class(creative_device):
# GetTeams() ile bulunan takımları barındırır
var Teams : []team = array{}
OnBegin<override>()<suspends> : void =
Print("Verse Device Started!")
set Teams = Self.GetPlayspace().GetTeamCollection().GetTeams()
AllPlayers := GetPlayspace().GetPlayers()
#Yeni bir oyuncu oyuna katıldığında takımların yeniden dengelenmesine olanak tanıyan PlayerAddedEvent olayına abone ol
Self.GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded)
Print("Beginning to balance teams")
BalanceTeams()
# Oyuna katılan yeni bir oyuncuyu işler
OnPlayerAdded(InPlayer : player) : void =
Print("A new Player joined, assigning them to a team!")
BalanceTeams()
<#
Her oyuncu için, oyuncunun takımındaki oyuncu sayısını bul. Takım listesini yinele
ve en az sayıda oyuncuya sahip takıma ya da
eşitlik varsa başladığı takıma oyuncuyu ata.
#>
BalanceTeams() : void =
AllPlayers := GetPlayspace().GetPlayers()
for (TeamPlayer : AllPlayers, CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]):
# Takımlar dengeli değilse Oyuncuları yeni bir takıma ata
var TeamSize:int = 0
if(set TeamSize = GetPlayspace().GetTeamCollection().GetAgents[CurrentTeam].Length):
Print("Size of this player's starting team is {TeamSize}")
SmallestTeam : ?team = FindSmallestTeam(TeamSize)
if (TeamToAssign := SmallestTeam?, GetPlayspace().GetTeamCollection().AddToTeam[TeamPlayer, TeamToAssign]):
Print("Attempting to assign player to a new team")
FindSmallestTeam(CurrentTeamSize : int) : ?team =
var SmallestTeam : ?team = false
var TeamSize : int = CurrentTeamSize
<#
Her takım için takımdaki oyuncu sayısını al. SmallestTeam değerinden az sayıda oyuncu varsa
SmallestTeam değerini Team olarak ayarla ve TeamSize değerini yeni Takımdaki oyuncu sayısına güncelle
#>
for(Team : Teams, CandidateTeamSize := GetPlayspace().GetTeamCollection().GetAgents[Team].Length, TeamSize > CandidateTeamSize):
set SmallestTeam = option{Team}
set TeamSize = CandidateTeamSize
Print("Found a team with less players: {CandidateTeamSize}")
return SmallestTeam
Kendi Kendine Yapabileceklerin
Bu kılavuzu tamamlayarak oyuncu takımlarını otomatik olarak dengeleyen bir cihazı Verse kullanarak oluşturmayı öğrenmiş oldun.
Öğrendiklerini kullanarak bir oyuncuya karşı dört oyuncu gibi asimetrik oyun modları için kasıtlı olarak dengesi bozulmuş takımlar oluşturmayı dene.