Birçok deneyimde, oyuncu deneyimi verilerini zaman içinde izlemek için oyuncu istatistikleri kullanılır. Yüksek puan, kazanılan toplam oyun sayısı, toplam oyun süresi ve toplanan eşyalar gibi istatistikler oyunculara ilerleme hissi verir ve oyuncuları deneyimine geri dönmeye teşvik eden harika yollardır.
Verse Sürekliliği, Verse kodlarına kalıcı veriler eklemene olanak sağlayan güçlü bir araçtır. Kalıcı veriler oyuncu başına ve ada başına kaydedilir, oyun oturumları arasında aynı kalır. Kalıcı veriler, oyun oturumları arasında oyuncu ilerlemesini izlemene olanak sağlayarak daha önce UEFN'de bulunmayan çeşitli benzersiz ve ilginç oyun deneyimlerinin önünü açar.
Bu eğitimde, Verse ile özel oyuncu istatistiklerini nasıl oluşturacağın ve bunları deneyimin birden fazla kez oynandığında kalıcı olacak şekilde nasıl ayarlayacağın gösterilecektir. Bu eğitimi bitirdikten sonra, oyun içi sıralamaları oluşturmak için sürekliliği nasıl kullanacağını öğrenmek amacıyla Verse’te Kendi Oyun İçi Sıralamanı Oluştur bölümüne göz at!
Kullanılan Verse Dili Özellikleri
Sınıf: Bu örnek, tek bir istatistiği yöneten bir Verse sınıfının yanı sıra tek oyuncu için bir grup istatistiği izleyen kalıcı bir 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ıyor.
2 adet Buton cihazı: Oyuncu cihazla etkileşime girdiğinde mevcut puanına bir puan ekler. Bir oyunun sonunu simüle etmek için başka bir düğme cihazı kullanacak, oyuncunun mevcut puanına bağlı olarak galibiyet veya mağlubiyetlerine ekleme yapacaksın.
1 adet Pano cihazı: Oyuncuya kalıcı verilerin gösterilmesi genellikle önemlidir. Bu bazen test amacıyla, bazen de oyuncu katılımını artırmak veya ilerlemeyi göstermek için yapılır. Verilerin ne zaman gösterileceğine ve hangi verilerin gösterileceğine ilişkin gereksinimler deneyimden deneyime değişmekle birlikte, bu örnekte bir Pano cihazında puan, yüksek puan, galibiyetler ve mağlubiyetler için istatistik verilerini göstereceksin.
Kalıcı Oyuncu İstatistiklerini İzleme
Öncelikle, oyuncu başına hangi istatistikleri izlemek istediğini tanımlamak önemlidir. Örneğin, bir oyuncunun tüm zamanlardaki puanını, geçerli sıralamasını veya bir turdaki en iyi süresini takip etmek isteyebilirsin. Bu örnekte, her oyuncu için bir istatistik değerleri tablosunda puan, galibiyet ve mağlubiyetleri izleyeceksin. Bunu, ana kalıcı sınıfın olacak olan player_stats_table adındaki bir sınıfta yapacaksın.
player_stats_table sınıfını oluşturmak için aşağıdaki adımları izle:
Verse Gezgini ile
player_stats_table.verseadında yeni bir Verse dosyası oluştur.Yeni Verse dosyasında
player_stats_tableadında yeni bir sınıf oluştur.<persistable>ve<final>değiştiricilerini sınıfına ekle.<persistable>değiştiricisi, sınıftaki verilerin kalıcı olmasını sağlar ve kalıcı veriler geçersiz kılınamayacağından veya alt sınıf oluşturulamayacağından<final>değiştiricisini gerektirir.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Tracks different persistable stats for each player. player_stats_table := class<final><persistable>:player_stats_tabletablosunaScore,WinsveLossesadında üçintdeğeri ekle. Bunlar her oyuncu için oyun boyunca sırasıyla skoru, galibiyetleri ve mağlubiyetleri izler. Ayrıca,player_stats_tabletablosunun geçerli sürümünü takip etmek içinVersionadlı birintekle.Verse# Tracks different persistable stats for each player. player_stats_table := class<final><persistable>: # The version of the current stats table. Version<public>:int = 0 # The score of a player. Score<public>:int = 0 # The number of wins for a player. Wins<public>:int = 0Bir
player_stats_table sınıfıörneği oluşturmak için<constructor>fonksiyonu kullanacaksın. Verse kalıcılığı, değişken alanlar içeren sınıfların kalıcı olmasına izin vermediğinden bu oluşturucu gereklidir. Bir oluşturucu kullanmak, değişken olan mevcut bir kalıcı istatistiğin kopyasını oluşturarak kalıcı sınıf değerlerini güncellemene, kopyayı güncellemene ve ardından sınıfın orijinal örneğini değiştirilen değerlerle değiştirmene olanak sağlar. DosyanaMakePlayerStatsTable()adında yeni bir oluşturucu fonksiyon ekle. Bu oluşturucu,player_stats_tablesınıfının orijinal (önceki) bir örneğini alacak ve verilen orijinal değerlerden yeni bir tane oluşturacaktır.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 Score := OldTable.Score Wins := OldTable.Wins Losses := OldTable.LossesTüm
player_stats_tablessınıflarını takip etmek için,playerileplayer_stats_tableörnekleri arasında başka bir kalıcıweak_mapkullanacaksın. Bu zayıf haritayı dosyana ekle.Verse# Maps players to a table of their player stats. var PlayerStatsMap:weak_map(player, player_stats_table) = map{}Tamamlanmış
player_stats_tablesınıfın şimdi şu şekilde görünmelidir:Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Tracks different persistable stats for each player. player_stats_table := class<final><persistable>: # The version of the current stats table. Version<public>:int = 0 # The score of a player.
Tüm Oyuncular İçin Oyuncu İstatistiklerini Yönetme
player_stats_table sınıfın tek bir oyuncu için istatistikleri izlemeni sağlar ancak henüz bunları yönetmenin bir yolu yoktur. Her oyuncu puan kazandığında istatistik tablolarını güncellemen gerekir ve deneyiminin tasarımına bağlı olarak aynı anda birçok oyuncu olabilir.
Bunu çözmek için, tüm oyuncuların istatistiklerini yönetmek ve bir oyuncu kazandığında, kaybettiğinde veya puan aldığında istatistik değişikliklerini kaydetmek için başka bir sınıf kullanacaksın. Yönetici sınıfını ayarlamak için aşağıdaki adımları izle.
Verse Gezgini ile
player_stats_manageradında yeni bir Verse dosyası oluştur. Bu dosyada yeni birplayer_stats_managersınıfı oluştur.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Manages and updates player_stat_tables for each player. player_stats_manager := class():player_stats_managersınıfının birkaç görevi yerine getirmesi gerekir. Bir oyuncu içinplayer_stats_tableoluşturması, her oyuncu içinScore,WinsveLossesdeğerini güncellemesi ve bir oyuncu içinplayer_stats_tabledöndürmesi gerekir. Bunların her birini ayrı fonksiyonlarda ele alacaksınız.player_stats_managersınıf tanımına yeni birInitializePlayer()fonksiyonu ekle. Bu fonksiyon belirtilen oyuncu için istatistikleri başlatır.Verse# Initialize stats for the given player. InitializePlayer(Player:player):void=InitializePlayer()fonksiyonunda, belirtilen oyuncununPlayerStatsMapiçinde zaten var olup olmadığını kontrol et. Yoksa, o oyuncunun haritadaki değerini yeni birplayer_stats_tableolarak ayarla. TamamlananInitializePlayer()fonksiyonun aşağıdaki gibi görünmelidir:Verse# Initialize stats for the given player. InitializePlayer(Player:player):void= if: not PlayerStatsMap[Player] set PlayerStatsMap[Player] = player_stats_table{} else: Print("Unable to initialize player stats")player_stats_managersınıf tanımına yeni birInitializeAllPlayers()fonksiyonu ekle. Bu fonksiyon bir dizi oyuncuyu alır ve tümüneInitializePlayer()çağrısı yapar. TamamlananInitializeAllPlayers()fonksiyonun aşağıdaki gibi görünmelidir:Verse# Initialize stats for all current players. InitializeAllPlayers(Players:[]player):void = for (Player : Players): InitializePlayer(Player)Belirli bir oyuncunun istatistiklerini döndürmek için, o oyuncunun
player_stats_tabledeğerini döndüren bir fonksiyona ihtiyacın vardır.player_stats_managersınıf tanımına bir aracı alan yeni birGetPlayerStats()fonksiyonu ekle. Bir oyuncunun istatistik tablosunun mevcut olmaması durumunda bu fonksiyonun başarısız olmasına ve geri dönmesine izin vermek için<decides><transacts>değiştiricisini ekle.GetPlayerStats()içinde yeni birplayer_stats_tabledeğişkeni olanPlayerStatsoluştur.Verse# Return the player_stats_table for the provided Agent. GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table= var PlayerStats:player_stats_table = player_stats_table{}Bir
ififadesinde, bu fonksiyona aktarılanAgentdeğişkenini birPlayerolarak dönüştür ve ardındanPlayerStatsMapiçinden bu oyuncu içinplayer_stats_tableal. ArdındanMakePlayerStatsTable()fonksiyonunu çağırarakPlayerStatsöğesini o tabloya ayarla. Son olarakPlayerStatsdöndür. TamamlananGetPlayerStats()fonksiyonun aşağıdaki gibi görünmelidir:Verse# Return the player_stats_table for the provided Agent. GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table= var PlayerStats:player_stats_table = player_stats_table{} if: Player := player[Agent] PlayerStatsTable := PlayerStatsMap[Player] set PlayerStats = MakePlayerStatsTable(PlayerStatsTable) PlayerStatsScore, Wins ve Losses istatistiklerinin her birini güncellemek için her istatistiği ayrı ayrı güncelleyecek fonksiyonlar oluşturacaksın.
player_stats_managerdosyanaAddScore()adlı yeni bir fonksiyon ekle. Bu fonksiyon, puan ödülü verecek aracıyı ve onlara verilecekintödül sayısını alır.Verse# Adds to the given Agent's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore<public>(Agent:agent, NewScore:int):void=Veriler, önce oyuncunun kalıcı
weak_mapiçinde geçerli verilere sahip olduğunu doğrulayarak ve ardından bu verileri sınıfın güncellenmiş bir kopyasıyla değiştirerek güncellenir. Puanın işlenmesi için, oyuncunun puanınıPlayerStatsTablefonksiyonundan al, ardındanPlayerStatsMapiiçindeki tabloyuMakePlayerStatsTable()ile yeni birplayer_stats_tableoluşturmanın sonucuna ayarla ve ardından bu tablodaki skoru yeni skorla topla. Birden fazla alan içeren bir sınıfla çalışırken, sınıf oluşturucusu her güncelleme yapmak istediğinde tüm alanları açıkça kopyalamadan tek bir alanı kolayca güncellemeni sağlar.AddScore()fonksiyonun şu şekilde görünmelidir:Verse# Adds to the given Agent's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore<public>(Agent:agent, NewScore:int):void= if: Player := player[Agent] PlayerStatsTable := PlayerStatsMap[Player] CurrentScore := PlayerStatsTable.Score set PlayerStatsMap[Player] = player_stats_table: MakePlayerStatsTable<constructor>(PlayerStatsTable) Score := CurrentScore + NewScoreBu işlemi galibiyetler ve mağlubiyetler için tekrarla ve
MakePlayerStatsTable()fonksiyonunu çağırırken oyuncunun galibiyet veya mağlubiyetlerine sırasıylaNewWinsveNewLossesekle.Verse# Adds to the given Agent's wins and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddWin<public>(Agent:agent, NewWins:int):void= if: Player := player[Agent] PlayerStatsTable := PlayerStatsMap[Player] CurrentWins := PlayerStatsTable.Wins set PlayerStatsMap[Player] = player_stats_table: MakePlayerStatsTable<constructor>(PlayerStatsTable) Wins := CurrentWins + NewWinsNihai
player_stats_managerdosyan şu şekilde görünmelidir.Verseusing { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/Diagnostics } # Manages and updates player_stat_tables for each player. player_stats_manager := class(): # Return the player_stats_table for the provided Agent. GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table= var PlayerStats:player_stats_table = player_stats_table{}
Cihazlarla Kalıcılığı Test Etme
Artık kalıcılık sınıflarını ayarladığına göre, bunları bölümünde test etme zamanı geldi.
player_stats_example adlı yeni bir Verse cihazı oluştur. İzlenecek adımlar için Verse Kullanarak Kendi Cihazını Oluşturma bölümüne bakabilirsin.
player_stats_examplesınıf tanımının üst kısmına aşağıdaki alanları ekle:ScorePointsButtonadında düzenlenebilir birbutton_device. Bu buton etkinleştirildiğinde oyuncunun skoruna eklenir.Verse# Adds to the activating player's score. @editable ScorePointsButton:button_device = button_device{}StatsBillboardadında düzenlenebilir birbillboard_device. Bu, oyuncunun Puanını, Yüksek Puanını, Galibiyetlerini ve Mağlubiyetlerini gösterir.Verse# Displays the player's Score, High Score, Wins, and Losses @editable StatsBillboard:billboard_device = billboard_device{}CheckWinButtonadında düzenlenebilir bir button_device. Bu düğme her oyuncunun puanını sıfırlar ve oyuncunun puanına bağlı olarak onlara bir galibiyet veya mağlubiyet verir.Verse# Resets the player's score and award them a win or a loss # depending if their current score is greater than WinScore. @editable CheckWinButton:button_device = button_device{}WinScoreadında düzenlenebilir birint. Bu,CheckWinButtonetkinleştirildikten sonra oyuncuların bir galibiyet kazanmak için ulaşmaları gereken puandır.Verse# The score players need to reach to be awarded a win after # the CheckWinButton is activated. @editable WinScore:int = 10AwardScoreadında düzenlenebilir birint. Bu, butonla etkileşime girdiğinde oyunculara verilen skordur.Verse# The amount of score to award per button press. @editable AwardScore:int = 1PlayerStatsManageradında birplayer_stats_manager. Bu, tüm oyuncular için istatistikleri yönetir ve günceller.Verse# Manages and updates stats for each player. PlayerStatsManager:player_stats_manager = player_stats_manager{}Dört tamsayı (Skor, MaxScore, Galibiyetler ve Mağlubiyetler) alan `StatsMessage` adında bir mesaj. Bu mesajı panoda bir oyuncunun istatistiklerini görüntülemek için kullanacaksın.
Verse# Displays a player's stats on a billboard. StatsMessage<localizes>(Player:agent, Score:int, Wins:int, Losses:int):message = "{Player}, Stats:\n Score: {Score}\n Wins: {Wins}\n Losses: {Losses}"
Kodunu derle ve Verse tarafından oluşturulan cihazı adana sürükle. İzlenecek adımlar için Verse Cihazını Bölümüne Ekleme bölümüne bakabilirsin.
Cihazının Ayrıntılar panelinde, bölümündeki Buton cihazını ScorePointsButton olarak, Pano cihazını da StatsBillboard olarak ata.
Belirli bir oyuncunun istatistiklerini StatsBillboard üzerinde görüntülemek için,
player_stats_examplesınıf tanımına yeni birUpdateStatsBillboard()fonksiyonu ekle. Bu fonksiyon, istatistikleri görüntülenecek aracıyı alır.Verse# Retrieves the stats of the given player and displays their stats # on the StatsBillboard. UpdateStatsBillboard(Agent:agent):void=UpdateStatsBillboard()içinde, istatistik yöneticisininGetPlayerStats[]fonksiyonunu çağırarak belirtilen aracının mevcut istatistiklerini al. Ardından yeni birStatsMessage()öğesi geçirerek StatsBillboard üzerindeSetText()fonksiyonunu çağır. BuStatsMessage()oluşturmak için, aracının mevcut istatistiklerinden ulaşarak aracının skorunu, galibiyetlerini ve mağlubiyetlerini al. TamamlananUpdateStatsBillboard()fonksiyonun aşağıdaki gibi görünmelidir:Verse# Retrieves the stats of the given player and displays their stats # on the StatsBillboard. UpdateStatsBillboard(Agent:agent):void= if: # Get the current stats of the given agent. CurrentPlayerStats := PlayerStatsManager.GetPlayerStats[Agent] then: StatsBillboard.SetText( StatsMessage( Player := Agent,player_stats_examplesınıf tanımınaAddScore()adlı yeni bir fonksiyon ekle. Bu fonksiyon bir aracıyı alır ve ScorePointsButton ile her etkileşime girdiğinde bu aracının puanına ekleme yapar.Verse# Adds to the given player's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore(Agent:agent):void=AddScore()içinde, belirtilen aracının mevcut istatistiklerinin yanı sıra mevcut puanını da al. ArdındanPlayerStatsManageröğesindenAddScore()fonksiyonunu çağır, yeni bir ödül puanı vermek için aracıyı veAwardScore’u aktar. Son olarak, belirtilen aracıyı aktararakUpdateStatsBillboard()fonksiyonunu çağır. TamamlananAddScore()fonksiyonun aşağıdaki gibi görünmelidir:Verse# Adds to the given player's score and updates both their stats table # in PlayerStatsManager and the billboard in the level. AddScore(Agent:agent):void= if: CurrentPlayerStats := PlayerStatsManager.GetPlayerStats[Agent] CurrentScore := CurrentPlayerStats.Score then: Print("Current Score is: {CurrentScore}") PlayerStatsManager.AddScore(Agent, AwardScore) UpdateStatsBillboard(Agent)CheckWin butonuyla etkileşime geçildiğinde oyuncuya bir galibiyet veya mağlubiyet vermek için player_stats_manager sınıf tanımına yeni bir
CheckWin()fonksiyonu ekle.Verse# Awards a player a win or a loss when they interact # with the CheckWinButton. CheckWin(Agent:agent):void=İlk olarak aracının mevcut puanını takip etmek için bir
CurrentScoredeğişkeni tanımla. Ardından,AddScore()fonksiyonunda olduğu gibi oyuncu istatistikleri tablosundan geçerli puanını al.Verse# Awards a player a win or a loss when they interact # with the CheckWinButton. CheckWin(Agent:agent):void= var CurrentScore:int = 0 if: PlayerStats := PlayerStatsManager.GetPlayerStats[Agent] set CurrentScore = PlayerStats.ScoreAracının geçerli puanı,
WinScoredeğerinden büyüksePlayerStatsManagerfonksiyonuna bir galibiyet kaydetmen gerekir. Aksi takdirde mağlubiyet kaydet. Son olarak, negatif birCurrentScoreileAddScore()fonksiyonunu çağırarak aracının puanını sıfırla, ardından aracının istatistiklerini istatistik panosunda göster. TamamlananCheckWin()fonksiyonun aşağıdaki gibi görünmelidir:Verse# Awards a player a win or a loss when they interact # with the CheckWinButton. CheckWin(Agent:agent):void= var CurrentScore:int = 0 if: PlayerStats := PlayerStatsManager.GetPlayerStats[Agent] set CurrentScore = PlayerStats.Score then: Print("Current Score is: {CurrentScore}") if:OnBegin()içinde,ScorePointsButton.InteractedWithEventöğesiniAddScore()fonksiyonuna veCheckWinButton.InteractedWithEventöğesiniCheckWin()fonksiyonuna bağla. ArdındanGetPlayers()fonksiyonunu çağırarak oyundaki her oyuncunun dizisini al ve hepsini istatistik yöneticisininInitializeAllPlayers()fonksiyonunu kullanarak başlat.Verse# Runs when the device is started in a running game OnBegin<override>()<suspends>:void= # Register Button Events ScorePointsButton.InteractedWithEvent.Subscribe(AddScore) CheckWinButton.InteractedWithEvent.Subscribe(CheckWin) Players := GetPlayspace().GetPlayers() # Initialize player stats PlayerStatsManager.InitializeAllPlayers(Players)Kodunu kaydet ve derle.
Kalıcılığı Bölümünde 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ı veriler sayfasındaki Kalıcı Verilerle Test Etme bölümünü incele.
Oturumunu ayarladıktan sonra, bölümünü oynatarak test ettiğinde, ScorePoints düğmesi ile etkileşim oyuncunun puanına eklenmeli ve bu güncelleme billboardda gösterilmelidir. CheckWin düğmesi ile etkileşim, oyuncunun puanına bağlı olarak oyuncunun galibiyetlerine veya mağlubiyetlerine eklenmelidir. Lobiye döndükten ve adaya yeniden girdikten sonra, oyuncunun istatistikleri devam etmeli ve toplam galibiyetleri / mağlubiyetleri ile yüksek puanları güncellendiğinde billboardda gösterilmelidir.
Kendi Kendine Yapabileceklerin
Bu kılavuzu tamamlayarak, oynanış oturumları boyunca devam eden ve oyuncu başına izlenen kalıcı veriler oluşturmak için Verse’ü nasıl kullanacağını öğrendin. Şimdi kendi deneyimini geliştirmek için kalıcılığı nasıl uyarlayabileceğini keşfetmeye hazır mısın?
Oyuncunun ulaştığı son kontrol noktasını hatırlayan bir kayıt dosyası sistemi oluşturabilir misin?
Hangi karakterlerle konuştuğunu ve onlarla mevcut ilişkini hatırlayan bir sisteme ne dersin?
Oyunculara hedeflere ulaşmaları için oturumlarda yalnızca sınırlı bir süre veren ve başarısız olursa ilerlemelerini sıfırlayan bir sisteme ne dersin?
Tam Kod
Bu eğitim bölümünde oluşturulan kodun tamamı şöyledir.
player_stats_table.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Tracks different persistable stats for each player.
player_stats_table := class<final><persistable>:
# The version of the current stats table.
Version<public>:int = 0
# The score of a player.
player_stats_manager.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# Manages and updates player_stat_tables for each player.
player_stats_manager := class():
# Return the player_stats_table for the provided Agent.
GetPlayerStats(Agent:agent)<decides><transacts>:player_stats_table=
var PlayerStats:player_stats_table = player_stats_table{}
player_stats_example.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Game }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
# A Verse-authored creative device that can be placed in a level
player_stats_example := class(creative_device):
# Adds to the activating player's score.
@editable