Hi Guys, To begin, I’m Italian therefor I apologize in advance for bad English…
I’ve a question on my raycast code, is based on Ben’s code but i use direct movement so it works completely different, i want use the player raycast system on the enemy, i think should be enough pass a value for player or enemy, put a if statement that switch the variables (EnemyLayer/Component=>PlayerLayer/Component)
I’m also looking for detecting if the target is moving, for do this i need to get the rigidbody component or there is another way?
The Code Detect the targets with a custom collider, add/remove from a List of target, switch from target, detect if the target is behind a wall (not visible) or if is visible detect if he is behind a cover object or totally clear.
That,s the Code
public class Trigger_Target : MonoBehaviour
{
[SerializeField] GameObject laserAimStartPoint;
[SerializeField] float aimOffset = 1f;
public GameObject Target_Selected=null;
public List<GameObject> Target_List;
private float maxRaycastDepth = 100f;
private int i=0;
private int state; // 0 for not visible, 1 for inCover, 2 for clean Target
const int ENEMY_LAYER = 10;
const int ENVIROMENT_LAYER = 11;
const int COVER_LAYER = 16;
const int WALKABLE_LAYER = 9;
public delegate void Target_State(int target_State);
public event Target_State NotifyTargetState;
private void Start()
{
}
//Detecting Enemy
private void OnTriggerEnter(Collider enemy)
{
if (enemy.GetComponent<Enemy>())
Target_List.Add(enemy.gameObject);
}
private void OnTriggerExit(Collider enemy)
{
if (Target_Selected && Target_Selected.name==enemy.name)
{
Target_Selected = null;
Target_List.Remove(enemy.gameObject);
}
else Target_List.Remove(enemy.gameObject);
}
//TO DO Check Accurately if all Ok then Remove
/*private void OnTriggerStay(Collider enemy)
{
if (Target_List.Contains(enemy.gameObject)) { }
else if (enemy.GetComponent<Enemy>())
{
Target_List.Add(enemy.gameObject);
}
}*/
private void Update()
{
if (Target_Selected)
{
Raycast_Enemy();
}
}
public void Raycast_Enemy()
{ if (Target_Selected)
{
Vector3 raycastDir = (Target_Selected.transform.position+new Vector3(0,aimOffset,0)) - laserAimStartPoint.transform.position;
Ray fire = new Ray(laserAimStartPoint.transform.position, raycastDir);
if (RaycastForVisibility(fire)) { return; } //Check if Enemy is visible
if (RaycastForInCover(fire)) { return; } //Check if Enemy is in Cover
}
}
private bool RaycastForVisibility(Ray fire)
{
RaycastHit hitInfo;
LayerMask layerMask = (1 << ENVIROMENT_LAYER)|(1<<ENEMY_LAYER)|(1<<WALKABLE_LAYER);
Physics.Raycast(fire, out hitInfo, maxRaycastDepth,layerMask);
GameObject gameObjectHit = hitInfo.collider.gameObject;
var EnemyHit = gameObjectHit.GetComponent<Enemy>();
if (EnemyHit)
{
return false;
}
else
{
if (state != 0)
{
state = 0;
NotifyTargetState(state);
}
return true;
}
}
private bool RaycastForInCover(Ray fire)
{
RaycastHit hitInfo;
LayerMask layerMask = (1 << COVER_LAYER) | (1 << ENEMY_LAYER);
Physics.Raycast(fire, out hitInfo, maxRaycastDepth,layerMask);
GameObject gameObjectHit = hitInfo.collider.gameObject;
var coverHit = gameObjectHit.GetComponent<InCover>();
var enemyHit = gameObjectHit.GetComponent<Enemy>();
if (coverHit)
{
if (state != 1)
{
state = 1;
NotifyTargetState(state);
}
return true;
}
else if (enemyHit)
{
if (state != 2)
{
state = 2;
NotifyTargetState(state);
}
return true;
}
else
{
return false;
}
}
public void Target_Selection()
{
//Selecting Target
if (i <= Target_List.Count - 1)
{
Target_Switch(i);
}
//Resetting Target Selection
else if (i > Target_List.Count - 1)
{
i = 0;
Target_Switch(i);
Target_List.RemoveAll(GameObject => GameObject == null); //Removing destroyed Object
}
//Remove Target Selection
else if (Target_List.Count == 0)
{
Target_Selected = null;
}
}
private void Target_Switch(int List)
{ if (Target_List.Count > 0)
{
Target_Selected = Target_List[i];
i++;
}
}
}
}