Advanced D&D (Doors and Drawers)

Advanced D&D (Doors and Drawers)

One of my all time favorite games is Amnesia: The Dark Descent, which is not really surprising coming from someone working on a first person horror game.   I could go on and on about that game and all of the great design choices it made to really pull the player into its world. I could… but I won’t. What I will talk about though is the way that game forces the player to manually interact with its world. In most games when the player is presented with a openable container, the act of opening it is either triggered by running into it or by simply pressing a button. In Amnesia though, it’s done by first grabbing the door with a click and then slowly moving the mouse to move the door.  It’s a very small change that I found really drew me into the game. The player is forced to use his/her hand to actually do the work of opening doors and drawers. It allows cases where you partially open a door to peek at a monster and helps maintain player immersion.

I decided to implement a similar system in MMN. I looked around for a good tutorial to implement this system but being as picky as I am, I managed to find something I didn’t like about each one of them. So once I figured out how to get it working, I decided to write my own.

 


How to implement a physics-based door and drawer system


 

Note: First of all, let me give fair warning that all the screens in this post come directly from MMN and thus may contain code that is unnecessary for this example. I’ll do my best to explain the important parts and cut out the unnecessary ones.

ScreenShot00025

The best way to implement a system like this is to think about the real world counterpart. If I want to open a door/drawer my first step is to look at the door/drawer, my second step is to grab the door/drawer, my third step is to apply a force to the door/drawer and my last step is to let go of the door/drawer. So those four sections of code for interacting with the door plus the initial door setup makes only 5 small steps toward implementing the system. Simple right? Let’s look at each of them individually.

Note: I’m sick of writing door/drawer so from now on doors and drawers will be referred to as D&D. I hope this doesn’t cause any confusion.

Step #1 – D&D Setup:

First of all we want these D&Ds to act as realistically as possible, which means we don’t want them running pre-canned animations. We want them to be physics-based, which means we’ll enable physics on the parts of the mesh we want to move. Once you’ve done that, you’ll notice immediately how your door just fell over and your drawer fell out of its shelf. That’s because while we want some forces to be able to manipulate these objects, we don’t want all of them to. We need to constrain the way these things can physically move and to do that we use a Physics Constraint (RTFM).

Physics constraints are pretty simple. You just give them a component and a set of rules, and they make sure the component doesn’t break those rules. For the door I used a physics constraint like a set of hinges. I’ve seen a lot of people use two but I’ve found only one is necessary. Just put it on the door in line with where hinges would go and set the component name to the name of the mesh you want to move.DoorPhysicsConstraint

For doors the physics constraint is pretty straight forward. You want to only allow rotational movement around the z-axis so the settings look something like this.

DoorSwingPhysicsConstraint

The drawer on the other hand moves laterally so I set my physics component in the direct middle of the drawer and gave it limited linear movement. Dialing in the linear limit is unfortunately  just an exercise or trial and error.

DrawerPhysicsConstraint

One more thing that I chose to do to each of these was to tag the mesh I wanted to be able to move as “slidable”.

DrawerTags

Step #2 – Looking at the D&D:

Note: All code below this point is on the player character class.

So I’m not going into the look control code for MMN. It’s pretty much just the out-of-the-box FPS blueprint that comes with Unreal, but when a player tries to interact with the world I need to know what they are looking at. I’m always very cautious about putting any code in an update event because it gets called constantly, but Milo’s UI updates depending on what he’s looking at. So the following code runs in my game every tick but if you don’t need the information all the time it would be much more efficient to move it to the mouse click event before executing the code in step three.

UpdateInteractionTarget_Whole

So this is my entire update code. I’ll walk you through it bit by bit. A lot of it is only necessary for MMN’s UI, but the main idea is I’m seeing where the player is looking, checking to see if what they are looking at is important, and if it is I’m storing it.

It all starts with a simple line trace. I just take the camera, draw a line from it to some arbitrary distance and see if I hit anything of interest.

LineTrace

 Note: The values it’s storing at the end (with the exception of hit location) are local and temporary. I have an actual variable I plan to store the values in but I only want to do that if I’m sure these values are important/valid.

You may notice a strange node called “GetStaticMeshParent”. I’ve found it easiest to put a box collider as a child of the mesh I’m attempting to move to get the line trace hit. “GetStaticMeshParent” is a function I wrote that takes the collider and returns its parent wich is really the component that I’m after. I’ve included it below.

GetStaticMeshParent

Now that I’ve done the trace I need to see if I hit anything. If not, I should clear all the values from the last time I ran this method. If I did, I should check to see if what I hit was the same thing I hit last time (if it is I don’t need to update because all the values are already stored).

ValuesValid

Now I check to see if what I hit has all the proper tags and interfaces.

PropperTagsAndInterfaces

Note: The interface check here is for updating UIs – probably not necessary for your code.

Note part 2: “Does this an Interactable actor?”… sorry… I didn’t proofread that comment before I took the screenshot. It’s supposed to say “Is that an interactable actor and does the component have the proper tags?”

If it passed all those tests, I store the values. Ignore the execution lines that go out of frame.

update

 

Step #3 – Grabbing the D&D:

So now the D&D’s are set up, and we know what we want to grab. Next all we need to do is grab it. To grab we’re going to use a Physics Handle (RTFM). The physics handle allows us to move an object through space, in this case a D&D. It’s a component attached to my Player Character.  I initialize my D&D grab with a left mouse down but you can bind this to any event.

InitSlide

Note: The “Hide Hand” code here should be ignored.

Here I grabbed the component we stored earlier at the location we stored earlier using the Physics Handle component on my character.

 

Step #4 – Applying a force to the D&D:

Applying force needs to be done directly in proportion to the mouse movement, so it’s best to bind it to that event. Notice that I prevent mouse information from changing look direction while I’m sliding something.

SlideMouseInput

The actual slide code is pretty simple. I just take my Physics Handle and move its target along the forward vector from the camera component.

UpdateSlide

Step #5 – Letting go of the D&D:

To release the D&D just call “Release Component” on your Physics Handle….. In retrospect I’m not sure that one needed a whole bullet point.

 

 

Anyway I hope that helps. If you have any questions feel free to leave a comment and I’ll do my best to answer it.

 

 


17 thoughts on “Advanced D&D (Doors and Drawers)”

  • 1
    chemicalbear on March 22, 2016 Reply

    Hi there, great post. i’ve been figuring out how to do this for a while. It looks like you have the system fully working but i can’t see the nodes in the first image because the resolution is too bad. I therefore can’t see the beginning of the blueprint structure. I’m fairly new to using blueprint so a larger image to follow or along with or a more detailed explanation would be very appreciated.

    Thanks

    • 2
      ciszekrm on March 22, 2016 Reply

      Hey sorry for any confusion. That first big blueprint screenshot is only there to give you an idea what the whole system kind of looks like. All the other blue print pictures in part 2 are just zoomed in sections of that first picture. Unfortunately its difficult to take a screenshot that’s both detailed enough to show the nodes and big enough to show the entire blueprint. If you’re still having trouble I can take another look at it.

  • 3
    desotel on March 30, 2016 Reply

    Is it possible to do a video tutorial, I’m having trouble creating return nodes and get static mesh parent. is this for the door BP or would it be first person character?

    • 4
      ciszekrm on March 30, 2016 Reply

      “Is it possible to do a video tutorial” – hopefully. It’s already on my to do list but that list is pretty long. The fact that there seems to be some interest gets it moved up a bit though.

      “is this for the door BP or would it be first person character?” – All steps except #1 are on the player character.

      • 5
        desotel on March 30, 2016 Reply

        Okay, thanks, I see it now. I know it be a long tutorial, but hey, it’ll help a lot of people I can’t find a single tutorial about recreating the amnesia Door you’d probably be one of the first to do it. 😀

        • 6
          ciszekrm on March 30, 2016 Reply

          There are a couple of video tutorials out there already for it but the ones I’ve seen tackle it a bit differently. I find this method to be more intuitive to feel a bit smoother in the end for the player.

          • 7
            James Pitt on June 3, 2016

            I totally agree, I’d love to see a video tutorial!

  • 8
    dawars00 on August 18, 2016 Reply

    Thanks for the tutorial, based on it I managed to accomplis this in VR
    https://www.instagram.com/p/BJQF7kThlcQ/

    • 9
      The Undead Dev on August 18, 2016 Reply

      Awesome! I’m glad this helped! Thanks for leaving a reply. It’s really nice to know when posts are appreciated.

  • 10
    Okan Murat Tutay on March 14, 2017 Reply

    there is not “clear interaction taget” function opening ! Please show it

    • 11
      The Undead Dev on March 17, 2017 Reply

      Hey sorry for the missing image. The “Clear Interaction Target” is a custom function that just clears values of the variables I was using. I’ll try to take a screenshot of it when I get a chance.

  • 12
    Vincent on March 16, 2017 Reply

    Hi, thank you for the tutorial but same problem as Okan Murat Tutay for me. I can’t find the “Clear Interaction Target neither the BP Milo ??? Otherwise it seems to be a great tutorial Thank you in advance

    • 13
      The Undead Dev on March 17, 2017 Reply

      Hey sorry for the missing image. The “Clear Interaction Target” is a custom function that just clears values of the variables I was using. I’ll try to take a screenshot of it when I get a chance.

      • 14
        Vincent on March 22, 2017 Reply

        Thank you for your answer ! I would really enjoy a screenshot so thanks a lot !

  • 15
    fuuuuzzzzyVlatko on March 29, 2017 Reply

    Good Job! One of the most helpful tutorials online!
    One request: since there is request for video tutorial of this posted more then a year (it would be very helpful thou! ), is there any way that you can post scene with this blueprint? Some elements are missing and some are unclear at least for me.

    Thanks in advance!

    VLatko

    • 16
      The Undead Dev on March 30, 2017 Reply

      Hey, thanks for comment! Yeah there is a lot I’d really like to do with this as seeing that it’s unexpectedly become the single most popular thing I’ve ever written. I might even be down to post cleaned up source code. Unfortunately right now I’ve got zero free time due to a lot of things going on in my personal life. If/when that stuff clears up though I’d really like to come back to writing this blog and adding to this post will be high priority.

    • 17
      Michael Sabates on May 19, 2017 Reply

      I agree. There seems to be missing elements that I just can’t seem to figure out.

Comment on this post!