Section 10: Outline and Glow Effects - Lecture 168

Material Pulse when Interping
This commit is contained in:
charnet3d 2023-06-18 11:17:23 +01:00
parent a635927bfd
commit 0d55a2ef39
18 changed files with 196 additions and 8 deletions

View File

@ -46,6 +46,7 @@ r.GenerateMeshDistanceFields=True
r.DynamicGlobalIlluminationMethod=1
r.ReflectionMethod=1
r.Shadow.Virtual.Enable=1
r.CustomDepth=3
[/Script/WorldPartitionEditor.WorldPartitionEditorSettings]
CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet'

BIN
Content/_Game/Ammo/Ammo9mmBP.uasset (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/_Game/Curves/MaterialPulseCurve.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/_Game/Maps/DefaultMap.umap (Stored with Git LFS)

Binary file not shown.

BIN
Content/_Game/Materials/PostProcess/M_SMG_Mat.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/_Game/Materials/PostProcess/PP_Highlight.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/_Game/Materials/SMGMaterials/F_Belica_Guns.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
Content/_Game/Materials/SMGMaterials/M_SMG_Mat.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/_Game/Materials/SMGMaterials/M_SMG_Mat_Inst.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@ -88,3 +88,13 @@ void AAmmo::OnAmmoSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor
}
}
}
void AAmmo::EnableCustomDepth()
{
AmmoMesh->SetRenderCustomDepth(true);
}
void AAmmo::DisableCustomDepth()
{
AmmoMesh->SetRenderCustomDepth(false);
}

View File

@ -53,4 +53,7 @@ private:
public:
FORCEINLINE UStaticMeshComponent* GetAmmoMesh() const { return AmmoMesh; }
FORCEINLINE EAmmoType GetAmmoType() const { return AmmoType; }
virtual void EnableCustomDepth() override;
virtual void DisableCustomDepth() override;
};

View File

@ -10,6 +10,7 @@
#include "Camera/CameraComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Sound/SoundCue.h"
#include "Curves/CurveVector.h"
// Sets default values
AItem::AItem() :
@ -26,7 +27,14 @@ AItem::AItem() :
ItemIntepY(0.f),
InterpInitialYawOffset(0.f),
ItemType(EItemType::EIT_MAX),
InterpLocIndex(0)
InterpLocIndex(0),
MaterialIndex(0),
bCanChangeCustomDepth(true),
// Dynamic Material Parameters
GlowAmount(150.f),
FresnelExponent(3.f),
FresnelReflectFraction(4.f),
PulseCurveTime(5.f)
{
// 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;
@ -64,6 +72,11 @@ void AItem::BeginPlay()
//Set Item properties based on ItemState
SetItemProperties(ItemState);
// Set custom depth to disabled
InitializeCustomDepth();
StartPulseTimer();
}
void AItem::setActiveStars()
@ -119,6 +132,65 @@ void AItem::PlayPickupSound()
}
}
void AItem::EnableCustomDepth()
{
if (bCanChangeCustomDepth)
ItemMesh->SetRenderCustomDepth(true);
}
void AItem::DisableCustomDepth()
{
if (bCanChangeCustomDepth)
ItemMesh->SetRenderCustomDepth(false);
}
void AItem::InitializeCustomDepth()
{
DisableCustomDepth();
}
void AItem::OnConstruction(const FTransform& Transform)
{
if (MaterialInstance)
{
DynamicMaterialInstance = UMaterialInstanceDynamic::Create(MaterialInstance, this);
ItemMesh->SetMaterial(MaterialIndex, DynamicMaterialInstance);
}
EnableGlowMaterial();
}
void AItem::UpdatePulse()
{
if (ItemState != EItemState::EIS_Pickup) return;
const float ElapsedTime { GetWorldTimerManager().GetTimerElapsed(PulseTimer) };
if (PulseCurve)
{
const FVector CurveValue{ PulseCurve->GetVectorValue(ElapsedTime) };
DynamicMaterialInstance->SetScalarParameterValue(TEXT("GlowAmount"), CurveValue.X * GlowAmount);
DynamicMaterialInstance->SetScalarParameterValue(TEXT("FresnelExponent"), CurveValue.Y * FresnelExponent);
DynamicMaterialInstance->SetScalarParameterValue(TEXT("FresnelReflectFraction"), CurveValue.Z * FresnelReflectFraction);
}
}
void AItem::EnableGlowMaterial()
{
if (DynamicMaterialInstance)
{
DynamicMaterialInstance->SetScalarParameterValue(TEXT("GlowBlendAlpha"), 0);
}
}
void AItem::DisableGlowMaterial()
{
if (DynamicMaterialInstance)
{
DynamicMaterialInstance->SetScalarParameterValue(TEXT("GlowBlendAlpha"), 1);
}
}
void AItem::PlayEquipSound()
{
if (Character)
@ -141,6 +213,9 @@ void AItem::Tick(float DeltaTime)
// Handle Item interping when in the EquipInterping state
ItemInterp(DeltaTime);
// Get curve values from PulseCurve and set dynamic material parameters
UpdatePulse();
}
void AItem::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp,
@ -247,6 +322,19 @@ FVector AItem::GetInterpLocation()
return FVector(0.f);
}
void AItem::ResetPulseTimer()
{
StartPulseTimer();
}
void AItem::StartPulseTimer()
{
if (ItemState == EItemState::EIS_Pickup)
{
GetWorldTimerManager().SetTimer(PulseTimer, this, &AItem::ResetPulseTimer, PulseCurveTime);
}
}
void AItem::SetItemState(EItemState State)
{
ItemState = State;
@ -360,6 +448,8 @@ void AItem::StartItemCurve(AShooterCharacter* Char)
// Initial Yaw Offset between Camera and Item
InterpInitialYawOffset = ItemRotationYaw - CameraRotationYaw;
bCanChangeCustomDepth = false;
}
void AItem::FinishInterping()
@ -374,5 +464,8 @@ void AItem::FinishInterping()
}
// Set scale back to normal
SetActorScale3D(FVector(1.f));
bCanChangeCustomDepth = true;
DisableCustomDepth();
}

View File

@ -12,6 +12,7 @@ class USphereComponent;
class UCurveFloat;
class AShooterCharacter;
class USoundCue;
class UCurveVector;
UENUM(BlueprintType)
enum class EItemRarity : uint8
@ -82,6 +83,14 @@ protected:
void PlayPickupSound();
virtual void InitializeCustomDepth();
virtual void OnConstruction(const FTransform& Transform) override;
void ResetPulseTimer();
void StartPulseTimer();
void UpdatePulse();
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
@ -187,6 +196,39 @@ private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item Properties", meta = (AllowPrivateAccess = true))
int32 InterpLocIndex;
/** Index for the material we'd like to change at runtime */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item Properties", meta = (AllowPrivateAccess = true))
int32 MaterialIndex;
/** Dynamic instance that we can change at runtime */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item Properties", meta = (AllowPrivateAccess = true))
UMaterialInstanceDynamic* DynamicMaterialInstance;
/** Material instance used with the dynamic material instance */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item Properties", meta = (AllowPrivateAccess = true))
UMaterialInstance* MaterialInstance;
bool bCanChangeCustomDepth;
/** Curve to drive the dynamic material parameters */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Item Properties", meta = (AllowPrivateAccess = true))
UCurveVector* PulseCurve;
FTimerHandle PulseTimer;
/** Time for the pulse timer */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Item Properties", meta = (AllowPrivateAccess = true))
float PulseCurveTime;
UPROPERTY(VisibleAnywhere, Category = "Item Properties", meta = (AllowPrivateAccess = true))
float GlowAmount;
UPROPERTY(VisibleAnywhere, Category = "Item Properties", meta = (AllowPrivateAccess = true))
float FresnelExponent;
UPROPERTY(VisibleAnywhere, Category = "Item Properties", meta = (AllowPrivateAccess = true))
float FresnelReflectFraction;
public:
FORCEINLINE UWidgetComponent* GetPickupWidget() const { return PickupWidget; }
@ -207,4 +249,10 @@ public:
/** Called from the AShooterCharacter class */
void StartItemCurve(AShooterCharacter* Char);
virtual void EnableCustomDepth();
virtual void DisableCustomDepth();
void EnableGlowMaterial();
void DisableGlowMaterial();
};

View File

@ -723,6 +723,9 @@ void AShooterCharacter::SetItemPickupWidgetVisibility(AItem* Item, bool visibili
if (Item && Item->GetPickupWidget())
{
Item->GetPickupWidget()->SetVisibility(visibility);
visibility ?
Item->EnableCustomDepth() :
Item->DisableCustomDepth();
}
}
@ -750,6 +753,9 @@ void AShooterCharacter::EquipWeapon(AWeapon* WeaponToEquip)
EquippedWeapon = WeaponToEquip;
EquippedWeapon->SetItemState(EItemState::EIS_Equipped);
EquippedWeapon->DisableGlowMaterial();
EquippedWeapon->DisableCustomDepth();
}
}

View File

@ -43,12 +43,14 @@ void AWeapon::ThrowWeapon()
float RandomRotation{ 30.f };
ImpulseDirection = ImpulseDirection.RotateAngleAxis(RandomRotation, FVector(0.f, 0.f, 1.f));
ImpulseDirection *= 20000.f;
ImpulseDirection *= 2000.f;
GetItemMesh()->AddImpulse(ImpulseDirection);
bFalling = true;
GetWorldTimerManager().SetTimer(ThrowWeaponTimer, this,
&AWeapon::StopFalling, ThrowWeaponTime);
EnableGlowMaterial();
}
void AWeapon::DecrementAmmo()
@ -74,4 +76,5 @@ void AWeapon::StopFalling()
{
bFalling = false;
SetItemState(EItemState::EIS_Pickup);
StartPulseTimer();
}