Always snap to grid

Legacy:Proximity- And Damage-Triggered Doors

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

This tutorial will show you a way to create doors that can open when shot or when a player approaches it. The door will close after some time if no player is near it anymore.

Using this type of door might help a lot when porting Quake maps. It might add a new tactical twist to your map since players now can't rely on the opponent being near a door when it opens. On the other hand, closing doors will not be as harmful for a fire fight anymore because the players can simply shoot it to instantly reopen it, even if the door hasn't finished closing yet.

Prerequisites[edit]

In this tutorial we will be creating a multi-part door. When any of the door parts is hit, the whole door should open, i.e. all parts should start moving at the same time. Unfortunalety, regular movers don't provide the neccessary functionality, so we need to use the custom DamageTriggerMover. Single-part doors with similar functionality are probably possible with a regular Mover as well, but will require a different trigger setup then.

Our door mechanism will consist of:

  • two DamageTriggerMovers as the door parts (You can add more movers to your door, if you like. This trigger/mover system can be extended quite easily.)
  • one Trigger to detect player proximity
  • one TriggeredCondition to store the Trigger's state for...
  • one ScriptedTrigger (1) that closes the door after some time when no player is nearby
  • another ScriptedTrigger (2) that opens the door when a player touches the Trigger

Door Movers[edit]

Place your DamageTriggerMovers like you would place any regular mover. Set their Object -> InitialState to TriggerToggle, match their ReturnGroup -> ReturnGroup names and give them the same MoverEvents -> DamageEvent names. It's probably also a good idea to set their Mover -> MoverEncroachType to ME_CrushWhenEncroach or ME_IgnoreWhenEncroach, so they don't get out of sync when something blocks one of them.

Now you need to decide, which of your movers will be the leader of your door's ReturnGroup. This "leading mover" will receive the events for opening or closing the door. Set its Events -> Tag to the event you want to control the door with. That event will be fired by the ScriptedTriggers and should be unique for each door. You also need to specify an event name in MoverEvents -> OpenedEvent, that will be used by ScriptedTrigger (1) to find out, when to start checking whether the door should close again.

Example of mover properties so far:

Property Leading Mover Other Door Parts
Events -> Tag MyDoor
Mover -> MoverEncroachType ME_CrushWhenEncroach ME_CrushWhenEncroach You could also use ME_IgnoreWhenEncraoch here.
MoverEvents -> DamageEvent MyDoorHit MyDoorHit
MoverEvents -> OpenedEvent MyDoorOpened
Object -> InitialState TriggerToggle TriggerToggle
ReturnGroup -> bIsLeader True False
ReturnGroup -> ReturnGroup MyDoor MyDoor This is not associated with Tags/Events in any way, it's just convenient to use the same name as the leader's Tag.

After setting up the movers as described above, you can playtest your map and the movers will do exactly... nothing.

If your movers activate when you run into them or shoot them, something is wrong! Make sure they are really DamageTriggerMovers and that their initial state really is TriggerToggle.

Door Controls[edit]

Let's add some functionality to the door. The basic door control will be handled by a ScriptedTrigger that opens the door when triggered and closes it again after some time. Player proximity is detected by a Trigger.

Open, Wait, Close[edit]

Add an Actor >> Keypoint >> AIScript >> ScriptedSequence >> ScriptedTrigger. It will control the door movers with a script that works like this:

door is closed or closing
Wait for event MyDoorHit
Trigger event MyDoor (to open the door)
Wait for event MyDoorOpened
door is open
Wait 2 seconds
If player is near door (starts a new subsection)
  Go to "door is open" (to wait a little longer)
End subsection
Trigger event MyDoor (to close the door)
Go to "door is closed or closing"

The lines starting with bold words in the above algorithm can be translated directly into ScriptedActions for ScriptedTrigger (1):

Action Parameter Name Parameter Value Comment
0 ACTION_WaitForEvent ExternalEvent MyDoorHit waits for the door to be hit
1 ACTION_TriggerEvent Event MyDoor opens the door
2 ACTION_WaitForEvent ExternalEvent MyDoorOpened waits for the door to finish opening
3 ACTION_WaitForTimer PauseTime 2 wait 2 seconds
4 ACTION_IfCondition TriggeredConditionTag MyDoorProximity check, if player is near the door (see next section of this tutorial)
5 ACTION_GotoAction ActionNumber 3 go to action 3 ("wait 2 seconds")
6 ACTION_EndSection end of the IfCondition section
7 ACTION_TriggerEvent Event MyDoor close the door
8 ACTION_GotoAction ActionNumber 0 go to action 0 ("wait for the door to be hit")

You can playtest the map again and the doors should already open when you shoot them, even though the If Condition in the script will probably throw an error because we haven't placed the specified TriggeredCondition yet. The door doesn't yet react to player proximity, so you can get crushed it you stand between the movers when they close.

Don't hurt me![edit]

To tell the door that a player is still nearby, we add an actor >> Triggers >> Trigger to the doorway and adjust its collision size. If a cylinder doesn't really fit the area you need, add a volume with the desired shape and match its Volume -> AssociatedActorTag with the Trigger's Events -> Tag. Specify the Trigger's Events -> Event (in our example "MyDoorProximity") and check that its Object -> InitialState is NormalTrigger.

Add an actor >> Triggers >> TriggeredCondition and set its Events -> Tag to the same as the Trigger's event (in our case "MyDoorProximity", again). Match its Events -> Tag with the Trigger's Events -> Event and set its TriggeredCondition -> bTriggerControlled to True and the other properties in that group to false.

Summary of properties:

Property TriggeredCondition Trigger
Events -> Event MyDoorProximity
Events -> Tag MyDoorProximity MyDoorProximityVolume
(only when using a volume as described above)
Object -> InitialState NormalTrigger
TriggeredCondition -> bEnabled False
TriggeredCondition -> bToggled False
TriggeredCondition -> bTriggerControlled True

After adding these two actors your damage-triggered door should already stay open when a player is nearby, but it still only opens when you shoot it.

Open up wide![edit]

Our door is only missing a single feature: It doesn't open automatically when a player walks up close to it. We already have a Trigger that fires an event when a player touches it, so let's just use it to open the door.

Add another ScriptedTrigger and set it up to translate the player proximity event into the door hit event, which already opens the door properly:

Action Parameter Name Parameter Value Comment
0 ACTION_WaitForEvent ExternalEvent MyDoorProximity waits for a player to touch the trigger
1 ACTION_WaitForTimer PauseTime 0.01 In my tests the script managed to crash the game with an Infinite Recursion message – this prevented it from happening.
2 ACTION_TriggerEvent Event MyDoorHit triggers the other ScriptedTrigger, which opens the door
3 ACTION_GotoAction ActionNumber 0 go to action 0 ("wait for player touch")

That's all! Your door should now open when it gets hit or when a player approaches it and will only close again if the player is no longer nearby.

Related Topics[edit]

Comments[edit]

FreshMeat: Would you kindly put some notes in here for those of us who only want to proximity trigger double doors? Trying to sort out the damage stuff from the proximity stuff has me confused.

Wormbo: Only proximity triggering can be done with regular movers and a much simpler setup. I think a good example of proximity-triggered movers is the UT2004 map DM-Reconstruct by AngelMapper, which uses it in a very unique way.

Tarquin: Indeed. IIRC, you just stick a Trigger to detect player presence, and change a few settings of the mover.