ue4描边

效果图:

 

第一步,创建C++ Basic Code

 

第二步,定义键盘和鼠标输入的映射

 

第三步,修改 Rendering 中的 Custom Depth - Stencil Pass

 

第四步,找到GlobalPostProcessVolume [如果没有的话自行拖放一个PostProcessVolume组件] 

 

将 unbound 勾选上

 

再修改 Blendables 为 PPI_OutlineColored

 

 

完整代码如下:

MyPlayer.h

 

 
  1. // Fill out your copyright notice in the Description page of Project Settings.

  2.  
  3. #pragma once

  4.  
  5. #include "GameFramework/Character.h"

  6. #include "MyPlayer.generated.h"

  7.  
  8. UCLASS()

  9. class OUTLINECPLUSPLUS_API AMyPlayer : public ACharacter

  10. {

  11. GENERATED_BODY()

  12.  
  13. public:

  14. // Sets default values for this character's properties

  15. AMyPlayer();

  16.  
  17. void MoveForward(float val);

  18. void MoveRight(float val);

  19. void LookYaw(float val);

  20. void LookPitch(float val);

  21. void Use();

  22.  
  23. class AInteractableActor* FindFocusedActor();

  24. void HandleHighlight();

  25.  
  26. // Called when the game starts or when spawned

  27. virtual void BeginPlay() override;

  28.  
  29. // Called every frame

  30. virtual void Tick( float DeltaSeconds ) override;

  31.  
  32. // Called to bind functionality to input

  33. virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

  34.  
  35. private:

  36. UPROPERTY(EditDefaultsOnly)

  37. float InteractionDistance = 300.f; // 交互的范围

  38. class AInteractableActor* FocusedActor;

  39. // 用于 LineTraceSingleByChannel

  40. FCollisionQueryParams TraceParams;

  41. };

 

MyPlayer.cpp

 

 

 

 
  1. // Fill out your copyright notice in the Description page of Project Settings.

  2. #include "InteractableActor.h"

  3. #include "MyPlayer.h"

  4.  
  5. // Sets default values

  6. AMyPlayer::AMyPlayer()

  7. {

  8. // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.

  9. PrimaryActorTick.bCanEverTick = true;

  10.  
  11. TraceParams = FCollisionQueryParams(FName(TEXT("TraceParams")), false, this);

  12. TraceParams.bTraceComplex = false;

  13. TraceParams.bTraceAsyncScene = false;

  14. TraceParams.bReturnPhysicalMaterial = false;

  15. }

  16.  
  17. // Called when the game starts or when spawned

  18. void AMyPlayer::BeginPlay()

  19. {

  20. Super::BeginPlay();

  21.  
  22. }

  23.  
  24. // Called every frame

  25. void AMyPlayer::Tick( float DeltaTime )

  26. {

  27. Super::Tick( DeltaTime );

  28.  
  29. if (Controller && Controller->IsLocalController())

  30. {

  31. HandleHighlight();

  32. }

  33.  
  34. }

  35.  
  36. // Called to bind functionality to input

  37. void AMyPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)

  38. {

  39. Super::SetupPlayerInputComponent(PlayerInputComponent);

  40.  
  41. InputComponent->BindAxis("MoveForward", this, &AMyPlayer::MoveForward);

  42. InputComponent->BindAxis("MoveRight", this, &AMyPlayer::MoveRight);

  43. InputComponent->BindAxis("LookYaw", this, &AMyPlayer::LookYaw);

  44. InputComponent->BindAxis("LookPitch", this, &AMyPlayer::LookPitch);

  45. InputComponent->BindAction("Use", IE_Pressed, this, &AMyPlayer::Use);

  46.  
  47. }

  48. // 前后移动

  49. void AMyPlayer::MoveForward(float val)

  50. {

  51. FRotator Rotation(0, GetActorRotation().Yaw, 0); // Roll, Yaw, Pitch

  52. FVector forward = FRotationMatrix(Rotation).GetScaledAxis(EAxis::X);

  53. AddMovementInput(forward, val);

  54. }

  55.  
  56. // 左右移动

  57. void AMyPlayer::MoveRight(float val)

  58. {

  59. FRotator Rotation(0, GetActorRotation().Yaw, 0); // Roll, Yaw, Pitch

  60. FVector right = FRotationMatrix(Rotation).GetScaledAxis(EAxis::Y);

  61. AddMovementInput(right, val);

  62. }

  63.  
  64. // 左右转向

  65. void AMyPlayer::LookYaw(float val)

  66. {

  67. AddControllerYawInput(val);

  68. }

  69.  
  70. // 上下转向

  71. void AMyPlayer::LookPitch(float val)

  72. {

  73. // 注意方向相反

  74. AddControllerPitchInput(val);

  75. }

  76.  
  77. // 按 E 键与激活对象进行交互

  78. void AMyPlayer::Use()

  79. {

  80. AInteractableActor* Interactable = FindFocusedActor();

  81. if (Interactable)

  82. {

  83. // OnInteract_Implementation

  84. Interactable->OnInteract(this);

  85. }

  86. }

  87.  
  88. AInteractableActor* AMyPlayer::FindFocusedActor()

  89. {

  90. if (!Controller)

  91. {

  92. return nullptr;

  93. }

  94.  
  95. FVector Location;

  96. FRotator Rotation;

  97. FHitResult Hit(ForceInit);

  98. Controller->GetPlayerViewPoint(Location, Rotation);

  99.  
  100. FVector Start = Location;

  101. FVector End = Start + (Rotation.Vector() * InteractionDistance);

  102.  
  103. // 通过 “射线拾取” 选定对象

  104. GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Camera, TraceParams);

  105. if (Hit.bBlockingHit) // 击中

  106. {

  107. // 获取当前被击中的对象的引用

  108. AInteractableActor* MyCastActor = Cast<AInteractableActor>(Hit.GetActor());

  109. if (MyCastActor)

  110. {

  111. return MyCastActor;

  112. }

  113. }

  114. return nullptr;

  115. }

  116.  
  117. void AMyPlayer::HandleHighlight()

  118. {

  119. AInteractableActor* NewHighlight = FindFocusedActor();

  120. if (NewHighlight)

  121. {

  122. // 如果当前描边和新激活的对象不是同一个

  123. if (FocusedActor != NewHighlight)

  124. {

  125. if (FocusedActor)

  126. {

  127. // 当前描边对象取消描边

  128. FocusedActor->OnEndFocus();

  129. }

  130. // 描边新激活对象

  131. NewHighlight->OnBeginFocus();

  132. FocusedActor = NewHighlight;

  133. }

  134. }

  135. else

  136. {

  137. if (FocusedActor)

  138. {

  139. // 取消描边

  140. FocusedActor->OnEndFocus();

  141. FocusedActor = nullptr;

  142. }

  143. }

  144. }

 

 

 

InteractableActor.h

 

 
  1. // Fill out your copyright notice in the Description page of Project Settings.

  2.  
  3. #pragma once

  4.  
  5. #include "GameFramework/Actor.h"

  6. #include "OutlineCPlusPlus.h"

  7. #include "InteractableActor.generated.h"

  8.  
  9. UCLASS()

  10. class OUTLINECPLUSPLUS_API AInteractableActor : public AActor

  11. {

  12. GENERATED_BODY()

  13.  
  14. public:

  15. // Sets default values for this actor's properties

  16. AInteractableActor();

  17.  
  18. // Called when the game starts or when spawned

  19. virtual void BeginPlay() override;

  20.  
  21. // Called every frame

  22. virtual void Tick( float DeltaSeconds ) override;

  23.  
  24. UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Interaction)

  25. void OnInteract(AActor* Caller) ;

  26. virtual void OnInteract_Implementation(AActor* Caller);

  27.  
  28. void OnBeginFocus();

  29. void OnEndFocus();

  30.  
  31. private:

  32. UPROPERTY(EditDefaultsOnly)

  33. uint32 bCanInteract : 1;

  34. TArray<UMeshComponent*> Meshes;

  35. UPROPERTY(EditDefaultsOnly)

  36. EStencilColor Color = EStencilColor::SC_Green;

  37.  
  38. };

 

InteractableActor.cpp

 

 

 

 
  1. // Fill out your copyright notice in the Description page of Project Settings.

  2.  
  3. #include "MyPlayer.h"

  4. #include "InteractableActor.h"

  5.  
  6.  
  7. // Sets default values

  8. AInteractableActor::AInteractableActor()

  9. {

  10. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.

  11. PrimaryActorTick.bCanEverTick = true;

  12.  
  13. }

  14.  
  15. // Called when the game starts or when spawned

  16. void AInteractableActor::BeginPlay()

  17. {

  18. Super::BeginPlay();

  19.  
  20. for (UActorComponent* Mesh : GetComponentsByClass(UMeshComponent::StaticClass()))

  21. {

  22. UMeshComponent* thisMesh = Cast<UMeshComponent>(Mesh);

  23. if (thisMesh)

  24. {

  25. Meshes.Push(thisMesh);

  26. }

  27. }

  28.  
  29. }

  30.  
  31. // Called every frame

  32. void AInteractableActor::Tick( float DeltaTime )

  33. {

  34. Super::Tick( DeltaTime );

  35.  
  36. }

  37.  
  38. void AInteractableActor::OnInteract_Implementation(AActor* Caller)

  39. {

  40. AMyPlayer* Player = Cast<AMyPlayer>(Caller);

  41.  
  42. if (Player)

  43. {

  44. GEngine->AddOnScreenDebugMessage(-1,

  45. 5.f,

  46. FColor::Red,

  47. FString::Printf(TEXT("Now deleting the interactable actor! "))

  48. );

  49.  
  50. // 销毁自己

  51. Destroy();

  52. }

  53.  
  54. }

  55.  
  56. void AInteractableActor::OnBeginFocus()

  57. {

  58. if (bCanInteract)

  59. {

  60. for (UMeshComponent* Mesh : Meshes)

  61. {

  62. Mesh->SetRenderCustomDepth(true);

  63. Mesh->SetCustomDepthStencilValue((uint8)Color);

  64. }

  65. }

  66. }

  67.  
  68. void AInteractableActor::OnEndFocus()

  69. {

  70. if (bCanInteract)

  71. {

  72. for (UMeshComponent* Mesh : Meshes)

  73. {

  74. Mesh->SetRenderCustomDepth(false);

  75. }

  76. }

  77. }

  78.  

 

 

 

颜色 的 Enum 

 

 
  1. UENUM(BlueprintType)

  2. enum class EStencilColor : uint8

  3. {

  4. SC_Green = 250 UMETA(DisplayName = "Green"),

  5. SC_Blue = 251 UMETA(DisplayName = "Blue"),

  6. SC_Red = 252 UMETA(DisplayName = "Red"),

  7. SC_White = 253 UMETA(DisplayName = "White")

  8. };

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值