Dungeon Escape

The gargoyle is taken off it’s pedestal.

The dungeon escape game is a tech demonstration of creating a Grabber Component for the Pawn/Player. It also demonstrates the use of Unreal’s “Mass” to activate Trigger Events such as rotating, opening and closing doors using Unreal Engine’s C++ Components. In order to escape the dungeon, the player has to place the required objects in the trigger volume to open the door in order for the player to exit the level.

void UGrabber::SetupInputComponent()
{
	InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();

	if (InputComponent)
	{
		InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
		InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
	}
}

The grab key is binded to the right-mouse button.

FVector UGrabber::GetPlayersReach() const
{
	FVector PlayerViewpointLocation;
	FRotator PlayerViewpointRotation;

	GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(OUT PlayerViewpointLocation, OUT PlayerViewpointRotation);

	return PlayerViewpointLocation + (PlayerViewpointRotation.Vector() * Reach);
}
FHitResult UGrabber::GetFirstPhysicsBodyInReach() const
{
	FHitResult Hit;
	//Ray cast out to a certain distance (Reach)
	FCollisionQueryParams TraceParams(FName(TEXT("")), false, GetOwner());
	
	GetWorld()->LineTraceSingleByObjectType
	(
		OUT Hit,
		GetPlayersWorldPos(),
		GetPlayersReach(),
		FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
		TraceParams
	);
	return Hit;
}

Line Trace from the player to the first physics body.

void UGrabber::Grab()
{
	UE_LOG(LogTemp, Warning, TEXT("Grabber pressed"));
	
	FHitResult HitResult = GetFirstPhysicsBodyInReach();
	UPrimitiveComponent* ComponentToGrab = HitResult.GetComponent(); 
	AActor* ActorHit = HitResult.GetActor();
	
	//If we hit something then attach the physics handle.
	if (ActorHit)
	{	if (!PhysicsHandle){return;}
	
		PhysicsHandle->GrabComponentAtLocation
		(	ComponentToGrab,
			NAME_None,
			GetPlayersReach()
		);
	}
}

Grab function by attaching a physics handle.

float UOpenDoor::TotalMassOfActors() const
{
	float TotalMass = 0.f;

	//Find All Overlapping Actors.
	TArray<AActor*> OverlappingActors;
	if (!PressurePlate) {return TotalMass;}
	PressurePlate->GetOverlappingActors(OUT OverlappingActors);

	//Add Up Their Masses.
	for (AActor* Actor : OverlappingActors)
	{
		TotalMass+= Actor->FindComponentByClass<UPrimitiveComponent>()->GetMass();
	}
	return TotalMass;
}

Finding Total Mass of Actors in Trigger Volume.

void UOpenDoor::OpenDoor(float DeltaTime)
{
	CurrentYaw = FMath::FInterpTo(CurrentYaw, OpenAngle, DeltaTime, DoorOpenSpeed);
	FRotator DoorRotation = GetOwner()->GetActorRotation();
	DoorRotation.Yaw = CurrentYaw;
	GetOwner()->SetActorRotation(DoorRotation);

	CloseDoorSound = false;
	if (!AudioComponent) {return;}
	if (!OpenDoorSound)
	{
		AudioComponent->Play();
		OpenDoorSound = true;
	}
}

The door opens when the trigger volume’s mass parameters are met and closes/remains shut when they are not met.

Leave a comment

Design a site like this with WordPress.com
Get started