Section 10: Outline and Glow Effects - Lecture 168
Material Pulse when Interping
This commit is contained in:
parent
a635927bfd
commit
0d55a2ef39
|
@ -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)
BIN
Content/_Game/Ammo/Ammo9mmBP.uasset (Stored with Git LFS)
Binary file not shown.
BIN
Content/_Game/Assets/Textures/HorizontalLines/HorizontalLines.uasset (Stored with Git LFS)
Normal file
BIN
Content/_Game/Assets/Textures/HorizontalLines/HorizontalLines.uasset (Stored with Git LFS)
Normal file
Binary file not shown.
Binary file not shown.
BIN
Content/_Game/Maps/DefaultMap.umap (Stored with Git LFS)
BIN
Content/_Game/Maps/DefaultMap.umap (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/_Game/Materials/SMGMaterials/F_SMG_Glow_Material.uasset (Stored with Git LFS)
Normal file
BIN
Content/_Game/Materials/SMGMaterials/F_SMG_Glow_Material.uasset (Stored with Git LFS)
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/_Game/Weapons/BaseWeapon/BaseWeaponBP.uasset (Stored with Git LFS)
BIN
Content/_Game/Weapons/BaseWeapon/BaseWeaponBP.uasset (Stored with Git LFS)
Binary file not shown.
|
@ -88,3 +88,13 @@ void AAmmo::OnAmmoSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AAmmo::EnableCustomDepth()
|
||||
{
|
||||
AmmoMesh->SetRenderCustomDepth(true);
|
||||
}
|
||||
|
||||
void AAmmo::DisableCustomDepth()
|
||||
{
|
||||
AmmoMesh->SetRenderCustomDepth(false);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue