mj1.at Michael Jaros' Techblog


Tutorial: How to use the PedSpace package to create the supermarket demo scene

The PedSpace package provides basic pedestrian simulation using a source-sink paradigm and a hierarchical behavioral model. This tutorial explains how to create the supermarket demo scene using the package. It will take about 90 minutes to complete. Alternatively, you can just open the demo scene shipped with the PedSpace package to skip everything but the first section (project setup). Basic knowledge about how Unity works is required in order to complete this tutorial. Saving your scene and project often is recommended.

Prepare the project

To get started, we create a new Unity project and scene, configure a few general settings and create the top level of our scene hierarchy.

  1. Start Unity, create a new project (File/New Project) and choose a reasonable name, e.g. supermarket-tutorial.
  2. Import pedspace.unitypackage (Assets/Import Package/Custom Package).
  3. Save the scene in the root of your project's Assets/ folder, e.g. as supermarket.
  4. Configure input (Edit/Project Settings/Input, then expand the Axes node in the inspector, add 6 to the current value of the size field) according to screenshot: You need to add 6 new bindings. For the JumpCrouch binding, use the following values instead of the ones provided:

    gravity: 5000
    sensitivity: 5

  5. Add mappings for the following additional keys:
    • Help (h)
    • ClearSelection (c)
    • Destroy (x)
    • Size1 (1)
    • Size2 (2)
    • Size3 (3)
    • SelectMode (f1)
    • MoveMode (f2)
    • SpawnMode (f3)
    • ToggleCameraMode (f6)
    • ToggleHeatmap (f7)

    Use the following settings:

    gravity: 1000
    dead: 0.001
    sensitivity: 1000
    positive button: (the respective button as indicated above)

  6. Configure tags and layers (Edit/Project Settings/Tags & Layers) according to the screenshot. Layers will be used for toggling a heatmap visualization or displaying certain objects on the map only.
  7. Erase the main camera from the scene.
  8. Create the following empty game objects (GameObject/Create empty) and set their position to 0/0/0:


Import and instantiate the model

For this example, a 3D model of a small, 2-storey supermarket has been prepared. We will import that model into Unity and adjust its parameters as necessary. After we have created an instance of the model, we will create a navigation mesh to allow path planning on each of the two floors.


  1. Import the supermarket model Assets\supermarkt.dae (Assets/Import New Asset).
  2. Configure the supermarket model's import settings:

    model: scale factor: 0.0254
    model: read/write enabled: off
    model: import blendshapes: off
    model: generate colliders: on
    rig: animation type: none

  3. Create an instance of the supermarket model inside Geometry/ in the hierarchy.
  4. Expand the supermarkt/building object in the hierarchy, select the supermarkt/building/L1 child object and assign layer L1 to it in the inspector (apply to all children? yes)
  5. Select the supermarkt object in the hierarchy and change its Static flag in the inspector (apply to all children? yes).
  6. On the Navigation tab, select the Bake section, change radius to 0.3 and select Bake. Check in the scene view that all parts of the building are walkable (the blue-shaded areas on the floor should cover both floors and the stairs and should not be interrupted at narrow passages).
  7. Collapse the supermarkt object in the hierarchy.
  8. For better overview, you can disable rendering of L1 in the layers box on top right of the screen (the L1 floor will disappear in scene view).
  9. Create a new plane (GameObject/3D Object/Plane) and move it into Geometry/
  10. Configure the plane:

    position: 0/0/0
    scale: 15/1/15

Create master and UI game objects

We will create master and UI objects in this step. The master object controls a few central aspects of the simulation such as high-level agent navigation, heatmap display, and camera enumeration. The UI objects Player and Observer allow walking or flying interaction with the virtual environment.

  1. Create an instance of ObserverPrefab.
  2. Rename the instance to Observer.
  3. Configure Observer:

    position: -10/1/15
    rotation: 0/180/0

  4. Create an instance of PlayerPrefab.
  5. Rename the instance to Player.
  6. Configure Player:

    position: -10/1/15
    rotation: 0/180/0

  7. Create an instance of MasterPrefab.
  8. Rename the instance to Master
  9. Configure Master:

    Statistics Grid Interval: 0.5
    Statistics Grid Size X : 40
    Statistics Grid Size Z : 40
    Statistics Grid Offset X : -20
    Statistics Grid Offset Z : -20

  10. Remove the Train Manager component from the Master game object.
  11. Create 2 instances of MNLGridDisplayPrefab.
  12. Move instances into the Master object.
  13. Rename instances to MNLGridDisplayL0, MNLGridDisplayL1.
  14. MNLGridDisplayL0 is configured correctly already. Configure MNLGridDisplayL1:

    master navigation level: L1
    friendly name: Heatmap L1

  15. Select each of the two instances and move the objects in scene view so the green grids are close above the respective floor (L0 grid above the L0 floor, L1 grid above L1 floor).
  16. Create 7 instances of CameraPositionPrefab inside CameraPositions/ in hierarchy.
  17. Rename instances - the following names are recommended:


  18. Position instances - the following positions are recommended:


  19. Position child objects (camera direction) - the following positions are recommended (each position corresponds to the respective parent object in the previous itemization):


  20. Select the OverviewMapIcon children of all camera position objects created in the previous steps.
  21. Configure the respective OverviewMapIcon children of the selected objects:

    scale: 0,2/0,2/1

  22. Add a point light (GameObject/Light/Point Light) inside Light/.
  23. Position the point light at (-10/25/-10).
  24. Configure the point light:

    range: 150

  25. Select the OverviewCamera child of the Master object.
  26. Position OverviewCamera child to (-10/100/-10).
  27. Configure Camera component of OverviewCamera:

    size: 20

  28. Select the OverviewMapIcon child of the Observer and Player objects.
  29. Configure the respective OverviewMapIcon children of both objects:

    position: 0/2,5/0
    scale: 0,25/0,25/0,25

  30. Select the ObserverMapCamera and PlayerMapCamera children of the Observer and Player objects.
  31. Configure Camera component of both objects:

    size: 5

Create Activities

Agents have strategies that allow them to choose from a set of activities defined for the scene. After creating it, each agent will follow its individual activity list. If agents often cannot reach their activities, the Activity's radius may be too small compared to the NavMeshAgent's stopping distance. In this step, we will create some activities that are typical for a supermarket.

  1. Create 32 instances of ActivityPrefab inside NavigationTargets/ in hierarchy
  2. Rename instances - the following values are recommended:


  3. Position instances - the following positions are recommended:


  4. Set activitydelaymin to 3 on all objects inside NavigationTargets, set to 6 on cash desk 1 and 2 (not the work activities).
  5. Set activitydelaymax to 15 on all objects inside NavigationTargets, set to 9 on cash desk 1 and 2 (not the work activities).
  6. Set activitydelaymin and activitydelaymax to 999999 on CashDesk1WorkActivity and CashDesk2WorkActivity.
  7. Set hasqueue to true on CashDesk1Activity and CashDesk2Activity
  8. Add an empty child to CashDesk1Activity and CashDesk2Activity, and assign them as a reference to the Activity component's queue point field of the each of the two. Note the yellow vector indicator in scene view.
  9. Position the child objects. The following position is recommended:


  10. Set the classification component's classname field to normal on all activities
  11. Set the classification component's classname field to frozen on Fridge1Activity and Fridge2Activity
  12. Set the classification component's classname field to fresh on FreshShelf1Activity and FreshShelf2Activity
  13. Set the classification component's classname field to bag on BagActivity
  14. Set the classification component's classname field to cashdesk on CashDesk1Activity, CashDesk2Activity
  15. Set the classification component's classname field to work on CashDesk1WorkActivity, CashDesk2WorkActivity
  16. Assign product groups such as 'fruit', 'milk' to the friendly name fields of all shelves, baskets, and fridges.
  17. Set the friendly names of BagActivity, CashDesk1Activity, CashDesk2Activity, CashDesk1WorkActivity, CashDesk2WorkActivity to table, cash desk 1, cash desk 2, cash desk 1, cash desk 2.
  18. Set radius to 0,5 on all activities.
  19. Set icon to shop2.png on all activities
  20. Set icon to fresh.png on FreshShelf1Activity and FreshShelf2Activity
  21. Set icon to shopping-bag.png on BagActivity
  22. Set icon to euro.png on CashDesk1WorkActivity, CashDesk2WorkActivity, CashDesk1Activity, CashDesk2Activity

Create Sources and Sinks

Sources and sinks are used to generate, teleport, and destroy agents. Of course we need to place a source and a sink at our entrance. Although it would not be necessary, we will use another two pairs of source and sink to the stairs in our model to demonstrate how the master navigation works together with nav mesh navigation, i.e. the agents will not use the navigation mesh to change the floor, but they will teleport there.

    Note: If you assign the sprite renderer prefab to the respective field in an icon component, it will display its icon above the game object, otherwise the icon will be provided for reference through other game objects only.

  1. Create 3 instances of AgentSourcePrefab and 3 instances of AgentSinkPrefab inside NavigationTargets in the hierarchy.
  2. Rename AgentSourcePrefab instances to EntranceSource, L0_L1_Source, L1_L0_Source.
  3. Rename AgentSinkPrefab instances to ExitSink, L0_L1_Sink, L1_L0_Sink.
  4. Position EntranceSource and ExitSink at the entrance. The following positions are recommended:


  5. Position L0_L1_Sink and L1_L0_Source at the bottom of the stairs. The following positions are recommended:


  6. Position L1_L0_Sink and L0_L1_Source at the top of the stairs. The following positions are recommended:


  7. Set icon to stiege on L0_L1_Sink and L1_L0_Sink
  8. Set icon to ausgang_rechts on ExitSink
  9. Set the transport target of L0_L1_Sink to L0_L1_Source. Note the yellow connection.
  10. Set the transport target of L1_L0_Sink to L1_L0_Source. Note the yellow connection.
  11. Set classname and friendly name to stairs on L0_L1_Source, L0_L1_Sink, L1_L0_Source, L1_L0_Sink.
  12. Set classification to entrance on EntranceSource and ExitSink.
  13. Set friendly name to entrance on EntranceSource.
  14. Set friendly name to exit on ExitSink.
  15. Set flock mode to ONE_AT_A_TIME on EntranceSource.
  16. Set radius to 2,5 on CashDesk1Activity and CashDesk2Activity.
  17. Set radius to 0,75 on all sinks.
  18. Set master navigation level to L0 on all activities, sources and sinks.
  19. Set master navigation level to L1 on Basket3Activity, Basket4Activity, and NormalShelf10Activity through NormalShelf19Activity.
  20. Set master navigation level to L1 on L1_L0_Sink and L0_L1_Source.
  21. Configure EntranceSource:

    baggage_probability: 0
    xspread: 0
    yspread: 0
    zspread: 0
    min delay: 5
    max delay: 15

Adapt Strategies

Strategies determine where and how many agents are created, what kinds of activities they select, and how they leave the scene again. The strategies in the PedSpace package are written for the train station domain and designed to be replaced if the package is used in a different domain. Two new strategies (WORK and SHOP) have been prepared for the supermarket example. In this step we will replace the original strategies with these new ones.

  1. Remove original Assets/Scripts/Strategies.js script.
  2. Move Demo/custom-Strategies.js script to your Assets/Scripts folder and rename it to Strategies.js - it contains strategies for shoppers and employees.
  3. Update reference to Strategies.js script in Strategies component of Master object (if the reference is broken, the component's name may not be displayed, but the component can be identified by the exclamation mark).


We should now be ready to run our simulation.


TODO: How does it work?

Unity 2015-03-01 17-30-27-86

Unity 2015-03-01 17-28-00-87

Posted by mj

Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

Trackbacks are disabled.