Jump to content
JP Shep

Crowds: When X happens do this OR this

Recommended Posts


So I've hit a wall while building my crowd sim.  

I've learned how to get agents to transition from one state to another but what I haven't been able to figure out is how to get some agents to transition into one state and other agents to transition into a second state off the same trigger.

For example:  

-> Starts in Idle state

--> After 1 second transition into walking state

---> After two seconds some agents transition into a jogging state while others transition into a sprinting state.

Then from there more random agents transition into different states and so on.


I've thought about maybe separating my agents into different groups and subgroups or using more than one crowd source but I'm worried that it might get too complicated and cause odd behavior.

I went through most of the crowds example files on its shelf tab and they were super helpful.  

The Stadium one in particular had something that I thought could be it but I don't have much experience using VEX expressions, I attached a snapshot from inside that examples CrowdSim.


One of the crowd trigger nodes is named: crowdtrigger_half and has this code on it:

// setting i@trigger to 1 will enable
// setting i@trigger to 0 will disable

if (@ptnum%1==2) {
    i@trigger = 0;
else {
    i@trigger = 1;


think it's saying if the point number 1 is equal to point number 2 then disable the trigger, else, enable it.


Is this the way I should be trying to build my sim or do I have it all wrong?



crowd stadium example.png

Share this post

Link to post
Share on other sites

I am no guru on Crowds, I just stumbled upon:

if (@ptnum%1==2) {

that never happens, or does it? These are odd/even numbers:

if (@ptnum%2==1) {


Share this post

Link to post
Share on other sites

The way I handle this is to create extra attributes for each agent inside the crowdsource  setup area, near the end of the network. Then reference those inside the crowd_sim node. This way you simplify the crowd transition step. I'll place each crowd transition in VEX code mode then simply reference the attribute to determine if the transition flag needs to be set.

if (s@agentgroup == "relay"){
    i@trigger = i@relay_start_trigger;

So the set of attributes you assign to your agents depends upon the type of simulation you are conducting. For instance vehicle traffic would have a different set of attributes compared to a combat system.

Here is an example of a staggered start time based upon a custom float.

// Each agent begins with a staggered start time based upon it's id.
i@trigger = f@stateduration > f@sf_start_time;

In a combat system I wrote here were some attributes I assigned to my agents inside the crowd source node.

// The final name of your Crowd Trigger node becomes an attribute name here.
// If you add more crowdtriggers to the network make sure to zero them here as well.

// Clear all crowdtrigger flags.
i@crowdtrigger_idle_walk = 0;
i@crowdtrigger_walk_attack = 0;
i@crowdtrigger_walk_defend = 0;
i@crowdtrigger_walk_dying = 0;
i@crowdtrigger_walk_hurt = 0;

So I would name my crowd transition nodes like the trigger flags. Inside the crowd sim node I would drop down a crowd transition node and name it "crowdtrigger_idle_walk". All this node will do is transition from idle state to walk state.

This simplifies crowd triggering because then each crowd trigger node has the same exact VEX code inside it.

int success = 0;
string attribute_name = "crowdtrigger_" + "`$OS`";
int attribute_value = pointattrib("op:/obj/crowd_sim:crowdobject/Geometry",attribute_name, i@id, success);
if (success) {
    setpointattrib(geoself(), "trigger" , i@id, attribute_value, "set");
} else {
    printf("Problem fetching attribute [%s] %d.\n", attribute_name, attribute_value);

You build the attribute name off of the node name (i.e. $OS global), then fetch the point attribute from the agent point then set the i@trigger to the attribute value. This way you can simply set values to the attributes on the points and the next frame the they will be relayed to any trigger states. This also allows you to set values on other agents, in the case of a kill state when one agent defeats another.


So how do all these values get updated?


To make all this work you need to add in a render loop which takes place in a pop wrangle which runs every frame.

Here is some example update code that would run in a pop wrangle.

string handle_path = "op:/obj/crowd_sim:crowdobject/Geometry";                      // Path to our database of attributes.
vector goal_location = point(handle_path,"P",i@relay_id);                           // Fetch the point location in the scatter.
float relay_distance = length(goal_location - @P);                                  // Get distance between my location and the relay location.
setpointattrib(geoself(), "relay_point_distance", i@id, relay_distance, "set");     // Assign this location to an attribute on myself. 

All this code really does is calculate the distance between current location and a goal location and store the result back upon itself.

Then a crowd transition will review that value on the next frame.

// Transition to stand when I am close to my goal location.
if (f@relay_point_distance < 0.25) {i@trigger = 1;} else {i@trigger = 0;}


Feel free to check out my video tutorial on constructing a relay race using the crowd system. In the video I demonstrate a setup such as I have described above.


Edited by Atom
  • Thanks 1

Share this post

Link to post
Share on other sites

Thank you so much Atom!  I'm going through your post and video right now!

You have no idea how much I appreciate this.


Just out of curiosity, what programming language is used in VEX?

I know I'll have to learn how to code to become a better Houdini artist and I would like to start learning the correct one.

Share this post

Link to post
Share on other sites

VEX is based off the C language syntax, but it is it's own language so check out the docs from SideFX.

Share this post

Link to post
Share on other sites

Hey Atom,

I really wanted to thank you for linking me your tutorial and breaking things down.  

I was able to learn how to control individual agents based off their point ID's and cause specific transitions.

For some reason the Pop Wrangles after my crowd solver just error-ed out but I was still able to cause the transitions.

I plan on using the same technique for more personal crowd sims but this is what I was able to achieve so far:


  • Like 1

Share this post

Link to post
Share on other sites

Nice work, glad you are getting good results.

Share this post

Link to post
Share on other sites

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