Jump to content
Lorenz94

Dynamic Draw on Map With EH

Recommended Posts

Hello,

I'm finally back on Arma with some work done, and at the moment I'm stuck on a script because of performance issues.

 

What I am trying to achieve is a Polygon drawn from a vehicle in the direction of sight of its driver, updated eachframe and broadcasted to all the players of the same faction.

 

I can get the polygon on map, but the EachFrame EH drops my FPS really fast when the map is opened and things get worse letting the mission run. Spawing a while loop is not an alternative, since it is not as high in priority and the drawing process is kinda laggish.

 

Have you any idea on how to fix this (and some advice on broadcasting this particular event)?


Really thank you, as usual, for your big support on this incredible Forum!

Share this post


Link to post
Share on other sites

How am I supposed to remoteExec a drawPolygon command?

Locally I use: 

Spoiler

_map drawPolygon [pilotCone, [0, 0.3, 0.6, 1]];

 

 

where "pilotCone" is an array containing locations and bearings.


With remoteExec, the following isn't working and I really don't know how to manage this.

Spoiler

[_map, [pilotCone, [0, 0.3, 0.6, 1]]] remoteExec [drawPolygon, blufor];

 



Thank you!

Share this post


Link to post
Share on other sites

You are missing quotes around it. It should be a STRING.

[_map, [pilotCone, [0, 0.3, 0.6, 1]]] remoteExec ["drawPolygon", blufor];

 

Share this post


Link to post
Share on other sites
4 hours ago, Lorenz94 said:

Hello,

I'm finally back on Arma with some work done, and at the moment I'm stuck on a script because of performance issues.

 

What I am trying to achieve is a Polygon drawn from a vehicle in the direction of sight of its driver, updated eachframe and broadcasted to all the players of the same faction.

 

I can get the polygon on map, but the EachFrame EH drops my FPS really fast when the map is opened and things get worse letting the mission run. Spawing a while loop is not an alternative, since it is not as high in priority and the drawing process is kinda laggish.

 

Have you any idea on how to fix this (and some advice on broadcasting this particular event)?


Really thank you, as usual, for your big support on this incredible Forum!

 

Broadcasting an eachframe event to every player of a side is a terrible idea. Imagine having 10 players receiving this command, the server has to push out 600 remoteExecs per second at 60fps...

Why not just run the function from initPlayerLocal.sqf? This way you can be sure every client is running it locally without stressing out the server.

 

Also the proper syntax of remoteExec requires the script command to be in quotation marks, as seen on the wiki.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
2 minutes ago, Grumpy Old Man said:

Also the proper syntax of remoteExec requires the script command to be in quotation marks, as seen on the wiki.

Beat you to it hehe. :happy:

  • Like 1

Share this post


Link to post
Share on other sites

Thank you guys. Since I need this to be displayed for all aircraft under certain conditions, should I check with a while loop and a sleep interval every x seconds and flag all new found vehicles with a variable to draw what I need? It is very important to have the draw thing on EachFrame, or the polygon will lag.

 

Thank you!

Share this post


Link to post
Share on other sites
51 minutes ago, Lorenz94 said:

Thank you guys. Since I need this to be displayed for all aircraft under certain conditions, should I check with a while loop and a sleep interval every x seconds and flag all new found vehicles with a variable to draw what I need? It is very important to have the draw thing on EachFrame, or the polygon will lag.

 

Thank you!

You can do all that from inside the eachFrame eventhandler.

It's always good to have a single EH that does stuff for every aircraft, instead of having an EH for every aircraft:

 

//bad:
{
	addMissionEventHandler ["EachFrame",{
		//do stuff
	}];
} forEach (vehicles select {typeof _x isKindOf "Air"});

//good:
addMissionEventHandler ["EachFrame",{
	{
		//do stuff
	} forEach (vehicles select {typeof _x isKindOf "Air"});
}];

Just as an example, but you'll catch my drift.

 

So to draw a polygon for each aircraft you can simply do this:

//initPlayerLocal.sqf:
GOM_fnc_getPilotPolygon = {
	params ["_vehicle"];
	[[_vehicle modelToWorldVisual [-10,0,0],_vehicle modelToWorldVisual [10,0,0],_vehicle modelToWorldVisual [-250,500,0],_vehicle modelToWorldVisual [250,500,0]],[0,0,1,1]]
};

findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw",{
	{
		(_this#0) drawPolygon ([_x] call GOM_fnc_getPilotPolygon);
	} forEach (vehicles select {typeOf _x isKindOf "Air"});

}];

Getting pretty solid 60fps with ~20 aircraft.

 

 

Cheers

  • Like 3
  • Thanks 3

Share this post


Link to post
Share on other sites

Really thank you GOM!

I was doing it differently since I need to have the polygon pointing towards each pilot and copilot line of sight.. I used a couple of nested EH but this way is really simple compared to that!

 

Thank you again, I'm trying it right now.

  • Like 1

Share this post


Link to post
Share on other sites

Here I am! I tested your code and works pefectly. I've done some edit to fit my needs, anyway my problem now is having the cone been displayed only when the gunner is using the turret.

 

Spoiler

map = findDisplay 12 displayCtrl 51;

BRZ_fnc_cone =
	{
		params ["_aircraft", "_copilot"];

		_canRenderCone = cameraView;

		if (_canRenderCone == "Gunner") then {

			//cone draw code

			copilotCone = [..., ..., ...];


			[map, [copilotCone, [0,0.3,0.6,1]]] remoteExec ["drawPoligon", blufor];
		};
	};

map ctrlAddEventHandler ["Draw",
	{
		{
			_copilot = _x turretUnit [0];

			if (_copilot == player) then {
				[_x, _copilot] remoteExec ["BRZ_fnc_cone", owner _copilot];
			};
		} forEach (vehicles select {typeOf _x isKindOf "Air"});
	}
];

 

Without using remote execution the function works and does what it is supposed to do; if I try to print into a hint "map" and "copilotCone" I get all my stuff correctly, but there's something wrong with the remoteExec syntax I think, even if it doesn't give errors.

Thank you!

  • Confused 1

Share this post


Link to post
Share on other sites
10 hours ago, Lorenz94 said:

Here I am! I tested your code and works pefectly. I've done some edit to fit my needs, anyway my problem now is having the cone been displayed only when the gunner is using the turret.

 

  Reveal hidden contents


map = findDisplay 12 displayCtrl 51;

BRZ_fnc_cone =
	{
		params ["_aircraft", "_copilot"];

		_canRenderCone = cameraView;

		if (_canRenderCone == "Gunner") then {

			//cone draw code

			copilotCone = [..., ..., ...];


			[map, [copilotCone, [0,0.3,0.6,1]]] remoteExec ["drawPoligon", blufor];
		};
	};

map ctrlAddEventHandler ["Draw",
	{
		{
			_copilot = _x turretUnit [0];

			if (_copilot == player) then {
				[_x, _copilot] remoteExec ["BRZ_fnc_cone", owner _copilot];
			};
		} forEach (vehicles select {typeOf _x isKindOf "Air"});
	}
];

 

Without using remote execution the function works and does what it is supposed to do; if I try to print into a hint "map" and "copilotCone" I get all my stuff correctly, but there's something wrong with the remoteExec syntax I think, even if it doesn't give errors.

Thank you!

What did you misunderstand when GOM says don't remoteExec any stuff. Really, aircraft are public. So, you can run the code locally for each player. Map is local, EH can be. So?

Use remoteExecution for something local (like addAction script) to be shared (hint...) or triggered on server (addscore...)

 

Share this post


Link to post
Share on other sites
1 hour ago, pierremgi said:

What did you misunderstand when GOM says don't remoteExec any stuff. Really, aircraft are public. So, you can run the code locally for each player. Map is local, EH can be. So?

Use remoteExecution for something local (like addAction script) to be shared (hint...) or triggered on server (addscore...)

 

I have understood what GOM said, but this time I would like to know if the gunner of each aircraft is or not looking through the turret, so I need to remoteExec the command cameraView on the gunner’s pc since this command is local!

 

I have no clue of other ways to check if a player is just sitting as a copilot or if it is looking inside a turret to laser point something.

Share this post


Link to post
Share on other sites

A "gunner" of an aircraft is not necessary the copilot.
pilot is usually at turret -1 :   youraircraft turretUnit [-1]

copilot is usually at turret 0 :  youraircraft turretUnit [0]

 

you can have several other turrets like 1 for loadmaster or door gunner....

 

For your camera, see getCameraViewDirection (AG command, should work without remoteExec)

Share this post


Link to post
Share on other sites
12 minutes ago, pierremgi said:

A "gunner" of an aircraft is not necessary the copilot.
pilot is usually at turret -1 :   youraircraft turretUnit [-1]

copilot is usually at turret 0 :  youraircraft turretUnit [0]

 

you can have several other turrets like 1 for loadmaster or door gunner....

 

For your camera, see getCameraViewDirection (AG command, should work without remoteExec)

Please have a look at the code snippet in the post you reacted at.

I know what's the id of the turret I need, and what I would like to know is if this particular turret is being used or not (in the case of the helicopter I'm using, the copilot has the ability to use, with right mouse click, the laser pointer camera). This can be achieved locally with cameraView, that returns a string indicating if the local player is in 1st, 3rd or down sight with its camera. Now, it would be great to have my cone drawed to the map only when the turret is being used (so if the copilot of the helicopter has clicked right mouse button and it is currently looking through the laser pointer camera).

For this reason, I thought that remote executing the "cameraView" command to the machine where the copilot/laserpointer-camera-guy is and then have all the needed calculations (orientation and thus cone coordinates) only on the copilot machine was a good idea, then remote executing "back to other" Blufor clients the resulting cone to be drawn.

Maybe now my aim is more clear, so please don't get "angry", I'm not ignoring your or else' posts, simply I'm trying to think using what I have/know :)

Is there any other way to get this information, since the cameraView command works only locally? getCameraView direction returns a player's head direction (that faces forward of the aircraft when using the laser pointer turret).


Thank you for your time.

Share this post


Link to post
Share on other sites

just try something like:

 

inside your EH Draw,

if (cameraView == "gunner") then { vehicle player setVariable ["angleCam",round player getRelDir (positionCameraToWorld [0,0,1000]),true] } else { vehicle player setVariable ["angleCam",0,true] };

 

locally. The last param of setVariable set to true means broadcast over net. So, you can draw you polygon picking the angleCam variable which is attached to the vehicle player (locally). 

  • Like 1

Share this post


Link to post
Share on other sites
29 minutes ago, pierremgi said:

just try something like:

 

inside your EH Draw,

if (cameraView == "gunner") then { vehicle player setVariable ["angleCam",round player getRelDir (positionCameraToWorld [0,0,1000]),true] } else { vehicle player setVariable ["angleCam",0,true] };

 

locally. The last param of setVariable set to true means broadcast over net. So, you can draw you polygon picking the angleCam variable which is attached to the vehicle player (locally). 

This is perfect and works the way I intended to do.

I didn't remember about setVariable broadcast ability at all! Thank you!

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×