效果图:

第一步,创建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 values
AMyPlayer::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 spawned
void AMyPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMyPlayer::Tick( float DeltaTime )
{Super::Tick( DeltaTime );if (Controller && Controller->IsLocalController()){HandleHighlight();}}// Called to bind functionality to input
void 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 values
AInteractableActor::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 spawned
void AInteractableActor::BeginPlay()
{Super::BeginPlay();for (UActorComponent* Mesh : GetComponentsByClass(UMeshComponent::StaticClass())){UMeshComponent* thisMesh = Cast<UMeshComponent>(Mesh);if (thisMesh){Meshes.Push(thisMesh);}}}// Called every frame
void 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 官方文档

利用第三方后期处理材质(PostProcess Material)对物体进行描边【UE4】【C++】相关推荐

  1. Unreal 后期处理材质范例

    from: https://docs.unrealengine.com/latest/CHN/Engine/Rendering/PostProcessEffects/PostProcessMateri ...

  2. Unreal4 后期处理材质

    后期处理材质     本页面的内容: 后期处理图表 使用后期处理材质 制作简单的后期处理材质 后期处理材质的关键设置 在不同材质实例之间进行混合 材质表现"SceneTexture" ...

  3. opengl地球贴纹理_一文看懂材质/纹理 Material, Texture, Shading, Shader 的区别

    在计算机图形学和三维设计中,有几个容易混淆的概念.今天我们来一举拿下. 概念整理 可以这么总结: Material 是表现 Shading 的数据集.其他几个概念都是生成这一数据集的资源或者工具. 这 ...

  4. UE4后期处理材质:扁平化风格描边

    1.利用基础颜色实现扁平化渲染 2.创建多边形描边 3.创建法线描边 4.完善描边效果 后期处理体积:用于应用或修改渲染到屏幕上的视觉效果,自定义后期处理材质通过改动渲染缓冲(在渲染画面上叠加RGB值 ...

  5. UE4 后期处理材质

    1 在利用后期处理材质在视口上显示UI参考图标位置 如图操作 2 在后期盒子中添加后期材质

  6. 【Unity】11.5 物理材质 (Physics Material)

    分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 物理材质 (Physics Material) 用于调整碰撞对象的摩擦力和反弹效果. 二.创建物理材质 要创建物理材质 ...

  7. 利用第三方浏览器漏洞钓鱼

    6.4 利用第三方浏览器漏洞钓鱼 现在各种各样的浏览器导出不穷,然而都是建立在IE内核基础上的,而且在安全方面,这些"扩展"版本浏览器远比IE差了许多,很可能IE正常访问的页面,被 ...

  8. 如何利用第三方数据进行大数据分析

    企业如何避免迷失在数据网络中?通过掌握大数据和第三方数据.但是,掌握第三方数据可能会非常具有挑战性,称其遵守严格的数据隐私规范是不可错过的.数据在增长,可以利用的机会也在增加.为了从第三方数据孤岛中获 ...

  9. 利用第三方服务平台实现简单的短信验证功能

    在本篇文章中,将会利用第三方服务平台实现短信验证功能. 首先,先介绍一下刚才提及的第三方服务平台:mob.com 移动开发者服务平台 该平台呢,主要有以下几点功能: 1.为IOS.Android的AP ...

最新文章

  1. 关于动态规划,你想知道的都在这里了!
  2. 在Office 2007 Word文档中插入两种页码方法
  3. 给Xshell设置舒适的配色方案
  4. ansible(5)——使用通配符操作ansible命令
  5. (转)python3 计算字符串、文件md5值
  6. primefaces_PrimeFaces Mobile入门
  7. 【转】ORACLE中的子查询 ---OCP--047--46
  8. 【转】MySQL日期函数与日期转换格式化函数大全
  9. C语言程序设计实践-C语言应用实践
  10. 使用Excel生成符合正态分布的随机数
  11. JS 事件捕获、事件冒泡以及事件委托图文详解
  12. C++中的常对象和常对象成员
  13. 火萤视频壁纸(让你的桌面丰富多彩)
  14. CookGAN Causality based Text-to-Image Synthesis
  15. 现在做电商晚了吗?电商可以赚零花钱吗?
  16. K-SVD: An Algorithm for Designing Overcomplete Dictionaries for Sparse Representation
  17. win10关闭杀毒防护
  18. 管理跨国虚拟团队的技巧
  19. mysql触发器的作用及语法
  20. 机器的思考故事——计算机能学会牛顿第二定律吗?

热门文章

  1. 解决手机无法连接到电脑的问题
  2. 【新版阿里云控制台】使用体验与介绍
  3. ux许可服务器关机或未响应,ug11许可证错误解决方法96 nx许可证错误-96 ug打开错误代码96 ug12安装第二次时出现96错误 ug12提示许可证错误96 ug11许可证96...
  4. Chrome 96 版本无法发送跨域请求的问题 解决方案
  5. 信管专业如果考计算机证考什么,信管专业可以考的证书
  6. 福利应用更新,这几款都是老司机喜欢的
  7. [luogu1768]天路
  8. TortoiseSVN环境搭建
  9. 中南大学计算机技术考研科目,中南大学计算机技术(工程硕士专业学位)研究生考试科目和考研参考书目...
  10. Busybox 命令大全~~