Hello,
I have a small problem that I can’t seem to figure out. Hopefully I can describe and summarize the problem well enough to answer any queries about the problem.
Scene Hierarchy:
Actor1 - Layer: Faction1 - 1x1x1 in scale
-
- AggroTrigger - Layer: Faction1 - 10’ cubed
Actor2 - Layer: Faction2 - 1x1x1 in scale
- AggroTrigger - Layer: Faction1 - 10’ cubed
-
- AggroTrigger - Layer: Faction2 - 10’ cubed
Wall1 - Layer: Environment - 10x3x3 in scale
Wall2 - Layer: Environment - 10x3x3 in scale
- AggroTrigger - Layer: Faction2 - 10’ cubed
Scene Layout:
In the middle of the scene is Wall1 with Wall2 is parallel beside it. On one side is Actor1 and Actor2 is on the opposite side. All objects are on 0 z-axis.
Lame Text Visual:
1 = Actor1
2 = Actor2
| = wall
1 | | 2
Desired Effect:
Actor1 will move away from Actor2 if there is no line of sight. If Actor1 and Actor2 has a clear line of sight with one another, they will attack each other.
Problem:
At the start, Actor1 does what it is supposed to. With the walls in the way, there is no line of sight. However, when Actor1 goes outside the AggroTrigger, Actor1 and Actor2 for some reason see each other through the walls and start attacking each other.
Technical Setup:
OnTriggerEnter and OnTriggerExit are used on the AggroTrigger. When an enemy actor enters the trigger, it gets put into a list of enemies in range. When there is an enemy in range, a line of sight function is activated to see if the actor can see any of its targets. If it can’t see its target, do what it was doing. The line of sight function uses a Physics.Raycast with the same range as the AggroTrigger (AggroTrigger has a 20’ radius, the raycast is 20’ long).
Code Snippits:
I summarized, simplified, cleaned up, and commented the code as best as I could for easier viewing. The CheckLoS() function is where the Physics.Raycast part is at and is where I theorize where the issue lies.
// A script that when an object enters an aggro trigger, it puts the target into an array.
// Then it will use a Physics.Raycast to see if the target is in the line of sight.
// If the target is in line of sight, attack target.
var attackTarget : Transform; // the target the actor attacks
var aggroRange : int = 20; // how far away can the actor get aggro? used in raycast
var aggroArray : Array = new Array(); // all targets in aggro range
var aggro : boolean = false; // is the actor attacking something?
function Update()
{
// if the actor has aggro...
if (aggro)
{
// move towards and attack target
}
// if the aggro list isn't empty and the actor doesn't have an aggro target...
else if (aggroArray.length > 1 !aggro)
{
// check the line of sight
CheckLoS();
}
// if no aggro...
else
{
// move towards destination
}
}
function OnTriggerEnter (hit : Collider)
{
// layer 15 is the environment layer
if (hit.gameObject.layer != gameObject.layer hit.gameObject.layer != 15 hit.gameObject.layer != 16 hit.gameObject.name != "AggroRange")
{
// add target to aggro list
}
}
function OnTriggerExit (hit : Collider)
{
// layer 15 is the environment layer
if (hit.gameObject.layer != gameObject.layer hit.gameObject.layer != 15)
{
// remove target from aggro list
}
}
// a function that checks to see if the aggro object in range can be seen
function CheckLoS()
{
var targetDirection : Vector3;
var hit : RaycastHit;
// cycles through the aggroArray
for (var i : int = 0; i < aggroArray.length; i++)
{
// gets the direction of the target in the array
targetDirection = gameObject.transform.TransformDirection(array_AggroObject[i].transform.position);
targetDirection -= gameObject.transform.position;
// casts a ray towards the direction of the target. If it hits something...
if (Physics.Raycast (transform.position, targetDirection, hit, aggroRange))
{
// if the raycast hits an environment layer or something that has the same layer as the actor, check next array index
// use transform.root because the actors have a child that is a trigger. want to make sure i have the actor instead.
if (hit.transform.root.gameObject.layer == 15 || hit.transform.root.gameObject.layer == gameObject.layer)
{
aggro = false;
}
// if raycast hits something else, the actor has aggro, and exits the function
else
{
aggro = true;
attackTarget = aggroArray[i].gameObject.transform);
return;
}
}
}
}
The adding and subtracting, toggling of aggro, los, ect… that all works. It’s just the Physics.Raycast shooting through the wall and reaching something it isn’t supposed to is my problem. This code was virtually re-written so there may be small bugs, but that isn’t the point of this post.
Any info would be appreciated. Thanks in advance.
-S