c++蓝图实现摄像机靠近角色时,角色消失,防止遮挡视线
以虚幻4自带的ThirdPersonCharacter为例
1. 对材质处理
打开虚幻4自带的ThirdPersonCharacter所使用的材质蓝图
将输出结点的蓝图断开 添加以下结点
目的是将透明度开放出来,让其他组件可读取和写入
2.创建组件
蓝图方式
创建一个Actor Component 并创建两个函数和两个变量(因为所使用的材质有两个)
其中两个变量的类型是 Material Instance Dynamic
Fade_BeginPlay:
有一个输入,无输出
输入mesh类型为Primitive Component
为了截图清楚 凑到一起了 所以线条很乱
其中 Create Dynamic Material Instance 中的 parent 分别是所使用的两个材质名
Fade_EventTick:
两个输入 无输出
功能实现可以参考c++代码来理解 详见c++注释
c++方式
创建c++类的Actor Component
.h文件
/**************************************************************************
Copyright:聚集地
Author: 赣榆乌鸦Nevermore
Date:2021-07-27
Description:当摄像机与character距离过近时 character渐隐 以防遮挡实现
*** 注意使用本函数需要的"Opacity"变量需要手动在材质蓝图中设置,详见M_Male_Body蓝图里中文注释的部分 ***
是蓝图AC_FadeWhenCameraClose的c++化尝试
尝试用c++编写该组件 目前宣告失败 -7.27-成功啦!!!!我们是冠军!!!!
**************************************************************************/
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "AC_FadeWhenCameraIsClose.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class PROJECT_63_API UAC_FadeWhenCameraIsClose : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UAC_FadeWhenCameraIsClose();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
//动态材质
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category ="Nevermore|Material" )
UMaterialInstanceDynamic* PlayerBodyMaterial;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Nevermore|Material")
UMaterialInstanceDynamic* PlayerChestLogoMaterial;
/*
和公开属性类似,使用宏 UFUNCTION 即可。UFUNCTION() 负责将C++函数公开给反射系统。
**BlueprintCallable ** 选项将其公开给蓝图虚拟机。
每一个公开给蓝图的函数都需要一个与之关联的类别(Category),这样右键点击快捷菜单的功能才能正确生效。
*/
UFUNCTION(BlueprintCallable, Category = "Nevermore|BPFunc_Lib")
virtual void Fade_BeginPlay(UPrimitiveComponent* mesh);
UFUNCTION(BlueprintCallable, Category = "Nevermore|BPFunc_Lib")
virtual void Fade_EventTick(FVector CameraLocation, FVector Location);
};
.cpp文件
/**************************************************************************
Copyright:聚集地
Author: 赣榆乌鸦Nevermore
Date:2021-07-27
Description:当摄像机与character距离过近时 character渐隐 以防遮挡实现
*** 注意使用本函数需要的"Opacity"变量需要手动在材质蓝图中设置,详见M_Male_Body蓝图里中文注释的部分 ***
是蓝图AC_FadeWhenCameraClose的c++化尝试
尝试用c++编写该组件 目前宣告失败 -7.27-成功啦!!!!我们是冠军!!!!
**************************************************************************/
#include "AC_FadeWhenCameraIsClose.h"
#include "Components/PrimitiveComponent.h"
#include "Kismet/KismetMaterialLibrary.h"
#include "Kismet/KismetMathLibrary.h"
#include"Kismet/KismetStringLibrary.h"
#include"Kismet/KismetSystemLibrary.h"
// Sets default values for this component's properties
UAC_FadeWhenCameraIsClose::UAC_FadeWhenCameraIsClose()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UAC_FadeWhenCameraIsClose::BeginPlay()
{
Super::BeginPlay();
// ...
}
// Called every frame
void UAC_FadeWhenCameraIsClose::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
/**************************************************
@brief : 创建两个动态材质,替换character本身使用的材质,这样就取得了对character材质的控制权
可由蓝图的BeginPlay调用
@author : Nevemore
@input :
mesh:character的网格体
@output :
@time : 2021-07-27
@AD: 可以用数组方式将他改得更有普遍性,不过现在用不到,我懒得优化了
**************************************************/
//目前宣告失败 -成功啦!!!!!我们是冠军!!!
void UAC_FadeWhenCameraIsClose::Fade_BeginPlay(UPrimitiveComponent* mesh) {
//这里的动态材质创建方式与蓝图不同,更具有普遍性,是通过数字来获取材质
UMaterialInstanceDynamic* t1 = mesh->CreateDynamicMaterialInstance(0);
UMaterialInstanceDynamic* t2 = mesh->CreateDynamicMaterialInstance(1);
PlayerBodyMaterial = t1;
PlayerChestLogoMaterial = t2;
if (IsValid(mesh)) {
//将创建的动态材质重新赋予character
mesh->SetMaterial(0, PlayerBodyMaterial);
mesh->SetMaterial(1, PlayerChestLogoMaterial);
}
}
/**************************************************
@brief : 距离过近时character 隐身
@author : Nevemore
@input :
CameraLocation:摄像机的位置
Location:character的位置
@output :
@time : 2021-07-27
@AD:
**************************************************/
void UAC_FadeWhenCameraIsClose::Fade_EventTick(FVector CameraLocation, FVector Location){
//计算出两者之间的差值
float t1= UKismetMathLibrary::Vector_Distance(CameraLocation, Location);
//返回从一个范围映射到另一个范围的值
//以此代码为例
//当t1的值在50-90之间时,就会返回一个0.3-1的相应的值
float t2= UKismetMathLibrary::MapRangeClamped(t1, 50.000000, 90.000000, 0.300000, 1.000000);
//将t2转成string打印到屏幕
FString t3= UKismetStringLibrary::Conv_FloatToString(t2);
UKismetSystemLibrary::PrintString(this, t3, true, true, FLinearColor(1.000000, 0.244451, 0.435678, 1.000000), 0.000000);
//当动态材质存在时,改变材质蓝图中名为 "Opacity"的变量值
//注意 "Opacity"变量需要手动在材质蓝图中设置,详见M_Male_Body蓝图里中文注释的部分
if (IsValid(PlayerBodyMaterial) && IsValid(PlayerChestLogoMaterial)) {
PlayerBodyMaterial->UMaterialInstanceDynamic::SetScalarParameterValue(FName(TEXT("Opacity")), t2);
PlayerChestLogoMaterial->UMaterialInstanceDynamic::SetScalarParameterValue(FName(TEXT("Opacity")), t2);
}
}
3.在蓝图中调用
把要用的component装上
然后调用
其中mesh和Follow Camera 直接从components里拖进去就可以
4. 演出效果
远距离
距离过近