Casusun görünmezliği, Savunmacıya ait hedefi yakalaması sırasında ilginç bir sorun oluşturur. Savunmacılar, hedeflerini kapıp üslerine geri koşuyor olabilecek görünmez bir oyuncuyu nasıl bulacak? Bu sorunu çözmek için bir görsel yardım kullanabilirsin. Bu örnekteki görsel yardım, Savunmacılara Casusun nerede olduğunu gösterecek bir nesnedir.
Elinde bir hedef tutan oyuncunun kafasının üzerinde duracak bir obje oluşturmayı öğrenmek için aşağıdaki adımları izle.
Eşya Ele Geçirme Yöneticisini Oluşturma
- Verse Gezgini kullanarak item_capture_manager adlı yeni bir Verse cihazı oluştur ve cihazı bölüme sürükle.
item_capture_manager
dosyasının en üstüne:using { /UnrealEngine.com/Temporary/SpatialMath }
ekleyerekvector3
yapısına erişim sağla. Bir oyuncunun başının üstünde duran göstergeleri nereye ışınlayacağını bilmek için bunu kullanacaksın. Bir oyuncununfort_character
değerine erişmek içinusing { /Fortnite.com/Characters }
ifadesini de ekle.using { /Fortnite.com/Devices } using { /Verse.org/Simulation } using { /Fortnite.com/Characters } using { /UnrealEngine.com/Temporary/Diagnostics } using { /UnrealEngine.com/Temporary/SpatialMath }
item_capture_manager
sınıf tanımına aşağıdaki alanları ekle:CaptureItemSpawners
adlı düzenlenebilir bir Ele Geçirilecek Eşya Oluşturma Yeri cihazları dizisi. Bu dizi, Casuslar için Ele Geçirilecek Eşya Oluşturma Yeri cihazını içerir.item_capture_manager := class(creative_device): Logger:log = log{Channel := triad_item_capture_log_channel} # Ele geçirilecek eşyayı çıkaran ele geçirilecek eşya oluşturma yeri. @editable CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{}
CaptureItemIndicator
adlı düzenlenebilir bir kreatif nesnesi. Bu nesne, hedefi yakaladığında Casusun başının üzerinde durur.# Ele geçirilecek eşyayı çıkaran ele geçirilecek eşya oluşturma yeri. @editable CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{} # CaptureItemSpawner’dan bir eşyayı tuttuğunda oyuncunun başının # üzerinde duracak bir nesne. @editable CaptureItemIndicator:creative_prop = creative_prop{}
MapIndicator
adlı düzenlenebilir bir harita göstergesi cihazı. Bu cihaz, bölümde CaptureItemSpawner’ın altında duracak ve her takımın hedeflerinin nerede olduğunu haritada gösterecektir.# CaptureItemSpawner’dan bir eşyayı tuttuğunda oyuncunun başının # üzerinde duracak bir nesne. @editable CaptureItemIndicator:creative_prop = creative_prop{} # Her takımın hedeflerinin nerede olduğunu haritada gösteren gösterge @editable MapIndicator:map_indicator_device = map_indicator_device{}
UpdateRateSeconds
veVerticalOffset
adlı iki düzenlenebilir kayan değer. BirincisiCaptureItemIndicator
konumunun ne kadar hızlı değiştiğini, ikincisi iseCaptureItemIndicator
kayan değerinin oyuncunun başından ne kadar uzakta durduğunu kontrol eder.# Her takımın hedeflerinin nerede olduğunu haritada gösteren gösterge @editable MapIndicator:map_indicator_device = map_indicator_device{} # CaptureItemIndicator göstergesinin konumunu ne sıklıkla güncelleyeceğini belirtir. @editable UpdateRateSeconds:float = 0.15 # CaptureItemIndicator göstergesinin oyuncunun başından ne kadar yüksekte duracağını belirtir. @editable VerticalOffset:float = 180.0
ItemGrabbedMessageDevice
adlı düzenlenebilir bir gösterge paneli mesajı cihazı. Bu cihaz, bir hedef alındığında her oyuncuya bir mesaj gönderir.# CaptureItemIndicator göstergesinin oyuncunun başından ne kadar yüksekte duracağını belirtir. @editable VerticalOffset:float = 180.0 # Bir oyuncu Ele Geçirilecek Eşyayı tuttuğunda bir mesaj görüntüler. @editable ItemGrabbedMessageDevice:hud_message_device = hud_message_device{}
ScoreManagerDevice
adlı düzenlenebilir bir puan yöneticisi cihazı. Bu cihaz, bir oyuncu hedefi ele geçirdiğinde takıma puan verir# Bir oyuncu Ele Geçirilecek Eşyayı tuttuğunda bir mesaj görüntüler. @editable ItemGrabbedMessageDevice:hud_message_device = hud_message_device{} # Bir oyuncu ele geçirilecek eşyayı aldığında puan verir. @editable ScoreManagerDevice:score_manager_device = score_manager_device{}
ReturnTime
adlı düzenlenebilir bir kayan sayı. Ele geçirilecek eşyanın CaptureItemSpawner’a geri dönmeden önce bir geri dönme süresi varsa göstergeleri CaptureItemSpawner’a ne zaman geri döndüreceğini bilmek için bu geri dönme süresinin uzunluğunu izlemen gerekir.
item_capture_manager
sınıf tanımınaFollowCharacter()
adlı yeni bir metot ekle. Bu metot birfort_character
alır ve başının üzerindeki göstergeleri kullanarak karakteri takip eder. Elinde bir hedef tutan oyuncu için bunlardan birini üretmen gerekeceğinden bu fonksiyona<suspends>
belirleyicisini ekle.# CaptureItemIndicator’ın bir oyuncuyu sürekli olarak başının üstünde takip etmesine neden olur. # CaptureItemIndictator için güncelleme döngüsü ile oyuncunun # eşyayı ele geçirip geçirmediği, bırakıp bırakmadığı veya avlanıp avlanmadığı arasında yarış yapar. FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("FollowCharacter fonksiyonu üretildi")
Hedefi Tutarken Yarış Yapma
Bir oyuncu hedefi yakaladığında ne olacağını düşünmek önemlidir. Oyuncu şunları yapabilir:
- Oyuncu etrafta dolaşabilir. Bu durumda CaptureItem’ının ve Harita göstergelerinin oyuncunun konumuna göre sürekli güncellenmesi gerekir. Bu bir döngü içinde yapılabilir.
- Oyuncu hedefi ele geçirebilir. Bu durumda göstergelerin, CaptureItemSpanwer’a görüş açısının dışında bir yerde dönmelidir çünkü göstergeler bir oyuncu ele geçirilecek eşyayı tutmadığında görünür olmamalıdır.
- Oyuncu hedefi bırakabilir veya avlanabilir; bu durumda göstergelerin eşyanın bırakıldığı yerde kalması ve ele geçirilecek eşya geri döndüğünde CaptureItemSpawner’a geri dönmesi gerekir.
Bunu gerçekleştirmek için bir race ifadesi ayarlaman gerekir. Yukarıdaki üç koşul arasında bir race
ifadesi kullanarak oyuncunun hedefi düşürmesini veya ele geçirmesini beklerken göstergenin konumunu güncellemeye devam edebilirsin.
FollowCharacter()
fonksiyonuna birrace
ifadesi ekle. Yarışı birloop
,CaptureItemSpawner
fonksiyonununItemCapturedEvent
olayı için birAwait()
,CaptureItemSpawner
fonksiyonununItemCapturedDroppedEvent
olayı için birAwait()
veFortCharacter
fonksiyonununEliminatedEvent()
olayı için birAwait()
arasında gerçekleşecek şekilde ayarla.FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("FollowCharacter fonksiyonu üretildi") race: loop: CaptureItemSpawner.ItemCapturedEvent.Await() CaptureItemSpawner.ItemDroppedEvent.Await() FortCharacter.EliminatedEvent().Await()
loop
dizisindeFortCharacter
konumunu al ve birTransform
değişkenine kaydet.loop: Transform := FortCharacter.GetTransform()
- Şimdi hem
CaptureItemIndicator
hem deMapIndicator
nesnelerini,Transform
fonksiyonunun aktarma ve dönüşünün yanı sıra daha önce ayarladığınVerticalOffset
değerineUpdateRateSeconds
boyunca taşımak için birMoveTo()
fonksiyonu oluştur. HemCaptureItemIndicator
hem deMapIndicator
nesnelerinin, birbirinin ifadelerinin tamamlanmasını beklemeyip tam olarak aynı zamanda taşınması gerektiğinden her ikiMoveTo()
fonksiyonunu daSpawn{}
kullanarak birlikte oluşturman gerekir. Aktarma;X
,Y
veZ
koordinatlarından oluşan birvector3
olduğundanVerticalOffset
değerini yeni birvector3
içine yerleştirmen gerekir.VerticalOffset
değeri bir oyuncunun başının üzerindeki dikey mesafe olduğu için bunuvector3
fonksiyonununZ
değeri olarak ayarla.loop: Transform := FortCharacter.GetTransform() spawn{CaptureItemIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} spawn{MapIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)}
- Son olarak
0.0
saniye uyu. Bu, döngünün her simülasyon güncellemesinde yalnızca bir kez çalışmasını veMoveTo()
fonksiyonları üreterek kontrolden çıkmamasını sağlar.FollowCharacter()
kodun şu anda aşağıdaki gibi görünmelidir:# CaptureItemIndicator’ın bir oyuncuyu sürekli olarak başının üstünde takip etmesine neden olur. # CaptureItemIndictator için güncelleme döngüsü ile oyuncunun # eşyayı ele geçirip geçirmediği, bırakıp bırakmadığı veya avlanıp avlanmadığı arasında yarış yapar. FollowCharacter(FortCharacter:fort_character)<suspends>:void= Logger.Print("FollowCharacter fonksiyonu üretildi") race: loop: Transform := FortCharacter.GetTransform() spawn{CaptureItemIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} spawn{MapIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)} # Bu döngünün her simülasyon güncellemesinde yalnızca bir kez çalıştığından emin olmak istiyoruz, bu nedenle bir oyun tiki uyuyoruz. Sleep(0.0) CaptureItemSpawner.ItemCapturedEvent.Await() CaptureItemSpawner.ItemDroppedEvent.Await() FortCharacter.EliminatedEvent().Await() Logger.Print("Hedef düşürüldü veya yakalandı")
Göstergeleri Sıfırlama
- Ele geçirilecek eşya ele geçirildiğinde veya geri döndüğünde göstergeleri gözden uzak bir şekilde
CaptureItemSpawner
’a geri göndermen gerekir. Bu örnekte göstergeleriCaptureItemSpawner
’ın yukarısına ışınlayacaksın. Bunu yapmak içinitem_capture_manager
sınıf tanımınaReturnIndicators()
adlı yeni bir fonksiyon ekle.# Haritayı ve ele geçirilecek eşya göstergelerini, çıkma yerlerinin üzerindeki başlangıç konumlarına geri döndürür. ReturnIndicators(InAgent:agent):void=
CaptureItemSpawner
dönüşümünü al ve birSpawnerTransform
değişkenine kaydet. Ardından,CaptureItemIndicator
veMapIndicator
nesneleriniCaptureItemSpawner
’ın dönüşüm ve dönüşüne taşımak için birMoveTo()
fonksiyonu oluştur. Bunu yaparken bunlarıCaptureItemSpawner
’ın yukarısına yerleştirmek içinloop
içinde yaptığın gibi birVerticalOffset
ekle. Nesnenin görüş açısından uzakta kalmasını istersenVerticalOffset
değerini büyük bir sayıyla çarpabilirsin; bu örnekte de 10 ile çarpıyoruz. TamamlananReturnIndicators()
metodun şu şekilde görünmelidir:# Haritayı ve ele geçirilecek eşya göstergelerini, çıkma yerlerinin üzerindeki başlangıç konumlarına geri döndürür. ReturnIndicators():void= SpawnerTransform := CaptureItemSpawner.GetTransform() # CaptureItemIndicator ve MapIndicator’ı haritanın yukarısında alanın dışında bir yere gizleyerek çıkma yerine geri ışınla. spawn{CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)} spawn{MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)} Logger.Print(“Göstergeler ele geçirilecek eşya oluşturma yerine döndürüldü”)
Hedefi Tutan, Bırakan ve Ele Geçiren Oyuncuları İşleme.
item_capture_manager
sınıf tanımınaOnItemPickedUp()
adlı yeni bir metot ekle. Bu metot biragent
alır ve bu karakter için birFollowCharacter()
örneği üretir.# Bir oyuncu hedefi yakaladığında her oyuncuya sinyal gönder OnItemPickedUp(InAgent:agent):void= Logger.Print(“Hedef Tutuldu”)
InAgent
içinFortCharacter
örneğini al ve buFortCharacter
örneğini kullanarak birFollowCharacter()
fonksiyonu üret. TamamlananOnItemPickedUp()
metodun şu şekilde görünmelidir:# Bir oyuncu hedefi yakaladığında her oyuncuya sinyal gönder OnItemPickedUp(InAgent:agent):void= Logger.Print(“Hedef Tutuldu”) if(FortCharacter := InAgent.GetFortCharacter[]): ItemGrabbedMessageDevice.Show() spawn{FollowCharacter(FortCharacter)}
item_capture_manager
sınıf tanımınaOnItemCaptured()
adlı yeni bir metot ekle. Bu metot, hedefi ele geçirenagent
’ı alır.# Eşya ele geçirildiğinde, ele geçiren takıma puan ver ve göstergeleri geri gönder. OnItemCaptured(CapturingAgent:agent):void= Logger.Print("Hedef Yakalandı")
OnItemCaptured()
metodunda, ele geçiren oyuncunun takımına puan vermek içinScoreManagerDevice
cihazını etkinleştir ve göstergeleri geri göndermek içinReturnIndicators()
çağrısı yap.# Eşya ele geçirildiğinde, ele geçiren takıma puan ver ve göstergeleri geri gönder. OnItemCaptured(CapturingAgent:agent):void= Logger.Print("Hedef Yakalandı") ScoreManagerDevice.Activate() ReturnIndicators()
item_capture_manager
sınıf tanımınaOnItemDropped()
adlı yeni bir metot ekle. Bu metot, eşyayı bırakanagent
’ı alır.# Bir oyuncu eşya bıraktığında ReturnTime 0’dan büyükse # bir WaitForReturn() fonksiyonu oluştur. OnItemDropped(InAgent:agent):void= Logger.Print("Hedef Bırakıldı”)
- Hedef bırakıldığında, göstergeler hedef alınana veya
CaptureItemSpawner
’a geri dönene kadar hedefin yanında kalmalı. Göstergeleri ne zaman geri göndereceğini bilmek için daha önce ayarladığınReturnTime
değişkenini kullanacaksın.ReturnTime
değeri0.0
veya daha büyükse o kadar süre bekleyip ardından göstergeleri geri döndürmen gerekir.ReturnTime
negatifse hedefin geri dönme süresi yoktur, dolayısıyla göstergeleri taşıman gerekmez. Göstergeleri geri taşımak için bir sonraki adımda tanımlayacağınWaitForReturn()
adında yeni bir yardımcı fonksiyon oluştur.# Bir oyuncu eşya bıraktığında ReturnTime 0’dan büyükse # bir WaitForReturn() fonksiyonu oluştur. OnItemDropped(InAgent:agent):void= Logger.Print("Hedef Bırakıldı”) if(ReturnTime >= 0.0): spawn{WaitForReturn()} else: Logger.Print(“Bırakılan hedef geri dönmez”)
item_capture_manager
sınıf tanımınaWaitForReturn()
adlı yeni bir metot ekle. Bu fonksiyon,ReturnTime
değeri kadar bir süre bekler ve bekleme tamamlanana kadar hedef alınmadıysa göstergeleri geri gönderir. Bu metoda<suspends>
değiştiricisini ekleyerekSleep()
fonksiyonuna izin ver.# ReturnTime değeri kadar bir süre bekle, ardından göstergeleri geri gönder. WaitForReturn()<suspends>:void= Logger.Print(“Göstergeleri geri döndürmek için bekleniyor...”)
- Göstergeleri geri döndürmen gerekip gerekmediği, hedefin
ReturnTime
süresi dolmadan önce alınıp alınmadığına bağlıdır. Alındıysa göstergeleri geri göndermemelisin aksi takdirde göstergeler hemen oyuncuya geri sıçrayıp tuhaf görüntülere neden olabilir. Bunu çözmek için değerin bir yarışın sonucuna eşit olduğu bir mantık değişkeni kullanacaksın.# ReturnTime değeri kadar bir süre bekle, ardından göstergeleri geri gönder. WaitForReturn()<suspends>:void= Logger.Print(“Göstergeleri geri döndürmek için bekleniyor...”) # Ele geçirilecek eşya süre dolmadan önce alınmadıysa CaptureItem ve # Harita göstergelerini geri döndür. ShouldReturn:logic := race:
WaitForReturn()
fonksiyonunun iki koşul arasında yarışması gerekir.ReturnTime
biter ve hedefCaptureItemSpawner
’a geri döner, bu durumda göstergeleri geri döndürmen gerektiğindenShouldReturn
değeritrue
olmalıdır. Ya da hedefReturnTime
dolmadan önce alınır, bu durumdaShouldReturn
değerifalse
olmalıdır. Bu koşulların her biri bir değer döndürdüğünden yarışı iki ayrıblock
kullanarak yapacaksın.ShouldReturn:logic := race: block: block:
- İlk blokta
ReturnTime
değeri kadar bir süre içinSleep()
fonksiyonunu çağır, ardındantrue
döndür. İkinci bloktaCaptureItemSpawner.ItemPickedUpEvent
içinAwait()
fonksiyonunu çağır ve false döndür. Bunlardan hangisi önce tamamlanırsa onun içinShouldReturn
değişkeni başlatılacak.ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() yanlış
ShouldReturn
değeri true ise göstergeleri geri döndürmen gerekir.ShouldReturn
değişkenitrue
olarak değerlenirseReturnIndicators()
çağrısı yap.WaitForReturn()
kodun şu anda aşağıdaki gibi görünmelidir:# ReturnTime değeri kadar bir süre bekle, ardından göstergeleri geri gönder. WaitForReturn()<suspends>:void= Logger.Print(“Göstergeleri geri döndürmek için bekleniyor...”) # Ele geçirilecek eşya süre dolmadan önce alınmadıysa CaptureItem ve # Harita göstergelerini geri döndür. ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() yanlış if(ShouldReturn?): ReturnIndicators()
- Şimdi
OnBegin()
dizisindeCaptureItemSpawner
’ınItemPickedUpEvent
olayınıOnItemGrabbed()
metoduna,ItemCapturedEvent
olayınıOnItemCaptured()
metoduna veItemDroppedEvent
olayını daOnItemDropped()
metoduna bağla.OnBegin<override>()<suspends>:void= CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp) CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured) CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped) SpawnerTransform := CaptureItemSpawner.GetTransform()
- Son olarak
OnBegin()
içinde, kod yürütüldüğündeCaptureItemIndicator
veMapIndicator
’daMoveTo()
çağrısı yaparak göstergeleri başlangıç konumlarına getir.OnBegin()
kodun şu anda aşağıdaki gibi görünmelidir:OnBegin<override>()<suspends>:void= CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp) CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured) CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped) SpawnerTransform := CaptureItemSpawner.GetTransform() # CaptureItemIndicator ve MapIndicator’ı haritanın altında alanın dışında bir yere gizleyerek çıkma yerine geri ışınla. CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds) MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)
-
Editöre geri dönerek kodu kaydet, derle ve cihazı bölüme sürükle. Bölümünde
CaptureItemIndicator
olarak görev yapmasını istediğin uygun bir nesneyi seç. Bu nesne yeterince görünür olduğu sürece her şey olabilir. Bu örnekte bir Elmas kullanacaksın. Ayrıntılar panelinde CaptureItemSpawner’ı InfiltratorCaptureSpawner’a, CaptureItemIndicator’ı da seçtiğin nesneye ata. Ayrıca MapIndicator’ı Casusların harita göstergesine, ItemGrabbedMessageDevice’ı Casusların Gösterge Paneli Mesajı cihazına ve ScoreManagerDevice’ı Casusların puan yöneticisine ata. Casusların ele geçirilecek eşyası geri dönmediğinden ReturnTime değerini bir negatif sayı olarak ayarla.Saldırganlar için de bir
item_capture_manager
örneği oluşturmalısın. Takımların görünümünde karışıklık olmaması için CaptureItemIndicator’ı Casus nesnelerinden farklı bir nesneyle değiştirmeyi unutma ve bunu diğer tüm cihazlara atadığından emin ol. Saldırganların ele geçirilecek eşyası belirlenen süreden sonra geri döndüğünden ReturnTime değerini bir pozitif sayı olarak ayarla. - Bölümün oynanış testini yapmak için UEFN araç çubuğunda Oturumu Başlata tıkla. Bölümüne oynanış testi yaptığında bir oyuncu bir hedefi yakaladığı zaman başının üzerinde bir nesne olmalıdır. Nesne, oyuncuyla birlikte hareket etmeli ve oyuncu hedefi düşürdüğünde veya ele geçirdiğinde nesne, ele geçirilecek eşya oluşturma yerine geri ışınlanmalıdır.

Sonraki Adım
Bu eğitimin sonraki adımında oyunculara bir oyunda ne yapmaları gerektiğini hızlıca söylemeyi ve oyuncu deneyimini geliştirirken nelere odaklanman gerektiğini öğreneceksin.