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_managerdosyasının en üstüne:using { /UnrealEngine.com/Temporary/SpatialMath }ekleyerekvector3yapı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_characterdeğ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_managersınıf tanımına aşağıdaki alanları ekle:CaptureItemSpawnersadlı 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{}CaptureItemIndicatoradlı 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{}MapIndicatoradlı 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{}UpdateRateSecondsveVerticalOffsetadlı iki düzenlenebilir kayan değer. BirincisiCaptureItemIndicatorkonumunun ne kadar hızlı değiştiğini, ikincisi iseCaptureItemIndicatorkayan 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.0ItemGrabbedMessageDeviceadlı 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{}ScoreManagerDeviceadlı 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{}ReturnTimeadlı 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_managersınıf tanımınaFollowCharacter()adlı yeni bir metot ekle. Bu metot birfort_characteralı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 birraceifadesi ekle. Yarışı birloop,CaptureItemSpawnerfonksiyonununItemCapturedEventolayı için birAwait(),CaptureItemSpawnerfonksiyonununItemCapturedDroppedEventolayı için birAwait()veFortCharacterfonksiyonununEliminatedEvent()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()loopdizisindeFortCharacterkonumunu al ve birTransformdeğişkenine kaydet.loop: Transform := FortCharacter.GetTransform()- Şimdi hem
CaptureItemIndicatorhem deMapIndicatornesnelerini,Transformfonksiyonunun aktarma ve dönüşünün yanı sıra daha önce ayarladığınVerticalOffsetdeğerineUpdateRateSecondsboyunca taşımak için birMoveTo()fonksiyonu oluştur. HemCaptureItemIndicatorhem deMapIndicatornesnelerinin, birbirinin ifadelerinin tamamlanmasını beklemeyip tam olarak aynı zamanda taşınması gerektiğinden her ikiMoveTo()fonksiyonunu daSpawn{}kullanarak birlikte oluşturman gerekir. Aktarma;X,YveZkoordinatlarından oluşan birvector3olduğundanVerticalOffsetdeğerini yeni birvector3içine yerleştirmen gerekir.VerticalOffsetdeğeri bir oyuncunun başının üzerindeki dikey mesafe olduğu için bunuvector3fonksiyonununZdeğ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.0saniye 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_managersı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= CaptureItemSpawnerdönüşümünü al ve birSpawnerTransformdeğişkenine kaydet. Ardından,CaptureItemIndicatorveMapIndicatornesneleriniCaptureItemSpawner’ı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çinloopiçinde yaptığın gibi birVerticalOffsetekle. Nesnenin görüş açısından uzakta kalmasını istersenVerticalOffsetdeğ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_managersınıf tanımınaOnItemPickedUp()adlı yeni bir metot ekle. Bu metot biragentalı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”)InAgentiç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_managersı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çinScoreManagerDevicecihazı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_managersı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ığınReturnTimedeğişkenini kullanacaksın.ReturnTimedeğeri0.0veya daha büyükse o kadar süre bekleyip ardından göstergeleri geri döndürmen gerekir.ReturnTimenegatifse 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_managersınıf tanımınaWaitForReturn()adlı yeni bir metot ekle. Bu fonksiyon,ReturnTimedeğ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
ReturnTimesü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.ReturnTimebiter ve hedefCaptureItemSpawner’a geri döner, bu durumda göstergeleri geri döndürmen gerektiğindenShouldReturndeğeritrueolmalıdır. Ya da hedefReturnTimedolmadan önce alınır, bu durumdaShouldReturndeğerifalseolmalıdır. Bu koşulların her biri bir değer döndürdüğünden yarışı iki ayrıblockkullanarak yapacaksın.ShouldReturn:logic := race: block: block:- İlk blokta
ReturnTimedeğeri kadar bir süre içinSleep()fonksiyonunu çağır, ardındantruedöndür. İkinci bloktaCaptureItemSpawner.ItemPickedUpEventiçinAwait()fonksiyonunu çağır ve false döndür. Bunlardan hangisi önce tamamlanırsa onun içinShouldReturndeğişkeni başlatılacak.ShouldReturn:logic := race: block: Sleep(ReturnTime) true block: CaptureItemSpawner.ItemPickedUpEvent.Await() yanlış ShouldReturndeğeri true ise göstergeleri geri döndürmen gerekir.ShouldReturndeğişkenitrueolarak 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’ınItemPickedUpEventolayınıOnItemGrabbed()metoduna,ItemCapturedEventolayınıOnItemCaptured()metoduna veItemDroppedEventolayı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üğündeCaptureItemIndicatorveMapIndicator’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
CaptureItemIndicatorolarak 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.