Objelerin üzerindeki adım ile hareket etme, dönme veya ölçeklenmenin üçü de aynı anda yapılır. Ancak aynı anda birden fazla biçimde hareket eden nesneler için animasyonlar oluştururken dikkate alınması gereken bazı önemli zorluklar bulunmaktadır.
Animasyon denetleyicisi aynı anda yalnızca bir animasyon oynatabildiğinden, farklı animasyonlarda harekete ettirme, döndürme ve ölçeklendirme yapamazsın. Bir nesneyi animasyon başına birden çok kez döndürmek isteyebileceğin için bu animasyonlar ayrıca birden fazla anahtar kareye ihtiyaç duyar. Tüm anahtar kareleri önceden oluşturman gerektiğinden nesnenin yolculuğundaki her noktada konumu, dönüşü ve ölçeği de hesaplaman gerekir. Nesnen eşit oranda dönüş yapmazsa ne olur? Yarım dönüş olursa ne yaparsın?
Bir sonraki bölümde çok fazla matematiksel işlem bulunmakta ancak sonunda, hayallerindeki Fall Guys parkurunu yapmak için nesneleri birden fazla noktaya taşıyabilecek, döndürebilecek ve ölçeklendirebilecek ayrıca karmaşık, dinamik ve (en önemlisi de!) eğlenceli platform oluşturma zorlukları oluşturabileceksin.
Hareket Eden, Dönen ve Ölçeklenen Animasyonlar Oluşturma
Bir şeyleri bir araya getirmeye başlamak için şu adımları izle:
Verse Gezgini ile
movable_propöğesinden devralınananimating_propadında yeni bir Verse sınıfı oluştur. Özelliklerini UEFN’de kullanıma açmak için bu sınıfa<concrete>belirleyicisi ekle.Verse# A prop that translates, rotates, and scales to a destination using animation. animating_prop<public> := class<concrete>(movable_prop):{ /Fortnite.com/Devices/CreativeAnimation } kullanmave{ /UnrealEngine.com/Temporary/SpatialMath } kullanmaifadelerini dosyanın üst kısmına ekleyerek bu modülleri içe aktar. Nesnene animasyon uygulamak için bunlara ihtiyacın var. Ayrıca bu bölümde kullanılan araç ipuçlarına burada yer verilmiştir.Verseusing { /Fortnite.com/Devices } using { /Fortnite.com/Devices/CreativeAnimation } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/SpatialMath } RotationRateTip<localizes>:message := "The time it takes to make one AdditionalRotation in seconds." UseEasePerKeyframeTip<localizes>:message := "Whether this prop should use the MoveEaseType for each keyframe. False will use the Linear ease type on each frame." # A prop that translates, rotates, and scales to a destination using animation. animating_prop<public> := class<concrete>(movable_prop):animating_propsınıf tanımının üst kısmına aşağıdaki alanları ekle:AdditionalRotationadında düzenlenebilir birdönüş. Anahtar kare başınaRootProp’a uygulanacak dönüş budur.Verse# The additional rotation to apply to the RootProp per keyframe. @editable {ToolTip := AdditionalRotationTip} AdditionalRotation:rotation = rotation{}RotationRateadlı bir düzenlenebilirkayan değer. BirAdditionalRotationyapılması için gereken saniye cinsinden süredir.Verse# The time it takes to make one AdditionalRotation in seconds. @editable {ToolTip := RotationRateTip} var RotationRate:float = 1.0UseEasePerKeyFrameadlı düzenlenebilir birmantık. Her anahtar karenin interpolasyon içinMoveEaseTypekullanıp kullanmayacağını belirler. Bu örnekte, bununfalseolarak ayarlanması, her kare için varsayılan olarak doğrusal interpolasyon türünün kullanılmasını sağlar.Verse# Whether this prop should use the MoveEaseType per each frame of animation. # Setting this to false will use the linear MoveEaseType on each frame. @editable UseEasePerKeyframe:logic = trueMoveTargetsadlı düzenlenebilir bircreative_propdizisi. Bunlar, kök nesnenin seyahat edeceği farklı Kreatif nesneleridir.Verse# The Creative prop target for the RootProp to move toward. @editable {ToolTip := MoveTargetsTip} var MoveTargets:[]creative_prop = array{}TargetTransformadlı birdönüştürmedeğişkeni. Bu, kök nesnenin şu anda seyahat ettiği dönüşümdür.Verse# The transform the prop is currently targeting. var TargetTransform:transform = transform{}
Sınıf tanımın şu şekilde görünmelidir:
Verseusing { /Fortnite.com/Devices } using { /Fortnite.com/Devices/CreativeAnimation } using { /Verse.org/Simulation } using { /UnrealEngine.com/Temporary/SpatialMath } RotationRateTip<localizes>:message := "The time it takes to make one AdditionalRotation in seconds." UseEasePerKeyframeTip<localizes>:message := "Whether this prop should use the MoveEaseType for each keyframe. False will use the Linear ease type on each frame." # A prop that translates, rotates, and scales to a destination using animation. animating_prop<public> := class<concrete>(movable_prop):animating_propsınıfındaMove()fonksiyonunu geçersiz kıl. Ardından birforifadesindeMoveTargetsdizisindeki herMoveTargets’ı yinele. Her birMoveTarget’ın geçerliliğini kontrol et ve geçerliyseTargetTransformöğesiniMoveTargetdönüştürmesine ayarla.Verse# Move and rotate the RootProp toward the MoveTarget, or MoveTransform if one is set. Move<override>()<suspends>:void= # Move to each target in the MoveTargets array. for: MoveTarget:MoveTargets do: # Set the TargetTransformto the MoveTarget if the # MoveTarget is set. Otherwise set it to the MoveTransform.movement_behaviorsdosyana geri dönerekBuildMovingAnimationKeyframes()adlı yeni bir metot ekle. Bu fonksiyon, bir hedef dönüşümüne doğru hareket eden ve dönen nesnenin animasyonunu yapan bir dizi anahtar kare oluşturur ve döndürür. Bu fonksiyon,animating_propözelliğinden çeşitli parametreler alır:MoveDuration,RotationRate,AdditionalRotation,OriginalTransform(nesnenin başlangıç dönüşümü),TargetTransform,MoveEaseTypeveUseEasePerKeyframeadlı yeni birmantıkdeğeri. Her bir anahtar kare içinMoveEaseTypekullanıp kullanmayacağını belirler. Fonksiyon imzası şu şekilde görünmelidir:Verse# Builds an array of keyframes that animate movement and rotation from the OriginalTransform to the TargetTransform. BuildMovingAnimationKeyframes(MoveDuration:float, RotationRate:float, AdditionalRotation:rotation, OriginalTransform:transform, TargetTransform:transform,MoveEaseType:move_to_ease_type, UseEasePerKeyframe:logic):[]keyframe_delta=BuildMovingAnimationKeyframes()içinde aşağıdaki değişkenleri başlat:Anahtar Kareleradında birkeyframe_deltadeğişken dizisi. Sonunda döndüreceğin dizidir.Verse# The array of keyframes to return. var KeyFrames:[]keyframe_delta = array{}TotalTimeadlı birkayan değerdeğişkeni. Şu ana kadar animasyon için harcanan toplam süredir.Verse# The total amount of time spent animating. var TotalTime:float = 0.0StartTransformveEndTransformadlı ikidönüştürmedeğişkeni. Bunlar, her bir anahtar karenin başlangıcında ve sonunda nesnenin başlangıç ve bitiş dönüşümleridir. Her ikisini deOriginalTransformolarak başlat.Verse# The starting transform for building keyframes. This is the # transform of the RootProp at the start of each keyframe. var StartTransform:transform = OriginalTransform # The ending transform for building keyframes. This is the # transform of the RootProp at the end of each keyframe. var EndTransform:transform = OriginalTransformAdditionalRotationolarak başlatılan,RotationToApplyadlı birdönüşdeğişkeni. Her bir anahtar kare için nesneye uygulayacağın gerçek dönüştür. Genellikle buAdditionalRotationolur ancak kesirli bir dönüş yapman gerekiyorsa bu değeri değiştirmen gerekir.Verse# The actual rotation to apply to the RootProp. Usually this is the # AdditionalRotation, but will change in cases with fractional rotations. var RotationToApply:rotation = AdditionalRotationAnimationTimeadlı birkayan değerdeğişkeni. # Her anahtar kare için gerekli saniye cinsinden süredir. RootProp’un saniyedeRotationRatekadar dönüş yapması gerektiğinden bunu1,0 / RotationRateolarak başlat.Verse# The time it takes for each keyframe of animation to complete. # This is initialized to 1.0/Rotation rate since the RootProp needs to make a # RotationRate number of rotations per second. var AnimationTime:float = 1.0 / RotationRateTotalRotationsadlı birkayandeğer. Tüm animasyon boyunca gerçekleştirilecek toplam dönüş sayısıdır veMoveDuration * RotationRateolarak başlatılır. Bunun birtamsayıdeğil dekayan sayıolmasının nedeni, bir animasyonun sonunda olduğu gibi, tam bir dönüş yapmana gerek olmayan durumların üstesinden gelmektir.Verse# The total number of rotations to make. TotalRotations:float = MoveDuration * RotationRateTimePerRotationadlı birkayandeğer. Bir dönüşün tamamlanması için gereken saniye cinsinden süredir. Fonksiyonun şu şekilde görünmelidir.Verse# Builds an array of keyframes that animate movement and rotation from the OriginalTransform to the TargetTransform. BuildMovingAnimationKeyframes(MoveDuration:float, RotationRate:float, AdditionalRotation:rotation, OriginalTransform:transform, TargetTransform:transform,MoveEaseType:move_to_ease_type, UseEasePerKeyframe:logic):[]keyframe_delta= # The array of keyframes to return. var KeyFrames:[]keyframe_delta = array{} # The total amount of time spent animating. var TotalTime:float = 0.0 # The starting transform for building keyframes. This is the
Takip edilmesi gereken çok fazla değer olduğundan RotationRate olarak 2,5 ve MoveDuration olarak 5,0 değeriyle örnek bir hesaplama yapalım.
Rotation Rate = 2.5 rotations/second
Move Duration = 5.0 seconds
Animation Time =
1.0 seconds/Rotation Rate =
1.0/2.5 = 0.4 seconds
Total Rotations =
Move Duration /Rotation Rate =
2,5 RotationRate ve 5,0 MoveDuration değeri ile, her biri 0,4 saniye süren toplam 12,5 dönüş yapacaksın. Bu durumda animasyonun sonunda fazladan bir yarım dönüş yapman gerekir. Ayrıca animasyon süresi ve her bir dönüş sürenin aynı olduğunu görebilirsin. Tam dönüşten daha azını yapman gerektiği durumlar dışında bu durum, neredeyse her zaman geçerlidir. Başlangıçta aynı değerde olsalar bile, daha sonraki matematiksel işlemleri yapabilmek için her iki değişkeni de takip etmen gerekir.
Döngüde Anahtar Kareler Oluşturma
Oluşturmaya başlayalım! Anahtar karelerini oluşturan döngüyü ayarlamak için aşağıdaki adımları izle.
BuildMovingAnimationKeyframes()fonksiyonuna birdöngü (loop)ifadesi ekle. Döngü her yinelendiğinde yeni bir anahtar kare oluşturursun ve anahtar kareler dizisine eklersin. Döngünün başlangıcında,TotalTimedeğeriniTimePerRotationile güncelle.Verse# Build each keyframe of animation and add it to the Keyframes array. # The loop breaks when the TotalTime goes past the MoveDuration. loop: # Add the TimePerRotation to the TotalTime. set TotalTime += TimePerRotationNesnenin bu anahtar karenin sonunda olması gereken yer olan
EndTransformöğesini oluştur.EndTransformöğesini aşağıdaki parametrelerle yeni dönüşüme ayarla:Translationdeğerini,OriginalTransformileTargetTransformarasındakiLerp()çağrısının sonucuna ayarla.Lerp()fonksiyonu iki değer ve0,0ile1,0arasında bir Lerp oranı alır. Ardından Lerp oranına göre ikisinin arasında bir yerde yeni bir değer oluşturur. Lerp oranı, 1,0 değerine ne kadar yakınsa dönüşüm deTargetTransformöğesine o kadar yakın olacaktır, bunun tam tersi de olabilir.Verse# Build the ending transform for the RootProp to move to. set EndTransform = transform: # Use Lerp() to find how far between the StartingTransform and the TargetTransform the RootProp should translate. # Do the same for scale, and rotate the starting transform by the RotationToApply. # The Lerp Parameter is based on the total number of rotations since the RootProp should guarantee that it makes # at least that many rotations over the whole animation. Translation := Lerp(OriginalTransform.Translation, TargetTransform.Translation, (TotalTime * RotationRate) / (TotalRotations))Orijinal dönüşümün dönüşünü ve
RotationToApplyile döndürülen orijinal dönüşümü ileterekdönüşüMakeShortestRotationBetween()sonucuna ayarla.VerseTranslation := Lerp(OriginalTransform.Translation, TargetTransform.Translation, (TotalTime * RotationRate) / (TotalRotations)) Rotation := MakeShortestRotationBetween(OriginalTransform.Rotation, OriginalTransform.Rotation.RotateBy(RotationToApply))~~~Ölçekdeğerini,OriginalTransform.ScaleileTargetTransform.ScalearasındakiLerp()çağrısının sonucuna ayarla. Bunun, ölçeklendirilmesi gereken değer değil, nesnenin ölçeklendirilmesi gereken ölçek olduğunu unutma. TamamlanmışEndTransform’un şu şekilde görünmelidir:Verse# Build the ending transform for the RootProp to move to. set EndTransform = transform: # Use Lerp() to find how far between the StartingTransform and the TargetTransform the RootProp should translate. # Do the same for scale, and find the shortest rotation between the original transform and a rotation to apply to it. Translation := Lerp(OriginalTransform.Translation, TargetTransform.Translation, LerpParameter) Rotation := MakeShortestRotationBetween(OriginalTransform.Rotation, OriginalTransform.Rotation.RotateBy(RotationToApply)) Scale := Lerp(OriginalTransform.Scale, TargetTransform.Scale, LerpParameter)
Bitiş dönüşümünü ayarladıktan sonra bir ana kare oluşturmanın zamanı geldi! Bu büyük ölçüde
MoveToEase()fonksiyonu için yaptığın işlemin aynısıdır.KeyFrameadında yeni birkeyframe_deltadeğişkeni oluştur.DeltaLocationöğesini dönüşüm yer değiştirmelerinin bitişi ve başlangıcı arasındaki farka ayarla.DeltaRotationöğesini bitiş dönüşümünün dönüşüne ayarla. Ölçekteki değişikliği hesaplaman gerektiğindenDeltaScaleöğesini, bitiş dönüşümünün ölçeğinin başlangıç dönüşümünün ölçeğine bölünmesiyle elde edilen sonuca ayarla.Zaman,AnimationTimeolmalı veInterpolationType, birififadesinin sonucu olmalıdır.UseEasePerKeyframetrue iseMoveEaseTypekullan. Aksi halde doğrusal tür kullan. Anahtar kare ifadesi şu şekilde görünmelidir:Verse# Build the animation keyframe to animate the RootProp. Keyframe := keyframe_delta: DeltaLocation := EndTransform.Translation - StartTransform.Translation, DeltaRotation := EndTransform.Rotation, DeltaScale := EndTransform.Scale/StartTransform.Scale, Time := AnimationTime, # Use the MoveEaseType for interpolation if UseEasePerKeyframe is true, # otherwise use the Linear movement type. Interpolation := if:Anahtar karen hazır olduğuna göre artık onu
Anahtar Karelerdizisine ekleyebilirsin. Ardından bir sonraki anahtar kare için güncellemek üzereStartTransformöğesiniEndTransformolarak ayarlamalısın. Son olarak;TotalTime,MoveDurationdeğerinden büyükse döngüden çık.Verse# Add the new keyframe to the KeyFrames array, and set the # StartTransform to the EndTransform. set Keyframes += array{Keyframe} set StartTransform = EndTransform # Break out of the loop if the TotalTime passes the MoveDuration. if: TotalTime >= MoveDuration then: breakDikkate alınması gereken önemli bir uç durum var: Tam dönüşten daha azını yapman gerektiğinde ne olur?
TotalTimeöğesineTimePerRotationeklediğin için,TotalTimedöngünün başlangıcındakiMoveDurationdeğerinden daha fazla olabilir. Bu durumda, kalan süreyi kullanman ve farkı hesaba katarak daha kısa bir animasyon süresiyle tam dönüşten daha azını yapman gerekir. Bu durumu göz önünde bulundurmak için şu adımları izle:Döngünün başlangıcında
TotalTimedeğerini güncelledikten sonra birififadesi başlat. İçerisinde, birLeftoverTimedeğişkeni başlat ve bu değişkeniTotalTimedeğerininMoveDurationdeğerinden çıkarılmasından elde edilen sonuca (0,0değerinden büyük olup olmadığını kontrol ederek) ayarla. Bu ifade, yalnızca karşılaştırma true iseLeftoverTimedeğişkeni atar.Verseloop: # Add the TimePerRotation to the TotalTime. set TotalTime += TimePerRotation if: # If the TotalTime is greater than the MoveDuration, the final keyframe needs # to be shortened. This means making a fraction of a rotation. LeftoverTime := TotalTime - MoveDuration > 0.0Bir dönüşün ne kadarını yapman gerektiğini bilmek için yeni bir
Roation Fractiondeğişkeni başlat ve bunuTimePerRotationileLeftoverTimearasındaki farkınTimePerRotationile bölünmesiyle elde edilen değere ayarla.Verseif: # If the TotalTime is greater than the MoveDuration, the final keyframe needs # to be shortened. This means making a fraction of a rotation. LeftoverTime := TotalTime - MoveDuration > 0.0 # The fraction of a rotation to make. RotationFraction := (TimePerRotation - LeftoverTime)/TimePerRotationRotationFractionöğesinden değiştirilmiş bir dönüş oluşturmak içinSlerp[]kullan. Bu, küresel interpolasyonu yürüten ve benzer parametrelere sahipLerp()sürümüdür. İki farklı dönüş arasındaki en kısa dönüşü bulur ve lerp parametresine göre bir dönüş döndürür.IdentityRotation()ileRotationToApplytarafından döndürülenIdentityRotation()arasında interpolasyon yaparak, lerp parametresi olarakRotationFractionkullanarakSlerp[]çağrısı yap.EndTransformöğesinin hangi son dönüşte olması gerektiğiyle değil yalnızca hangi kesirli dönüşü uygulaman gerektiğini bulmakla ilgileniyorsanIdentityRotation()kullanırsın.Verseset TotalTime += TimePerRotation if: # If the TotalTime is greater than the MoveDuration, the final keyframe needs # to be shortened. This means making a fraction of a rotation. LeftoverTime := TotalTime - MoveDuration > 0.0 # The fraction of a rotation to make. RotationFraction := (TimePerRotation - LeftoverTime)/TimePerRotation # Make a modified fractional rotation by using Slerp(). The Slerp() function does spherical interpolationBu değerler ayarlandığında,
RotationToApplyöğesiniModifiedRotationolarak ayarla, animasyonunu ne kadar kısaltacağını öğrenmek içinAnimationTimeöğesiniRotationFractionile çarp ve son olarakEndTransformöğesini hesaplarken bundan daha fazla çıkmasını istemediğin içinTotalTimeöğesiniMoveDurationolarak ayarla.VerseModifiedRotation := Slerp[IdentityRotation(), IdentityRotation().RotateBy(RotationToApply), RotationFraction] then: # Set the RotationToApply to the modified rotation, and multiply the animation time by # the RotationFraction to get the modified animation time. set RotationToApply = ModifiedRotation set AnimationTime = AnimationTime * RotationFraction # Since the TotalTime should not go past the MoveDuration, # set TotalTime to MoveDuration. set TotalTime = MoveDuration
Fonksiyonunun sonunda, döngünün ardından
Anahtar Karelerdizisini döndür. TamamlanmışBuildMovingAnimationKeyframes()fonksiyonun şu şekilde görünmelidir:Verse# Builds an array of keyframes that animate movement and rotation from the OriginalTransform to the TargetTransform. BuildMovingAnimationKeyframes(MoveDuration:float, RotationRate:float, AdditionalRotation:rotation, OriginalTransform:transform, TargetTransform:transform,MoveEaseType:move_to_ease_type, UseEasePerKeyframe:logic):[]keyframe_delta= # The array of keyframes to return. var Keyframes:[]keyframe_delta = array{} # The total amount of time spent animating. var TotalTime:float = 0.0 # The starting transform for building keyframes. This is theArtık anahtar karelerini oluşturma mantığını tanımladığına göre animasyonlarını yapabilirsin. Animasyonunu oluşturmak ve çağırmak için ayrı bir fonksiyon kullanırsın.
animating_propsınıfına yeni birBuildAndPlayAnimation()fonksiyonu ekle. Diğer asenkron fonksiyonları çağırmasına izin vermek için bu fonksiyona<suspends>değiştiricisini ekle.Verse# Builds an animation from an array of keyframes, then calls MoveToEase() # to animate the prop. BuildAndPlayAnimation()<suspends>:void=BuildAndPlayAnimation()içerisinde,Anahtar Kareleradında yeni birkeyframe_deltadizisi başlat. ArdındanKeyframesözelliğiniBuildMovingAnimationKeyframes()çağrısı sonucuna ayarla. Nesnenin konumuMove()çağrıları arasında değişiklik gösterdiğinden başlangıç dönüşümü olarakRootProp.GetTransform()kullan.animation_modedeğişkeninianimation_mode.OneShotolarak başlat,Anahtar Karelerdizisini veAnimationModeözelliğini ileterekMoveToEase()çağrısı yap.Tamamlanmış
BuildMovingAnimationKeyframes()fonksiyonun şu şekilde görünmelidir:Verse# Builds an animation from an array of keyframes, then calls MoveToEase() # to animate the prop. BuildAndPlayAnimation()<suspends>:void= var Keyframes:[]keyframe_delta = array{} # Build the animation, using the RootProp as the target transform. set Keyframes = BuildMovingAnimationKeyframes(MoveDuration, RotationRate, AdditionalRotation, RootProp.GetTransform(), TargetTransform, MoveEaseType, UseEasePerKeyframe) # Set the animation mode to OneShot. var AnimationMode:animation_mode := animation_mode.OneShotMove()fonksiyonundayken,TargetTransformöğesini hareketli hedefler dönüşümüne ayarladıktan sonraBuildAndPlayAnimation()için çağrı yap.Verse# Move to each target in the MoveTargets array. for: MoveTarget:MoveTargets do: # Set the TargetTransform to the MoveTarget if the # MoveTarget is set. Otherwise set it to the MoveTransform. if: MoveTarget.IsValid[] then: set TargetTransform = MoveTarget.GetTransform()
Değerlendirilmesi gereken bir konu daha var. Hareketli hedefler ayarlamazsan ne olur? Bu durumda nesnen yeni bir hedefe gitmeden yerinde dönmeye devam eder. Bu sorunu düzeltmek için Move() fonksiyonunun üst kısmına bir if ifadesi ekle. if özelliğindeyken MoveTargets.Length = 0 olup olmadığını kontrol et ve öyleyse TargetTransform öğesini kök nesnenin dönüşümüne ayarla. Ardından, BuildAndPlayAnimation() için çağrı yap. Bu şekilde, hareketli bir hedef belirlemesen de nesnenin animasyonu devam eder. Tamamlanmış Move() animasyonu şu şekilde görünmelidir:
# Move and rotate the RootProp toward the MoveTarget, or MoveTransform if one is set.
Move<override>()<suspends>:void=
# If there are no targets to move to, this prop will rotate in place.
if:
MoveTargets.Length = 0
then:
set TargetTransform = RootProp.GetTransform()
# Build and play the animation.
BuildAndPlayAnimation()
Şimdi prop_animator sınıfında animating_prop için referans vermen gerekiyor. prop_animator özelliğinde, MoveAndRotateProps adında düzenlenebilir bir animating_prop dizisi ekle. OnBegin() özelliğinde, başka bir for ifadesinde, Setup() çağrısı yaparak MoveAndRotateProps içerisinde bulunan her nesneyi başlat. Tamamlanmış prop_animator sınıfın şu şekilde görünmelidir:
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
TranslatingPropsTip<localizes>:message = "The props that translate (move) using animation."
RotatingPropsTip<localizes>:message = "The props that rotate using animation."
ScalingPropsTip<localizes>:message = "The props that scale using animation."
AnimatingPropsTip<localizes>:message = "The props that both move and rotate using animation."
# Coordinates moving props through animation by calling each movable_prop's Setup() method.
Kodunu kaydet ve derle.
Tebrikler, tüm kod bu kadar! Artık her şeyi birbirine bağlama zamanı.
Yeni oluşturduğunuz animating_prop sınıfı, nesneleri hareket ettirebilir, döndürebilir ve ölçeklendirebilir. Ancak, ManageMovement() gibi çeşitli fonksiyonları devralması gerektiğinden hâlâ moveable_prop sınıfına bağlıdır. animating_prop sınıfının her üç hareket türünü de gerçekleştirebildiği göz önünde bulundurulduğunda, sınıfın tek başına durabilmesi için animating_prop özelliğini tüm moveable_prop mantığını içerecek şekilde yeniden düzenlemeyi faydalı bulabilirsin. animating_prop ile moveable_prop dosyalarını tek bir dosyada birleştiren yeniden düzenleme örneğini buraya ekleyebilirsin. Ayrıca prop_animator verse cihaz sınıfını da içerir. Kodunun çalışması için yine de movement_behaviors fonksiyonuna gerek var ancak bu yeniden düzenleme, ihtiyaç duyulan dosya sayısını beşten ikiye düşürür. Bu kod Tam Kod bölümünde de yer alır.
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
EasingCategory<localizes>:message := "These control the type of movement easing applied to the prop."
LogicCategory<localizes>:message := "These control different aspects of the prop's logic."
PropsCategory<localizes>:message := "These are the props that move associated with this device."
RotationCategory<localizes>:message := "These control how the prop rotates."
TimingCategory<localizes>:message := "These control the timing of parts of the prop's movmement."
Nesneleri Cihazlara Bağlama
Editördeyken, nihai hedeften önce bir boşluk oluşturmak için dönen nesne bölümünden sonra parkurun bir bölümünü sil. Bölümüne başka bir FG01 SpinningBar Çift S ve FG01 Uçan Platform M ekle. Nesneleri SpinningMovingBar ve TranslatingPlatform olarak adlandır, ardından her nesnenin hareket edeceği hedefler olacak birkaç FG01 Düğme Ampul nesnesi ekle. Bunları PlatformTarget olarak adlandır. Platformları ve çubuğu boşluğun üzerine yerleştir ve hedefleri platformların hareket etmesini istediğin yere yerleştirdiğinden emin ol. Bu örnekte, dönen çubuk bir taraftan diğer tarafa hareket ederken platform ileri geri hareket etmektedir.
Dönen çubuğun ve hareketli platformun kurulumu. Oklar, her bir nesnenin hangi yönde hareket ettiğini gösterir. Dönen çubuk ve platform ileri geri hareket eder ve dönen çubuk hareket ettikçe kendi etrafında da döner.
Anahat Düzenleyicisi’nde özellik animatörü seç. Dönen çubuğun için AnimatingProps öğesine bir dizi elementi ekle. Her değeri aşağıdaki için ayarla:
| Seçenek | Değer | Açıklama |
|---|---|---|
Ek Dönüş | 90,0 | Bu nesne her seferinde 90 derecelik bir dönüş yapar. |
Dönüş Hızı | 1,5 | Bu nesne her |
Her Anahtar Kare Başına Hızlanmayı Kullan | yanlış | Nesneyi tutarlı bir hızda hareket ettirmek ve döndürmek için her anahtar karede doğrusal hızlanma türünü kullanır. |
MoveTargets | Platform hedeflerine atanan 2 eleman. | Bunlar çubuğun hareket etmesini istediğin hedeflerdir. |
RootProp | SpinningMovingBar | Bu, animasyonunu yaptığın nesnedir. |
Hareketli platformun için TranslatingProps öğesine başka bir dizi elementi ekle. Platform hedeflerine MoveTargets ve TranslatingPlatform özelliğine RootProp ata.
Oturumu Başlat öğesine bas ve engelli parkurunu tamamlamayı dene!
Kendi Kendine Yapabileceklerin
Hepsi bu kadar! Artık Verse’ü kullanarak kendi Fall Guys engelli parkurunu oluşturmak için ihtiyacınız olan her şeye sahipsin!
Buradaki kodu, herhangi bir deneyiminde ve hatta Fall Guys projelerinin dışında kreatif nesnelerinin animasyonu için kullanabilirsin!
Öğrendiklerini kullanarak aşağıdakileri dene:
Çeşitli yönlerde veya anahtar kareler arasında rastgele dönen engeller oluştur.
Yalnızca oyuncu üzerinde durduğunda veya belirli bir mesafeye yaklaştığında etkinleşen engeller yap.
Belirlenen süreden sonra platformların nasıl kaybolacağını veya çok uzun süre kaldıklarında oyuncuyu tehlikeli konumlara nasıl taşıyacağına karar ver.
Tam Kod
Bu bölümde animating_prop için yeniden düzenleme örneği de dahil olmak üzere, tam yerleşik kod verilmiştir.
moveable_prop.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
MoveDurationTip<localizes>:message = "The amount of time the prop takes to move to its destination."
MoveEaseTypeTip<localizes>:message = "The animation easing applied to the movement."
MoveEndDelayTip<localizes>:message = "The delay after the movement finishes."
MoveOnceAndStopTip<localizes>:message = "Whether the RootProp should stop in place after it finishes moving."
MoveStartDelayTip<localizes>:message = "The delay before the movement starts."
MoveTargetsTip<localizes>:message = "The array of CreativeProp to move toward. These targets can be children of the RootProp."
translating_prop.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
MovePositionTip<localizes>:message = "The optional position to move to World Space. Use this if you do not want to set a MoveTarget."
# A prop that moves (translates) toward either a Creative prop target
# or a position in world space.
translating_prop<public> := class<concrete>(movable_prop):
related_prop.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
AdditionalRotationTip<localizes>:message = "The rotation to apply to the RootProp."
ShouldRotateForeverTip<localizes>:message = "Whether the RootProp should rotate forever."
MatchRotationTargetTip<localizes>:message = "The optional prop whose rotation the RootProp should rotate to. Use this if you do not want to set an Additional Rotation."
# A prop that rotates by an additional rotation or rotates to match
scaling_prop.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
MatchScaleTargetTip<localizes>:message = "The optional position to move to World Space. Use this if you do not want to set a MoveTarget."
# A prop that scales toward either a given scale or a Creative prop's scale.
scaling_prop<public> := class<concrete>(movable_prop):
# The array of vector3 targets for the RootProp to scale to.
animating_prop.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
RotationRateTip<localizes>:message := "The time it takes to make one AdditionalRotation in seconds."
UseEasePerKeyframeTip<localizes>:message := "Whether this prop should use the MoveEaseType for each keyframe. False will use the Linear ease type on each frame."
# A prop that translates, rotates, and scales to a destination using animation.
animating_prop<public> := class<concrete>(movable_prop):
movement_behaviors.verse
# This file stores functions common to animating Creative props using keyframes.
# It also defines the move_to_ease_type enum to help in building animations.
using { /Fortnite.com/Devices }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Fortnite.com/Characters}
using { /Fortnite.com/Devices/CreativeAnimation }
# Represents the different movement easing types.
move_to_ease_type<public> := enum {Linear, Ease, EaseIn, EaseOut, EaseInOut}
prop_animator.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
TranslatingPropsTip<localizes>:message = "The props that translate (move) using animation."
RotatingPropsTip<localizes>:message = "The props that rotate using animation."
ScalingPropsTip<localizes>:message = "The props that scale using animation."
MoveAndRotatePropsTip<localizes>:message = "The props that both move and rotate using animation."
# Coordinates moving props through animation by calling each moveable_prop's Setup() method.
animating_props.verse (animating_prop yeniden düzenleme örneği)
using { /Fortnite.com/Devices }
using { /Fortnite.com/Devices/CreativeAnimation }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/SpatialMath }
EasingCategory<localizes>:message := "These control the type of movement easing applied to the prop."
LogicCategory<localizes>:message := "These control different aspects of the prop's logic."
PropsCategory<localizes>:message := "These are the props that move associated with this device."
RotationCategory<localizes>:message := "These control how the prop rotates."
TimingCategory<localizes>:message := "These control the timing of parts of the prop's movmement."