From 0d55a2ef396adb49a8c3c434527b5c0f8adb27d0 Mon Sep 17 00:00:00 2001 From: charnet3d Date: Sun, 18 Jun 2023 11:17:23 +0100 Subject: [PATCH] Section 10: Outline and Glow Effects - Lecture 168 Material Pulse when Interping --- Config/DefaultEngine.ini | 1 + Content/_Game/Ammo/Ammo9mmBP.uasset | 4 +- .../HorizontalLines/HorizontalLines.uasset | 3 + .../_Game/Curves/MaterialPulseCurve.uasset | 3 + Content/_Game/Maps/DefaultMap.umap | 4 +- .../Materials/PostProcess/M_SMG_Mat.uasset | 3 + .../Materials/PostProcess/PP_Highlight.uasset | 3 + .../SMGMaterials/F_Belica_Guns.uasset | 3 + .../SMGMaterials/F_SMG_Glow_Material.uasset | 3 + .../Materials/SMGMaterials/M_SMG_Mat.uasset | 3 + .../SMGMaterials/M_SMG_Mat_Inst.uasset | 3 + .../Weapons/BaseWeapon/BaseWeaponBP.uasset | 4 +- Source/Shooter/Ammo.cpp | 10 ++ Source/Shooter/Ammo.h | 3 + Source/Shooter/Item.cpp | 95 ++++++++++++++++++- Source/Shooter/Item.h | 48 ++++++++++ Source/Shooter/ShooterCharacter.cpp | 6 ++ Source/Shooter/Weapon.cpp | 5 +- 18 files changed, 196 insertions(+), 8 deletions(-) create mode 100644 Content/_Game/Assets/Textures/HorizontalLines/HorizontalLines.uasset create mode 100644 Content/_Game/Curves/MaterialPulseCurve.uasset create mode 100644 Content/_Game/Materials/PostProcess/M_SMG_Mat.uasset create mode 100644 Content/_Game/Materials/PostProcess/PP_Highlight.uasset create mode 100644 Content/_Game/Materials/SMGMaterials/F_Belica_Guns.uasset create mode 100644 Content/_Game/Materials/SMGMaterials/F_SMG_Glow_Material.uasset create mode 100644 Content/_Game/Materials/SMGMaterials/M_SMG_Mat.uasset create mode 100644 Content/_Game/Materials/SMGMaterials/M_SMG_Mat_Inst.uasset diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index f1138c37..06edc61f 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -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' diff --git a/Content/_Game/Ammo/Ammo9mmBP.uasset b/Content/_Game/Ammo/Ammo9mmBP.uasset index 2199afeb..31c64492 100644 --- a/Content/_Game/Ammo/Ammo9mmBP.uasset +++ b/Content/_Game/Ammo/Ammo9mmBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:613e5e0ddf8c3d4541eb8316d6ac6d2cea9e8fcc6ffccdb7e5d72991f7b2f93a -size 52067 +oid sha256:3fe361a9c8705ae9bd274f4ef3430a8764046794e7886d51fd9f8696036b72f3 +size 51743 diff --git a/Content/_Game/Assets/Textures/HorizontalLines/HorizontalLines.uasset b/Content/_Game/Assets/Textures/HorizontalLines/HorizontalLines.uasset new file mode 100644 index 00000000..7db58908 --- /dev/null +++ b/Content/_Game/Assets/Textures/HorizontalLines/HorizontalLines.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c711446669e3987318c5e9478d1ecfde61dd8e0696c0a659c78e9c5358030d23 +size 25548 diff --git a/Content/_Game/Curves/MaterialPulseCurve.uasset b/Content/_Game/Curves/MaterialPulseCurve.uasset new file mode 100644 index 00000000..c947e355 --- /dev/null +++ b/Content/_Game/Curves/MaterialPulseCurve.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36e0a183f28225dc5b4153ec04d4b38da57b571f62d9ee08b7ad4ff2cf01e177 +size 2303 diff --git a/Content/_Game/Maps/DefaultMap.umap b/Content/_Game/Maps/DefaultMap.umap index f4cc8a91..38cd464d 100644 --- a/Content/_Game/Maps/DefaultMap.umap +++ b/Content/_Game/Maps/DefaultMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c42f20adb0b1bbf4255ba4b0085eea5bc25453354f2cfa23be9418cd7ee1481 -size 78653 +oid sha256:761a1383f0c734fe1848c4f7eee24936f56aa91447cbc53d51ec4892e792768f +size 97937 diff --git a/Content/_Game/Materials/PostProcess/M_SMG_Mat.uasset b/Content/_Game/Materials/PostProcess/M_SMG_Mat.uasset new file mode 100644 index 00000000..0c03238e --- /dev/null +++ b/Content/_Game/Materials/PostProcess/M_SMG_Mat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad4640f6817c747fccad71d5fbe357c85d2667bf24b0347336510956f69b7803 +size 1491 diff --git a/Content/_Game/Materials/PostProcess/PP_Highlight.uasset b/Content/_Game/Materials/PostProcess/PP_Highlight.uasset new file mode 100644 index 00000000..4d1bbd12 --- /dev/null +++ b/Content/_Game/Materials/PostProcess/PP_Highlight.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e0010a42a43d849c594576e394fbe5de7db421eb4806a7c0ef88059755d60ad +size 69716 diff --git a/Content/_Game/Materials/SMGMaterials/F_Belica_Guns.uasset b/Content/_Game/Materials/SMGMaterials/F_Belica_Guns.uasset new file mode 100644 index 00000000..0c1467ee --- /dev/null +++ b/Content/_Game/Materials/SMGMaterials/F_Belica_Guns.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff6f5f874e62a75e6414af6a7b016a2e9bca75716fd6e9ba132aa939ef0150e7 +size 49738 diff --git a/Content/_Game/Materials/SMGMaterials/F_SMG_Glow_Material.uasset b/Content/_Game/Materials/SMGMaterials/F_SMG_Glow_Material.uasset new file mode 100644 index 00000000..801bfc91 --- /dev/null +++ b/Content/_Game/Materials/SMGMaterials/F_SMG_Glow_Material.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b54361603d18c032bef8612271043ceab49cd69c672a5e70b950f9fd01a48c22 +size 22614 diff --git a/Content/_Game/Materials/SMGMaterials/M_SMG_Mat.uasset b/Content/_Game/Materials/SMGMaterials/M_SMG_Mat.uasset new file mode 100644 index 00000000..8ceb68dc --- /dev/null +++ b/Content/_Game/Materials/SMGMaterials/M_SMG_Mat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e65d7852ec8f76d883bf7179b1da8b48c677d304dc4d34d664fba805889454b9 +size 16244 diff --git a/Content/_Game/Materials/SMGMaterials/M_SMG_Mat_Inst.uasset b/Content/_Game/Materials/SMGMaterials/M_SMG_Mat_Inst.uasset new file mode 100644 index 00000000..b1c08a44 --- /dev/null +++ b/Content/_Game/Materials/SMGMaterials/M_SMG_Mat_Inst.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:392bedc57eb696120a1420760af330afba45c5bfabf82bb84cd02797a398d46c +size 23085 diff --git a/Content/_Game/Weapons/BaseWeapon/BaseWeaponBP.uasset b/Content/_Game/Weapons/BaseWeapon/BaseWeaponBP.uasset index d02ff3fd..3e2c3723 100644 --- a/Content/_Game/Weapons/BaseWeapon/BaseWeaponBP.uasset +++ b/Content/_Game/Weapons/BaseWeapon/BaseWeaponBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad04d53929dbdf1f5246beeb58b5ac1649feaeaaeef5f6ac1d859f7915d44856 -size 51672 +oid sha256:1ea69c8a68479d7792f1b2e75405aac7d620901a5a8a073a0bea58fcb03d4dd0 +size 53632 diff --git a/Source/Shooter/Ammo.cpp b/Source/Shooter/Ammo.cpp index a4cfbd30..6685664e 100644 --- a/Source/Shooter/Ammo.cpp +++ b/Source/Shooter/Ammo.cpp @@ -88,3 +88,13 @@ void AAmmo::OnAmmoSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor } } } + +void AAmmo::EnableCustomDepth() +{ + AmmoMesh->SetRenderCustomDepth(true); +} + +void AAmmo::DisableCustomDepth() +{ + AmmoMesh->SetRenderCustomDepth(false); +} diff --git a/Source/Shooter/Ammo.h b/Source/Shooter/Ammo.h index 26ae12e1..26d3a8e5 100644 --- a/Source/Shooter/Ammo.h +++ b/Source/Shooter/Ammo.h @@ -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; }; diff --git a/Source/Shooter/Item.cpp b/Source/Shooter/Item.cpp index 0425ba32..fdc20b52 100644 --- a/Source/Shooter/Item.cpp +++ b/Source/Shooter/Item.cpp @@ -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(); } diff --git a/Source/Shooter/Item.h b/Source/Shooter/Item.h index 6ddeea55..256242a6 100644 --- a/Source/Shooter/Item.h +++ b/Source/Shooter/Item.h @@ -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(); }; diff --git a/Source/Shooter/ShooterCharacter.cpp b/Source/Shooter/ShooterCharacter.cpp index c95715f0..f93df1b2 100644 --- a/Source/Shooter/ShooterCharacter.cpp +++ b/Source/Shooter/ShooterCharacter.cpp @@ -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(); } } diff --git a/Source/Shooter/Weapon.cpp b/Source/Shooter/Weapon.cpp index ba39ed85..418ebd21 100644 --- a/Source/Shooter/Weapon.cpp +++ b/Source/Shooter/Weapon.cpp @@ -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(); }