Bu eğitim, Kalıcı Oyuncu İstatistikleri bölümündeki kavramları temel aldığı için önce oraya bir göz at!
Sıralamalar rekabet oyunlarının başlıca unsurlarından biridir ve oyuncuların becerilerini sergilemesine ve adlarını duyurmasına olanak tanır. Sıralamalar oyuncuların bir ilerleme duygusu geliştirmesine yardımcı olur ve kendilerini zirveye tırmanırken görebilmeleri için oyuncuları sürekli olarak geri gelmeye teşvik eder.
Verse Sürekliliği, bu sıralamaları oluşturmana ve deneyimine rekabetçi bir boyut katmana olanak tanıyan araçlar sağlar. Kalıcı oyuncu istatistikleri eğitiminde, oyun oturumları arasında kalıcı hale getirilebilir verileri nasıl takip edebileceğini ve bu verileri farklı olaylara göre nasıl değiştirip güncelleyeceğini zaten görmüştün. Şimdi bu bilgileri uygulayarak tam yerel sıralamalar oluşturmayı, oyuncu istatistiklerini sıralamayı ve hepsini bir yarış oyununda bir araya getirmeyi öğreneceksin!
Kullanılan Verse Dili Özellikleri
Sınıf: Bu örnek, oyuncu başına bir grup istatistiğini takip eden, kalıcı hâle getirilebilir bir Verse sınıfı oluşturur.
Oluşturucu: Oluşturucu, ilişkili olduğu sınıfın bir örneğini oluşturan özel bir fonksiyondur.
weak_map: weak_map, üzerinde yineleneme yapılamayan basit bir haritadır. Verse kalıcı verilerinin bir weak_map içinde saklanması gerekir.
Bölümü Kurmak
Bu örnekte aşağıdaki nesne ve cihazlar kullanılır:
3 adet Pano Cihazı: Bu cihazlar her bir oyuncunun yaşam süresi istatistiklerini gösterir ve bu istatistikleri, lobideki en iyi oyuncuları göstermek için yaşam süresi puanlarına göre sıralarsın.
3 adet Oyuncu Referansı Cihazı: Panolarla birlikte kullanıldığında oyuncu referansları, en iyi performans gösteren oyuncularının adını öne çıkarır, böylece diğer oyuncular oyun sırasında kime dikkat etmeleri gerektiğini bilir.
3 adet Kontrol Noktası Cihazı: Bunlar oyuncuların yarışı tamamlamak için içinden hızlıca ilerlediği kontrol noktalarıdır.
1 adet Yarış Yöneticisi Cihazı: Bu cihaz, oyuncuların yarışı ne zaman başlattığını ve bitirdiğini takip eder ve bitirme sırasına göre oyunculara puan ödülü verir.
1 adet Malzeme Kamyonu Çıkma Yeri Cihazı: Bu cihaz yarış sırasında kullanacağın aracı çıkarır ancak bunu deneyimine uygun herhangi bir araçla değiştirebilirsin.
Bölümünü ayarlamak için şu adımları izle:
Panolar ve Oyuncu Referansları
Oyuncu istatistiklerini göstermek için pano ve oyuncu referansı cihazlarının bir kombinasyonunu kullanacaksın. Her pano bir oyuncunun yaşam süresi istatistiklerini gösterirken oyuncu referansı o oyuncunun görsel bir temsilini gösterir. Bu öğeleri eklemek için aşağıdaki adımları izle:
Bölümüne üç adet Oyuncu Referansı cihazı ekle ve bunları yan yana yerleştir.
Her oyuncu referansı için Anahat Düzenleyicisi’nde seçim yap. Ayrıntılar panelindeki Kullanıcı Seçenekleri altında Özel Renk ayarını, lobide birinci, ikinci ve üçüncü en iyi performansı gösteren oyuncuları göstermesini istediğin renkle değiştir. Bu örnekte altın, gümüş ve bronz renkleri kullanılıyor.
Bölümüne üç Pano cihazı ekle ve her bir oyuncu referansının önüne bir tane yerleştir. Oyun başladığında Verse kullanarak bunları her bir oyuncunun istatistikleriyle güncelleyeceksin.
Kontrol Noktaları, Malzeme Kamyonu ve Yarış Yöneticisi
Bu bir yarış olduğu için yarışacağın bir şeyler olmalı! Ayrıca içinden geçeceğin kontrol noktaları ve oyun sırasında yarışı yönlendirecek bir yarış yöneticisine ihtiyacın olacak. Bu öğeleri eklemek için aşağıdaki adımları izle:
Bölümüne üç tane Yarış Kontrol Noktası cihazı ekle. Bu cihazları, oyuncuların içinden geçmesini istediğin sırayla yerleştir. Her kontrol noktası için Anahat Düzenleyicisi’nde Kontrol Noktası Numarası’nın, oyuncuların kontrol noktaları arasından geçiş sırasıyla eşleştiğinden emin ol.
Bölümüne bir adet Yarış Yöneticisi cihazı ekle. Bu cihaz, yarışı yürütecek ve oyuncuları kontrol noktalarına yönlendirecek. Daha sonra bu cihazdan
RaceCompletedEvent()olayını dinleyerek bir oyuncunun yarışı ne zaman bitirdiğini öğreneceksin.Bölümüne bir adet Malzeme Kamyonu Çıkma Yeri cihazı ekle. Araç kullanmak isteğe bağlıdır ancak bu kılavuzda Pist Yarışı Şablonu’na uyacak bir malzeme kamyonu kullanılır ve oyunculara sürecekleri bir araç verilir.
İstatistikler Tablonda Değişiklik Yapma
Bu örnekte Kalıcı Oyuncu İstatistikleri bölümündeki player_stats_table dosyasının değiştirilmiş bir versiyonu kullanılıyor. Bu dosyanın görünümü o örnekteki dosyaya benzer ancak uygulamayı değiştiren bazı önemli farklılıkları vardır.
Oyuncu istatistikleri tablonu oluşturmak için aşağıdaki adımları izle:
player_stats_tablesınıfında:Mağlubiyetleristatistiğini kaldır.SkoristatistiğiniPuanile değiştir.Verse# Tracks different persistable stats for each player. player_stats_table<public>:= class<final><persistable>: # The version of the current stats table. Version<public>:int = 0 # The Points of a player. Points<public>:int = 0 # The number of Wins for a player.
Güncellenmiş istatistikleri yansıtmak için dosyandaki
MakePlayerStatsTable()oluşturucu fonksiyonunu değiştir.Verse# Creates a new player_stats_table with the same values as the previous player_stats_table. MakePlayerStatsTable<constructor>(OldTable:player_stats_table)<transacts> := player_stats_table: Version := OldTable.Version Points := OldTable.Points Wins := OldTable.Winsplayer_stats_table.verse dosyana
player_and_statsadlı yeni bir yapı ekle. Bu yapı birplayerve onunplayer_stats_tablesınıfının referansını içerir ve her iki veriyi de tekrar tekrar almaya gerek kalmadan fonksiyonlarda kullanmana olanak tanır. Tamamlanmışplayer_and_statsyapın şu şekilde görünmelidir:Verse# Structure for passing a player and their stats as arguments. player_and_stats<public> := struct: Player<public>:player StatsTable<public>:player_stats_table
İstatistikleri Yönetme
Tıpkı Kalıcı Oyuncu İstatistikleri eğitiminde olduğu gibi oyuncular için istatistik değişikliklerini yönetip kaydederken bir yönetici dosyası kullanacaksın.
Değiştirdiğin player_stats_manager dosyasını derlemek için aşağıdaki adımları izle.
InitializeAllPlayers()veInitializePlayer()fonksiyon imzasınıInitializeAllPlayerStats()andInitializePlayerStat()ile değiştir. Bu adlar,GetPlayerStat()fonksiyonuyla ilişkiyi daha iyi yansıtır. Güncellenmiş fonksiyonun şu şekilde görünmelidir:Verse# Initialize stats for all current players. InitializeAllPlayerStats<public>(Players:[]player):void = for (Player : Players): InitializePlayerStat(Player) # Initialize stats for the given player. InitializePlayerStat<public>(Player:player):void= if: not PlayerStatsMap[Player] set PlayerStatsMap[Player] = player_stats_table{}AddScore()fonksiyon imzasınıAddPoints()olarak değiştir. Ardından,player_stats_tableartık bu değeri içermediğindenAddLosses()fonksiyonunu kaldır. Tamamlanmışplayer_stats_managerdosyan şu şekilde görünmelidir:Verse# This file handles the code for initializing, updating, and returning player_stats_tables # for each player. It also defines an abstract stat_type class to use for updating stats, and the # StatType module to use when displaying stats. using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Return the player_stats_table for the provided Agent. GetPlayerStats<public>(Agent:agent)<decides><transacts>:player_stats_table=
Oyuncu Sıralamaları Oluşturma
Sıralamalarında oyuncu verilerini göstermek için birkaç şeye ihtiyacın olacak. Panolardaki metni ve oyuncu referansı cihazlarındaki oyuncuları güncellemenin bir yolunu bulmalısın. Ayrıca, en iyi oyuncuların sıralamanda en önde olmasını istediğin için bu cihazları sıralaman gerekir. Bu fonksiyonlar bölümdeki cihazları değiştirme gibi benzer bir hedefe sahip olduğundan fonksiyonları ortak bir dosyada gruplandırmak iyi bir fikirdir.
Bölüm içinde cihazlarını güncelleyen fonksiyonlar oluşturmak için aşağıdaki adımları izle:
player_leaderboards.verse adlı yeni bir Verse dosyası oluştur. Bu dosya, bölüm içinde sıralamalarını güncellerken ortak kullanılan fonksiyonları depolar.
Panodaki metin için bağımsız değişkenler geçirebileceğin bir mesaj kullanacaksın.
CurrentPlayer,PointsveWinsdeğeri alan ve hepsimessagetüründe olup birleştirilmiş metnimessageolarak döndürenStatsMessageadlı yeni bir mesaj oluştur.Verse# The message to display on the stats billboard. StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message= "{CurrentPlayer}:\n{Points}\n{Wins}"StatsMessagemesajına eklenen girdiler için birer tane olacak şekilde üç tane dahamessagedeğişkeni ekle.PlayerTextmesajı birAgentalır,PointsTextmesajı bu aracının puanlarını alır,WinsTextmesajı ise bu aracının galibiyetlerini alır.StatsMessage, verilerini bölümde anlaşılır bir şekilde göstermek için bunların tümünden bir mesaj oluşturur.Verse# The message to display on the stats billboard. StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message= "{CurrentPlayer}:\n{Points}\n{Wins}" PlayerText<localizes>(CurrentPlayer:agent):message = "Player {CurrentPlayer}" PointsText<localizes>(Points:int):message = "Total Points {Points}" WinsText<localizes>(Wins:int):message = "{Wins} Total Wins"Bir panoyu güncellemek için Oyuncu Kalıcı İstatistikleri eğitimindeki
UpdateStatsBillboard()fonksiyonunu çağır. Bu fonksiyon, Verse cihazından ayrı bir dosyada tanımlandığı için hangi panoyu güncelleyeceğini belirtmek üzere ilave bağımsız değişken olarak birStatsBillboardeklemen gerekir.Verse# Updates the given billboard device to display the stats of the given player. UpdateStatsBillboard<public>(Player:agent, StatsBillboard:billboard_device):void=Öncelikle
GetPlayerStats[]fonksiyonunu kullanarak, bağımsız değişken olarak geçirilen oyuncu istatistiklerini al. Artık ayrı bir sınıf olmadığı için birplayer_stats_managerreferansına ihtiyacın yok. Sonra oyuncuyu veCurrentPlayerStatsfonksiyonundanPointsveWinsdeğerlerini kullanarak yeni birStatsMessageoluştur. Son olarak bölüm içinde pano metnini güncellemek içinStatsBillboardüzerindeSetText()çağrısı yap. TamamladığınUpdateStatsBillboard()fonksiyonu şunun gibi görünmelidir:Verse# Updates the given billboard device to display the stats of the given player. UpdateStatsBillboard<public>(Player:agent, StatsBillboard:billboard_device):void= if: CurrentPlayerStats := GetPlayerStats[Player] then: PlayerStatsText := StatsMessage( PlayerText(Player), PointsText(CurrentPlayerStats.Points), WinsText(CurrentPlayerStats.Wins)) StatsBillboard.SetText(PlayerStatsText)
Oyuncuları Sıralama ve En İyi Oyuncuyu Gösterme
Devam etmeden önce bu panoları nasıl sıralayacağını düşünmelisin. En fazla puana sahip oyuncu mu en üstte gösterilsin yoksa en çok galibiyet alan oyuncu mu? Farklı istatistiklere göre sıralamak istersen ne olacak? Bunları yönetmek için bir metoda ihtiyacın vardır ve bu metot, bir sıralama algoritmasıdır. Bir sıralama algoritması ve karşılaştırma fonksiyonu kullanarak hangi kriterlere göre sıralayacağını belirtebilirsin. Daha sonra panolarını ve oyuncu referanslarını sıralayarak deneyimindeki en iyi oyuncuları gösterebilirsin. Bu örnekte Birleştirme Sıralaması algoritması kullanılıyor ancak sen istediğini uygulamakta özgürsün.
Panolarına karşılaştırma ve sıralama ekleyerek bölümündeki cihazları güncellemek için aşağıdaki adımları izle.
player_stats_tabledosyana geri dönüp her istatistiğin için karşılaştırma fonksiyonları tanımla. Bunların her biri birLeftveRightplayer_and_statsyapısı alır ve bunları belirli bir istatistiğe göre karşılaştırır. Bu fonksiyonlar<decides><transacts>değiştiricilerine sahiptir, bu nedenle karşılaştırma başarısız olursa fonksiyon da başarısız olur. Örneğin,LeftdeğerininRightdeğerinden daha az olduğunu bildirmek. player_stats_table.versedosyanaLeft.PointsMorePointsComparison()adlı yeni bir fonksiyon ekle. Bu fonksiyon,değerininRight.Pointsdeğerinden büyük olup olmadığını kontrol eder ve büyük değilse başarısız olur. Başarılı olursaLeft` döndürür.Verse# Returns Left if Left has greater Points than Right. MorePointsComparison<public>(Left:player_and_stats, Right:player_and_stats)<decides><transacts>:Left= Left.StatsTable.Points > Right.StatsTable.Points LeftBu fonksiyonu, biri daha düşük puan karşılaştırması için, ikisi galibiyet karşılaştırması için olmak üzere üç kez kopyala. Karşılaştırma fonksiyonların şu şekilde görünmelidir:
Verse# Returns Left if Left has greater Points than Right. MorePointsComparison<public>(Left:player_and_stats, Right:player_and_stats)<decides><transacts>:player_and_stats= Left.StatsTable.Points > Right.StatsTable.Points Left # Returns Left if Left has less Points than Right. LessPointsComparison<public>(Left:player_and_stats, Right:player_and_stats)<decides><transacts>:player_and_stats= Left.StatsTable.Points < Right.StatsTable.Points LeftBirleştirme Sıralaması algoritmasını ekle. Bu algoritmayı ayrı bir dosyaya veya modüle yerleştirebilir ve sağlanan test dosyası üzerinde test edebilirsin.
player_leaderboardsdosyasına geri dönüpUpdateStatsBillboards()adlı yeni bir fonksiyon ekle. Bu fonksiyon bir aracılar (oyuncu veya AI) dizisi ve bir pano dizisi alır, bunları sıralar ve bölümdeki her panoyu güncellemek içinUpdateStatsBillboard()çağrısı yapar.Verse# Update the stats billboards by sorting them based on the amount of lifetime points # each player has. UpdateStatsBillboards<public>(Players:[]agent, StatsBillboards:[]billboard_device):void=UpdateStatsBillboards()fonksiyonu içindePlayerAndStatsArrayadlı yeni birplayer_and_statsdizi değişkeni başlat. Bunu, birforifadesinin sonucuna eşit olacak şekilde ayarla. Buforifadesinde heragentiçin söz konusuagent’a ait olanplayerdeğerini al veGetPlayerStats[]fonksiyonunu kullanarakplayer_stats_tableyapısını getir. Ardındanplayerve onun istatistik tablosundan oluşturulmuş birplayer_and_statsyapısı döndür.VerseUpdateStatsBillboards<public>(Players:[]agent, StatsBillboards:[]billboard_device):void= var PlayerAndStatsArray:[]player_and_stats = for: Agent:Players Player := player[Agent] PlayerStats := GetPlayerStats[Player] do: player_and_stats: Player := Player StatsTable := PlayerStatsPlayerAndStatsArraydizini sıralamak için, diziyi veMorePointsComparisonfonksiyonunu iletenMergeSort()çağrısının sonucuna göre yeni birSortedPlayersAndStatsdeğişkeni başlat. Birforifadesi içinde sıralamayı yaptıktan sonra, eleman dizininiPlayerIndexdeğişkeninde depolayarakSortedPlayerAndStatsiçindeki her elemanı yinele.PlayerIndexdeğişkenini kullanarakStatsBillboardsdizisi içinde dizin oluştur, ardından güncellenecek oyuncuyu ve panoyu geçirerekUpdateStatsBillboardçağrısı yap. TamamladığınUpdateStatsBillboard()fonksiyonu şunun gibi görünmelidir:Verse# Update the stats billboards by sorting them based on the amount of lifetime points # each player has. UpdateStatsBillboards<public>(Players:[]agent, StatsBillboards:[]billboard_device):void= var PlayerAndStatsArray:[]player_and_stats = for: Agent:Players Player := player[Agent] PlayerStats := GetPlayerStats[Player] do: player_and_stats:Oyuncu referanslarını güncellemek için
UpdatePlayerReferences()adında buna benzer bir fonksiyon kullanacaksın. Bu fonksiyon panolar yerine birplayer_reference_devicedizisi alır ve sonundaUpdateStatsBillboard()çağırmak yerine her oyuncu için oyuncu referans cihazındaRegister()fonksiyonunu çağırır. Yukarıdaki değişiklikleri yaparakUpdateStatsBillboard()kodunu yeni birUpdatePlayerReferences()fonksiyonuna kopyala. TamamladığınUpdatePlayerReferences()fonksiyonu şunun gibi görünmelidir:Verse# Update the player references devices by sorting them based on the amount # of lifetime points each player has. UpdatePlayerReferences<public>(Players:[]player, PlayerReferences:[]player_reference_device):void= var PlayerAndStatsArray:[]player_and_stats = for: Agent:Players Player := player[Agent] PlayerStats := GetPlayerStats[Player] do: player_and_stats:
Bölümündeki Oyuncu Sıralamaları
Her şey hazır olduğuna göre, şimdi oyuncularını sahneye almanın zamanı geldi! Oyuncuların butonla etkileşime girdiklerinde puan kazanmalarını sağlayacak bir cihaz oluşturup oyuncu referanslarını ve panolarını en iyi oyuncuların önde ve ortada yer alacağı şekilde sıralayacaksın. Bölümünde oyuncu sıralamalarını test edecek bir Verse cihazı oluşturmak için aşağıdaki adımları izle:
player_leaderboards_example adlı yeni bir Verse cihazı oluştur. İzlenecek adımlar için Verse Kullanarak Kendi Cihazını Oluştur kısmına bakabilirsin.
player_leaderboards_example classtanımının üst kısmına aşağıdaki alanları ekle:PlayerReferencesadlı düzenlenebilir bir Oyuncu Referansı cihazları dizisi. Bunlar, yarıştaki her oyuncunun görsel gösterimini sağlar.Verse# Visual representations of each player. @editable PlayerReferences:[]player_reference_device = array{}Leaderboardsadlı düzenlenebilir bir Pano cihazları dizisi. Bunlar, bölümdeki bir panoda her bir oyuncunun istatistiklerini gösterir.Verse# Billboards that display each player's stats. @editable Leaderboards:[]billboard_device = array{}RaceManageradlı düzenlenebilir bir Yarış Yöneticisi cihazı. Yarış Yöneticisi ile olaylara bağlanacak ve bir oyuncu yarışı bitirdiğinde haber alacaksın.Verse# Tracks when players complete a race, with the players in the first spot being awarded a win. @editable RaceManager:race_manager_device = race_manager_device{}PlacementRequiredForWinadlı düzenlenebilir bir tamsayı. Bu, bir oyuncunun galibiyeti kazanabilmesi için yerleşmesi gereken sıradır.Verse# The placement of a player must be at or below to award a win. @editable PlacementRequiredForWin:int = 1PointsPerPlaceadlı düzenlenebilir bir tamsayı dizisi. Bunlar, her oyuncunun yerleştiği sıraya göre kazandığı puan sayılarıdır.Verse# The number of points a player in each place earns. # Adjust this to award your players the desired amount of score # based on their placement. @editable PointsPerPlace:[]int = array{5, 3, 1}CurrentFinishOrderadlı bir tamsayı değişkeni. Bu, yarışı yeni tamamlayan son oyuncunun yerleştiği sıradır.Verse# The spot of the player who just finished the race. # The first three players to finish the race will be awarded a win. var CurrentFinishOrder:int = 0
Yerleşilen Sıraya Dayalı İstatistik Ödülleri
Bir oyuncu yarışı bitirdiğinde, istatistiklerini yerleştiği sırasına göre güncellemek istiyorsun. İyi bir sıraya yerleşen oyuncular daha fazla puan almalı, en iyi sıraya yerleşen oyuncularsa galibiyeti kazanmalı.
Yarışı bitiren oyunculara puan ödülü vermek için şu adımları takip et:
Bunu yönetmek için
player_leaderboards_examplesınıf tanımınaRecordPlayerFinish()adlı yeni bir fonksiyon ekle. Bu fonksiyon, puan ödülü verilecek oyuncuyu parametre olarak alır.Verse# When a player finishes the race, award them points based on their placement, and award them a win if # their placement was better than the PlacementRequiredForWin. RecordPlayerFinish(Player:agent):void=RecordPlayerFinish()fonksiyonunda, geçerliCurrentFinishOrderdeğeriniPlayerFinishOrderadlı yeni birintiçinde alarak bu oyuncunun yerleştiği sırayı al. Ardından, bir sonraki bitiren oyuncunun aynı yere yerleşmemesi içinCurrentFinishOrderdeğerini bir artır.VerseRecordPlayerFinish(Player:agent):void= PlayerFinishOrder:int = CurrentFinishOrder set CurrentFinishOrder += 1Şimdi sıra, istatistik ödüllerini vermeye geldi. Bu oyuncuya kaç puan verileceğini bilmek için bir
ififadesindePlayerFinishOrderdeğişkenini kullanarakPointsPerPlacedizisi içinde dizin oluştur. Ardından, ilgili oyuncuya belirtilen miktarda puan vermek içinAddPoints()çağrısı yap.Verseset CurrentFinishOrder += 1 if: PointsToAward := PointsPerPlace[PlayerFinishOrder] then: AddPoints(Player, PointsToAward)Oyuncunun yerleştiği sıra, galibiyeti kazanmaya yetecek kadar yüksekse istatistik tablosuna bir galibiyet kaydetmen gerekir. Başka bir
ififadesinde,PlayerFinishOrderdeğerininPlacementRequiredToWindeğerinden küçük olup olmadığını kontrol et. Küçükse oyuncuyu ve ona verilecek galibiyeti geçirerekAddWin()fonksiyonunu çağır. TamamladığınRecordPlayerFinish()fonksiyonun şu şekilde görünmelidir:Verse# When a player finishes the race, award them points based on their placement, and award them a win if # their placement was better than the PlacementRequiredForWin. RecordPlayerFinish(Player:agent):void= PlayerFinishOrder:int = CurrentFinishOrder set CurrentFinishOrder += 1 if: PointsToAward := PointsPerPlace[PlayerFinishOrder] then: AddPoints(Player, PointsToAward)
Oyuncuların Yarışı Bitirmesini Bekleme
Artık istatistik kaydın hazır olduğuna göre, bir oyuncu yarışı bitirdiğinde bunu öğrenmen ve oyuncunun istatistiklerini güncellemen gerekiyor. Bunu yapmak için yarış yöneticisinin RaceCompletedEvent() fonksiyonunu dinle. Bu olay, herhangi bir oyuncu yarışı bitirdiğinde tetiklenir, dolayısıyla bunu bir asenkron fonksiyon içinde sürekli olarak dinlemen gerekir.
player_leaderboards_examplesınıf tanımınaWaitForPlayerToFinishRace()adlı yeni bir fonksiyon ekle. Bu fonksiyon, bir oyuncuyu alır ve onun yarışı bitirmesini bekler.Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void=WaitForPlayerToFinishRace()içinde, birraceifadesinde iki döngü başlat. Bu döngülerden ilki oyuncunun yarışı bitirmesini bekleyecek, diğeriyse bir oyuncunun yarışı bitirmeden oturumdan ayrılması durumunda ne olacağını yönetecek. Bir oyuncu oyundan ayrıldığında döngünün sonsuza kadar devam etmesini istemeyiz, bu nedenle böyle bir durumda döngüden çıkmanın bir yolu olması gerekir.Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void= race: # Waiting for this player to finish the race and then record the finish. loop: # Waiting for this player to leave the game. loop:Birinci döngüde
RaceManager.RaceCompletedEventolayını bekle ve sonucuFinishingPlayeradlı bir değişkende depola. Bu olay herhangi bir oyuncu yarışı bitirdiğinde tetiklendiğinden, kaydettiğin oyuncunun takip ettiğin oyuncu olduğundan emin olman gerekir.FinishingPlayerdeğerini bu döngünün izlediği oyuncuyla karşılaştır. İki değer eşitse oyuncuyuRecordPlayerFinish()fonksiyonuna geçir ve döngüden çık.Verse# Waiting for this player to finish the race and then record the finish. loop: FinishingPlayer := RaceManager.RaceCompletedEvent.Await() if: FinishingPlayer = Player then: RecordPlayerFinish(Player) breakİkinci döngüde,
PlayerRemovedEvent()oyun alanı olayını bekle. Daha önce olduğu gibi, oyundan az önce ayrılan oyuncuyu al veLeavingPlayerdeğişkeninde depola. Az önce ayrılan oyuncu bu döngünün beklediği oyuncuysa döngüden çık. TamamladığınWaitForPlayerToFinishRace()fonksiyonun şunun gibi görünmelidir:Verse# When a player finishes the race, record a finish in their stats table. WaitForPlayerToFinishRace(Player:agent)<suspends>:void= race: # Waiting for this player to finish the race and then record the finish. loop: FinishingPlayer := RaceManager.RaceCompletedEvent.Await() if: FinishingPlayer = Player then: RecordPlayerFinish(Player)
Tümünü Birbirine Bağlama
Fonksiyonlarını ayarladığına göre şimdi sıra bunları cihazlarına bağlayıp yarışa başlamaya geldi!
Mantığını cihazlarına bağlamak için şu adımları takip et:
OnBegin()fonksiyonu içinde,GetPlayers()fonksiyonunu kullanarak oyun alanındaki tüm oyuncuları al. Her oyuncununplayer_stats_tablesdeğişkenini ayarlamak için bu diziyiInitializeAllPlayerStats()fonksiyonuna geçir.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Get the players in the current race and create a player_stat_table # for each of them. Players := GetPlayspace().GetPlayers() InitializeAllPlayerStats(Players)Bölüm içi panoları her oyuncunun geçerli verileriyle güncellemek için
PlayersveLeaderboardsdizilerini geçirerekUpdateStatsBillboards()çağrısı yap. Ardından bölüm içi referansları oyuncularla eşleşecek şekilde güncellemek içinUpdatePlayerReferences()fonksiyonunu çağır. Son olarak birforifadesinde her oyuncu için birWaitForPlayerToFinishRace()fonksiyonu oluştur. TamamladığınOnBegin()fonksiyonu şu şekilde görünmelidir:Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Get the players in the current race and create a player_stat_table # for each of them. Players := GetPlayspace().GetPlayers() InitializeAllPlayerStats(Players) UpdateStatsBillboards(Players, Leaderboards) UpdatePlayerReferences(Players, PlayerReferences) # Wait for all players to finish the race.Kodunu kaydet ve derle.
player_leaderboards_example cihazını bölümüne sürükle. Oyuncu referanslarını PlayerReferences dizisine atayıp sıranın kaydını tut. İlk dizindeki cihaz, en iyi oyuncunun oyuncu referansına, ikinci dizin ikinci en iyi oyuncunun oyuncu referansına vb. karşılık gelmelidir. Sıralamalar için de aynı şeyi yap; bunların oyuncu referansı cihazlarıyla uyumlu olduğundan emin ol. Yarış Yöneticisi cihazını da atamayı unutma!
Kalıcı Sıralamalarını Test Etme
Kalıcı verilerini bir editör oturumunda test edebilirsin ancak oturumu kapatıp yeniden başlattığında bu veriler sıfırlanır. Verilerinin oturumlar arasında kalıcı olması için bir oynanış testi oturumu başlatman ve Ada Ayarları içindeki belirli ayarları değiştirmen gerekir. Kalıcı verileri hem editör hem de oynanış testi oturumlarında test etmek üzere adanı ayarlamayla ilgili bilgi almak için Kalıcı Verilerle Test Etme bölümünü incele ve Ada Ayarlarında belirli ayarları değiştir. Kalıcı verileri hem editör hem de oynanış testi oturumlarında test etmek üzere adanı ayarlamayla ilgili bilgi almak için Kalıcı Verilerle Test Etme bölümünü incele.
Oturumunu ayarladıktan sonra, bölümünü test ettiğinde yarışı bitiren oyunculara yerleştikleri sıraya göre puan verilmeli. Oyuncular, yerleştikleri sıra yeterince yüksekse galibiyetle ödüllendirilmeli ve bu istatistikler oyun oturumları arasında kalıcı olmalı. Oyuncular ve istatistikleri sıralanmalı, en fazla puanı olan oyuncu ilk sırada görünmeli.
Kendi Kendine Yapabileceklerin
Bu kılavuzu tamamlayarak, bölümündeki oyuncuların kalıcı istatistiklerini gösteren sıralamaları nasıl oluşturacağını öğrendin. Ayrıca bu sıralamaların, en iyi oyuncuların kim olduğunu herkesin bilmesini sağlamak üzere nasıl sıralanacağını ve güncelleneceğini de öğrendin. Bu eğitimi kendi deneyimlerine uyarlamaya çalış ve en iyiden de iyisini ortaya çıkar!
Tam Kod
player_stats_table.verse
# This file defines a player_stats_table, a collection of persistable player statistics.
# It also contains functions to compare stats tables by each of the stats to order players
# when sorting.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Structure for passing a player and their stats as arguments.
player_and_stats<public> := struct:
player_leaderboards.verse
# This file contains the code that updates the billboards, player references, and UI on the island
# to display a player's stats from their player stats table. It also handles adding wins and points to a
# player's stats table.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation}
# The message to display on the stats billboard.
StatsMessage<localizes>(CurrentPlayer:message, Points:message, Wins:message):message=
"{CurrentPlayer}:\n{Points}\n{Wins}"
player_stats_manager.verse
# This file handles the code for initializing, updating, and returning player_stats_tables
# for each player. It also defines an abstract stat_type class to use for updating stats, and the
# StatType module to use when displaying stats.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Return the player_stats_table for the provided Agent.
GetPlayerStats<public>(Agent:agent)<decides><transacts>:player_stats_table=
player_leaderboards_example.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { PlayerLeaderboard }
# See https://dev.epicgames.com/documentation/en-us/uefn/create-your-own-device-in-verse for how to create a verse device.
# A Verse-authored creative device that can be placed in a level
player_leaderboards_example := class(creative_device):
# Visual representations of each player.