
Suatu kali, perlu untuk menulis modul untuk menyembunyikan objek antara kamera dan karakter, atau antara beberapa karakter untuk game RTS. Saya ingin berbagi untuk mereka yang memulai perjalanan mereka di Unreal Engine. Tutorial ini, jika Anda bisa menyebutnya demikian, akan menggunakan C ++, tetapi dalam proyek terlampir di github akan ada opsi pada Blueprint, fungsi keduanya sama.
Jadi, ayo pergi. Kami membagi tugas kami menjadi beberapa hal kecil:
- Dapatkan objek antara kamera dan karakter.
- Ubah materi benda-benda ini ke yang diinginkan.
- Ubah materi kembali menjadi apa jika objek tidak mengganggu peninjauan karakter kita.
Kami membutuhkan 2 timer, satu untuk menambahkan objek ke array untuk bekerja dengannya, dan yang kedua untuk mengubah objek itu sendiri, dalam hal ini saya mengubah materi dari normal menjadi sedikit transparan. Anda dapat mengganti bahan ini dengan yang cocok untuk Anda.
SFadeObjectsComponent.h
FTimerHandle timerHandle_ObjectComputeTimer; FTimerHandle timerHandle_AddObjectsTimer;
Segera setelah objek berada dalam array, untuk pekerjaan lebih lanjut kita perlu mengingat beberapa propertinya, misalnya, bahan apa yang dimilikinya sebelum kita mengubahnya, karena kita harus mengubahnya kembali. Juga, dalam kasus kami, kami bersembunyi, dan bila perlu, kami mengembalikan keadaan awal objek secara bertahap, jadi kami perlu mengingat keadaan saat ini.
Untuk melakukan ini, kami akan membuat struktur: 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; }
Kami juga memerlukan beberapa pengaturan yang tersedia dari Blueprint untuk operasi komponen kami yang fleksibel. Seperti jenis tabrakan untuk mengidentifikasi objek, ukuran kapsul (balok itu sendiri) dari karakter ke kamera, semakin besar ukurannya, semakin banyak objek di sekitar karakter yang akan ditangkap.
Jarak di mana objek akan disembunyikan.
UPROPERTY(EditAnywhere, Category = "Fade Objects") float workDistance;
Dan tentu saja, karakter kelas itu sendiri atau aktor lain di TKP.
UPROPERTY(EditAnywhere, Category = "Fade Objects") UClass* playerClass;
Kami tidak akan menganalisis semua variabel yang digunakan, Anda dapat secara mandiri membiasakan diri dengan sumber.
Mari beralih ke implementasi. Di BeginPlay, jalankan timer kami. Alih-alih timer, Anda dapat, tentu saja, menggunakan EventTick, tetapi lebih baik tidak melakukan ini, operasi itu sendiri untuk mengubah bahan jika sejumlah besar objek cukup mahal untuk CPU.
SFadeObjectsComponent.cpp
GetWorld()->GetTimerManager().SetTimer(timerHandle_AddObjectsTimer, this, &USFadeObjectsComponent::AddObjectsToHide, addObjectInterval, true); GetWorld()->GetTimerManager().SetTimer(timerHandle_ObjectComputeTimer, this, &USFadeObjectsComponent::FadeObjWorker, calcFadeInterval, true);
Fungsi menambahkan objek ke array. Di sini saya ingin mencatat bahwa itu tidak hanya menambah aktor sendiri dalam adegan, tetapi juga komponen dan SkeletalMesh, jika perlu. 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;
Fungsi untuk bekerja dengan objek yang mengubah bahan dari aslinya ke yang diperlukan dan sebaliknya. void USFadeObjectsComponent::FadeObjWorker() { if (fadeObjects.Num() > 0) {
Tidak ada yang istimewa untuk diceritakan di sini, beberapa potong kode dan sebagainya dengan komentar. Video di awal menunjukkan hasilnya. Saya ingin menambahkan hanya pengaturan dengan mana komponen diinisialisasi.
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;
Mungkin seseorang akan berguna. Atau seseorang akan mengatakan pendapatnya di komentar.
Tautan ke sumber