Leopard20 813 Posted July 3, 2017 Hi. I am trying to make a script where the nearby AI names appear next to them (using drawIcon3D) when a certain key is pressed. I want their names to appear the instant the key is pressed and start to fade out in the next 5 seconds. How can I do that? P.S: I don't want you to describe all the steps! So far my script successfully shows the AI names (when the player is within 50 meters of them); I just need help with the fade out part. Share this post Link to post Share on other sites
mrcurry 496 Posted July 3, 2017 Well depends how you are showing the names but if you are using something running on each frame just save the last time the key was pressed and calculate the alpha value of the colour based on how long it was since the key was pressed. Checkout linearConversion command, it does the math for you. 1 Share this post Link to post Share on other sites
pokertour 30 Posted July 3, 2017 in the init you can use something like this : waituntil {!(IsNull (findDisplay 46))}; _keyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", "if (_this select 1 == 50) then {Exec what you want}"]; 50 is the digit number of Key https://community.bistudio.com/wiki/DIK_KeyCodes ops, sorry i don't read this part " I just need help with the fade out part. " :) Edit : Did you try with a "For" in your script maybe somthing like this i can't test : _alpha = 1; for "_i" from 1 to 10 do { drawIcon3D ["", [1,0,0,_alpha], position cursorTarget, 0, 0, 0, "Target", 1, 0.05, "PuristaMedium"]; _alpha = _alpha - 0.1; sleep 0.5; }; 1 Share this post Link to post Share on other sites
Leopard20 813 Posted July 3, 2017 1 hour ago, pokertour said: in the init you can use something like this : waituntil {!(IsNull (findDisplay 46))}; _keyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", "if (_this select 1 == 50) then {Exec what you want}"]; 50 is the digit number of Key https://community.bistudio.com/wiki/DIK_KeyCodes ops, sorry i don't read this part " I just need help with the fade out part. " :) Edit : Did you try with a "For" in your script maybe somthing like this i can't test : _alpha = 1; for "_i" from 1 to 10 do { drawIcon3D ["", [1,0,0,_alpha], position cursorTarget, 0, 0, 0, "Target", 1, 0.05, "PuristaMedium"]; _alpha = _alpha - 0.1; sleep 0.5; }; Thanks for your reply. This is part of the script that I'm writing. I added the code you said as follows (I use button 4 (not Numpad 4) to show the names): ["MY_SQUAD_POS", "onEachFrame", { { _MY_UNIT_ICON = "a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_stand_ca.paa"; _MY_UNITPOS = visiblePosition _x; _MY_UNIT_STANCE = unitPos _x; _MY_ASSIGNED_TEAM_COLOR = assignedTeam _x; if (_MY_UNIT_STANCE == "MIDDLE") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_crouch_ca.paa";}; if (_MY_UNIT_STANCE == "DOWN") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_prone_ca.paa";}; if (surfaceIsWater (_MY_UNITPOS)) then {_MY_UNITPOS = visiblePositionASL _x;}; waituntil {!(IsNull (findDisplay 46))}; _keyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", "if (_this select 1 == 5) then { _alpha = 1; _MY_TEAM_COLOR = [1,1,1,_alpha]; if (_MY_ASSIGNED_TEAM_COLOR == "GREEN") then {_MY_TEAM_COLOR = [0,0.8,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "RED") then {_MY_TEAM_COLOR = [1,0,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "BLUE") then {_MY_TEAM_COLOR = [0,0,1,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "YELLOW") then {_MY_TEAM_COLOR = [0.8,0.8,0,_alpha];}; for "_i" from 1 to 10 do { if (player distance _MY_UNITPOS <= 25) then {drawIcon3D [_MY_UNIT_ICON,_MY_TEAM_COLOR,_MY_UNITPOS, 1.2,1.2, 0, (name _x), 1, 0.04, "PuristaMedium"];}; _alpha = _alpha - 0.1; sleep 0.5; }; }"]; } count MY_Selected_Team; }] call BIS_fnc_addStackedEventHandler; true But now nothing is shown. Any idea why? P.S: I am new to script writing. Go easy on me! Share this post Link to post Share on other sites
pokertour 30 Posted July 3, 2017 Which part of my example did you copy in your script ? Did you enabled the "ShowScriptError" on arma 3 launcher ? it's more easy to know where is the problem :) 1 Share this post Link to post Share on other sites
HallyG 239 Posted July 3, 2017 Right, just a few things to help you out here: Firstly, you are adding a eventHandler to a display on each frame when you only need to add it at the beginning (for example at the start of the script). Secondly, the code supplied to the eventHandler contains private variables which will be undefined when it is called and hence will not display and icon. Thirdly, sleep and waitUntil require script suspension. EachFrame is an unscheduled environment and hence does not have script suspension by itself. This is my version for you, with some comments to help explain: // Spawn the script since waitUntil requires script suspension (debug console is unscheduled environment which is where I am testing this from) h = [] spawn { // Wait until display 46 is shown waituntil {!(isNull (findDisplay 46))}; // Add key down eventhandler to display // Only need to add to the display once hence it is outside the loop and at the begining of the script _keyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", { if (_this select 1 == 5) then { // If key is presssed setVariable on player to flag that icons should be displayed player setVariable ["lastTimeShown", time]; }; }]; ["MY_SQUAD_POS", "onEachFrame", { { _MY_UNIT_ICON = "a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_stand_ca.paa"; _MY_UNITPOS = visiblePosition _x; _MY_UNIT_STANCE = unitPos _x; _MY_ASSIGNED_TEAM_COLOR = assignedTeam _x; if (surfaceIsWater (_MY_UNITPOS)) then {_MY_UNITPOS = visiblePositionASL _x;}; // If the unit is not within range, don't bother which the rest of the script if !(player distance _MY_UNITPOS <= 25) exitWith {}; if (_MY_UNIT_STANCE == "MIDDLE") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_crouch_ca.paa";}; if (_MY_UNIT_STANCE == "DOWN") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_prone_ca.paa";}; // Get the last time the button was pressed, if the button has never been pressed, return -1 private _lastTime = player getVariable ["lastTimeShown", -1]; // Could change the alpha value dependent on other conditions here _alpha = 1; // Alpha decreases linearly from 1 to 0 // This will decrease across the time period from when the button is pressed, to 3 seconds after it is pressed _alpha = linearConversion [_lastTime, _lastTime + 3, time, _alpha, 0, true]; // If alpha is 0 (can't see icon) or button has never been pressed, dont bother with the rest of the script if (_alpha <= 0 || _lastTime isEqualTo -1) exitWith {false}; _MY_TEAM_COLOR = [1,1,1,_alpha]; if (_MY_ASSIGNED_TEAM_COLOR == "GREEN") then {_MY_TEAM_COLOR = [0,0.8,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "RED") then {_MY_TEAM_COLOR = [1,0,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "BLUE") then {_MY_TEAM_COLOR = [0,0,1,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "YELLOW") then {_MY_TEAM_COLOR = [0.8,0.8,0,_alpha];}; drawIcon3D [ _MY_UNIT_ICON, _MY_TEAM_COLOR, _MY_UNITPOS, 1.2,1.2, 0, (name _x), 1, 0.04, "PuristaMedium" ]; true; } count MY_Selected_Team; }] call BIS_fnc_addStackedEventHandler; }; 2 Share this post Link to post Share on other sites
Leopard20 813 Posted July 3, 2017 16 minutes ago, pokertour said: Which part of my example did you copy in your script ? Did you enabled the "ShowScriptError" on arma 3 launcher ? it's more easy to know where is the problem :) I used the for loop you suggested and the _keydown part. I think the error was in using quotaion marks " instead of brackets { } in the line where _keydown is defined. Now that I have replaced " with { }, when I press button 4 the game freezes for a few seconds and then continues, again without showing anything. Share this post Link to post Share on other sites
Leopard20 813 Posted July 3, 2017 37 minutes ago, HallyG said: Right, just a few things to help you out here: Firstly, you are adding a eventHandler to a display on each frame when you only need to add it at the beginning (for example at the start of the script). Secondly, the code supplied to the eventHandler contains private variables which will be undefined when it is called and hence will not display and icon. Thirdly, sleep and waitUntil require script suspension. EachFrame is an unscheduled environment and hence does not have script suspension by itself. This is my version for you, with some comments to help explain: // Spawn the script since waitUntil requires script suspension (debug console is unscheduled environment which is where I am testing this from) h = [] spawn { // Wait until display 46 is shown waituntil {!(isNull (findDisplay 46))}; // Add key down eventhandler to display // Only need to add to the display once hence it is outside the loop and at the begining of the script _keyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", { if (_this select 1 == 5) then { // If key is presssed setVariable on player to flag that icons should be displayed player setVariable ["lastTimeShown", time]; }; }]; ["MY_SQUAD_POS", "onEachFrame", { { _MY_UNIT_ICON = "a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_stand_ca.paa"; _MY_UNITPOS = visiblePosition _x; _MY_UNIT_STANCE = unitPos _x; _MY_ASSIGNED_TEAM_COLOR = assignedTeam _x; if (surfaceIsWater (_MY_UNITPOS)) then {_MY_UNITPOS = visiblePositionASL _x;}; // If the unit is not within range, don't bother which the rest of the script if !(player distance _MY_UNITPOS <= 25) exitWith {}; if (_MY_UNIT_STANCE == "MIDDLE") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_crouch_ca.paa";}; if (_MY_UNIT_STANCE == "DOWN") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_prone_ca.paa";}; // Get the last time the button was pressed, if the button has never been pressed, return -1 private _lastTime = player getVariable ["lastTimeShown", -1]; // Could change the alpha value dependent on other conditions here _alpha = 1; // Alpha decreases linearly from 1 to 0 // This will decrease across the time period from when the button is pressed, to 3 seconds after it is pressed _alpha = linearConversion [_lastTime, _lastTime + 3, time, _alpha, 0, true]; // If alpha is 0 (can't see icon) or button has never been pressed, dont bother with the rest of the script if (_alpha <= 0 || _lastTime != -1) exitWith {false}; _MY_TEAM_COLOR = [1,1,1,_alpha]; if (_MY_ASSIGNED_TEAM_COLOR == "GREEN") then {_MY_TEAM_COLOR = [0,0.8,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "RED") then {_MY_TEAM_COLOR = [1,0,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "BLUE") then {_MY_TEAM_COLOR = [0,0,1,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "YELLOW") then {_MY_TEAM_COLOR = [0.8,0.8,0,_alpha];}; drawIcon3D [ _MY_UNIT_ICON, _MY_TEAM_COLOR, _MY_UNITPOS, 1.2,1.2, 0, (name _x), 1, 0.04, "PuristaMedium" ]; true; } count MY_Selected_Team; }] call BIS_fnc_addStackedEventHandler; }; Thanks for your reply. I used the exact same version of your script but still nothing happens. Strange... Share this post Link to post Share on other sites
HallyG 239 Posted July 3, 2017 @Leopard20, my bad, I forgot to remove an exclamation mark. I edited my code above, so please try again! 1 Share this post Link to post Share on other sites
Leopard20 813 Posted July 3, 2017 39 minutes ago, HallyG said: Right, just a few things to help you out here: Firstly, you are adding a eventHandler to a display on each frame when you only need to add it at the beginning (for example at the start of the script). Secondly, the code supplied to the eventHandler contains private variables which will be undefined when it is called and hence will not display and icon. Thirdly, sleep and waitUntil require script suspension. EachFrame is an unscheduled environment and hence does not have script suspension by itself. This is my version for you, with some comments to help explain: // Spawn the script since waitUntil requires script suspension (debug console is unscheduled environment which is where I am testing this from) h = [] spawn { // Wait until display 46 is shown waituntil {!(isNull (findDisplay 46))}; // Add key down eventhandler to display // Only need to add to the display once hence it is outside the loop and at the begining of the script _keyDown = (findDisplay 46) displayAddEventHandler ["KeyDown", { if (_this select 1 == 5) then { // If key is presssed setVariable on player to flag that icons should be displayed player setVariable ["lastTimeShown", time]; }; }]; ["MY_SQUAD_POS", "onEachFrame", { { _MY_UNIT_ICON = "a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_stand_ca.paa"; _MY_UNITPOS = visiblePosition _x; _MY_UNIT_STANCE = unitPos _x; _MY_ASSIGNED_TEAM_COLOR = assignedTeam _x; if (surfaceIsWater (_MY_UNITPOS)) then {_MY_UNITPOS = visiblePositionASL _x;}; // If the unit is not within range, don't bother which the rest of the script if !(player distance _MY_UNITPOS <= 25) exitWith {}; if (_MY_UNIT_STANCE == "MIDDLE") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_crouch_ca.paa";}; if (_MY_UNIT_STANCE == "DOWN") then {_MY_UNIT_ICON = "\a3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\si_prone_ca.paa";}; // Get the last time the button was pressed, if the button has never been pressed, return -1 private _lastTime = player getVariable ["lastTimeShown", -1]; // Could change the alpha value dependent on other conditions here _alpha = 1; // Alpha decreases linearly from 1 to 0 // This will decrease across the time period from when the button is pressed, to 3 seconds after it is pressed _alpha = linearConversion [_lastTime, _lastTime + 3, time, _alpha, 0, true]; // If alpha is 0 (can't see icon) or button has never been pressed, dont bother with the rest of the script if (_alpha <= 0 || _lastTime isEqualTo -1) exitWith {false}; _MY_TEAM_COLOR = [1,1,1,_alpha]; if (_MY_ASSIGNED_TEAM_COLOR == "GREEN") then {_MY_TEAM_COLOR = [0,0.8,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "RED") then {_MY_TEAM_COLOR = [1,0,0,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "BLUE") then {_MY_TEAM_COLOR = [0,0,1,_alpha];}; if (_MY_ASSIGNED_TEAM_COLOR == "YELLOW") then {_MY_TEAM_COLOR = [0.8,0.8,0,_alpha];}; drawIcon3D [ _MY_UNIT_ICON, _MY_TEAM_COLOR, _MY_UNITPOS, 1.2,1.2, 0, (name _x), 1, 0.04, "PuristaMedium" ]; true; } count MY_Selected_Team; }] call BIS_fnc_addStackedEventHandler; }; AWESOME! It works like a charm!!! BTW, can you please explain what the spawn at the start does? That's the part I don't understand. Share this post Link to post Share on other sites
HallyG 239 Posted July 3, 2017 17 minutes ago, Leopard20 said: AWESOME! It works like a charm!!! BTW, can you please explain what the spawn at the start does? That's the part I don't understand. The purpose of the spawn was because I was testing the script quickly in the debug console. The debug console executes code in an unscheduled environment which does not allow script suspension. In the script, I am using the waitUntil command to wait until display 46 (the primary display) has been created before I add a "KeyDown" eventhandler to that display. In order to use waitUntil, without returning an error, it needs to be run in an environment which allows script suspension. In order to do this, I needed to spawn the script which then added the code to the scheduler and hence allowed script suspension. 1 Share this post Link to post Share on other sites
Leopard20 813 Posted July 3, 2017 @HallyG, thank you for your help and clear explanation. I appreciate it. @pokertour and @mrcurry, thank you too for your help. 2 Share this post Link to post Share on other sites