Jump to content

PhysicalTrigger Enter/Leave callbacks scope


photo

Recommended Posts

Hello.

 

I try to use trigger for PlayerActor (when PlayerActor enter to trigger do something);

 

I have class Game, that created and use in main.cpp. So, when I set enter/leave callbacks to trigger, in this functions I can not set variables, that in Game class scope. How can I get variable robotActive from class Game?

 

#include <core/scripts/utils.h>

#include <source/scripts/Utils.h>

Node add_editor(Node node) {
engine.editor.addNode(node);
return node_remove(node);
}

class Game
{
private:
	PlayerActor player;
public:
	int robotActive = 110; // this is variable, that I want set in trigger's callback
	ObjectMeshSkinned meshWoman;
	PhysicalTrigger trigger;

	Game(PlayerActor player)
	{
		if (engine.editor.isLoaded())
			return 1;

		this.player = player;
	}

	~Game() 
	{
		log.message("Game::destructor()\n");
	}

	void enter_callback(Body body)
	{
		log.message("ENTER: " + this.robotActive + "\n");

		this.robotActive = 1; // this is work, but variable Game::robotActive don't change value

		log.message("ENTER: " + this.robotActive + "\n");

	}

	void leave_callback(Body body)
	{
		log.message("LEAVE: " + this.robotActive + "\n");

		this.robotActive = 0;

		log.message("LEAVE: " + this.robotActive + "\n");
	}

	int init()
	{
		log.message("Game::init()\n");

		// search the node by the specified name    
		int meshWomanIndex = engine.editor.findNode("robot");
		log.message("robot: " + meshWomanIndex + "\n");

		int meshDieIndex = engine.editor.findNode("cube");
		log.message("cube: " + meshDieIndex + "\n");

		if (meshDieIndex != -1)
		{        
			Node meshDie = engine.editor.getNode(meshDieIndex);

			GameObject data = new GameObject("dieData", NULL, NULL);
			data.node = meshDie;
			//meshDie.setData(data);
			meshDie.setData(format("x: %d y: %d",0,1));
		}

		if (meshWomanIndex != -1)
		{
			Node nodeWoman = engine.editor.getNode(meshWomanIndex);

			meshWoman = Utils::nodeCast(nodeWoman);

			trigger = add_editor(new PhysicalTrigger(SHAPE_BOX, vec3(10.0f, 10.0f, 2.0f)));
			trigger.setPosition(meshWoman.getPosition());
			trigger.setEnterCallback("Game::enter_callback");
			trigger.setLeaveCallback("Game::leave_callback");
		}

		return 1;
	}

	int shutdown()
	{
		log.message("Game::shutdown()\n");

		return 1;
	}

	int update()
	{
		trigger.renderVisualizer();

		// in this place variable robotActive always stay 110, even when activated trigger functions
		log.message("robotActive: " + robotActive + "\n");

		if (meshWoman != NULL && robotActive == 1)
		{
			log.message("update robot: \n");
		}

		return 1;
	}

};

 

Thanks

Link to comment

You can't use such callback function. Because script treats them as ordinary function in class namespace. There is trick in UnigineScript:

 


class Foo {
   PhysicalTrigger trigger;
   Foo() {
      trigger.setEnterCallback("Foo::enter_callback_redirector",this);
   }
   void enter_callback() {
      // do_some
   }
   void enter_callback_redirector(Foo foo) {
      foo.enter_callback();
   }
};

Link to comment

I change my code:

 

trigger.setEnterCallback("Game::enterCallbackRedirector", this);
trigger.setLeaveCallback("Game::leaveCallbackRedirector", this);

 

and add two functions:

 

void enterCallbackRedirector(Game game)
{
game.enter_callback();
}

void leaveCallbackRedirector(Game game)
{
game.leave_callback();
}

 

but now, when I enter to trigger zone, interpreter throw error:

 

Interpreter::runFunction(): bad argument type “Body” in “Game::enterCallbackRedirector” function mustbe “Game”.

Link to comment

Decision:

 

void enterCallbackRedirector(Body body, Game game)
{
game.enter_callback(body);
}

void leaveCallbackRedirector(Body body, Game game)
{
game.leave_callback(body);
}

void enter_callback(Body body)
{
log.message("ENTER: " + this.robotActive + "\n");

this.robotActive = 1;
}

void leave_callback(Body body)
{
log.message("LEAVE: " + this.robotActive + "\n");

this.robotActive = 0;
}

Link to comment

In additional to:

 

I'm writing GUI interface, and add some interaction:

 

<icon name="ToolBar::changeCameraIcon" export="1" toggleable="1" texture="player_dummy.png">
    <callback type="clicked">ToolBar::changeCameraClickHandler</callback>
</icon>

 

ToolBar - it's class, in this class saved pointer to my main Game class. And when I write function changeCameraClickHandler:

 

void changeCameraClickHandler() 
{
log.message("ToolBar::changeCameraClickHandler()\n");

log.message("game: " + typeinfo(game) + "\n");

game.changeCamera();
}

 

this in throw error, because in function changeCameraClickHandler I can not get access to game variable. It's the same problem like with Trigger's callback? I can only use namespaces instead classes? If so, in future releases will be more strong OOP support?

 

Thanks.

Link to comment

I try to use this variant:

 

void changeCameraClickHandler() 
{
log.message("ToolBar::changeCameraClickHandler()\n");

Game::changeCamera();
}

 

I don't know is it good practice or not, but it's work :)

Link to comment

I don't know is it good practice or not, but it's work :)

 

It works because you are now calling "static" function changeCamera() in namespace Game. Previously you tried to access a Game object instance without having a global reference to it.

Link to comment

Yes, I have some global variables in world script:

 

Editor editor;
Game game;

int init()
{
 game = new Game();
}

 

I try to use your example:

 

class Game
{
public:
	PlayerActor player;
	PlayerSpectator observer;

	Game(PlayerActor player)
	{
		if (engine.editor.isLoaded())
			return 1;

		player = new PlayerActor();

		engine.game.setPlayer(player);
	}

	~Game() 
	{
		log.message("Game::destructor()\n");
	}

	void changeCamera()
	{
		log.message("Game::changeCamera(): " + typeinfo(game) + "\n");
	}
};

 

but I have some problem:

 

18:16:14 Unigine~# world_load main

18:16:14 log.message("Game::changeCamera(): " + typeinfo(game) + "\n");

18:16:14 source/scripts/Game.h:103: Interpreter::parse_expression(): unknown token "game" in "game" expression

 

So I can't get access to global variable game inside a class member function Game::changeCamera() :)

Link to comment

So I can't get access to global variable game inside a class member function Game::changeCamera() :)

 

Not sure, but I think this would require some kind of forward declaration capability which is most probably not supported within UNIGINE script (but I am not expert). Anyway I think you should stay with working static function call Game::changeCamera() because this is a straight-forward implmentation.

Link to comment

I prepare test_gui scene, this is source:

test.cpp:

Game game;
ToolBar toolBar;

int init()
{
game = new Game();
toolBar = new ToolBar(game);

return 1;
} 

Game.h

class Game
{
public:
	int cameraType = 1;
	Game()
	{

	}

	~Game() 
	{
		log.message("Game::destructor()\n");
	}

	void changeCamera()
	{
		log.message("Game::changeCamera(): " + typeinfo(this) + "\n");
		log.message("Game::cameraType(): " + cameraType + "\n");

		cameraType = 2;

		log.message("Game::cameraType(): " + cameraType + "\n");
	}
};

ToolBar.h

class ToolBar
{
private:
	Game game;
public:
	UserInterface ui;

	WidgetVBox vBox;
	WidgetIcon changeCameraIcon;

	ToolBar(Game game)
	{
		this.game = game;

		log.message("game: " + typeinfo(this.game) + "\n");

		ui = engine.gui.addUserInterface(engine.getGui(), "test_gui/scripts/ToolBar.ui");

		Gui gui = engine.getGui();
		gui.addChild(vBox, GUI_ALIGN_OVERLAP);
		vBox.setPosition(2, 42);
	}

	void changeCameraClickHandler() 
	{
		log.message("ToolBar::changeCameraClickHandler()\n");

		//game.changeCamera(); // not work at all
		Game::changeCamera(); // function call like static
	}
};

ToolBar.ui

<?xml version="1.0" encoding="utf-8"?>
<ui version="1.0">

<vbox name="ToolBar::vBox" export="1">
   <icon name="ToolBar::changeCameraIcon" export="1" toggleable="1" texture="player_dummy.png">
     <callback type="clicked">ToolBar::changeCameraClickHandler</callback>
   </icon>
</vbox>

</ui>

 

If I call function like static Game::changeCamera() than I can't get Game's variables. How this situation can be solved?

 

In attachment full source.

Thanks.

test_gui.zip

Link to comment

Decision:

Write class Global with members variables:

 

class Global
{
public:
	Editor editor;
	Game game;

	Game getGame()
	{
		return game;
	}

	Game getEditor()
	{
		return editor;
	}
};

 

In other classes we can write:

Game game = Global::getGame();
game.changeCamera();

 

For some reason I cant access to variables right Game::game, but function getGame() return correct pointer;

Link to comment
×
×
  • Create New...