Jump to content
LSValmont

hideObjectGlobal preventing Ai targeting... (WORKAROUND FOUND!)

Recommended Posts

Agent dogs with an attached invisible unit so that other Ai can attack them...

 

The problem is... as soon as I hide their models using hideObjectGlobal the Ai no longer targets them... as the below pic shows when unhidden the Ai shoots at them just fine.

 

Spoiler

Arma3-x64-2020-04-29-02-20-01.png

 

This is how I create the hidden agent:

vVirtualEnemy = {
params ["_unit"]; 
_ai = createAgent ["I_Survivor_F", [0,0,0], [], 0, "CAN_COLLIDE"];
_ai setFace "";
//hideObjectGlobal _ai;
_ai disableAI "ALL";
//{_ai enableAI _x} forEach ["ANIM","TEAMSWITCH","CHECKVISIBLE"];
[_ai, "Acts_AidlPsitMstpSsurWnonDnon01"] remoteExec ["switchMove", 0];
_ai enableStamina false;
_ai setUnitPos "MIDDLE";
_ai disablecollisionwith _unit; 
_unit disablecollisionwith _ai; 
_ai attachTo [_unit, [0,0,0]];
_unit setVariable ["_attAi", _ai, true];
_unit addEventHandler ["Killed", {deleteVehicle ((_this # 0) getVariable "_attAi")}];
//_ai forceSpeed 2;
//_ai setAnimSpeedCoef 3;
[_ai] join (group _unit);
_ai addRating -100000; // Make sure is renegade!
_ai allowdamage false;
_ai setSpeaker "NoVoice";
_ai setSkill 0;
};

How can I hide the virtual unit's models yet still be targeteable by other enemy ai?

Share this post


Link to post
Share on other sites

well cannot see something invisible right?

You can probably instead of spawning I_Survivor_F use the "fake" units that are used as pilots in UAV's, they are not hidden but they have a invisible model. Maybe thats sufficient

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
13 hours ago, Dedmen said:

well cannot see something invisible right?

You can probably instead of spawning I_Survivor_F use the "fake" units that are used as pilots in UAV's, they are not hidden but they have a invisible model. Maybe thats sufficient

 

That is a good tip! I will give it a try!

 

I guess these fake Invisible UAV pilots are: "B_UAV_AI", "O_UAV_AI" or "I_UAV_AI" depending on side.

 

Do you by any chance know if they can be spawned as agents, become renegades and are they attacked by enemy Ai?

 

Also, @Grumpy Old Man once said a long time ago about those UAV fake units that:

 

On 9/29/2016 at 9:13 AM, Grumpy Old Man said:

Thing is, these AI units are basically deleting themselves when not spawned inside a vehicle.

 

Cheers

Share this post


Link to post
Share on other sites

It seems @johnnyboy attaches the unit underground to prevent them being visible.

 

Perhaps there is also an animation that makes the model barely visible?

 

Looking for solutions urgently before I run out of free time 😉 

Share this post


Link to post
Share on other sites

Here's the code from JBOY_Dog that gets AI to fire on dogs.  It uses invisible target object B_TargetSoldier.  AI won't target it unless this object is crewed via createVehicleCrew.  One lame thing that occurs is the AI will shout "Static Weapon" when they are aware of the target.  As you can see in the code, I had to adjust attachTo position of target under different circumstances.  I don't recall why that was.  I know this did work pretty well though.

Spoiler

//////////////////////////////////////////////////////////
// JBOY_AIFightsDogs.sqf
// Created by: johnnyboy
// nul = [_targetObj,_dog] execvm "JBOY_Dog\JBOY_AIFightsDogs.sqf";
//
//////////////////////////////////////////////////////////
if (!isServer)  exitwith {};
params ["_dude","_dog"];
if (isPlayer _dude) exitwith {};
//*************************************************
// Execute this on each Unit being attacked by dog(s)
// First assign unit a "pack attack variable"
// If already has variable, then exit, so script only executing once per unit
//*************************************************
if !(isnil {_dude getvariable "vAttackedByDogs"} )  exitwith {};
_dude setvariable ["vAttackedByDogs",true,true];

// delayed reaction to dog attack
_reactionDistance = 5 + random 15;
waituntil {sleep .5; (_dog distance _dude) <= _reactionDistance or !alive _dog or !alive _dude };
//sleep 3+random 10;
// **********************************************
// Get dude ready to fight and reveal all near dogs to him.
// **********************************************
_dude setUnitPos "UP"; 
_dude setBehaviour "COMBAT"; 

_assignedDog = _dog;
_nearDogs = [];
{
   if (alive _x) then
   {
        _nearDogs pushBack _x;    // add dog to enemy dog list that dude knowsabout
   };
} foreach ((getpos _dude) nearObjects ["Dog_Base_F", 200]);  // all near dogs
  
// **********************************************
// Initially target assigned dog
// **********************************************
_targetDog = _assignedDog;
sleep 1;
dostop _dude;
// **********************************************
// Create an invisible target for AI to shoot at (aka bullet magnet). For debugging, attach a sphere so we can see where target is.
// **********************************************
//_bulletMagnetUnitType = "B_Survivor_F";
_bulletMagnetUnitType = "B_TargetSoldier";
_bulletMagnet = createVehicle [_bulletMagnetUnitType, [0,0,0], [], 0, "CAN_COLLIDE"];
//_sphere = createVehicle ['Sign_Sphere25cm_F', [0,0,0], [], 0, "CAN_COLLIDE"];
//_sphere attachTo [_bulletMagnet,[0,0,0]];
//_bulletMagnet setunitPOS "DOWN";
_bulletMagnet lockTurret [[0],true]; // target object has a gunner position, so lock it so player isn't offered "get in gunner" option when near dog
createVehicleCrew _bulletMagnet;
_bulletMagnet enableCollisionWith _dog;
_bulletMagnet attachTo [_dog,[0,-1,.3]];//[_dog,[0,-1,.3]];

_enemy = _bulletMagnet;
_enemy allowdamage false;

_cnt = 0;
_dude reveal _enemy;
_dude doTarget _enemy;
_dude dofire _enemy;
_dude setVariable ["vTargetDog", _enemy, true];
 sleep 2;
 // *****************************************************************************
 // Spawn separate loop for targeting with different sleep timing. Less frequent 
 // target changing will hopefully reduce rifle raising/lowering retardation.
 // *****************************************************************************
_nul= [_dude, _nearDogs, _bulletMagnet]
spawn
{
    params["_dude", "_nearDogs","_bulletMagnet"];
  
    // **********************************************
    // Loop until all dogs dead, or dude dead, or no dogs left with an assigned target (i.e., attack called off)
    // **********************************************
    _prevTarget = objNull;
    while {alive _dude and ({alive _x and (_x distance _dude)<100} count _nearDogs) > 0} do
    {
        //_nearDogs deleteAt (_nearDogs find _targetDog);
        _targetDog = [_dude, _nearDogs] call JBOY_getClosestObjFromArray; // target closest dog
        // This handles case where player accidentally commands dogs to attack friendlies so friendlies shoot at dog
        // But if player commands dog to stop, the following will then have friendlies stop shooting at dog.  Without this, friendlies continue to shoot at dog no matter what.
        if (_targetDog getVariable "vSide" == side _dude and _targetDog getVariable "vCommand" != "attack") then 
        {
            _targetDog = objNull;  // prevents following if statement from targeting the dog
            _nearDogs = _nearDogs - [_targetDog]; // remove dog from near dogs array to end ai shooting at him
        };
        _enemy = _targetDog;
        if (_prevTarget != _targetDog) then  // assign new target.
        {
        _prevTarget = _targetDog;
             _dude dowatch objnull;
            _enemy = _bulletMagnet;
            _dude setVariable ["vTargetDog", _enemy, true];
            //_enemy = (_targetDog getVariable "vBulletMagnet");
            _bulletMagnet enableCollisionWith _targetDog;
            _dude reveal _enemy;
            if ((_dude distance _targetDog) > 15) then
            {
                detach _bulletMagnet;
                _bulletMagnet attachTo [_targetDog,[0,-1.5,.5]]; //[_targetDog,[0,-1.5,.5]];
                _dude reveal _bulletMagnet;
                // watch only when far
                //_dude doWatch  _targetDog;
            _dude doTarget _enemy;
            _dude dofire _enemy;
            } else
            {
               detach _bulletMagnet;
               _bulletMagnet attachTo [_targetDog,[0,-.3,.5]]; // set target back further so shooter adjusts shooting angle
               _dude reveal _bulletMagnet;
               // target and fire when close
            _dude doTarget _enemy;
            _dude dofire _enemy;
            };
            /*
            _dude doWatch  _targetDog;
            _dude doTarget _enemy;
            _dude dofire _enemy;
            */
       };
        //_dude doWatch ([_dude, (_dude distance _targetDog)-4, ([_dude, _targetDog] call BIS_fnc_dirTo)] call BIS_fnc_relPos);
        sleep .2;
    };
};  // End spawn.
// *****************************************************************************
// This loop for firing.  It sleeps less to fire more often.
// *****************************************************************************
while {alive _dude and ({alive _x and (_x distance _dude)<100} count _nearDogs) > 0} do
{
    if (isPlayer _dude) exitwith {}; // In case player spawns into AI during group respawn.
    _cnt = _cnt + 1;
    if (count _nearDogs >0) then
    {        
       //if (abs(getdir _dude - ([_dude, _enemy] call BIS_fnc_dirTo)) < 80 and ((_dude distance _enemy)) <100) then
       if (abs(getdir _dude - ([_dude, (_dude getVariable "vTargetDog")] call BIS_fnc_dirTo)) < 45 and ((_dude distance (_dude getVariable "vTargetDog"))) <100) then
       {
            for "_i" from 0 to (3+random 5) do
            {
                 JBOYDogGameLogic action ["useWeapon",_dude,_dude,0];
                 // _dude forceWeaponFire [ weaponState _dude select 1, weaponState _dude select 2];
                 sleep .01;
            };
        };
        sleep .3;
    };
}; // End While
_dude setvariable ["vAttackedByDogs",false,true];

if (alive _dude) then
{
    _dude setUnitPos "AUTO"; 
    _dude doWatch objNull;
    _dude setBehaviour "SAFE";
} else 
{
    deleteVehicle _bulletMagnet;
};

 

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
On 4/29/2020 at 2:38 PM, johnnyboy said:

Here's the code from JBOY_Dog that gets AI to fire on dogs.  It uses invisible target object B_TargetSoldier.  AI won't target it unless this object is crewed via createVehicleCrew.  One lame thing that occurs is the AI will shout "Static Weapon" when they are aware of the target.  As you can see in the code, I had to adjust attachTo position of target under different circumstances.  I don't recall why that was.  I know this did work pretty well though.

  Reveal hidden contents


//////////////////////////////////////////////////////////
// JBOY_AIFightsDogs.sqf
// Created by: johnnyboy
// nul = [_targetObj,_dog] execvm "JBOY_Dog\JBOY_AIFightsDogs.sqf";
//
//////////////////////////////////////////////////////////
if (!isServer)  exitwith {};
params ["_dude","_dog"];
if (isPlayer _dude) exitwith {};
//*************************************************
// Execute this on each Unit being attacked by dog(s)
// First assign unit a "pack attack variable"
// If already has variable, then exit, so script only executing once per unit
//*************************************************
if !(isnil {_dude getvariable "vAttackedByDogs"} )  exitwith {};
_dude setvariable ["vAttackedByDogs",true,true];

// delayed reaction to dog attack
_reactionDistance = 5 + random 15;
waituntil {sleep .5; (_dog distance _dude) <= _reactionDistance or !alive _dog or !alive _dude };
//sleep 3+random 10;
// **********************************************
// Get dude ready to fight and reveal all near dogs to him.
// **********************************************
_dude setUnitPos "UP"; 
_dude setBehaviour "COMBAT"; 

_assignedDog = _dog;
_nearDogs = [];
{
   if (alive _x) then
   {
        _nearDogs pushBack _x;    // add dog to enemy dog list that dude knowsabout
   };
} foreach ((getpos _dude) nearObjects ["Dog_Base_F", 200]);  // all near dogs
  
// **********************************************
// Initially target assigned dog
// **********************************************
_targetDog = _assignedDog;
sleep 1;
dostop _dude;
// **********************************************
// Create an invisible target for AI to shoot at (aka bullet magnet). For debugging, attach a sphere so we can see where target is.
// **********************************************
//_bulletMagnetUnitType = "B_Survivor_F";
_bulletMagnetUnitType = "B_TargetSoldier";
_bulletMagnet = createVehicle [_bulletMagnetUnitType, [0,0,0], [], 0, "CAN_COLLIDE"];
//_sphere = createVehicle ['Sign_Sphere25cm_F', [0,0,0], [], 0, "CAN_COLLIDE"];
//_sphere attachTo [_bulletMagnet,[0,0,0]];
//_bulletMagnet setunitPOS "DOWN";
_bulletMagnet lockTurret [[0],true]; // target object has a gunner position, so lock it so player isn't offered "get in gunner" option when near dog
createVehicleCrew _bulletMagnet;
_bulletMagnet enableCollisionWith _dog;
_bulletMagnet attachTo [_dog,[0,-1,.3]];//[_dog,[0,-1,.3]];

_enemy = _bulletMagnet;
_enemy allowdamage false;

_cnt = 0;
_dude reveal _enemy;
_dude doTarget _enemy;
_dude dofire _enemy;
_dude setVariable ["vTargetDog", _enemy, true];
 sleep 2;
 // *****************************************************************************
 // Spawn separate loop for targeting with different sleep timing. Less frequent 
 // target changing will hopefully reduce rifle raising/lowering retardation.
 // *****************************************************************************
_nul= [_dude, _nearDogs, _bulletMagnet]
spawn
{
    params["_dude", "_nearDogs","_bulletMagnet"];
  
    // **********************************************
    // Loop until all dogs dead, or dude dead, or no dogs left with an assigned target (i.e., attack called off)
    // **********************************************
    _prevTarget = objNull;
    while {alive _dude and ({alive _x and (_x distance _dude)<100} count _nearDogs) > 0} do
    {
        //_nearDogs deleteAt (_nearDogs find _targetDog);
        _targetDog = [_dude, _nearDogs] call JBOY_getClosestObjFromArray; // target closest dog
        // This handles case where player accidentally commands dogs to attack friendlies so friendlies shoot at dog
        // But if player commands dog to stop, the following will then have friendlies stop shooting at dog.  Without this, friendlies continue to shoot at dog no matter what.
        if (_targetDog getVariable "vSide" == side _dude and _targetDog getVariable "vCommand" != "attack") then 
        {
            _targetDog = objNull;  // prevents following if statement from targeting the dog
            _nearDogs = _nearDogs - [_targetDog]; // remove dog from near dogs array to end ai shooting at him
        };
        _enemy = _targetDog;
        if (_prevTarget != _targetDog) then  // assign new target.
        {
        _prevTarget = _targetDog;
             _dude dowatch objnull;
            _enemy = _bulletMagnet;
            _dude setVariable ["vTargetDog", _enemy, true];
            //_enemy = (_targetDog getVariable "vBulletMagnet");
            _bulletMagnet enableCollisionWith _targetDog;
            _dude reveal _enemy;
            if ((_dude distance _targetDog) > 15) then
            {
                detach _bulletMagnet;
                _bulletMagnet attachTo [_targetDog,[0,-1.5,.5]]; //[_targetDog,[0,-1.5,.5]];
                _dude reveal _bulletMagnet;
                // watch only when far
                //_dude doWatch  _targetDog;
            _dude doTarget _enemy;
            _dude dofire _enemy;
            } else
            {
               detach _bulletMagnet;
               _bulletMagnet attachTo [_targetDog,[0,-.3,.5]]; // set target back further so shooter adjusts shooting angle
               _dude reveal _bulletMagnet;
               // target and fire when close
            _dude doTarget _enemy;
            _dude dofire _enemy;
            };
            /*
            _dude doWatch  _targetDog;
            _dude doTarget _enemy;
            _dude dofire _enemy;
            */
       };
        //_dude doWatch ([_dude, (_dude distance _targetDog)-4, ([_dude, _targetDog] call BIS_fnc_dirTo)] call BIS_fnc_relPos);
        sleep .2;
    };
};  // End spawn.
// *****************************************************************************
// This loop for firing.  It sleeps less to fire more often.
// *****************************************************************************
while {alive _dude and ({alive _x and (_x distance _dude)<100} count _nearDogs) > 0} do
{
    if (isPlayer _dude) exitwith {}; // In case player spawns into AI during group respawn.
    _cnt = _cnt + 1;
    if (count _nearDogs >0) then
    {        
       //if (abs(getdir _dude - ([_dude, _enemy] call BIS_fnc_dirTo)) < 80 and ((_dude distance _enemy)) <100) then
       if (abs(getdir _dude - ([_dude, (_dude getVariable "vTargetDog")] call BIS_fnc_dirTo)) < 45 and ((_dude distance (_dude getVariable "vTargetDog"))) <100) then
       {
            for "_i" from 0 to (3+random 5) do
            {
                 JBOYDogGameLogic action ["useWeapon",_dude,_dude,0];
                 // _dude forceWeaponFire [ weaponState _dude select 1, weaponState _dude select 2];
                 sleep .01;
            };
        };
        sleep .3;
    };
}; // End While
_dude setvariable ["vAttackedByDogs",false,true];

if (alive _dude) then
{
    _dude setUnitPos "AUTO"; 
    _dude doWatch objNull;
    _dude setBehaviour "SAFE";
} else 
{
    deleteVehicle _bulletMagnet;
};

 

 

 

Wow @johnnyboy, that is indeed an elaborate work around but potentially far more resource consuming (as there are several sub scripts running in the background to make it work) than just attaching another agent to the dogs like I am currently doing.

 

My best solution is to spawn an invisible agent or make these agents not visible somehow... I will try @Dedmen solution as soon as I am home.

 

Since my dogs run server side, perhaps another solution is to hide them locally on the clients only, so other server spawned Ai units will still see the attached agents and fire at them. The problem could be that on player hosted missions the host will still see the attached units while hidden for the rest of the players...

Share this post


Link to post
Share on other sites

I was unaware of the uav pilot units.  Hope it works.  I think once Agents are invisible, they won't be fired upon by AI, but do try it to prove it one way or the other.

 

Note that if uav pilot doesn't work, try substituting B_TargetSoldier.  You may not need the extra complexities of spawned scripts that I had.

 

I have the proof of concept 99% done for moving animals attached to invisible AI.  Animals will indeed run much faster, and controlling animal movement is much simpler as its now a matter of giving simple doMove or moveTo commands.  Whether its worth modifying vDog for I don't know.  Will post it later.

  • Thanks 1

Share this post


Link to post
Share on other sites

 

16 hours ago, Dedmen said:

well cannot see something invisible right?

You can probably instead of spawning I_Survivor_F use the "fake" units that are used as pilots in UAV's, they are not hidden but they have a invisible model. Maybe thats sufficient

 

Ok I can confirm that those fake UAV pilots do not work. (at least as agents)

 

6 hours ago, johnnyboy said:

I was unaware of the uav pilot units.  Hope it works.  I think once Agents are invisible, they won't be fired upon by AI, but do try it to prove it one way or the other.

 

Note that if uav pilot doesn't work, try substituting B_TargetSoldier.  You may not need the extra complexities of spawned scripts that I had.

 

I have the proof of concept 99% done for moving animals attached to invisible AI.  Animals will indeed run much faster, and controlling animal movement is much simpler as its now a matter of giving simple doMove or moveTo commands.  Whether its worth modifying vDog for I don't know.  Will post it later.

 

I can also now confirm that none of these work:

_ai = createAgent ["O_TargetSoldier", [0,0,0], [], 0, "CAN_COLLIDE"];
_ai = createAgent ["I_TargetSoldier", [0,0,0], [], 0, "CAN_COLLIDE"];
_ai = createAgent ["O_UAV_AI", [0,0,0], [], 0, "CAN_COLLIDE"];
_ai = createAgent ["O_UAV_AI_F", [0,0,0], [], 0, "CAN_COLLIDE"];

 

Perhaps @Dedmen can include some invisible units that can be spawned as agents for performance reasons or even better a command like hideObjectGlobal but that only hides the model while the unit is still there.

 

So far there is no solution other than doing a bunch of scripts and workarounds to get to job done it seems.

 

EDIT: I've managed to hide the agent while still his body and legs remain above ground level but invisible but turning them upside down. An inventive work around for the time being that is way better than anything we had before in terms of what this script aims for. (Dogs being targeted by regular Ai)

 

Share this post


Link to post
Share on other sites

Ok I think I've managed to do it.

 

All I needed was to attach the Agent upside down to the dogs as only the heads are visible and so now the heads are under ground while the Ai units still fire at the Dogs!

 

_virtualTarget attachTo [_unit, [0,0,0-0.2]];

_virtualTarget setVectorUp [0,0,-1];

 

A fun pic of the testings...

 

Dogs with floating heads!!!

 

Arma3-x64-2020-04-29-20-54-31.png

 

Thank you all who contributed!

  • Haha 2

Share this post


Link to post
Share on other sites

How about using the virtual entities without textures instead?

{
	_this setobjecttextureglobal [_x, ""]
} forEach [0,1,2,3,4,5]

 

  • Like 2

Share this post


Link to post
Share on other sites
59 minutes ago, haleks said:

How about using the virtual entities without textures instead?


{
	_this setobjecttextureglobal [_x, ""]
} forEach [0,1,2,3,4,5]

 

 

Thank you @haleks!

 

I've managed to do it! This will mean that finally animals are easy targets for Ai!

 

Of course I will be releasing my full vDog script tomorrow and also if you want it you can use it for your Ravage Dogs (Who are currently Units and not Agents I believe) for a performance boost!

 

PS: Everything I do is always Ravage compatible and also immediately yours to use 😉 

Share this post


Link to post
Share on other sites

@LSValmont: One thing to note though - that unit will cast a shadow if overcast is low enough...

If an addon version is an option, you could configure a dummy unit with the invisible model.

 

  • Like 2

Share this post


Link to post
Share on other sites
2 hours ago, haleks said:

One thing to note though - that unit will cast a shadow

this; lodNoShadow = 1;

would this work on units like it does on vehicles?

  • Confused 1

Share this post


Link to post
Share on other sites

This script with the workaround for this has been released!

 

You can check it out here:

 

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

×