This page has been translated automatically.
Unigine Basics
1. Introduction
2. Managing Virtual Worlds
3. Preparing 3D Models
4. Materials
5. Cameras and Lighting
6. Implementing Application Logic
7. Making Cutscenes and Recording Videos
8. Preparing Your Project for Release
9. Physics
10. Optimization Basics
11. PROJECT2: First-Person Shooter
12. PROJECT3: Third-Person Cross-Country Arcade Racing Game

Adding Interactive Area

In games and VR applications, some actions are performed when you enter a specific area in the scene (for example, music starts, sound or visual effects appear). Let's implement this in our project: when you enter or teleport to a certain area, it rains inside it.

In UNIGINE, the World Trigger node is used to track when any node (collider or not) gets inside or outside of it (for objects with physical bodies, the Physical Trigger node is used).

  1. First of all, create a trigger to define the rain area. On the Menu bar, choose Create -> Logic -> World Trigger and place the trigger near the Material Ball, for example. Set the trigger size to (2, 2, 2).

  2. Create a new TriggerZone component that will turn the rain node on and off (in our case, it is a particle system simulating rain), depending on the trigger state. Add the following code to the component and then assign it to the World Trigger node:

    Source code (C++)
    #pragma once
    #include <UnigineComponentSystem.h>
    #include <UnigineWorlds.h>
    class TriggerZone :
        public Unigine::ComponentBase
    {
    public:
    	COMPONENT(TriggerZone, Unigine::ComponentBase);
    	COMPONENT_INIT(init);
    
    	// property name
    	PROP_NAME("TriggerZone");
    
    	// node to be controlled by the trigger
    	PROP_PARAM(Node, controlledNode);
    
    
    protected:
    	void init();
    
    	// event handlers for the trigger
    	void trigger_enter(const Unigine::NodePtr &player);
    	void trigger_leave(const Unigine::NodePtr &player);
    
    private:
    	// trigger node
    	Unigine::WorldTriggerPtr trigger;
    	// link to trigger event connections (all event connections will be removed on shutdown)
    	Unigine::EventConnections conns;
    };
    Source code (C++)
    #include "TriggerZone.h"
    
    using namespace Unigine;
    
    REGISTER_COMPONENT(TriggerZone);
    
    void TriggerZone::init()
    {
    	// check if the component is assigned to WorldTrigger
    	if (node->getType() != Node::WORLD_TRIGGER)
    	{
    		Log::error("Node %s (TriggerZone) error: this component can only be assigned to a WorldTrigger.\n", node->getName());
    		ComponentSystem::get()->removeComponent<TriggerZone>(node);
    		return;
    	}
    	// check if controlledNode is specified
    	if (controlledNode.nullCheck())
    	{
    		Log::error("Node %s (TriggerZone) error: 'controlledNode' is not assigned.\n", node->getName());
    		ComponentSystem::get()->removeComponent<TriggerZone>(node);
    		return;
    	}
    	// add event handlers to be executed when a node gets inside and outside the trigger
    	trigger = checked_ptr_cast<WorldTrigger>(node);
    	trigger->getEventEnter().connect(conns, this, &TriggerZone::trigger_enter);
    	trigger->getEventLeave().connect(conns, this, &TriggerZone::trigger_leave);
    }
    
    // handler function that enables ControlledNode when a Player enters the trigger
    void TriggerZone::trigger_enter(const NodePtr &player)
    {
    	if (!player->isPlayer())
    		return;
    	controlledNode->setEnabled(true);
    }
    
    // handler function that disables ControlledNode when a Player leaves the trigger
    void TriggerZone::trigger_leave(const NodePtr &player)
    {
    	if (!player->isPlayer())
    		return;
    	controlledNode->setEnabled(false);
    }
  3. Now, let's add the rain effect. Drag the rain_effect.node asset from the vr/particles folder of the UNIGINE Starter Course Project add-on to the scene, add it as the child to the trigger node and turn it off (the component will turn it on later).

  4. Drag the rain_effect node from the World Hierarchy window to the Controlled Node field of the TriggerZone (in the Parameters window).

    Save changes (Ctrl+S) you've made to the world.

  5. We also have to enable the Triggers Interaction option for the VR Player to make the trigger react on contacting it. Simply add the following line to the init_player() method of the VRPlayerSpawner component (Framework\Components\VRPlayerSpawner.cpp):

    Source code (C++)
    void VRPlayerSpawner::init_player(const PlayerPtr &player)
    {
    	// copy transform
    	player->setWorldTransform(node->getWorldTransform());
    
    	${#HL}$player->setTriggerInteractionEnabled(true); ${HL#}$
    
    	if (node->getType() >= Node::PLAYER_BEGIN &&
    		node->getType() <= Node::PLAYER_END)
    	{
    		PlayerPtr player_ref = checked_ptr_cast<Player>(node);
    		
    		// copy basic parameters
    		player->setFov(player_ref->getFov());
    		player->setZNear(player_ref->getZNear());
    		player->setZFar(player_ref->getZFar());
    		for (int i = 0 ; i < player_ref->getNumScriptableMaterials(); i++)
    			player->addScriptableMaterial(player_ref->getScriptableMaterial(i));
    	}
    
    	// unparent current node 
    	// (cause vr_group can be our parent and we don't want to turn off
    	// components that are children to us)
    	node->setWorldParent(NodePtr());
    }
  6. Save changes (Ctrl+S), rebuild the project, and run it via SDK Browser, then try to enter the area defined by the trigger — it should raininside.

Last update: 2024-11-06
Build: ()