標籤:下載連結 bre second tab ota on() super called font
:
第一步,建立C++ Basic Code
第二步,定義鍵盤和滑鼠輸入的映射
第三步,修改 Rendering 中的 Custom Depth - Stencil Pass
第四步,找到GlobalPostProcessVolume [如果沒有的話自行拖放一個PostProcessVolume組件]
將 unbound 勾選上
再修改 Blendables 為 PPI_OutlineColored
完整代碼如下:
MyPlayer.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Character.h"#include "MyPlayer.generated.h"UCLASS()class OUTLINECPLUSPLUS_API AMyPlayer : public ACharacter{GENERATED_BODY()public:// Sets default values for this character‘s propertiesAMyPlayer();void MoveForward(float val);void MoveRight(float val);void LookYaw(float val);void LookPitch(float val);void Use();class AInteractableActor* FindFocusedActor();void HandleHighlight();// Called when the game starts or when spawnedvirtual void BeginPlay() override;// Called every framevirtual void Tick( float DeltaSeconds ) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;private:UPROPERTY(EditDefaultsOnly)float InteractionDistance = 300.f;// 互動的範圍class AInteractableActor* FocusedActor;// 用於 LineTraceSingleByChannelFCollisionQueryParams TraceParams;};
MyPlayer.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "InteractableActor.h"#include "MyPlayer.h"// Sets default valuesAMyPlayer::AMyPlayer(){ // Set this character to call Tick() every frame. You can turn this off to improve performance if you don‘t need it.PrimaryActorTick.bCanEverTick = true;TraceParams = FCollisionQueryParams(FName(TEXT("TraceParams")), false, this);TraceParams.bTraceComplex = false;TraceParams.bTraceAsyncScene = false;TraceParams.bReturnPhysicalMaterial = false;}// Called when the game starts or when spawnedvoid AMyPlayer::BeginPlay(){Super::BeginPlay();}// Called every framevoid AMyPlayer::Tick( float DeltaTime ){Super::Tick( DeltaTime );if (Controller && Controller->IsLocalController()){HandleHighlight();}}// Called to bind functionality to inputvoid AMyPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){Super::SetupPlayerInputComponent(PlayerInputComponent);InputComponent->BindAxis("MoveForward", this, &AMyPlayer::MoveForward);InputComponent->BindAxis("MoveRight", this, &AMyPlayer::MoveRight);InputComponent->BindAxis("LookYaw", this, &AMyPlayer::LookYaw);InputComponent->BindAxis("LookPitch", this, &AMyPlayer::LookPitch);InputComponent->BindAction("Use", IE_Pressed, this, &AMyPlayer::Use);}// 前後移動void AMyPlayer::MoveForward(float val){FRotator Rotation(0, GetActorRotation().Yaw, 0);// Roll, Yaw, PitchFVector forward = FRotationMatrix(Rotation).GetScaledAxis(EAxis::X);AddMovementInput(forward, val);}// 左右移動void AMyPlayer::MoveRight(float val){FRotator Rotation(0, GetActorRotation().Yaw, 0);// Roll, Yaw, PitchFVector right = FRotationMatrix(Rotation).GetScaledAxis(EAxis::Y);AddMovementInput(right, val);}// 左右轉向void AMyPlayer::LookYaw(float val){AddControllerYawInput(val);}// 上下轉向void AMyPlayer::LookPitch(float val){// 注意方向相反AddControllerPitchInput(val);}// 按 E 鍵與啟用物件進行互動void AMyPlayer::Use(){AInteractableActor* Interactable = FindFocusedActor();if (Interactable){// OnInteract_ImplementationInteractable->OnInteract(this);}}AInteractableActor* AMyPlayer::FindFocusedActor(){if (!Controller){return nullptr;}FVector Location;FRotator Rotation;FHitResult Hit(ForceInit);Controller->GetPlayerViewPoint(Location, Rotation);FVector Start = Location;FVector End = Start + (Rotation.Vector() * InteractionDistance);// 通過 “射線拾取” 選取的物件GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Camera, TraceParams);if (Hit.bBlockingHit)// 擊中{// 擷取當前被擊中的對象的引用AInteractableActor* MyCastActor = Cast<AInteractableActor>(Hit.GetActor());if (MyCastActor){return MyCastActor;}}return nullptr;}void AMyPlayer::HandleHighlight(){AInteractableActor* NewHighlight = FindFocusedActor();if (NewHighlight){// 如果當前描邊和新啟用的對象不是同一個if (FocusedActor != NewHighlight){if (FocusedActor){// 當前描邊對象取消描邊FocusedActor->OnEndFocus();}// 描邊新啟用物件NewHighlight->OnBeginFocus();FocusedActor = NewHighlight;}}else{if (FocusedActor){// 取消描邊FocusedActor->OnEndFocus();FocusedActor = nullptr;}}}
InteractableActor.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"#include "OutlineCPlusPlus.h"#include "InteractableActor.generated.h"UCLASS()class OUTLINECPLUSPLUS_API AInteractableActor : public AActor{GENERATED_BODY()public:// Sets default values for this actor‘s propertiesAInteractableActor();// Called when the game starts or when spawnedvirtual void BeginPlay() override;// Called every framevirtual void Tick( float DeltaSeconds ) override;UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Interaction)void OnInteract(AActor* Caller) ;virtual void OnInteract_Implementation(AActor* Caller);void OnBeginFocus();void OnEndFocus();private:UPROPERTY(EditDefaultsOnly)uint32 bCanInteract : 1;TArray<UMeshComponent*> Meshes;UPROPERTY(EditDefaultsOnly)EStencilColor Color = EStencilColor::SC_Green;};
InteractableActor.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "MyPlayer.h"#include "InteractableActor.h"// Sets default valuesAInteractableActor::AInteractableActor(){ // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don‘t need it.PrimaryActorTick.bCanEverTick = true;}// Called when the game starts or when spawnedvoid AInteractableActor::BeginPlay(){Super::BeginPlay();for (UActorComponent* Mesh : GetComponentsByClass(UMeshComponent::StaticClass())){UMeshComponent* thisMesh = Cast<UMeshComponent>(Mesh);if (thisMesh){Meshes.Push(thisMesh);}}}// Called every framevoid AInteractableActor::Tick( float DeltaTime ){Super::Tick( DeltaTime );}void AInteractableActor::OnInteract_Implementation(AActor* Caller){AMyPlayer* Player = Cast<AMyPlayer>(Caller);if (Player){GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Now deleting the interactable actor! "))); // 銷毀自己Destroy();}}void AInteractableActor::OnBeginFocus(){if (bCanInteract){for (UMeshComponent* Mesh : Meshes){Mesh->SetRenderCustomDepth(true);Mesh->SetCustomDepthStencilValue((uint8)Color);}}}void AInteractableActor::OnEndFocus(){if (bCanInteract){for (UMeshComponent* Mesh : Meshes){Mesh->SetRenderCustomDepth(false);}}}
顏色 的 Enum
UENUM(BlueprintType)enum class EStencilColor : uint8{SC_Green = 250 UMETA(DisplayName = "Green"),SC_Blue = 251 UMETA(DisplayName = "Blue"),SC_Red = 252 UMETA(DisplayName = "Red"),SC_White = 253 UMETA(DisplayName = "White")};
第三方材質下載連結
PostProcess 官方文檔
利用第三方材質對物體進行描邊【UE4】【C++】