StealthAI¶
Gives the ability of the NPCControl to spot the player if it enters its field of vision (represented by 2 trigger colliders) which has the effect of triggering an event. The event id and the wideness of the field of vision are configurable as well as an option to set the entity.animstate to Sleep
at the start of the DoBehavior cycle.
Frequency meaning¶
The same than SetPath, but with the addition that if it's 5555, the entity.animstate is set to Sleep
at the start of the DoBehavior cycle (right after the returntoheight
logic).
Additional data¶
vectordata
: The same than SetPathbattleids[0]
: An event id that will be started when the player is spottedbattleids[1]
: A value that represents how wide the NPCControl's vision is. It's the z size of the trigger BoxCollider of the StealthCheck, a component attached to the entity.detect
that can spot the player if it collides with it and its SphereCollider. It also influences the z center of the BoxCollider with the value being half of this one floored.
SetUp¶
- entity.
detect
is ensured to be created which makes sure the entity has a wall detector - A new StealthCheck component gets childed to the entity.
detect
with a local position of Vector3.zero and aparent
field of this NPCControl. - entity.
alwaysactive
is set to true - entity.
extratimer
is set to true
DoBehavior¶
The same than SetPath, but with the addition that if the frequency is 5555, the entity.animstate is set to Sleep
at the start of the DoBehavior cycle (right after the returntoheight
logic).
Update (Inactive, every 3 frames)¶
Normally, when an entity is in a forcemove
, StopForceMove is called on it, but this behavior is an exception to this where it will not be called here.
Update (Common, end)¶
As long as the behavior exist on the NPCControl, actioncooldown
is set to 1.0 if the player is present and not digging
while the message lock is active. This has the overall effect to have the underlying SetPath logic operate as if it has a frequency of 1.0 meaning 1.0 frames of cooldown between movement.
LateUpdate (RefreshPlayer)¶
After the new inrange
value is set and the new value is true a StealthSpot coroutine is called. There is an exception where this doesn't happen if this is an Enemy when the freezecooldown
or dizzytime
hasn't expired yet.
OnTriggerEnter (If this is an NPC)¶
A StealthSpot coroutine starts if the other collider is the player.beemerang
and the square distance between this NPCControl and the player is less than 30.0
OnCollisionEnter (If this is an NPC)¶
If the other gameObject tag is Hornable
and the other's Hornable type is IceCube
(meaning it's a Dropplet ice cube), ShatterDroppletIce is called on the other's Hornable parent
(the Dropplet
NPCControl). This basically shatters the cube whenever an NPCControl with this behavior present (inrange
or not) collides with it.
StealthSpot¶
This is a public coroutine specific to this behavior (the only reason it's public is for StealthCheck to be able to start it). Its job is to verify that the NPCControl has indeed spotted the player and to process it if it has.
A Linecast will be performed from this NPCControl position + Vector3.up to the player position + Vector3.up for only layers Ground
, NoDigGround
and Player
.
For the spotting to register, all of the following conditions must be true:
startlife
is above 20.0- The Linecast hit any
playerdata
entity - The player is free (ignoring flying)
- The player isn't
digging
battleids[0]
isn't negative
If the above are met, StopForceMove is called on the entity followed by the event whose id is battleids[0]
starting with this NPCControl as the caller.
No matter if the spotting was processed or not, a frame is yielded.
StealthCheck¶
This is a component specifically involved with this behavior as it is attached to the entity.detect
on SetUp. Its job is to be the way the NPCControl can spot the player with 2 trigger colliders.
These colliders are added on the component's Start:
- A trigger SphereCollider with radius 1.5 and default position (meaning at the entity.
detect
's position) - A trigger BoxCollider with size (2.5, 2.0, NPCControl's
battleids[1]
) and center (0.0, 1.5, half of NPCControl'sbattleids[1]
floored)
The Start also puts the entity.detect
GameObject in layer 2, the built in layer of Unity to ignore raycasts.
From there, the only interesting logic this component has is an OnTriggerEnter where the method will call StealthSpot under the following conditions:
- The player must be present and free (flying counts as not free)
- If the other collider is the player.
beemerang
, it must be less than 30.0 away from the entity.detect
- If it's the player, the internal cooldown of the component must be expired
If the above is met, SteatlhStop is called which will verify that it is actually a spot. It also will set the internal cooldown to 3.0.
What this cooldown does is it prevents the player collider from doing anything for a certain time in frames. This cooldown is decremented on LateUpdate if it hasn't expired yet. The overall effect is no player collider spotting can happen if StealthSpot was called up to 3 frames ago by this component.