Suspended Object Trap: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (→‎Trap Trigger Creation: clarified several functions, outputs, flags etc.)
m (→‎top: Unicodifying, replaced: [[Image: → [[File:)
 
(8 intermediate revisions by 6 users not shown)
Line 1: Line 1:
[[File:Falling_object.jpg|thumb|An example of what this tutorial will accomplish.]]
====Introduction====
====Introduction====
[[Image:Falling_object.jpg|frame| An example of what this tutorial will accomplish.]]
This tutorial explains the process of creating a trap consisting of a heavy object suspended by a dynamic rope which can then be triggered to fall with devastating effect. This is an advanced tutorial covering entity creation, parenting, I/O configuration, keyframe editing, and flag manipulation. Overall completion time is estimated at 45 minutes to 1 hour.
This tutorial explains the process of creating a trap consisting of a heavy object suspended by a dynamic rope which can then be triggered to fall with devastating effect. This is an advanced tutorial covering entity creation, parenting, I/O configuration, keyframe editing, and flag manipulation. Overall completion time is estimated at 45 minutes to 1 hour.


Line 7: Line 7:
====Entity Creation====
====Entity Creation====
Create the following entities:
Create the following entities:
*A [[move_rope]],
*A {{ent|move_rope}},
*a [[keyframe_rope]],
*a {{ent|keyframe_rope}},
*a [[phys_lengthconstraint]],
*a {{ent|phys_lengthconstraint}},
*a [[env_spark]],
*a {{ent|env_spark}} (required due to [[Counter-Strike_Source_Entity_Overview#Counter-Strike_Round_Restarts|this problem]]),
*a [[prop_physics_override]] ''or'' a [[func_physbox]],
*a {{ent|prop_physics_override}} ''or'' a {{ent|func_physbox}},
*a [[logic_measure_movement]],
*a {{ent|logic_measure_movement}},
*a [[brush]] with the same or as-near-as-possible dimensions of the [[prop_physics_override]] / [[func_physbox]], tied ''(Ctrl+T)'' to a [[func_button]] entity.
*a [[brush]] with the same or as-near-as-possible dimensions of the {{ent|prop_physics_override}} / {{ent|func_physbox}}, tied ''(Ctrl+T)'' to a {{ent|func_button}} entity.


====Entity Placement====
====Entity Placement====
Place the following entities or brushes:
Place the following entities or brushes:
*Place the [[move_rope]] to where you'd like to anchor the rope.  
*Place the {{ent|move_rope}} to where you'd like to anchor the rope.  
*Place the [[prop_physics_override]] / [[func_physbox]] to where you'd like the object to hang from.
*Place the {{ent|prop_physics_override}} / {{ent|func_physbox}} to where you'd like the object to hang from.
**This tutorial will be using a prop instead of a physbox, but both can be used.  
**This tutorial will be using a prop instead of a physbox, but both can be used.  
*Place the [[keyframe_rope]] to where you'd like to anchor the rope to the [[prop_physics_override]] or [[func_physbox]].
*Place the {{ent|keyframe_rope}} to where you'd like to anchor the rope to the {{ent|prop_physics_override}} or {{ent|func_physbox}}.
**Hint: Just inside the surface of the prop or brush works best.
**Hint: Just inside the surface of the prop or brush works best.
**Remember your physics: once in game, the center of gravity of the prop and the anchor point will interact and your prop will reach a balance point accordingly.  
**Remember your physics: once in game, the center of gravity of the prop and the anchor point will interact and your prop will reach a balance point accordingly.  
*Place the [[phys_lengthconstraint]] in the exact same location of the [[keyframe_rope]] and drag the lengthconstraint's small white circle to the center of the [[move_rope]].
*Place the {{ent|phys_lengthconstraint}} in the exact same location of the {{ent|keyframe_rope}} and drag the lengthconstraint's small white circle to the center of the {{ent|move_rope}}.
*Place the [[env_spark]] in the exact same location of the [[keyframe_rope]].
*Place the {{ent|env_spark}} in the exact same location of the {{ent|keyframe_rope}}.
*Place the [[logic_measure_movement]] off to the side for easy access.  
*Place the {{ent|logic_measure_movement}} off to the side for easy access.  
*Place the [[brush]] in the same location as the [[prop_physics_override]] / [[func_physbox]].
*Place the {{ent|func_button}} in the same location as the {{ent|prop_physics_override}} / {{ent|func_physbox}}.
 


====Entity Properties Configuration====
====Entity Properties Configuration====
=====Naming=====
=====Naming=====
Naming your entities is arbitrary - you can choose what names you want. For the purposes of this tutorial the nomenclature is:
Naming your entities is arbitrary - you can choose what names you want. For the purposes of this tutorial the nomenclature is:
*[[move_rope]] : ''dynamic01_move_rope''
*{{ent|move_rope}} : ''dynamic01_move_rope''
*[[keyframe_rope]] : ''dynamic01_keyframe_rope''
*{{ent|keyframe_rope}} : ''dynamic01_keyframe_rope''
*[[phys_lengthconstraint]] : ''dynamic01_phys_lengthconstraint''
*{{ent|phys_lengthconstraint}} : ''dynamic01_phys_lengthconstraint''
*[[env_spark]] : ''dynamic01_env_spark''
*{{ent|env_spark}} : ''dynamic01_env_spark''
*[[prop_physics_override]] / [[func_physbox]] : ''dynamic01_prop_physics_override''
*{{ent|prop_physics_override}} / {{ent|func_physbox}} : ''dynamic01_prop_physics_override''
*[[logic_measure_movement]] : ''dynamic01_logic_measuremovement''
*{{ent|logic_measure_movement}} : ''dynamic01_logic_measuremovement''
*[[func_button]] : ''dynamic01_func_button''
*{{ent|func_button}} : ''dynamic01_func_button''


As you can see, each entity has the prefix ''dynamicXX'', followed by a descriptive suffix. This is a useful naming system when you have several dynamic systems and need to keep them separate.
As you can see, each entity has the prefix ''dynamicXX'', followed by a descriptive suffix. This is a useful naming system when you have several dynamic systems and need to keep them separate.
Line 47: Line 46:




{{entity-kvalue-start|[[move_rope]]}}
{{entity-kvalue-start|{{ent|move_rope}}}}
{{entity-kvalue|Name|dynamic01_move_rope|The name of the move_rope entity in this tutorial.}}
{{entity-kvalue|Name|dynamic01_move_rope|The name of the move_rope entity in this tutorial.}}
{{entity-kvalue|Next KeyFrame|dynamic01_keyframe_rope|The name of the keyframe_rope entity in this tutorial}}
{{entity-kvalue|Next KeyFrame|dynamic01_keyframe_rope|The name of the keyframe_rope entity in this tutorial.}}
{{entity-kvalue|Slack|0|No slack.}}
{{entity-kvalue|Slack|0|No slack.}}
{{entity-kvalue-end}}
{{entity-kvalue-end}}




{{entity-kvalue-start|[[keyframe_rope]]}}
{{entity-kvalue-start|{{ent|keyframe_rope}}}}
{{entity-kvalue|Name|dynamic01_keyframe_rope|The name of the keyframe_rope entity in this tutorial.}}
{{entity-kvalue|Name|dynamic01_keyframe_rope|The name of the keyframe_rope entity in this tutorial.}}
{{entity-kvalue|Slack|0|No slack here either.}}
{{entity-kvalue|Slack|0|No slack here either.}}
Line 60: Line 59:




{{entity-kvalue-start|[[env_spark]]}}
{{entity-kvalue-start|{{ent|env_spark}}}}
{{entity-kvalue|Name|dynamic01_env_spark|The name of the env_spark entity in this tutorial.}}
{{entity-kvalue|Name|dynamic01_env_spark|The name of the env_spark entity in this tutorial.}}
{{entity-kvalue|Parent|dynamic01_prop_physics_override|Tie the spark effect to the prop_physics_override entity.}}
{{entity-kvalue|Parent|dynamic01_prop_physics_override|Tie the spark effect to the prop_physics_override entity.}}
Line 66: Line 65:




{{entity-kvalue-start|[[phys_lengthconstraint]]}}
{{entity-kvalue-start|{{ent|phys_lengthconstraint}}}}
{{entity-kvalue|Name|dynamic01_phys_lengthconstraint|The name of the phys_lengthconstraint entity in this tutorial.}}
{{entity-kvalue|Name|dynamic01_phys_lengthconstraint|The name of the phys_lengthconstraint entity in this tutorial.}}
{{entity-kvalue|Entity1|dynamic01_prop_physics_override|Tie the lengthconstraint to the prop_physics_override entity too.}}
{{entity-kvalue|Entity1|dynamic01_prop_physics_override|Tie the lengthconstraint to the prop_physics_override entity too.}}
{{entity-kvalue-end}}
{{entity-kvalue-end}}


 
{{entity-kvalue-start|{{ent|logic_measure_movement}}}}
{{entity-kvalue-start|[[logic_measure_movement]]}}
{{entity-kvalue|Name|dynamic01_logic_measuremovement|The name of the logic_measure_movement entity in this tutorial.}}
{{entity-kvalue|Name|dynamic01_logic_measuremovement|The name of the logic_measure_movement entity in this tutorial.}}
{{entity-kvalue|Entity to Measure|dynamic01_env_spark|Tie the logic spark entity to the logic entity to measure the movement of the parented prop}}
{{entity-kvalue|Entity to Measure|dynamic01_env_spark|Tie the env_spark entity to the logic entity to measure the movement of the parented prop.}}
{{entity-kvalue|Measure Reference|dynamic01_move_rope|Tie the move_rope entity to the logic entity as a measure refence}}
{{entity-kvalue|Measure Reference|dynamic01_move_rope|Tie the move_rope entity to the logic entity as a measure refence.}}
{{entity-kvalue|Entity to Move|dynamic01_keyframe_rope|Send along the measured movements of the env_spark relative to the move_rope}}
{{entity-kvalue|Entity to Move|dynamic01_keyframe_rope|Send along the measured movements of the env_spark relative to the move_rope.}}
{{entity-kvalue|Movement Reference|dynamic01_move_rope|Tie the move_rope entity to the logic entity as a movement refence}}
{{entity-kvalue|Movement Reference|dynamic01_move_rope|Tie the move_rope entity to the logic entity as a movement refence.}}
{{entity-kvalue-end}}
{{entity-kvalue-end}}


Line 84: Line 82:
Time to change the func_button. First, texture it in <nowiki>inivs</nowiki> and then change its keyvalues like this:
Time to change the func_button. First, texture it in <nowiki>inivs</nowiki> and then change its keyvalues like this:


{{entity-kvalue-start|[[func_button]]}}
{{entity-kvalue-start|{{ent|func_button}}}}
{{entity-kvalue|Name|dynamic01_func_button|The name of the func_button entity in this tutorial.|}}
{{entity-kvalue|Name|dynamic01_func_button|The name of the func_button entity in this tutorial.}}
{{entity-kvalue|Parent|dynamic01_prop_physics_override|Tie this entity to the prop_physics_override.|}}
{{entity-kvalue|Parent|dynamic01_prop_physics_override|Tie this entity to the prop_physics_override.}}
{{entity-kvalue|Disable Receiving Shadows|Yes|Shadows are disabled otherwise the objects near the trigger have a shadow but no visible source of one.|}}
{{entity-kvalue|Disable Receiving Shadows|Yes|Shadows are disabled otherwise the objects near the trigger have a shadow but no visible source of one.}}
{{entity-kvalue|Move Direction (Pitch Yaw Roll)|0 0 0|To ensure the button will not move|}}
{{entity-kvalue|Move Direction (Pitch Yaw Roll)|0 0 0|To ensure the button will not move.}}
{{entity-kvalue|Speed|0|To ensure the button will not move|}}
{{entity-kvalue|Speed|0|To ensure the button will not move.}}
{{entity-kvalue|Lip|0|To ensure the button will not move|}}
{{entity-kvalue|Lip|0|To ensure the button will not move.}}
{{entity-kvalue-end}}
{{entity-kvalue-end}}


Now change its flags like this:
Now change its flags like this:
Line 100: Line 97:
{{entity-flag|Toggle|off|}}
{{entity-flag|Toggle|off|}}
{{entity-flag|Touch Activates|off|}}
{{entity-flag|Touch Activates|off|}}
{{entity-flag|Damage Activates|on|Will fire outputs when takes damage|}}
{{entity-flag|Damage Activates|on|Will fire outputs when takes damage.|}}
{{entity-flag|Use Activates|off|}}
{{entity-flag|Use Activates|off|}}
{{entity-flag|Starts locked|off|}}
{{entity-flag|Starts locked|off|}}
{{entity-flag|Sparks|off|}}
{{entity-flag|Sparks|off|}}
{{entity-flag-end}}
{{entity-flag-end}}


...and finally give it the following outputs:
...and finally give it the following outputs:
{{entity-output-start}}
{{entity-output-start}}
{{entity-output||OnDamaged|dynamic05_logic_measure_movement|Disable||0.00|No|Disable the logic_measure_movement|}}
{{entity-output||OnDamaged|dynamic05_logic_measure_movement|Disable||0.00|No|Disable the logic_measure_movement.|}}
{{entity-output||OnDamaged|dynamic05_keyframe_rope1|Break||0.00|No|OPTIONAL output, in multiplayer do not break, in singleplayer set to break|}}
{{entity-output||OnDamaged|dynamic05_keyframe_rope1|Break||0.00|No|OPTIONAL output, in multiplayer do not break, in singleplayer set to break.|}}
{{entity-output||OnDamaged|dynamic05_phys_lengthconstraint|Break||0.00|No|Break phys_lengthconstraint|}}
{{entity-output||OnDamaged|dynamic05_phys_lengthconstraint|Break||0.00|No|Break phys_lengthconstraint.|}}
{{entity-output||OnDamaged|dynamic05_env_spark|Kill||0.00|No|Kill the env_spark|}}
{{entity-output||OnDamaged|dynamic05_env_spark|Kill||0.00|No|Kill the env_spark.|}}
{{entity-output||OnDamaged|dynamic05_func_button|Kill||0.00|No|Kill the button itself to prevent any complications|}}
{{entity-output||OnDamaged|dynamic05_func_button|Kill||0.00|No|Kill the button itself to prevent any complications.|}}
{{entity-output-end}}
{{entity-output-end}}


 
[[Category:Level Design]]
[[Category:Level Design Tutorials]]

Latest revision as of 13:42, 8 January 2024

An example of what this tutorial will accomplish.

Introduction

This tutorial explains the process of creating a trap consisting of a heavy object suspended by a dynamic rope which can then be triggered to fall with devastating effect. This is an advanced tutorial covering entity creation, parenting, I/O configuration, keyframe editing, and flag manipulation. Overall completion time is estimated at 45 minutes to 1 hour.

The Source Hammer editor does not allow a user to directly attach an object to a rope. However, there is a workaround. The basic idea involves parenting the end of a rope to a secondary entity. This secondary entity is then used in conjunction with a few physics entities that measure the movement of the secondary entity and translate its movements back to the rope. We'll also be creating a trigger that will break the rope when it gets damaged causing the previously suspended object to crash down! Sounds complicated but don't worry, it'll make sense once it's done. Let's get started!

Entity Creation

Create the following entities:

Entity Placement

Place the following entities or brushes:

Entity Properties Configuration

Naming

Naming your entities is arbitrary - you can choose what names you want. For the purposes of this tutorial the nomenclature is:

As you can see, each entity has the prefix dynamicXX, followed by a descriptive suffix. This is a useful naming system when you have several dynamic systems and need to keep them separate.

Keyvalues for Rope Workaround

Here comes the tricky part where most errors are made. Set the keyvalues of the entities like this:


Class: move_rope
Keyvalues Comments
Name dynamic01_move_rope The name of the move_rope entity in this tutorial.
Next KeyFrame dynamic01_keyframe_rope The name of the keyframe_rope entity in this tutorial.
Slack 0 No slack.


Class: keyframe_rope
Keyvalues Comments
Name dynamic01_keyframe_rope The name of the keyframe_rope entity in this tutorial.
Slack 0 No slack here either.


Class: env_spark
Keyvalues Comments
Name dynamic01_env_spark The name of the env_spark entity in this tutorial.
Parent dynamic01_prop_physics_override Tie the spark effect to the prop_physics_override entity.


Class: phys_lengthconstraint
Keyvalues Comments
Name dynamic01_phys_lengthconstraint The name of the phys_lengthconstraint entity in this tutorial.
Entity1 dynamic01_prop_physics_override Tie the lengthconstraint to the prop_physics_override entity too.
Class: logic_measure_movement
Keyvalues Comments
Name dynamic01_logic_measuremovement The name of the logic_measure_movement entity in this tutorial.
Entity to Measure dynamic01_env_spark Tie the env_spark entity to the logic entity to measure the movement of the parented prop.
Measure Reference dynamic01_move_rope Tie the move_rope entity to the logic entity as a measure refence.
Entity to Move dynamic01_keyframe_rope Send along the measured movements of the env_spark relative to the move_rope.
Movement Reference dynamic01_move_rope Tie the move_rope entity to the logic entity as a movement refence.
Trap Trigger Creation

Time to change the func_button. First, texture it in inivs and then change its keyvalues like this:

Class: func_button
Keyvalues Comments
Name dynamic01_func_button The name of the func_button entity in this tutorial.
Parent dynamic01_prop_physics_override Tie this entity to the prop_physics_override.
Disable Receiving Shadows Yes Shadows are disabled otherwise the objects near the trigger have a shadow but no visible source of one.
Move Direction (Pitch Yaw Roll) 0 0 0 To ensure the button will not move.
Speed 0 To ensure the button will not move.
Lip 0 To ensure the button will not move.

Now change its flags like this:

Flag
Checkbox-off.png Don't move
Checkbox-off.png Toggle
Checkbox-off.png Touch Activates
Checkbox-on.png Damage Activates Will fire outputs when takes damage.
Checkbox-off.png Use Activates
Checkbox-off.png Starts locked
Checkbox-off.png Sparks

...and finally give it the following outputs:

My output Target entity Target input Parameter Delay Only once Comments
Entity-output-icon.png OnDamaged dynamic05_logic_measure_movement Disable 0.00 No Disable the logic_measure_movement.
Entity-output-icon.png OnDamaged dynamic05_keyframe_rope1 Break 0.00 No OPTIONAL output, in multiplayer do not break, in singleplayer set to break.
Entity-output-icon.png OnDamaged dynamic05_phys_lengthconstraint Break 0.00 No Break phys_lengthconstraint.
Entity-output-icon.png OnDamaged dynamic05_env_spark Kill 0.00 No Kill the env_spark.
Entity-output-icon.png OnDamaged dynamic05_func_button Kill 0.00 No Kill the button itself to prevent any complications.