Tanoda
ProximityDetector.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using UnityEngine;
11using System.Collections;
12using System.Collections.Generic;
14
15namespace Leap.Unity{
16
22 public class ProximityDetector : Detector {
28 [Tooltip("Dispatched when close enough to a target.")]
34 [Units("seconds")]
35 [MinValue(0)]
36 [Tooltip("The interval in seconds at which to check this detector's conditions.")]
37 public float Period = .1f; //seconds
38
43 [Header("Detector Targets")]
44 [Tooltip("The list of target objects.")]
45 [DisableIf("UseLayersNotList", true)]
46 public GameObject[] TargetObjects;
47
54 [Tooltip("Objects with this tag are added to the list of targets.")]
55 [DisableIf("UseLayersNotList", true)]
56 public string TagName = "";
57
58 [Tooltip("Use a Layer instead of the target list.")]
59 public bool UseLayersNotList = false;
60 [Tooltip("The Layer containing the objects to check.")]
61 [DisableIf("UseLayersNotList", false)]
62 public LayerMask Layer;
63
69 [Header("Distance Settings")]
70 [Tooltip("The target distance in meters to activate the detector.")]
71 [MinValue(0)]
72 public float OnDistance = .01f; //meters
73
79 [Tooltip("The distance in meters at which to deactivate the detector.")]
80 public float OffDistance = .015f; //meters
81
90 public GameObject CurrentObject { get { return _currentObj; } }
94 [Header("")]
95 [Tooltip("Draw this detector's Gizmos, if any. (Gizmos must be on in Unity edtor, too.)")]
96 public bool ShowGizmos = true;
97
98 private IEnumerator proximityWatcherCoroutine;
99 private GameObject _currentObj = null;
100
101 protected virtual void OnValidate() {
102 //Activate value cannot be less than deactivate value
103 if (OffDistance < OnDistance) {
105 }
106 }
107
108 void Awake() {
109 proximityWatcherCoroutine = proximityWatcher();
110 if (TagName != "") {
111 GameObject[] taggedObjects = GameObject.FindGameObjectsWithTag(TagName);
112 List<GameObject> targets = new List<GameObject>(taggedObjects.Length + TargetObjects.Length);
113 for (int t = 0; t < TargetObjects.Length; t++) {
114 targets.Add(TargetObjects[t]);
115 }
116 for (int t = 0; t < taggedObjects.Length; t++) {
117 targets.Add(taggedObjects[t]);
118 }
119 TargetObjects = targets.ToArray();
120 }
121 }
122
123 void OnEnable () {
124 StopCoroutine(proximityWatcherCoroutine);
125 StartCoroutine(proximityWatcherCoroutine);
126 }
127
128 void OnDisable () {
129 StopCoroutine(proximityWatcherCoroutine);
130 Deactivate();
131 }
132
133 IEnumerator proximityWatcher(){
134 bool proximityState = false;
135 float onSquared, offSquared; //Use squared distances to avoid taking square roots
136 while(true){
137 onSquared = OnDistance * OnDistance;
138 offSquared = OffDistance * OffDistance;
139 if(_currentObj != null){
140 if(distanceSquared(_currentObj) > offSquared){
141 _currentObj = null;
142 proximityState = false;
143 }
144 } else {
145 if (UseLayersNotList) {
146 Collider[] nearby = Physics.OverlapSphere(transform.position, OnDistance, Layer);
147 if(nearby.Length > 0) {
148 _currentObj = nearby[0].gameObject;
149 proximityState = true;
150 OnProximity.Invoke(_currentObj);
151 }
152 } else {
153 for (int obj = 0; obj < TargetObjects.Length; obj++) {
154 GameObject target = TargetObjects[obj];
155 if (distanceSquared(target) < onSquared) {
156 _currentObj = target;
157 proximityState = true;
158 OnProximity.Invoke(_currentObj);
159 break; // pick first match
160 }
161 }
162 }
163 }
164 if(proximityState){
165 Activate();
166 } else {
167 Deactivate();
168 }
169 yield return new WaitForSeconds(Period);
170 }
171 }
172
173 private float distanceSquared(GameObject target){
174 Collider targetCollider = target.GetComponent<Collider>();
175 Vector3 closestPoint;
176 if(targetCollider != null){
177 closestPoint = targetCollider.ClosestPointOnBounds(transform.position);
178 } else {
179 closestPoint = target.transform.position;
180 }
181 return (closestPoint - transform.position).sqrMagnitude;
182 }
183
184 #if UNITY_EDITOR
185 void OnDrawGizmos() {
186 if (ShowGizmos) {
187 if (IsActive) {
188 Gizmos.color = Color.green;
189 } else {
190 Gizmos.color = Color.red;
191 }
192 Gizmos.DrawWireSphere(transform.position, OnDistance);
193 Gizmos.color = Color.blue;
194 Gizmos.DrawWireSphere(transform.position, OffDistance);
195 }
196 }
197 #endif
198 }
199
206 [System.Serializable]
207 public class ProximityEvent : UnityEvent <GameObject> {}
208}
UnityEngine.Color Color
Definition: TestScript.cs:32
virtual void Deactivate()
Definition: Detector.cs:66
virtual void Activate()
Definition: Detector.cs:54