Hello,
I recently began an Unreal Engine project for a class and part of the tasking was to create a paintball-like splatter effect when firing the projectile. So, I followed the steps provided in our tutorial but experienced two different (but possibly same root cause) crashes.
To start, we were tasked with creating a new material. To this material, we needed to add a 2x2 Splatter texture as a TGA file, connect it to a SubUV_Function and use a Constant2Vector attached to the SubImages(V2) node to define the 2x2 grid that these textures would be pulled from. We would create a Scalar Parameter named Frame to tie into the Frame(S) Node. Then, the alpha from the SubUV_Function would get tied into the Opacity from the Material. For this to happen, we had to ensure that the Material Blend Mode was set to Translucent. So far, so good.
Next, we had to create a Constant3Vector that we would convert into a Parameter and name āColorā, change this to something like Red that would be visible, and tie it into Base Color. As soon as I did this it would crash with the following error stack:
UnrealEditor_FPSGAM415_patch_0!AFPSGAM415Projectile::OnHit() [C:***Source\FPSGAM415\FPSGAM415Projectile.cpp:61]
UnrealEditor_FPSGAM415_patch_0!AFPSGAM415Projectile::execOnHit() [C:***Intermediate\Build\Win64\UnrealEditor\Inc\FPSGAM415\UHT\FPSGAM415Projectile.gen.cpp:102]
UnrealEditor_CoreUObject
UnrealEditor_CoreUObject
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Core
UnrealEditor_Core
UnrealEditor_Core
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
kernel32
ntdll
After this, I made a little bit more progress by continuing the tutorial which instructs us to Change the Material Domain to Deferred Decal. Doing this made it so that tying in the āColorā Parameter no longer caused the crash, so I continued to work.
Next up, we were instructed to go to the C++ Classes and modify the Projectile class to spawn the decal and randomize the color and frame with every impact, in essence creating a splatter effect.
As soon as the class was saved, it was supposed to be usable. Instead, as soon as I loaded into the play preview, I could run around but as soon as I shot the gun, Unreal would crash on impact of the projectile, right when it should be running all the functions for the decal and color changes.
For reference, here are the new lines of code:
Projectile.h (I tried to just put a screenshot of the code for ease of reading, but that would exceed my attachments limit, so hereās the full thing)
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FPSGAM415Projectile.generated.h"
class USphereComponent;
class UProjectileMovementComponent;
UCLASS(config=Game)
class AFPSGAM415Projectile : public AActor
{
GENERATED_BODY()
/** Sphere collision component */
UPROPERTY(VisibleDefaultsOnly, Category=Projectile)
USphereComponent* CollisionComp;
/** Projectile movement component */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = "true"))
UProjectileMovementComponent* ProjectileMovement;
UPROPERTY(EditAnywhere)
UStaticMeshComponent* ballMesh;
UPROPERTY(EditAnywhere)
UMaterial* baseMat;
public:
AFPSGAM415Projectile();
/** called when projectile hits something */
UFUNCTION()
void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
/** Returns CollisionComp subobject **/
USphereComponent* GetCollisionComp() const { return CollisionComp; }
/** Returns ProjectileMovement subobject **/
UProjectileMovementComponent* GetProjectileMovement() const { return ProjectileMovement; }
};
Projectile.cpp
#include "FPSGAM415Projectile.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Components/SphereComponent.h"
#include "Components/DecalComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/GameplayStatics.h"
AFPSGAM415Projectile::AFPSGAM415Projectile()
{
// Use a sphere as a simple collision representation
CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
CollisionComp->InitSphereRadius(5.0f);
CollisionComp->BodyInstance.SetCollisionProfileName("Projectile");
CollisionComp->OnComponentHit.AddDynamic(this, &AFPSGAM415Projectile::OnHit); // set up a notification for when this component hits something blocking
// Players can't walk on it
CollisionComp->SetWalkableSlopeOverride(FWalkableSlopeOverride(WalkableSlope_Unwalkable, 0.f));
CollisionComp->CanCharacterStepUpOn = ECB_No;
ballMesh = CreateDefaultSubobject<UStaticMeshComponent>("Ball Mesh");
// Set as root component
RootComponent = CollisionComp;
ballMesh->SetupAttachment(CollisionComp);
// Use a ProjectileMovementComponent to govern this projectile's movement
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
ProjectileMovement->UpdatedComponent = CollisionComp;
ProjectileMovement->InitialSpeed = 3000.f;
ProjectileMovement->MaxSpeed = 3000.f;
ProjectileMovement->bRotationFollowsVelocity = true;
ProjectileMovement->bShouldBounce = true;
// Die after 3 seconds by default
InitialLifeSpan = 3.0f;
}
void AFPSGAM415Projectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
// Only add impulse and destroy projectile if we hit a physics
if ((OtherActor != nullptr) && (OtherActor != this) && (OtherComp != nullptr) && OtherComp->IsSimulatingPhysics())
{
OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation());
Destroy();
}
if (OtherActor != nullptr)
{
float ranNumX = UKismetMathLibrary::RandomFloatInRange(0.f, 1.f);
float ranNumY = UKismetMathLibrary::RandomFloatInRange(0.f, 1.f);
float ranNumZ = UKismetMathLibrary::RandomFloatInRange(0.f, 1.f);
float frameNum = UKismetMathLibrary::RandomFloatInRange(0.f, 1.f);
FVector4 randColor = FVector4(ranNumX, ranNumY, ranNumZ, 1.f);
auto Decal = UGameplayStatics::SpawnDecalAtLocation(GetWorld(), baseMat, FVector(UKismetMathLibrary::RandomFloatInRange(20.f, 40.f)), Hit.Location, Hit.Normal.Rotation(), 0.f);
auto MatInstance = Decal->CreateDynamicMaterialInstance();
MatInstance->SetVectorParameterValue("Color", randColor);
MatInstance->SetScalarParameterValue("Frame", frameNum);
}
}
Iām sure this is something I am messing up, but Ive gone back through multiple times to recreate the project, following the tutorial, with the same results, and crashes in the same places.