Skip to content

Instantly share code, notes, and snippets.

@arun02139
Created July 1, 2016 07:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arun02139/b685da8d8b4ca5c484a3342d737d1ca3 to your computer and use it in GitHub Desktop.
Save arun02139/b685da8d8b4ca5c484a3342d737d1ca3 to your computer and use it in GitHub Desktop.
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine.Assertions;
using System.Collections.Generic;
public class Eye : MonoBehaviour
{
// public for debugging
public List<Unit> eyeRangeUnits;
public RaycastHit hit;
Unit _unit;
UnitSight _unitSight;
int _unitBodyLayer;
int _obstacleLayer;
LayerMask _layerMask;
void Awake()
{
_unitBodyLayer = LayerMask.NameToLayer("Body");
_obstacleLayer = LayerMask.NameToLayer("Obstacle");
_layerMask = (1 << _obstacleLayer) | (1 << _unitBodyLayer);
_unit = GetComponentInParent<Unit> ();
_unitSight = GetComponentInParent<UnitSight> ();
eyeRangeUnits = new List<Unit> ();
}
void OnTriggerEnter(Collider other)
{
// only look for the 'body' of a unit ( the collider of the it's 3D model ) a unit may have
// multiple colliders on it, for vision, for detecting touch in a wider area, etc.)
if (other.name != "Body")
return;
// Debug.Log (string.Format ("{0}.OnTriggerEnter: {1} ", name, other.name));
Unit otherUnit = other.GetComponentInParent<Unit> ();
if (otherUnit != null && otherUnit.troopId != _unit.troopId)
{
Assert.IsFalse (eyeRangeUnits.Contains (otherUnit));
eyeRangeUnits.Add (otherUnit);
}
}
void OnTriggerExit(Collider other)
{
if (other.name != "Body")
return;
// Debug.Log (string.Format ("{0}.OnTriggerExit: {1}", name, other.name));
Unit otherUnit = other.GetComponentInParent<Unit> ();
if (otherUnit && otherUnit.troopId != _unit.troopId)
{
Assert.IsTrue (eyeRangeUnits.Contains (otherUnit));
eyeRangeUnits.Remove (otherUnit);
}
}
// loop through the units in range of the 'eye' collider and add / remove them from the
// unit sight 'watching' list (they could go in and out of sight behind obstacles, other
// units etc.)
void Update()
{
foreach (var unit in eyeRangeUnits)
{
// line-of-sight vector from this to other unit
var direction = unit.transform.position - _unit.transform.position;
// make sure that there is no obstacle blocking our direct line of sight (add a
// little buffer so raycast doesn't interesect with this unit's 'body' collider)
Ray ray = new Ray(_unit.transform.position + _unit.transform.forward * .5f, direction); // HARDCODE
if (Physics.Raycast (ray, out hit, 100f, _layerMask)) // HARDCODE
{
string hitLayerName = LayerMask.LayerToName (hit.transform.gameObject.layer);
// remove the unit if it is being watched but we can no longer see it
if (hit.transform.gameObject.layer == _obstacleLayer)
{
if (_unitSight.watching.Contains (unit)) {
_unitSight.watching.Remove (unit);
_unitSight.WatchingChange.Invoke ();
}
}
// add the unit if it wasn't being watched already
else if (hit.transform.gameObject.layer == _unitBodyLayer)
{
if (!_unitSight.watching.Contains (unit)) {
_unitSight.watching.Add (unit);
_unitSight.WatchingChange.Invoke ();
}
} else {
// safty-check: layer mask *should* only have two layers, so we shouldn't get here
Debug.LogWarning (string.Format ("Eye.Update: hitLayerName = {0} ({1})", hitLayerName, hit.transform.name));
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment