
ذات مرة ، كان من الضروري كتابة وحدة نمطية لإخفاء الأشياء بين الكاميرا والشخصية ، أو بين العديد من الشخصيات في لعبة RTS. أريد أن أشارك أولئك الذين بدأوا رحلتهم في محرك Unreal. هذا البرنامج التعليمي ، إذا كان يمكنك تسميته ، فسيستخدم C ++ ، ولكن في المشروع المرفق على github سيكون هناك خيار في Blueprint ، فإن وظيفة كليهما متطابقة.
وهكذا ، دعنا نذهب. نقسم مهمتنا إلى عدة صغيرة:
- احصل على الأشياء بين الكاميرا والشخصية.
- قم بتغيير مادة هذه الأشياء إلى تلك المطلوبة.
- قم بتغيير المادة مرة أخرى إلى ما كانت عليه إذا لم يتداخل الكائن مع مراجعة شخصيتنا.
نحتاج إلى مؤقتين ، أحدهما لإضافة كائنات إلى الصفيف للعمل معهم ، والثاني لتغيير الكائن نفسه ، في هذه الحالة أقوم بتغيير المادة من عادي إلى شفاف قليلاً. يمكنك استبدال هذه المواد بأي مناسبة لك.
SFadeObjectsComponent.h
FTimerHandle timerHandle_ObjectComputeTimer; FTimerHandle timerHandle_AddObjectsTimer;
بمجرد أن يكون الكائن في الصفيف ، لمزيد من العمل ، نحتاج إلى تذكر بعض خصائصه ، على سبيل المثال ، ما هي المادة التي كان عليها قبل أن نغيرها ، لأنه يجب علينا تغييرها مرة أخرى. أيضًا ، في حالتنا ، نخفي ، وعند الضرورة ، نعيد الحالة الأولية للكائن تدريجيًا ، لذلك نحتاج إلى تذكر حالته الحالية.
للقيام بذلك ، سنقوم بإنشاء هيكل: USTRUCT() struct FFadeObjStruct { GENERATED_USTRUCT_BODY() UPROPERTY() UPrimitiveComponent* primitiveComp; UPROPERTY() TArray<UMaterialInterface*> baseMatInterface; UPROPERTY() TArray<UMaterialInstanceDynamic*> fadeMID; UPROPERTY() float fadeCurrent; UPROPERTY() bool bToHide; void NewElement(UPrimitiveComponent* newComponent, TArray<UMaterialInterface*> newBaseMat, <UMaterialInstanceDynamic*> newMID, float currentFade, bool bHide) { primitiveComp = newComponent; baseMatInterface = newBaseMat; fadeMID = newMID; fadeCurrent = currentFade; bToHide = bHide; } void SetHideOnly(bool hide) { bToHide = hide; } void SetFadeAndHide(float newFade, bool newHide) { fadeCurrent = newFade; bToHide = newHide; }
نحتاج أيضًا إلى بعض الإعدادات المتاحة من Blueprint للتشغيل المرن لمكوننا. مثل نوع التصادم لتحديد الأشياء ، حجم الكبسولة (الحزمة نفسها) من الشخصية إلى الكاميرا ، كلما كان الحجم أكبر ، سيتم التقاط المزيد من الأشياء حول الشخصية.
المسافة التي سيتم إخفاء الأشياء عندها.
UPROPERTY(EditAnywhere, Category = "Fade Objects") float workDistance;
وبالطبع ، فئة الشخصيات نفسها أو الممثلين الآخرين في المشهد.
UPROPERTY(EditAnywhere, Category = "Fade Objects") UClass* playerClass;
لن نقوم بتحليل جميع المتغيرات المستخدمة ، يمكنك التعرف على المصادر بشكل مستقل.
دعنا ننتقل إلى التنفيذ. في BeginPlay ، قم بتشغيل مؤقتاتنا. بدلاً من المؤقتات ، يمكنك بالطبع استخدام EventTick ، ولكن من الأفضل عدم القيام بذلك ، فالعملية نفسها لتغيير المواد إذا كان عدد كبير من الكائنات باهظ الثمن بالنسبة لوحدة المعالجة المركزية.
SFadeObjectsComponent.cpp
GetWorld()->GetTimerManager().SetTimer(timerHandle_AddObjectsTimer, this, &USFadeObjectsComponent::AddObjectsToHide, addObjectInterval, true); GetWorld()->GetTimerManager().SetTimer(timerHandle_ObjectComputeTimer, this, &USFadeObjectsComponent::FadeObjWorker, calcFadeInterval, true);
وظيفة إضافة كائن إلى صفيف. هنا أود أن أشير إلى أنه لا يضيف الممثل نفسه فقط في المشهد ، ولكن أيضًا مكوناته و SkeletalMesh ، إذا لزم الأمر. void USFadeObjectsComponent::AddObjectsToHide() { UGameplayStatics::GetAllActorsOfClass(this, playerClass, characterArray); for (AActor* currentActor : characterArray) { const FVector traceStart = GEngine->GetFirstLocalPlayerController(GetWorld())->PlayerCameraManager->GetCameraLocation(); const FVector traceEnd = currentActor->GetActorLocation(); const FRotator traceRot = currentActor->GetActorRotation(); FVector traceLentgh = traceStart - traceEnd; const FQuat acQuat = currentActor->GetActorQuat(); if (traceLentgh.Size() < workDistance) { FCollisionQueryParams traceParams(TEXT("FadeObjectsTrace"), true, GetOwner()); traceParams.AddIgnoredActors(actorsIgnore); traceParams.bTraceAsyncScene = true; traceParams.bReturnPhysicalMaterial = false;
وظيفة للعمل مع الكائنات التي تغير المواد من الأصلي إلى المطلوب والعكس صحيح. void USFadeObjectsComponent::FadeObjWorker() { if (fadeObjects.Num() > 0) {
لا يوجد شيء خاص لإخباره هنا ، بعض الأجزاء من التعليمات البرمجية وما إلى ذلك مع التعليقات. يظهر الفيديو في البداية النتيجة. أريد إضافة الإعدادات التي تمت تهيئة المكون بها فقط.
PrimaryComponentTick.bCanEverTick = false; bEnable = true; addObjectInterval = 0.1f; calcFadeInterval = 0.05f; fadeRate = 10.0f; capsuleHalfHeight = 88.0f; capsuleRadius = 34.0f; workDistance = 5000.0f; nearCameraRadius = 300.0f; nearObjectFade = 0.3; farObjectFade = 0.1; immediatelyFade = 0.5f;
ربما شخص ما سيكون مفيدا. أو سيقول شخص ما رأيهم في التعليقات.
رابط للمصدر