• Advertisement
Sign in to follow this  

Trap and Puzzle for a Dungeon Crawler

Recommended Posts

Hello!

As part of my university course I have been working on a trap and a puzzle to be used in a dungeon crawler style game.

Trap

My initial thought for a trap is something that falls from the ceiling to damage the player, this can then be tailored to suit nearly any kind of map. Anything underground could have rocks and dirt, an ice cave could have falling icicles and a rocky cave could have stalactites.

The first thing for me to consider is how to convey that this trap has been triggered and that something is about to fall on the player, for this I took inspiration from the MMO’s Final Fantasy XIV and Wildstar.

These games both make heavy use of telegraphs as it is extremely important for the player to be aware of the mechanics during difficult encounters, these telegraphs are very visual and show the player exactly which parts of the area will be affected.

giphy.gif

I have decided to use this approach and create a circular telegraph to be projected onto the ground as the player triggers the trap, over time this will fill up red and once its filled the rock will reach the ground damaging anything beneath it.

The GIF below shows my work to emulate the telegraph.

giphy.gif

Rather than create the effect of the telegraph filling up with a timeline I have instead chosen to use an interp function in the trap blueprint. This will allow me to easily set the speed for tweaking and testing, however I may look at switching to a timeline later on if it proves to be the better option.

The next aspect to think about is the falling boulder, for now I have created a simple rock shape in 3ds max to use. Because of the speed of the falling boulder the player will not be able to see it properly, this means the boulder can be very simple and low poly. I have also added a sound effect and a particle effect for when the boulder hits to give the player some visual feedback that this trap is dangerous. These are currently just stock effects and sounds, but I can look into finding some more unique assets later that may make the trap feel more polished.

Below is a GIF showing the finished trap prototype, all of this can be tweaked and modified easily enough if I find I need to later on.

giphy.gif

 

Puzzle

 The puzzle is fairly straight forward, the player has to activate a number of platforms in the correct order to create a path. The platforms are activated using a bank of switches, with each switch corresponding to a platform. However when ever you activate a platform it will also activate any platform near it, meaning the player will have to plan a solution carefuly.

This puzzle can be scaled up and down by adding and removing the amount of platforms involved, or perhaps even extending the line into a grid of platforms.

My thoughts for introducing the player to this puzzle would involve using single platforms early on to reinforce the idea that these switches will activate platforms.

The Gif below shows the puzzle prototype in action, I have also taken care to lock the switches when any of the platforms are in motion to prevent potential bugs that may occur from too many switches being thrown at once.

giphy.gif

Thanks for reading my post! If you have any feedback on ways I can improve these projects then i would love to hear.

Thanks again!

Share this post


Link to post
Share on other sites
Advertisement

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By austin blaschke
      My Name is Austin Blaschke,
      Dear Everyone, I'm starting a big project and I need a team to help me with it. I'm mainly doing this for a full pitch purpose but also to make something valuable for the community. You will not be paid but if any of the projects makes a profit, it will be split equally among all members after we pitch the game. I'm looking for people who enjoy what they are doing and are willing to improve their skills and learn from their mistakes. I need anyone from music/sound production to game designers to code writers to visual designers and the whole yard. You do not need to be a professional and also no age limits are set but if possible i would like skilled investors to make this amazing. I'm not going to be doing this a 100% of the time because of educational purposes (College). I will be on every day, for around 2/3 hours but that doesn't mean that the whole operation is stopped. The development can still continue even without my presence.
      Im looking for a group of people that work well together and can work with anyone on this project looking for anyone. 
      Msg me at ablaschke99@gmail.com or join this discord server https://discord.gg/snhBvwF
    • By Martin H Hollstein
      Originally posted on Troll Purse development blog.
      Unreal Engine 4 is an awesome game engine and the Editor is just as good. There are a lot of built in tools for a game (especially shooters) and some excellent tutorials out there for it. So, here is one more. Today the topic to discuss is different methods to program player world interaction in Unreal Engine 4 in C++. While the context is specific to UE4, it can also easily translate to any game with a similar architecture.
      Interaction via Overlaps
      By and far, the most common tutorials for player-world interaction is to use Trigger Volumes or Trigger Actors. This makes sense, it is a decoupled way to set up interaction and leverages most of the work using classes already provided by the engine. Here is a simple example where the overlap code is used to interact with the player:
      Header
      // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "InteractiveActor.generated.h" UCLASS() class GAME_API InteractiveActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties InteractiveActor(); virtual void BeginPlay() override; protected: UFUNCTION() virtual void OnInteractionTriggerBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); UFUNCTION() virtual void OnInteractionTriggerEndOverlap(UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); UFUNCTION() virtual void OnPlayerInputActionReceived(); UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Interaction) class UBoxComponent* InteractionTrigger; } This is a small header file for a simple base Actor class that can handle overlap events and a single input action. From here, one can start building up the various entities within a game that will respond to player input. For this to work, the player pawn or character will have to overlap with the InteractionTrigger component. This will then put the InteractiveActor into the input stack for that specific player. The player will then trigger the input action (via a keyboard key press for example), and then the code in OnPlayerInputActionReceived will execute. Here is a layout of the executing code.
      Source
      // Fill out your copyright notice in the Description page of Project Settings. #include "InteractiveActor.h" #include "Components/BoxComponent.h" // Sets default values AInteractiveActor::AInteractiveActor() { PrimaryActorTick.bCanEverTick = true; RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root")); RootComponent->SetMobility(EComponentMobility::Static); InteractionTrigger = CreateDefaultSubobject<UBoxComponent>(TEXT("Interaction Trigger")); InteractionTrigger->InitBoxExtent(FVector(128, 128, 128)); InteractionTrigger->SetMobility(EComponentMobility::Static); InteractionTrigger->OnComponentBeginOverlap.AddUniqueDynamic(this, &ABTPEquipment::OnInteractionProxyBeginOverlap); InteractionTrigger->OnComponentEndOverlap.AddUniqueDynamic(this, &ABTPEquipment::OnInteractionProxyEndOverlap); InteractionTrigger->SetupAttachment(RootComponent); } void AInteractiveActor::BeginPlay() { if(InputComponent == nullptr) { InputComponent = ConstructObject<UInputComponent>(UInputComponent::StaticClass(), this, "Input Component"); InputComponent->bBlockInput = bBlockInput; } InputComponent->BindAction("Interact", EInputEvent::IE_Pressed, this, &AInteractiveActor::OnPlayerInputActionReceived); } void AInteractiveActor::OnPlayerInputActionReceived() { //this is where logic for the actor when it receives input will be execute. You could add something as simple as a log message to test it out. } void AInteractiveActor::OnInteractionProxyBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { if (OtherActor) { AController* Controller = OtherActor->GetController(); if(Controller) { APlayerController* PC = Cast<APlayerController>(Controller); if(PC) { EnableInput(PC); } } } } void AInteractiveActor::OnInteractionProxyEndOverlap(UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) { if (OtherActor) { AController* Controller = OtherActor->GetController(); if(Controller) { APlayerController* PC = Cast<APlayerController>(Controller); if(PC) { DisableInput(PC); } } } }  
      Pros and Cons
      The positives of the collision volume approach is the ease at which the code is implemented and the strong decoupling from the rest of the game logic. The negatives to this approach is that interaction becomes broad when considering the game space as well as the introduction to a new interactive volume for each interactive within the scene.
      Interaction via Raytrace
      Another popular method is to use the look at viewpoint of the player to ray trace for any interactive world items for the player to interact with. This method usually relies on inheritance for handling player interaction within the interactive object class. This method eliminates the need for another collision volume for item usage and allows for more precise interaction targeting.
      Source
      AInteractiveActor.h
      // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "InteractiveActor.generated.h" UCLASS() class GAME_API AInteractiveActor : public AActor { GENERATED_BODY() public: virtual OnReceiveInteraction(class APlayerController* PC); }  
      AMyPlayerController.h
      // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/PlayerController.h" #include "AMyPlayerController.generated.h" UCLASS() class GAME_API AMyPlayerController : public APlayerController { GENERATED_BODY() AMyPlayerController(); public: virtual void SetupInputComponent() override; float MaxRayTraceDistance; private: AInteractiveActor* GetInteractiveByCast(); void OnCastInput(); }  
      These header files define the functions minimally needed to setup raycast interaction. Also note that there are two files here as two classes would need modification to support input. This is more work that the first method shown that uses trigger volumes. However, all input binding is now constrained to the single ACharacter class or - if you designed it differently - the APlayerController class. Here, the latter was used.
      The logic flow is straight forward. A player can point the center of the screen towards an object (Ideally a HUD crosshair aids in the coordination) and press the desired input button bound to Interact. From here, the function OnCastInput() is executed. It will invoke GetInteractiveByCast() returning either the first camera ray cast collision or nullptr if there are no collisions. Finally, the AInteractiveActor::OnReceiveInteraction(APlayerController*)  function is invoked. That final function is where inherited classes will implement interaction specific code.
      The simple execution of the code is as follows in the class definitions.
      AInteractiveActor.cpp
      void AInteractiveActor::OnReceiveInteraction(APlayerController* PC) { //nothing in the base class (unless there is logic ALL interactive actors will execute, such as cosmetics (i.e. sounds, particle effects, etc.)) }  
      AMyPlayerController.cpp
      AMyPlayerController::AMyPlayerController() { MaxRayTraceDistance = 1000.0f; } AMyPlayerController::SetupInputComponent() { Super::SetupInputComponent(); InputComponent->BindAction("Interact", EInputEvent::IE_Pressed, this, &AInteractiveActor::OnCastInput); } void AMyPlayerController::OnCastInput() { AInteractiveActor* Interactive = GetInteractiveByCast(); if(Interactive != nullptr) { Interactive->OnReceiveInteraction(this); } else { return; } } AInteractiveActor* AMyPlayerController::GetInteractiveByCast() { FVector CameraLocation; FRotator CameraRotation; GetPlayerViewPoint(CameraLocation, CameraRotation); FVector TraceEnd = CameraLocation + (CameraRotation.Vector() * MaxRayTraceDistance); FCollisionQueryParams TraceParams(TEXT("RayTrace"), true, GetPawn()); TraceParams.bTraceAsyncScene = true; FHitResult Hit(ForceInit); GetWorld()->LineTraceSingleByChannel(Hit, CameraLocation, TraceEnd, ECC_Visibility, TraceParams); AActor* HitActor = Hit.GetActor(); if(HitActor != nullptr) { return Cast<AInteractiveActor>(HitActor); } else { return nullptr; } }  
      Pros and Cons
      One pro for this method is the control of input stays in the player controller and implementation of input actions is still owned by the Actor that receives the input. Some cons are that the interaction can be fired as many times as a player clicks and does not repeatedly detect interactive state without a refactor using a Tick function override.
      Conclusion
      There are many methods to player-world interaction within a game world. In regards to creating Actors within Unreal Engine 4 that allow for player interaction, two of these potential methods are collision volume overlaps and ray tracing from the player controller. There are several other methods discussed out there that could also be used. Hopefully, the two implementations presented help you decide on how to go about player-world interaction within your game. Cheers!
       
       
      Originally posted on Troll Purse development blog.
    • By AireSpringfield
      Hi, I'm currently studying physically based shading in UE4 described in Real Shading in Unreal Engine 4. 
      In the notes, the Material has 4 basic properties: BaseColor, Metallic, Roughness and Cavity.
      Here is their BRDF model in use:


      The use of roughness is clearly clarified, and I guess BaseColor is referred as \(c_{diff}\)c_diff in the diffuse component. Then  anyone knows how Metallic and Cavity is implemented in UE4? Exact fragments in the source code of the engine would be the best. Thanks a lot!!
    • By tgobbens
      Introduction 
      The architecture of software design is a much-debated subject. Every developer has his own opinion about what is good software design and what is not. Most developers agree on what is bad design, on what is good design there are a wide variety of opinions. Unfortunately, due to the nature of software development, there is no silver bullet; there is no one design strategy that always works.
      There are a couple of strategies that have proofed to be successful. These strategies have known strengths and weaknesses. The advantage of using such a strategy is allowing you to focus on building your game, instead of worrying if your codebase will implode after someone decided the game should function a bit different than how the code was originally written.
      Architecture
      In game development, the entity-component-system is an architectural pattern that is used successfully in small, medium and large games. The main strength of this strategy is the usage of the composition over inheritance pattern. This pattern prevents the build-up of complex object inheritance tree’s, that will make your code impossible to refactor without a lot of side-effects.
      So how does this pattern work, at its core, there are three elements; entity, components, and systems guess you didn’t see that coming. Let’s describe these one by one, I’m starting with the smallest and most simple one the “component”:
      Component
       The component represents a single attribute of an entity. Some examples of entities can be:
      Position Rotation Scale Physics body Texture Health Entity
       Entities are the “game-object” some examples:
      Ball Camera Player Enemy Bullet An entity can have multiple components, for example, a ball entity can have the following components: position, rotation, scale, texture and physics body. A camera entity might only have a position. Usually, all entities have a unique-id for fast access, but there can also be other ways of accessing entities.
      System
      The system is responsible for one aspect of the game, a simple game has can, for example, have the following systems:
      Rendering Physics GUI Sound AI What a system does is iterating over all entities that have components of the types defined by the system. For example, the physics system will act only on entities with a physics-component and a position-component. The rendering system will only act on entities that have a position and texture component. 
      For example, if a ball entity has a position and physics and texture component. The physics system will pick up the ball entity, as it has a physics and position component. The physics-system control a physics-engine, that will do its magic and calculate a new position for the ball. The physics system will set this new position on the position component.
      The rendering-system will also pick up the ball entity, as it acts on all entities that have a position and a texture component. The rendering system can render the ball using the texture and the position found with the ball entity (yes, the same component that was just updated by the physics-system).
      Now imagine you spend some time implementing the architecture described above, and you after, running it, realize the ball is not really moving very realistic. That might be because you forgot to take rotation into account.
      To fix it you now only have to create a rotation-component and add it to the ball entity. Now add in the physics system a check if the entity has a rotation component and if so just set the rotation on this component. In the rendering-system also add some code to check if there is a rotation component and if so render with this rotation.
      This is where the power of this architecture emerges, imagine you have not one ball entity but have a lot of entities like the ball, wall, player, ground, etc. and you forgot about the rotation. You only have to modify the rendering system and the physics system. Then by simple adding a rotation component to the entities you want to have rotation on, magically all those objects have a rotation. Now adding rotation seems like a trivial thing to do, but what does this architecture enforces is the separation of concerns (e.g. rendering and physics) while still allows adding new functionality. And important; It does this without the usage of inheritance but rather by composition.
      Possible features
      The architecture described above is in itself quite powerful. But there are some more interesting possibilities with this architecture. I will describe some of them below.
      Game-mechanic tweaking
      Creating a generic mechanic-tuning-utilities; as there are a limit number of component types, you can create a (developer) GUI-overlay that allows you to modify the values of a component. This will allow you to in real-time modify the values, e.g. the position, size, texture, acceleration, the weight of a certain entity his components. This will help you tremendously in fine-tuning game mechanics without the need to keep recompiling and reloading your game.
      Level-editor
      Taking this even a step further you could use the above system to load all entities and relevant components from a file, e.g. XML. This will also help you decrease compile and loading time, letting you focus more one tuning game mechanics. This could then be a very good start for creating a level-editor, letting a none technical team member (game-designers) tweak game mechanics.
      Dynamic loading
      Something else that can be managed using this system, is implementing an entity loading/unloading mechanism. You can define an interface with functions like initializing, loading, starting, stopping, unloading, destructing. Now you can implement a loading mechanism that guarantees the loading and initializing always happen asynchronously. This will allow you to load and unload entities in a uniform and controlled manner. You could also choose to run all the systems in a different thread you need to take some more care about modifying components, but this could allow you to do a lot of performance enhancements, as for example, the AI needs less frequent updates then a renderer.
      Real-world example
      Note this implementation is done in Java, as I’m using libGDX as the platform, but the architecture is certainly not limited to Java and can also be implemented in other languages like C++.
      Enough of the theory, now for a real implementation. As a hobby project, I have been creating a small iOS/Android game, my first implementation of this game was naïve, with one source file containing all logic. No need to explain this is a bad implementation, but this did allow me to check if my idea was fun and create a quick prototype and do some fast iterations from there.
      For reference, the “bad” implementation can still be found here:  https://github.com/tgobbens/fluffybalance/blob/master/core/src/com/balanceball/Balanceball.java  
      After I created this implementation I decided I wanted to implement the same game using a better manageable implementation.
      The “main” entry file can be found here: https://github.com/tgobbens/fluffybalance/blob/master/core/src/com/balanceball/BalanceBallSec.java.
      So, I’ve created my own entity-component-system. If you want to create your own game using an entity-component-system, and want the game to be ready as soon as possible then I wouldn’t recommend writing one yourself. However, if you want to learn about programming or just create something for fun, implementing such a system is easy, and you will learn a lot from doing this. Another reason to implement this yourself is you get a lot of freedom allowing you to add specific tricks and features that can help you improve your codebase.
      The entity component system can be found under https://github.com/tgobbens/fluffybalance/tree/master/core/src/com/sec and yes there are some optimisation and improvements opportunities in this code base. But it does show an easy to understand implementation. When trying to understand make sure you know what Java generic types are. It’s quite common you need to find a certain entity to update or get some info from. As there are a lot of components you know there will be only one instance from. I’ve added a method to get the first entity of a certain type. For example, give me the camera entity, or give me the first “game-world” entity. But there are also helper functions to get all entities of a certain type. The same trick is used for getting components of an entity.
      You will also find a basic type called “engine”, used for binding everything together. This will trigger the updates and holding references to all systems and entities. If you look for a “starting” point for the architecture this is where to start looking.
    • By nihitori
      The Emotional Music Vol. I pack focuses on beautiful and esoteric orchestral music, capable of creating truly emotive and intimate moods. It features detailed chamber strings, cello and piano as the main instruments, resulting in a subtle and elegant sound never before heard in video game royalty-free music assets.

      The pack includes 5 original tracks, as well as a total of 47 loops based on these tracks (long loops for simple use and short loops for custom / complex music layering).

      Unity Asset Store link: https://www.assetstore.unity3d.com/en/#!/content/107032
      Unreal Engine Marketplace link: https://www.unrealengine.com/marketplace/emotional-music-vol-i

      A 15 seconds preview of each main track is available on Soundcloud:
       
  • Advertisement