This article relates to the game "Counter-Strike 2". Click here for more information.
This article relates to the software/tool "Counter-Strike 2 Workshop Tools". Click here for more information.
This article's documentation is for Source 2. Click here for more information.

Creating a Glowing Chair with JavaScript in Counter-Strike 2

From Valve Developer Community
Jump to navigation Jump to search

English (en)Translate (Translate)

Creating a Glowing Chair with JavaScript in Counter-Strike 2

This tutorial will show you how to create a chair that glows when players are within its proximity.

Note: this tutorial assumes you know the basics of cs_script. You can check out the basics in this tutorial: Hello, Gordon: Getting Started with JavaScript for Counter-Strike 2

Interaction with the level

For (most) scripts to be useful, they have to interact with the game world in some way. This interaction can be split in two categories: inputs and outputs. Inputs are events in the world that the script reacts to. For example, the player steps into a trigger, which activates a function within a script. Outputs are effects on the game world which are triggered from within scripts. In our case, this is enabling a glow effect on a prop within the world. This tutorial aims to teach you how script inputs work and how the script can affect parts of the game world.

Level Setup

First, we need to set up a few things within our level. Start by adding a prop_dynamic entity. This will be our glowing chair. It its properties, set a name of your liking and give it a chair model. Note: some chair models are configured to be used like a prop_physics. In this case, the prop_dynamic will not work and will be deleted when the level loads. You can choose the one shown in the screenshot or find another one that works.

prop_dynamic property list, showing a modified name and model property
The properties that need to be modified on the glowing chair prop

Next, you need to wrap the chair in a trigger. Create a new block with the toolstrigger.vmat material and tie it to an entity with Control+T. Make it a trigger_multiple entity. Make sure it is large enough to encompass the entire chair and leave some space around the chair for good measure. Lastly, create a point_script entity and give it a name as well.

Complete level setup with the chair wrapped by a trigger and a point_script entity to the side of it
Finished level setup

Now we need to connect the trigger to the script entity. For this, create two outputs with the values shown below. For this, we will use the OnStartTouch and OnEndTouch outputs respectively, which fire when an entity starts and stops overlapping the trigger. To trigger the associated cs_script, use the RunScriptInput input on the point_script. Lastly, the parameter is used within the JavaScript itself, as will be seen later. Give these script events fitting names, like start_overlap and end_overlap or similar.

Two outputs for a trigger_multiple (OnStartTouch and OnEndTouch), which are connected to a point_script's RunScriptInput input. Each output specifies an input name for the script
Trigger outputs connected to the point_script entity

With this, our level setup is complete. Time to move on to scripting!

The Chair Glower Script

Create a new script in your scripts folder and name it something appropriate, like model_glower.js. Within it, add the following code:

import { Instance, BaseModelEntity } from "cs_script/point_script";

Instance.OnScriptInput("begin_overlap", () => {
    let chair = Instance.FindEntityByName("chair");
    if (chair instanceof BaseModelEntity) {
        chair.Glow();
    }
    
});

Instance.OnScriptInput("end_overlap", () => {
    let chair = Instance.FindEntityByName("chair");
    if (chair instanceof BaseModelEntity) {
        chair.Unglow();
    }
});

Let's break down what we're doing here. Firstly, we are referencing the parameters provided to RunScriptInput from the previous section. Instance.OnScriptInput() will be run as soon as a RunScriptInput input with the corresponding name as the parameter is fired. Within the callback function argument, we add the code that runs when the script input is triggered. For the begin_overlap input, this will be making the chair glow. To get a reference to the chair entity, we use Instance.FindEntityByName(), which uses the name we gave to the chair entity earlier. So if your chair entity has a different name than "chair", you need to adjust the code to include the correct name. Since Instance.FindEntityByName() only returns a reference to an Entity, we need to check whether the returned entity is of type BaseModelEntity. That's because the Glow() and Unglow() functions are only available for entities of the class BaseModelEntity. If the returned entity is indeed of that class, we call the Glow() function. The code is almost exactly the same for our end_overlap input, except we call Unglow() to stop the glow effect when the player exits the trigger.

Reference your newly created script in the point_script entity and run the level! The chair should now start glowing when you approach it and stop glowing if you move further away again.

Handling Multiplayer

Since Counter-Strike 2 is a multiplayer game, we need to handle the case where multiple player start and stop overlapping the trigger. In case we only want the chair to stop glowing if all players have left the trigger, we can easily add that functionality by keeping track of how many players are currently in the trigger. This code accomplishes just that:

import { Instance, BaseModelEntity } from "cs_script/point_script";

let overlap_count = 0;

Instance.OnScriptInput("begin_overlap", () => {
    overlap_count++;

    let chair = Instance.FindEntityByName("chair");
    if (chair instanceof BaseModelEntity) {
        chair.Glow();
    }
    
});

Instance.OnScriptInput("end_overlap", () => {
    overlap_count--;

    if (overlap_count <= 0) {
        let chair = Instance.FindEntityByName("chair");
        if (chair instanceof BaseModelEntity) {
            chair.Unglow();
        }
    }
});

We add a variable called overlap_count and initialize it to zero when the script starts. Then, whenever a player starts overlapping the trigger, we increment the variable by one. We decrement it by one if a player stops overlapping the trigger. Before we stop the glow on the chair, we check whether there are any players left overlapping the trigger. If not, we can call the Unglow() function like before.

Next Steps

The sky's the limit with scripting! Check out the Scripting API for a list of available classes and functions.