效果图:

第一步,创建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. linux下uptime命令详解
  2. vue 虚拟服务器,vue+webpack项目中使用dev-server搭建虚拟服务器,请求json文件数据,实现先后台分离开发...
  3. C#语法:多线程编程(Thread)
  4. Spring MVC 特性实现文件下载
  5. 不需要人际交往的计算机系,计算机对大学生人际交往影响.doc
  6. idea 构建spring_以Spring方式构建企业Java应用程序
  7. 《软件》2011年第6期刊登出 《DB 查询分析器》中断SQL语句的执行
  8. mysql trigger 有时 不执行_Mysql 寒假刷题TIPs
  9. [Head First设计模式]生活中学设计模式——组合模式
  10. Hive Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
  11. table表框去掉相邻的间隔
  12. 我的世界服务器自动刷矿机,我的世界服务器钻石大陆怎么做自动刷矿机 | 手游网游页游攻略大全...
  13. 二维空间:点到直线距离的计算
  14. 使用ECharts加载大数据量数据
  15. 业务智能化成为电信运营业的总体发展趋势
  16. 10. kafka消费者如何分配分区
  17. python解椭圆方程的例题_《椭圆》方程典型例题20例(含标准答案)
  18. 无约束优化:修正阻尼牛顿法
  19. 计算机网络05(DHCP服务)
  20. 计算机网络探针,基于探针技术网络安全审计系统NetworkS.PDF

热门文章

  1. 你为什么不能成为巴菲特?
  2. 学妹:校招开始了,作为应届生的我如何挑选校招offer!
  3. 澳洲Android技术移民,的Android Studio 2.2中本地开发移民问题
  4. [C++](13)stack queue priority_queue 模拟实现:容器适配器,deque介绍,仿函数详解
  5. 无线网卡Wireless-AC 9462 故障解决【神舟Z7M-KP7GC 】
  6. Linux裸机开发|RGBLCD显示实验
  7. 一电脑多开不同设置的Chrome浏览器方法
  8. Vue 如何提交表单数据
  9. 移动硬盘格式化怎样才能恢复数据
  10. 华为如何显示我的电脑连接到服务器,华为超级终端怎么连接电脑、电视、手表?鸿蒙超级终端关了怎么打开?...