Üst Öğe: learn-game-mechanics-in-unreal-editor-for-fortnite Order: 0 Type: Tutorial Tags: verse Tags: cihazlar Tags: NPC Davranışı Hero-image: hero2.png Topic-image: TopicImage.png Social-image: social2.png
Sıhhiyeciler birçok oyunda yaygın olarak görülen bir karakter arketipidir. Sıhhiyecinin görevi yakınındaki karakterleri iyileştirmektir. Ayrıca takım arkadaşları hasar aldıktan sonra onların iyileşmelerine yardımcı olur. Sıhhiyeciler oyuna bağlı olarak farklı roller üstlenebilirler. Örneğin bir hastanedeki hastalara hizmet veren doktorlar, takımlarının hem savaşmasına hem de iyileşmesine yardımcı olan çatışma sıhhiyecileri veya herhangi bir oyuncuyu iyileştiren tarafsız istasyonlar olabilirler.
Bu örnekte oluşturacağın sıhhiyeci karakteri bir mantık kuralı setini takip etmektedir.
- Boşta:
- Aracıları İyileştirmeye Başla
- İyileştirme Döngüsü
- Aracıya Git
Sıhhiyeci ilk başta boştadır ve bir aracı iyileştirme alanına girene kadar devriye gezer. Alana giren aracı, sıhhiyecinin iyileştirme kuyruğuna eklenir. Sıhhiyeci, iyileştireceği bir sonraki aracıyı takip etmelidir, bu yüzden kuyruk, ilk gelen ilk çıkar yapısında olduğu için bu amaçla faydalı bir veri yapısı sağlar. Diğer bir deyişle, iyileştirme alanına ilk giren karakter, iyileştirilecek ilk karakter olacaktır.
Sıhhiyeci iyileştireceği bir sonraki aracıyı aldığında öncelikle aracının canının iyileştirme eşiği altında olup olmadığını kontrol eder. Can eşiğin altındaysa aracının canı eşiğe ulaşana veya aracı iyileştirme alanından çıkana kadar onu belirli bir hızda iyileştirmeye başlar. İyileştirme sırasında sıhhiyeci sürekli olarak aracıya giderek ona yakın kalmaya çalışacaktır. Aracının canı yeniden eşik değerine ulaştığında sıhhiyeci iyileştirilecek olan bir sonraki aracıya geçer ve süreci baştan başlatır. İyileştirilecek bir aracı yoksa sıhhiyeci boşta durumuna geri döner.
Aşağıdaki Sonlu Durum Makinesini kullanarak sıhhiyeci NPC’nin mantığını görüntüleyebilirsin. Sonlu durum makineleri hakkında daha fazla bilgi için NPC Davranışlarını Anlama bölümüne göz at.

Bu kılavuzu tamamladığında NPC Davranış Kodunu kullanarak yakında olup canı belirli bir eşiğin altında olan diğer karakterleri iyileştiren özel bir sıhhiyeci karakterini nasıl oluşturacağını öğrenmiş olacaksın. Tam kod, referans olması için bu kılavuzun sonuna eklenmiştir.
Yeni Bir NPC Davranış Kodu oluşturma
Kendi NPC Sıhhiyeci Karakterini oluşturmaya başlamak için medic_example adlı yeni bir NPC Davranış kodu oluştur. Kendi NPC davranış kodunu oluşturma konusunda daha fazla bilgi için Kendi NPC Davranışını Oluşturma bölümüne bak. Visual Studio Code’da Verse dosyasını aç.
UEFN’de yakındaki oyuncuları iyileştiren bir sıhhiyeci karakteri çıkaran bir NPC Davranış Kodu oluşturmak için aşağıdaki adımları izle.
İyileştirme Kuyruğunu Uygulama
NPC Davranış Kodu, karakter hareketi ve hata ayıklama görselleştirmesi için kullanılan birkaç değerle başlar. Bu kodda hepsine ihtiyaç duymayacağın için gereksiz kodları şu anda kaldırmalısın.
-
medic_example
sınıf tanımının üst kısmındaOnBegin()
’den önceki değerleri kaldır. Sıhhiyeci karakterin diğer karakterlere gitmek için beklemeyecek ve iyileştirme sırasında onları takip edecektir. Bu örnek için hata ayıklama değerlerine ihtiyacın yok, dolayısıyla sıhhiyecin karakterleri iyileştirirken bunu görselleştirmek için diğer objeleri kullanacaksın. -
OnBegin()
’de, birinciif
ifadesinde karakterin arayüzlerini aldıktan sonrathen
ifadesinin içindeki kodu sil. Sıhhiyeci karakterin çıktıktan sonra noktalar arasında döngüye girmesi gerekmez. Bunun yerine çıkma noktasının çevresinde devriye gezerek karakterlerin iyileşmesini bekleyecektir. -
“DrawDebugLocation()” ve “DrawDebugLookAt()” fonksiyonlarını kaldır. Bu örnekte hata ayıklama değerlerini kullanmayacağın için onları kullanan ilişkili fonksiyonlara da ihtiyacın olmayacak.
Gerekli olmayan kodları kaldırdıktan sonra sıhhiyeci karakterini inşa etmeye başlayabilirsin.
-
medic_example
sınıf tanımının üst kısmına aşağıdaki değerleri ekle:-
HealingThreshold
düzenlenebilir kayan değeri. Karakterlerin iyileştirilebilmesi için bu can eşiğinin altında olması gerekir.# Bir karakterin iyileştirilebilmesi için altında olması gerektiği CP eşiği. @editable HealingThreshold:float = 50.0
-
“HealingDelay” adlı düzenlenebilir bir kayan değer ekle. Bu değer, karakterler iyileştirilirken her bir iyileştirme örneği arasında beklenmesi gereken süredir. Sıhhiyecinin daha yavaş veya daha hızlı iyileştirmesini istemene bağlı olarak bu değeri değiştir.
# Bir karakterin iyileştirilebilmesi için altında olması gerektiği CP eşiği. @editable HealingThreshold:float = 50.0 # Karakterleri iyileştirmeden önce beklenecek süre @editable HealingDelay:float = 1.5
-
HealingAmount
düzenlenebilir kayan değeri. Bu değer, iyileştirme örneği başına karakterlerin iyileştirileceği can miktarıdır. Sıhhiyeci NPC’in bir karakteri iyileştirdiğinde, karakteri herHealingDelay
saniyedeHealingAmount
kadar iyileştirecektir.# Karakterleri iyileştirmeden önce beklenecek süre @editable HealingDelay:float = 1.5 # Karakterlerin iyileştirme örneği başına iyileştirileceği miktar @editable HealingAmount:float = 5.0
-
HealVolume
düzenlenebilir düzenleyici alanı. Bu, karakterlerin iyileşmek için gireceği bölgedir. Bu örnekte bir düzenleyici alanı kullanacaksın, çünkü düzenleyici alanında sıhhiyecinin bağlanarak iyileşmeye ihtiyaç duyabilecek karakterler olup olmadığını kontrol edebileceği birAgentEntersEvent
vardır.# Karakterlerin iyileştirme örneği başına iyileştirileceği miktar @editable HealingAmount:float = 5.0 # Karakterlerin iyileşmek için gireceği bölge. @editable HealVolume:mutator_zone_device = mutator_zone_device{}
-
VFXSpawner
düzenlenebilir görsel efekt çıkma yeri. Görsel geribildirim, kodunun çalıştığından emin olmak açısından önemlidir. Bu nedenle, bir karakter iyileştirilirken efektler çıkarmak için bir görsel efekt çıkma yeri kullanacaksın.# Karakterlerin iyileşmek için gireceği bölge. @editable HealVolume:mutator_zone_device = mutator_zone_device{} # Karakterler iyileştirilirken görsel efekt oynatmak için görsel efekt çıkma yeri. @editable VFXSpawner:vfx_spawner_device = vfx_spawner_device {}
-
AgentToFollow
adlı değişken bir isteğe bağlıagent
. Bu, sıhhiyecinin karakteri iyileştirirken takip etmesi gereken bir karakter başvurusunu depolar.# Karakterler iyileştirilirken görsel efekt oynatmak için görsel efekt çıkma yeri. @editable VFXSpawner:vfx_spawner_device = vfx_spawner_device {} # İyileştirildiği sırada takip edilecek aracı var AgentToFollow:?agent = false
-
AgentsToHeal
adlı değişken bir aracılar kuyruğu. Birden fazla karakterin iyileştirilmeye ihtiyacı varsa sıhhiyecin karakterleriHealVolume
’a girdikleri sıraya göre iyileştirir. Kuyruk kodunu bir sonraki adımda ayarlayacaksın. Kuyruk veri yapısı hakkında daha fazla bilgi için Verse’te yığınlar ve kuyruklar bölümüne bak.# İyileştirildiği sırada takip edilecek aracı var AgentToFollow:?agent = false # Birden fazla aracının iyileşme bölgesine girmesi durumunda iyileştirilecek aracılar kuyruğu. var AgentsToHeal<public>:queue(agent) = queue(agent){}
-
UpdateRateSeconds
değişken kayan değeri. Bu değer,HealVolume
veVFXSpawner
konumunun güncellenmesi arasında beklenecek süredir.# Birden fazla aracının iyileşme bölgesine girmesi durumunda iyileştirilecek aracılar kuyruğu. var AgentsToHeal<public>:queue(agent) = queue(agent){} # HealVolume ve VFXSpawner konumunun ne kadar çabuk güncelleneceğini belirtmek için kullanılır UpdateRateSeconds<private>:float = 0.1
-
-
“AgentsToHeal” kuyruğunu uygulamak için bu adımın sonunda verilen kodu kullanacaksın.
- Verse Gezgini’ne geri dönerek projenin adına sağ tıkla ve Projeye yeni Verse dosyası ekle’yi seçerek Verse Kodu Oluştur penceresini aç.
-
Verse Kodu Oluştur penceresinde kodun olarak seçmek üzere Verse Sınıfı’na tıkla.
-
Sınıf Adı alanındaki metni “queue” olarak değiştirerek Verse sınıfına bir ad ver.
-
Verse dosyasını oluşturmak için Oluştur butonuna tıkla.
-
Verse Gezgini’nde Verse dosyanın adına çift tıklayarak dosyayı Visual Studio Code’da aç.
-
“queue” dosyandaki kodu aşağıdaki kodla değiştir. Bu kod bir liste verileri yapısı kullanarak
type
türünde genel bir kuyruk uygular. Kuyruk uygulaması, kuyruğu oluşturduğun türden bağımsız olarak çalışacağı için bu bir parametrik tür örneğidir. Örneğinde bir karakter kuyruğu kullanacağın içinmedic_example
içindeki kuyruk tanımınqueue(agent)
olacak.list(t:type) := class: Data:t Next:?list(t) queue<public>(t:type) := class<internal>: Elements<internal>:?list(t) = false Size<public>:int = 0 Enqueue<public>(NewElement:t):queue(t) = queue(t): Elements := option: list(t): Data := NewElement Next := Elements Size := Size + 1 Dequeue<public>()<decides><transacts>:tuple(queue(t), t) = List := Elements? (queue(t){Elements := List.Next, Size := Size - 1}, List.Data) Front<public>()<decides><transacts>:t = Elements?.Data CreateQueue<public><constructor>(InData:t where t:type) := queue(t): Elements := option: list(t): Data := InData Next := false Size := 1
-
Verse kodlarını ayrı klasörler halinde düzenlemen hem organize olmana yardımcı olabilir hem de sık kullanılan dosyalara kolayca başvurma yöntemleri sunabilir. Bunun bir örneği olarak bu projedeki NPC davranışlarını depolamak için bir klasör oluşturacaksın. Visual Studio Code’da, Yeni Klasör butonuna basarak UEFN projende yeni bir klasör oluştur. Klasöre
npc_behaviors
adını ver. Ardındanmedic_example
Verse dosyanı yeni klasöre sürükle.
medic_example
dosyasındaki kodun artık doğru şekilde derlenmelidir.
Bir Bölgenin İçindeki Karakterleri İyileştirme
Yaralı bir karakter HealVolume
bölgesine girdiğinde karakterin canı HealingThreshold
eşiğinin altındaysa sıhhiyeci karakterin onu iyileştirmeye başlamalıdır. Karakterin canı HealingThreshold
eşiğinin üzerine çıktığında sıhhiyecin o karakteri iyileştirmeyi bırakmalı ve iyileştirilmeye ihtiyaç duyan bir sonraki karaktere geçmelidir. Birden fazla karakter söz konusu olduğunda sıhhiyecin karakterleri HealVolume
’e girdikleri sıraya göre iyileştirmelidir. Karakterler HealVolume
’e girdiklerinde onları iyileştirmek için aşağıdaki adımları izle.
-
“medic_example” dosyana geri dönerek “OnBegin()”de “then” ifadesinden sonra bir “loop” başlat.
loop
içindeAgentsToHeal
kuyruğundanDequeue()
fonksiyonunun sonucunu al ve sonucuDequeueResult
adlı bir değişken içine kaydet.then: loop: # Kuyruktaki iyileştirilecek bir sonraki aracıyı al. İyileştirilecek bir aracı varsa AgentToHeal’i çağırarak onu iyileştir. # İyileştirilecek bir aracı yoksa HealVolume’e bir aracı girene kadar bekle if: DequeueResult := AgentsToHeal.Dequeue[]
-
DequeueResult
değişkeni, hem birinci öğesi kaldırılmış olarakAgentsToHeal
kuyruğunun hem de kuyruğun önündeki aracının bir kopyasını döndüren birtuple
fonksiyonudur.AgentsToHeal
’i demetteki birinci değere ayarlayarak güncelle ve ikinci değeriAgentToHeal
olarak kaydet.if: DequeueResult := AgentsToHeal.Dequeue[] set AgentsToHeal = DequeueResult(0) AgentToHeal := DequeueResult(1)
-
İyileştirilecek bir aracı olduğunda onu “HealVolume”’da olduğu sırada iyileştirmeye başlamalısın. Bunu gerçekleştirmek için
HealCharacter()
adlı yeni bir fonksiyon tanımlayacaksın.medic_example
sınıf tanımınaHealCharacter()
adlı yeni bir fonksiyon ekle. Bu fonksiyon, sıhhiyeci karakterlerin hemNavigatable
hem deFocusable
arayüzleri için fonksiyon bağımsız değişkeni olarakAgentToHeal
’i alır. Bir karakteri iyileştirirken çeşitli asenkron görevler gerçekleştirmesi gerektiğinden bu fonksiyona ““ değiştiricisini ekle. # Karakteri iyileştir, ardından HealingDelayAmount süresi kadar bekle. # Karakterin sağlığı HealingThreshold eşiğine ulaştığında # veya karakter HealVolume bölgesinden ayrıldığında sona erer. HealCharacter(AgentToHeal:agent, Navigatable:navigatable, Focusable:focus_interface)<suspends>:void=
-
HealCharacter
’da,AgentToHeal
’ın bölge içinde olup olmadığınıIsInVolume[]
’u çağırarak ve bağımsız değişken olarakAgentToHeal
’i ileterek kontrol et. Aracı bölgede ise onu iyileştirmeye başlayabilirsin. Tüm iyileştirilebilir aracılar, aracınınfort_character
’ının bir parçası olanhealthful
arayüzünü uygular. Aracının “fort_character” değerini al ve “CharacterToHeal” değerine kaydet.HealCharacter(AgentToHeal:agent, Navigatable:navigatable, Focusable:focus_interface)<suspends>:void= # Karakteri yalnızca HealVolume içindeyse iyileştir if: HealVolume.IsInVolume[AgentToHeal] CharacterToHeal := AgentToHeal.GetFortCharacter[]
-
Karakter iyileştirmeye hazır olduğunda sıhhiyecinin iyileştirilmekte olan karaktere yakın kaldığından emin olmalısın.
MakeNavigationTarget
’ı kullanarakAgentToHeal
’den birnavigation_target
oluştur ve onuNavigationTarget
adlı bir değişkene kaydet. Daha sonra sıhhiyecininAgentToHeal
’e gitmesini sağlamak için birbranch
ifadesinde NPC’ninnavigatable
arayüzünü kullanarakNavigateTo()
fonksiyonunu çağır. Ayrıcabranch
fonksiyonunda, sıhhiyecininAgentToHeal
e odaklandığından emin olmak içinMaintainFocus()
fonksiyonunu çağır. Bu bağlamda birbranch
ifadesi kullanarak hemNavigateTo()
hem deMaintainFocus()
’u asenkron bir şekilde aynı anda çalıştırabilir vebranch
sonrasında da herhangi bir kodu anında çalıştırabilirsin. Branch ifadeleri hakkında daha fazla bilgi için Verse’te branch sayfasına bak.# Karakteri yalnızca HealVolume içindeyse iyileştir if: HealVolume.IsInVolume[AgentToHeal] CharacterToHeal := AgentToHeal.GetFortCharacter[] then: Print("Karakter bölge içinde, iyileştirmeye başla") NavigationTarget := MakeNavigationTarget(AgentToHeal) branch: Navigatable.NavigateTo(NavigationTarget) Focusable.MaintainFocus(AgentToHeal)
-
Sıhhiyecin bir karakteri iyileştirirken görsel efekt oynatmak için “VFXSpawner”’ı etkinleştir. Ardından bir
defer
ifadesindeVFXSpawner
’ı devre dışı bırak.VFXSpawner
’ın devre dışı bırakılmasına ilişkin kod birdefer
ifadesinde olduğundan kod, geçerli kapsam çıkış yapana kadar çalışmayacaktır. Bu durumda kod yalnızca fonksiyon sona erdiğinde çalışacağı için fonksiyonda gerçekleşecek son şeyin bu olacağı kesindir. Defer ifadeleri hakkında daha fazla bilgi için defer sayfasına bak.branch: Navigatable.NavigateTo(NavigationTarget) Focusable.MaintainFocus(AgentToHeal) VFXSpawner.Enable() defer: VFXSpawner.Disable()
-
CharacterToHeal
iyileştirilirken şu iki koşuldan biri gerçekleştiğinde iyileştirme durmalıdır: Karakterin canıHealingThreshold
eşiğini aşacak düzeyde iyileştirilmiştir veya karakterHealVolume
bölgesinden çıkmıştır. Bunu başarmak için birrace
ifadesi kullanacaksın.HealVolume.AgentExitsEvent
üzerinde birloop
ileAwait()
arasında birrace
ifadesi oluştur.branch: Navigatable.NavigateTo(NavigationTarget) Focusable.MaintainFocus(AgentToHeal) VFXSpawner.Enable() defer: VFXSpawner.Disable() race: loop: HealVolume.AgentExitsEvent.Await()
-
loop
içindeGetHealth()
kullanarak karakterin mevcut canını al veCurrentHealth
adlı bir değere kaydet. Sonra birif
ifadesindeCurrentHealth
ileHealingAmount
değerlerinin toplamınınHealingThreshold
değerinden fazla olup olmadığını kontrol et. Fazlaysa sıhhiyecin iyileştirmeyi durdurmalı vebreak
ile döngüden çıkmalıdır. Ancak karakterin mevcut canı iyileştirme eşiğinin çok az altındaysa karakteri iyileştirme eşiğine kadar iyileştirmen gerekir. Birinci ifadenin içine,CurrentHealth
değerininHealingThreshold
eşiğinden az olup olmadığını kontrol eden ikinci birif
ifadesi ekle. Azsa karakterin canınıHealingThreshold
olarak ayarla.race: loop: CurrentHealth := CharacterToHeal.GetHealth() if(CurrentHealth + HealingAmount > HealingThreshold): if (CurrentHealth < HealingThreshold): CharacterToHeal.SetHealth(HealingThreshold) PrintNPCB("Karakter HealingThreshold eşiğine ulaştı, iyileştirme durduruluyor") break HealVolume.AgentExitsEvent.Await()
-
CurrentHealth
ileHealingAmount
değerlerinin toplamıHealingThreshold
değerinden büyük değilse karakterin canınıCurrent Health
ileHealingAmount
toplamı olarak ayarla.if(CurrentHealth + HealingAmount > HealingThreshold): if (CurrentHealth < HealingThreshold): CharacterToHeal.SetHealth(HealingThreshold) PrintNPCB("Karakter HealingThreshold eşiğine ulaştı, iyileştirme durduruluyor") break else: CharacterToHeal.SetHealth(CurrentHealth + HealingAmount)
-
loop
sonundaHealingDelay
kadar bir süre boyunca uyu. Bu uyku olmadan karakterler her simülasyon güncellemesinde iyileştirilecektir, bu nedenleHealingDelay
onların anında iyileştirilmesini önler. TamamladığınHealCharacter()
kodun aşağıdaki gibi görünmelidir.# Karakteri iyileştir, ardından HealingDelayAmount süresi kadar bekle. # Karakterin sağlığı HealingThreshold eşiğine ulaştığında # veya karakter HealVolume bölgesinden ayrıldığında sona erer. HealCharacter(AgentToHeal:agent, Navigatable:navigatable, Focusable:focus_interface)<suspends>:void= # Karakteri yalnızca HealVolume içindeyse iyileştir if: HealVolume.IsInVolume[AgentToHeal] CharacterToHeal := AgentToHeal.GetFortCharacter[] then: Print("Karakter bölge içinde, iyileştirmeye başla") NavigationTarget := MakeNavigationTarget(AgentToHeal) branch: Navigatable.NavigateTo(NavigationTarget) Focusable.MaintainFocus(AgentToHeal) VFXSpawner.Enable() defer: VFXSpawner.Disable() race: loop: CurrentHealth := CharacterToHeal.GetHealth() if(CurrentHealth + HealingAmount > HealingThreshold): if (CurrentHealth < HealingThreshold): CharacterToHeal.SetHealth(HealingThreshold) PrintNPCB("Karakter HealingThreshold eşiğine ulaştı, iyileştirme durduruluyor") break else: CharacterToHeal.SetHealth(CurrentHealth + HealingAmount) Sleep(HealingDelay) HealVolume.AgentExitsEvent.Await()
-
OnBegin()
dizisine dönerekloop
içindekithen
ifadesindeAgentToHeal
’ı,Navigable
arayüzünü veFocusable
arayüzünü ileterekHealCharacter()
’ı çağır.if: DequeueResult := AgentsToHeal.Dequeue[] set AgentsToHeal = DequeueResult(0) AgentToHeal := DequeueResult(1) then: Print("İyileştirilecek bir sonraki aracı kuyruktan çıkarıldı") HealCharacter(AgentToHeal, Navigatable, Focusable)
-
Sıhhiyecinin yakınında her zaman iyileştirilecek bir karakter olmayacak ve
Dequeue[]
fonksiyonu,AgentsToHeal
kuyruğunda aracı olmaması halinde başarısız olacaktır. Bu sorunu çözmek içinloop
’un sonuna birelse
ifadesi ekle. Buif
ifadesinin içindeHealingDelay
kadar bir süre içinSleep()
’i çağır, ardındanHealVolume.AgentEntersEvent
içinAwait()
’i uygula. Böylece sıhhiyeci karakterinAgentsToHeal
kuyruğunda sonsuza kadarDequeue[]
’yu çağırmayacak ve onun yerine döngüyü yeniden başlatmadan önce yeni bir karakterinHealVolume
bölgesine girmesini bekleyecektir. Tamamlanan döngün aşağıdaki gibi görünmelidir.loop: # Kuyruktaki iyileştirilecek bir sonraki aracıyı al. İyileştirilecek bir aracı varsa AgentToHeal’i çağırarak onu iyileştir. # İyileştirilecek bir aracı yoksa HealVolume’e bir aracı girene kadar bekle if: DequeueResult := AgentsToHeal.Dequeue[] set AgentsToHeal = DequeueResult(0) AgentToHeal := DequeueResult(1) then: Print("İyileştirilecek bir sonraki aracı kuyruktan çıkarıldı") HealCharacter(AgentToHeal, Navigatable, Focusable) else: Print("AgentsToHeal boş!") Sleep(HealingDelay) HealVolume.AgentEntersEvent.Await()
Karakterlerin Ne Zaman İyileştirme Bölgesinde Olduğunu Takip Etme
Karakterlerin HealVolume
’e ne zaman girdiğini veya buradan ne zaman çıktığını öğrenmek için HealVolume
’ün hem AgentEntersEvent
’ini hem de AgentExitsEvent
’ini yeni fonksiyonlara bağlayacaksın.
-
medic_example
sınıf tanımınaOnAgentEnters()
adlı yeni bir fonksiyon ekle. Bu fonksiyon,HealVolume
bölgesine yeni giren aracıyı alır veAgentsToHeal
kuyruğuna yerleştirir.OnAgentEnters(EnteredAgent:agent):void= Print("Aracı iyileştirme bölgesine girdi")
-
OnAgentEnters()
’da, bölgedeki aracının sıhhiyeci karakteri olup olmadığını kontrol et. Sıhhiyeci karakteriyseAgentsToHeal
kuyruğunu,Enqueue[]
’nunEnteredAgent
ile birlikte çağrılmasının sonucuna ayarla. TamamladığınOnAgentEnters()
fonksiyonun aşağıdaki gibi görünmelidir:OnAgentEnters(EnteredAgent:agent):void= Print("Aracı iyileştirme bölgesine girdi") if (EnteredAgent <> GetAgent[]): set AgentsToHeal = AgentsToHeal.Enqueue(EnteredAgent)
-
Bir aracı
HealVolume
bölgesinden çıktığında onuAgentsToHeal
kuyruğundan da çıkarman gerekmez. Bunun nedeni,OnBegin()
içindeki döngününDequeue[]
’yu zaten bir döngü içinde çağırıyor olmasıdır. Ancak bir aracı örneklerindeki bölgeden çıktığında kod çalıştırmak isteyebilirsin, bu yüzden şimdilik bunun için bir fonksiyon oluşturacaksın.medic_example
sınıf tanımınaOnAgentExits()
adlı yeni bir fonksiyon ekle.OnAgentExits(ExitAgent:agent):void= Print("Aracı iyileştirme bölgesinden çıktı")
-
OnBegin()
’de,HealVolume
’ünAgentEntersEvent
’iniOnAgentEnters
’a,AgentExitsEvent
’ini iseOnAgentExits
’e bağla. Bu, devre dışı durumda başlaması gerektiğinden burası, karakter çıkma yerindeDisable()
’ı çağırmak için iyi bir yerdir.OnBegin<override>()<suspends>:void= Print("Merhaba Yapay Zekâ!") VFXSpawner.Disable() HealVolume.AgentEntersEvent.Subscribe(OnAgentEnters) HealVolume.AgentExitsEvent.Subscribe(OnAgentExits)
İyileştirme Bölgesini Sıhhiyeciyle Birlikte Taşıma
Sıhhiyeci karakteri hareket ettiğinde HealVolume
bölgesinin de onun geçerli konumuna uyacak şekilde taşınması gerekir. Aynı durum VFXSpawner
için de geçerlidir. Bunu yapmak için DeviceFollowCharacter()
adlı yeni fonksiyonu kullanacaksın.
-
medic_example
sınıf tanımınaDeviceFollowCharacter()
adlı yeni bir fonksiyon ekle. Bu fonksiyonun cihaz konumlarını sürekli olarak güncellemek için asenkron bir şekilde çalışması gerekir. Bu nedenle fonksiyona ““ değiştiricisini ekle. DeviceFollowCharacter()<suspends>:void=
-
DeviceFollowCharacter()
fonksiyonunun içinde öncelikleGetAgent[]
’ı kullanarak aracıyı alıp ardındanGetFortCharater[]
’ı çağırarak sıhhiyecininfort_character
’ını al.DeviceFollowCharacter()<suspends>:void= if: # Bu davranışın ilişkili olduğu aracıyı (Yapay Zekâ Karakteri) al. Agent := GetAgent[] # Fortnite karakterine özgü davranışlara, olaylara, fonksiyonlara ve arayüzlere erişmek için aracının fort_character arayüzünü al. Character := Agent.GetFortCharacter[]
-
Şimdi
HealVolume
veVFXSpawner
’ı sürekli olarakCharacter
ın konumuna taşımalısın. Bunu, her iki cihazda da birMoveTo()
döngüsü oluşturarak yapabilirsin. Birloop
başlat veCharacter
’ın dönüşümünü alıp onuCharacterTransform
adlı bir değişkene kaydet.if: # Bu davranışın ilişkili olduğu aracıyı (Yapay Zekâ Karakteri) al. Agent := GetAgent[] # Fortnite karakterine özgü davranışlara, olaylara, fonksiyonlara ve arayüzlere erişmek için aracının fort_character arayüzünü al. Character := Agent.GetFortCharacter[] then: loop: CharacterTransform := Character.GetTransform()
-
Hem
VFXSpawner
hem deHealVolume
üzerindeMoveTo()
’yu çağırarak bunlarıCharacterTransform.Translation
’a veCharacterTransform.Rotation
’a taşı. SüreyiUpdateRateSeconds
saniye olarak ayarla. Son olarakUpdateRateSeconds
kadar bir süre içinSleep()
’i çağırarak cihazların her simülasyon güncellemesinde konumlarını güncellemesini önle. Her simülasyon güncellemesinde cihaz konumunun güncellenmesi, cihazlarında bozuk hareketlere neden olabilir. TamamladığınDeviceFollowCharacter()
kodun aşağıdaki gibi görünmelidir.DeviceFollowCharacter()<suspends>:void= if: # Bu davranışın ilişkili olduğu aracıyı (Yapay Zekâ Karakteri) al. Agent := GetAgent[] # Fortnite karakterine özgü davranışlara, olaylara, fonksiyonlara ve arayüzlere erişmek için aracının fort_character arayüzünü al. Character := Agent.GetFortCharacter[] then: loop: CharacterTransform := Character.GetTransform() VFXSpawner.MoveTo(CharacterTransform.Translation, CharacterTransform.Rotation, UpdateRateSeconds) HealVolume.MoveTo(CharacterTransform.Translation, CharacterTransform.Rotation, UpdateRateSeconds) Sleep(UpdateRateSeconds)
-
OnBegin()
’de, karakter arayüzlerini kaydettiğinif
ifadesinden sonra, fakat döngüden önce birDeviceFollowCharacter()
örneği çıkar.
Karakterini Bölüme Ekleme
-
Sıhhiyeci adlı yeni bir NPC Karakter Tanımı oluştur. Yeni NPC karakter tanımına tıklayarak NPC Karakter Tanımı ekranını aç.
-
NPC Karakter Tanımı ekranında aşağıdaki özellikleri değiştir:
-
NPC Karakter Türü altında Tür’ü Muhafız olarak ayarla. Muhafız arayüzünü kullanarak muhafızın tetikte veya şüpheci olduğu durumlara dair olaylar gibi muhafıza özgü karakter işlevselliklerine erişebilir ve takım arkadaşı olarak kullanılacak muhafızlar işe alabilirsin. Muhafızlar silah da kuşanabilirken Özel ve Vahşi Hayvan türündeki karakterler şu anda bunu yapamaz. Ad sekmesi altında karakterinin adını da değiştirebilirsin.
-
NPC Karakter Davranışı altında Davranış’ı Verse Davranışı olarak ayarla. Ardından NPC Davranış Kodu’nu
medic_example
olarak ayarla. Karakterin, muhafız arayüzündeki işlevselliklere erişmeye devam edecek, ancakOnBegin
veOnEnd
sırasında ne yapacağına karar vermek için senin Verse kodunu kullanacaktır. -
Karakterinin kozmetik görünümünü değiştirmek için Değiştiriciler sekmesindeki Muhafız Çıkma Değiştiricisi altında Kozmetik sekmesine tıkla. Önceden var olan bir kozmetiği seçebilir ya da Karakter Kozmetik Yeniden Hedeflemesi’ni etkinleştirerek özel bir model kullanabilirsin. Karakter kozmetiği yeniden hedeflemesini yalnızca muhafızlar ve Özel türdeki karakterler kullanabilir, vahşi hayvanlar ise kullanamaz. Karakter değiştiricileri ile farklı karakter türlerine bunlardan hangilerinin uygulandığı konusunda daha fazla bilgi için Karakter Tanımı sayfasına bak.
-
-
NPC karakter tanımını kaydet. İçerik Tarayıcısı’nda NPC karakter tanımını bölüme sürükle. Bunu yaptığında otomatik olarak yeni bir karakter çıkma yeri oluşturulacak ve NPC karakter tanımın oraya atanacaktır.

-
Bölüme bir düzenleyici alanı ve bir görsel efekt çıkma yeri cihazı sürükle.
-
Karakter çıkma yerini seç. Anahat Düzenleyicisi’ndeki Kullanıcı Seçenekleri altında:
-
AIBehavior Kodu geçersiz kılma’yı
medic_example
koduna ayarla. Anahat düzenleyicisindeAIBehavior
Kodunu geçersiz kılman bölümdeki cihazlara başvurabilmeni sağlayacak olup HealVolume’ün ile VFXSpawner’ını atamak için bu işlevselliğe ihtiyaç duyacaksın. -
HealVolume’ü düzenleyici alanı olarak, VFXSpawner’ı ise bölüme yerleştirdiğin görsel efekt çıkma yeri olarak ayarla.
-

-
Düzenleyici alanını seç. Anahat Düzenleyicisi’ndeki Kullanıcı Seçenekleri altında Alan Oyun Sırasında Görünür’ü True olarak ayarla. Bunun sonucunda
HealVolume
bölgesinin nerede olduğunu ve sıhhiyeci karakteriyle birlikte nasıl hareket ettiğini görselleştirebilmen mümkün olacaktır. -
Görsel Efekt Çıkma Yerini seç. Anahat Düzenleyicisi’ndeki Kullanıcı Seçenekleri altında Görsel Efekt seçeneğini istediğin bir efekte ayarla. Bu örnekte iyileşmeyi iletmek için Kabarcıklar efekti kullanılıyor, ancak sen havai fişekler veya kıvılcımlar gibi farklı bir şey de kullanmayı tercih edebilirsin. Görsel efekti karakterinin ihtiyaçlarına uyacak şekilde değiştir.
-
Bölümüne oynanış testi yapmak için UEFN araç çubuğunda Oturumu Başlat’a tıkla. Oynanış testi yaptığında karakterin, düzenleyici alanına giren yaralı karakterleri iyileştirmelidir. Bir karakter iyileştirilirken görsel efekt oynatılmalı ve sıhhiyeci, iyileştirilmekte olan karakteri takip edip ona odaklanmalıdır.

Tam Kod
CP’si belirli bir eşiğin altında olan karakterleri iyileştiren bir NPC Karakterinin tam kodu aşağıda verilmiştir.
medic_example.verse
using { /Fortnite.com/AI }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Devices }
using { /Verse.org/Colors }
using { /Verse.org/Random }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
# Bir NPC Tanımı veya bir Karakter Çıkma Yeri cihazının Davranış Kodu Geçersiz Kılmasında kullanılabilecek, Verse ile yazılmış bir NPC Davranışı.
medic_example<public> := class(npc_behavior):
# Bir karakterin iyileştirilebilmesi için altında olması gerektiği CP eşiği.
@editable
HealingThreshold:float = 50.0
# Karakterleri iyileştirmeden önce beklenecek süre
@editable
HealingDelay:float = 1.5
# Karakterlerin iyileştirme örneği başına iyileştirileceği miktar
@editable
HealingAmount:float = 5.0
# Karakterlerin iyileşmek için gireceği bölge.
@editable
HealVolume:mutator_zone_device = mutator_zone_device{}
# Karakterler iyileştirilirken görsel efekt oynatmak için görsel efekt çıkma yeri.
@editable
VFXSpawner:vfx_spawner_device = vfx_spawner_device {}
# İyileştirildiği sırada takip edilecek aracı
var AgentToFollow:?agent = false
# Birden fazla aracının iyileşme bölgesine girmesi durumunda iyileştirilecek aracılar kuyruğu.
var AgentsToHeal<public>:queue(agent) = queue(agent){}
# HealVolume ve VFXSpawner konumunun ne kadar çabuk güncelleneceğini belirtmek için kullanılır
UpdateRateSeconds<private>:float = 0.1
OnBegin<override>()<suspends>:void=
VFXSpawner.Disable()
HealVolume.AgentEntersEvent.Subscribe(OnAgentEnters)
HealVolume.AgentExitsEvent.Subscribe(OnAgentExits)
if:
# Bu davranışın ilişkili olduğu aracıyı (Yapay Zekâ Karakteri) al.
Agent := GetAgent[]
# Fortnite karakterine özgü davranışlara, olaylara, fonksiyonlara ve arayüzlere erişmek için aracının fort_character arayüzünü al.
Character := Agent.GetFortCharacter[]
# Karakterin seyahat edeceği belirli hedefler ayarlamak için karakterin gidilebilir arayüzünü al.
Navigatable := Character.GetNavigatable[]
# Karakterin ulaştıktan sonra odaklanacağı belirli hedefler ayarlamak için karakterin focus_interface’ini al.
Focusable := Character.GetFocusInterface[]
then:
# HealVolume ve VFXSpawner’ı, NPC Karakterini sürekli olarak takip edecek şekilde ayarla
spawn{DeviceFollowCharacter()}
loop:
# Kuyruktaki iyileştirilecek bir sonraki aracıyı al. İyileştirilecek bir aracı varsa AgentToHeal’i çağırarak onu iyileştir.
# İyileştirilecek bir aracı yoksa HealVolume’e bir aracı girene kadar bekle
if:
DequeueResult := AgentsToHeal.Dequeue[]
set AgentsToHeal = DequeueResult(0)
AgentToHeal := DequeueResult(1)
then:
PrintNPCB("İyileştirilecek bir sonraki aracı kuyruktan çıkarıldı")
HealCharacter(AgentToHeal, Navigatable, Focusable)
else:
PrintNPCB("AgentsToHeal boş!")
Sleep(HealingDelay)
HealVolume.AgentEntersEvent.Await()
else:
# Kod buraya düşerse aracı ile arayüzleri toplanırken bir hata olmuş demektir
PrintNPCB( "NPC Ayarında NPC Davranış Kodu Hatası",
?Duration := 6.0,
?TextColor := NamedColors.Red )
# Karakteri iyileştir, ardından HealingDelayAmount süresi kadar bekle.
# Karakterin sağlığı HealingThreshold eşiğine ulaştığında
# veya karakter HealVolume bölgesinden ayrıldığında sona erer.
HealCharacter(AgentToHeal:agent, Navigatable:navigatable, Focusable:focus_interface)<suspends>:void=
# Karakteri yalnızca HealVolume içindeyse iyileştir
if:
HealVolume.IsInVolume[AgentToHeal]
CharacterToHeal := AgentToHeal.GetFortCharacter[]
then:
PrintNPCB("Karakter bölge içinde, iyileştirmeye başla")
NavigationTarget := MakeNavigationTarget(AgentToHeal)
branch:
Navigatable.NavigateTo(NavigationTarget)
Focusable.MaintainFocus(AgentToHeal)
VFXSpawner.Enable()
defer:
VFXSpawner.Disable()
race:
loop:
CurrentHealth := CharacterToHeal.GetHealth()
if(CurrentHealth + HealingAmount > HealingThreshold):
if (CurrentHealth < HealingThreshold):
CharacterToHeal.SetHealth(HealingThreshold)
PrintNPCB("Karakter HealingThreshold eşiğine ulaştı, iyileştirme durduruluyor")
break
else:
CharacterToHeal.SetHealth(CurrentHealth + HealingAmount)
Sleep(HealingDelay)
HealVolume.AgentExitsEvent.Await()
# HealVolume ve VFXSpawner cihazlarını, karakterin konumunda MoveTo döngüsü oluşturarak
# karakteri sürekli takip edecek şekilde ayarla.
DeviceFollowCharacter()<suspends>:void=
if:
# Bu davranışın ilişkili olduğu aracıyı (Yapay Zekâ Karakteri) al.
Agent := GetAgent[]
# Fortnite karakterine özgü davranışlara, olaylara, fonksiyonlara ve arayüzlere erişmek için aracının fort_character arayüzünü al.
Character := Agent.GetFortCharacter[]
then:
# HealVolume ve VFXSpawner üzerinde MoveTo döngüsü oluşturarak konumlarını
# NPC Karakteriyle eşleştir
loop:
CharacterTransform := Character.GetTransform()
VFXSpawner.MoveTo(CharacterTransform.Translation, CharacterTransform.Rotation, UpdateRateSeconds)
HealVolume.MoveTo(CharacterTransform.Translation, CharacterTransform.Rotation, UpdateRateSeconds)
Sleep(UpdateRateSeconds)
# NPC Karakteri dışında bir aracı HealVolume bölgesine girdiğinde
# onu AgentsToHeal kuyruğuna ekle.
OnAgentEnters(EnteredAgent:agent):void=
PrintNPCB("Aracı iyileştirme bölgesine girdi")
if (EnteredAgent <> GetAgent[]):
set AgentsToHeal = AgentsToHeal.Enqueue(EnteredAgent)
# Bir aracı HealVolume bölgesinden çıktığında günlüğe PrintNPCB ekle
OnAgentExits(ExitAgent:agent):void=
PrintNPCB("Aracı iyileştirme bölgesinden çıktı")
# Varsayılan bir süre ve renk sağlayan özel sarmalayıcı.
PrintNPCB(Msg:string,?Duration:float = 3.0, ?TextColor:color = NamedColors.Green):void =
Print("[new_npc_behavior] {Msg}", ?Color := TextColor, ?Duration := Duration)
# Bu fonksiyon, NPC yok olduğunda veya dünyadan avlandığında çalışır.
OnEnd<override>():void =
if(Agent := GetAgent[]):
Print(medic_example_message_module.OnEndMessage(Agent))
else:
PrintNPCB("OnEnd")
queue.verse
list(t:type) := class:
Data:t
Next:?list(t)
queue<public>(t:type) := class<internal>:
Elements<internal>:?list(t) = false
Size<public>:int = 0
Enqueue<public>(NewElement:t):queue(t) =
queue(t):
Elements := option:
list(t):
Data := NewElement
Next := Elements
Size := Size + 1
Dequeue<public>()<decides><transacts>:tuple(queue(t), t) =
List := Elements?
(queue(t){Elements := List.Next, Size := Size - 1}, List.Data)
Front<public>()<decides><transacts>:t = Elements?.Data
CreateQueue<public><constructor>(InData:t where t:type) := queue(t):
Elements := option:
list(t):
Data := InData
Next := false
Size := 1
Kendi Kendine Yapabileceklerin
Bu kılavuzu tamamlayarak belirli bir eşiğin altındaki karakterleri otomatik olarak iyileştiren bir sıhhiyeci karakteri oluşturmayı öğrenmiş oldun. Öğrendiklerini kullanarak kendi özel davranışlarına sahip olan kendi sıhhiyeci karakterini oluşturmayı dene.
-
Bir düşmanın bölge içinde olup olmamasına göre hasar verme ve iyileştirme bölgeleri arasında geçiş yapan bir sıhhiyeci oluşturabilir misin?
-
Peki ya karakterleri iyileştirmek için tükenebilen bir kaynak kullanan bir sıhhiyeci? Sıhhiyeci bu kaynağı nasıl geri kazanırdı? Zaman içinde mi yoksa düşmanlara saldırarak mı geri kazanırdı?