UE4樣條線上生成燈光(根據視角的遠近改變燈光參數,類似模型LOD)


起因:前不久美術提出一個需求,需要讓樣條線的上生成點光源,然后需要相機的改變,使得樣條線上的燈光參數也改變,但有一個最大距離的燈光參數,和一個最小距離的參數,當小於這個最小距離則按照最小距離的參數設置,大於最大距離按照最大距離參數設置,並且需要在Editor模式下也能看見設置效果,要實現在Editor模式下也能看見,則UE4藍圖實現不了,必須使用C++調用UE4的GEditor這一個變量,此變量是全局變量,所以不用擔心引用問題,部分代碼為:

1 FLevelEditorViewportClient* Client = (FLevelEditorViewportClient*)GEditor->GetActiveViewport()->GetClient(); 
2        if (Client)
3         {
4             FVector ViewLoction = Client->GetViewLocation(); // 編輯器相機世界位置
5             FVector ActorLoction = GetActorLocation();  // 自身Actor的世界位置
6             float Lenght = (ViewLoction - ActorLoction).Size(); // 該長度則為編輯器模式相機位置與自身Actor位置長度
7             OnEditorViewPos(ViewLoction);  
8         }

 

現在雖然獲取了編輯器模式的相機位置,但是我們怎么才能使得Actor的Tick函數也能在編輯器里面響應呢?那就需要重寫ShouldTickIfViewportsOnly()函數:

virtual bool ShouldTickIfViewportsOnly() const override;
bool AEditorViewValue::ShouldTickIfViewportsOnly() const
{
    return true; // 把這個返回值設置為true,則Tick函數則可以在編輯器模式響應
}

 

既然已經可以在編輯器模式下使用Tick()函數,那怎么區分他在編輯器模式還是在游戲模式呢?可以使用 WITH_EDITOR 這個宏,但是我使用不是使用獨立窗口運行的話則這個宏不會改變,我的方法是在BeginPlay()這個函數里把一個布爾值設置則可以區分。

void AEditorViewValue::BeginPlay()
{
    Super::BeginPlay();

    bIsGameEnable = true;
}

 

喔,忘記一個點了,需要使用FLevelEditorViewportClient類和GEditor變量,需要導入該庫

#if WITH_EDITOR
#include "Editor.h"
#include "UnrealEd.h"
#include "LevelEditorViewport.h"
#endif // WITH_EDITOR
...
if
(Target.bBuildEditor == true) // 使用該庫是需要判定是否在編輯器模式,在編輯器模式下則導入該庫,不在則不導入 { PublicIncludePaths.AddRange( new string[] { // ... add public include paths required here ... } ); PrivateIncludePaths.AddRange( new string[] { //"Editor/UnrealEd/Private" // ... add other private include paths required here ... } ); PrivateDependencyModuleNames.AddRange( new string[] { "InputCore", "UnrealEd", "LevelEditor", } ); // @todo api: Only public because of WITH_EDITOR and UNREALED_API }
...

同時需要在c#中導入該類型庫!

 

好!基礎的框架已經弄好了,現在需要繼承該類做應用層的東西了!

 

應用層:現在我們在繼承的框架類的新類里寫一個需要修改的結構體,該結構體可在藍圖里面使用:

USTRUCT(BlueprintType)
struct FLightParameterSetting
{
    GENERATED_BODY()

    // 燈光個數
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = LightParameterSetting)
    int LightNumber = 0;

    ...

};
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LightSetting")
    FLightParameterSetting MinCameraPosLightParameter;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "LightSetting")
    FLightParameterSetting MaxCameraPosLightParameter;

 

接下來我們需要獲取游戲模式的相機,游戲模式的相機我們不知道他是否使用了USpringArmComponent類,所以我們需要判定

if (!MyPawn)
    {
        UE_LOG(LogTemp, Warning, TEXT("Map don't have Pawn"));
        return 0.f;
    }
    USpringArmComponent* Arm = Cast<USpringArmComponent>(MyPawn->GetComponentByClass(USpringArmComponent::StaticClass()));
    float ArmLength = Arm ? Arm->TargetArmLength : 0.f; // 判定相機Actor是否存在SpringArmComponent類,存在則相機位置不止是相機位置與Actor之間的長度
    float ActorLength = (MyPawn->GetActorLocation() - this->GetActorLocation()).Size(); // 游戲模式相機與Actor之間的距離

 

假如我們修改了編輯器的參數,我們需要刷新一次燈光值得話,我們需要重寫PreEditChange()函數!

 

其他應用層的修改就不必過多的贅述了,如果有什么問題可以回復我,需要插件源碼:https://github.com/Monocluar/UE4SpecialLightEditorPlugins


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM