Tanoda
Anchor.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
11using System;
12using System.Collections;
13using System.Collections.Generic;
14using UnityEngine;
16
17namespace Leap.Unity.Interaction {
18
19 public class Anchor : MonoBehaviour {
20
21 private static HashSet<Anchor> _allAnchors;
22 public static HashSet<Anchor> allAnchors {
23 get {
24 if (_allAnchors == null) {
25 _allAnchors = new HashSet<Anchor>();
26 }
27 return _allAnchors;
28 }
29 }
30
31 [Tooltip("Should this anchor allow multiple objects to be attached to it at the same time? "
32 + "This property is enforced by AnchorGroups and AnchorableBehaviours.")]
33 public bool allowMultipleObjects = false;
34
35 [Tooltip("Should this anchor attempt to enable and disable the GameObjects of attached "
36 + "AnchorableBehaviours when its own active state changes? If this setting is enabled, "
37 + "the Anchor will deactivate the attached objects when its own GameObject is deactivated "
38 + "or if its script is disabled, and similarly for becoming active or enabled.")]
40
41 private HashSet<AnchorGroup> _groups = new HashSet<AnchorGroup>();
42 public HashSet<AnchorGroup> groups { get { return _groups; } }
43
44 private HashSet<AnchorableBehaviour> _preferringAnchorables = new HashSet<AnchorableBehaviour>();
45
46 private HashSet<AnchorableBehaviour> _anchoredObjects = new HashSet<AnchorableBehaviour>();
50 public HashSet<AnchorableBehaviour> anchoredObjects { get { return _anchoredObjects; } }
51
52 public bool isPreferred { get { return _preferringAnchorables.Count > 0; } }
53
54 public bool hasAnchoredObjects { get { return _anchoredObjects.Count > 0; } }
55
56 #region Events
57
62 public Action OnAnchorPreferred = () => { };
63
67 public Action OnAnchorNotPreferred = () => { };
68
72 public Action WhileAnchorPreferred = () => { };
73
77 public Action OnAnchorablesAttached = () => { };
78
82 public Action OnNoAnchorablesAttached = () => { };
83
87 public Action WhileAnchorablesAttached = () => { };
88
89 #endregion
90
91 void Awake() {
92 allAnchors.Add(this);
93 }
94
95 void OnEnable() {
97 foreach (var anchObj in _anchoredObjects) {
98 anchObj.gameObject.SetActive(true);
99 }
100 }
101 }
102
103 void Start() {
104 initUnityEvents();
105 }
106
107 void Update() {
108 updateAnchorCallbacks();
109 }
110
111 void OnAnchorDisabled() {
113 foreach (var anchObj in _anchoredObjects) {
114 anchObj.gameObject.SetActive(false);
115 }
116 }
117 }
118
119 void OnDestroy() {
120 foreach (var group in groups) {
121 group.Remove(this);
122 }
123
124 allAnchors.Remove(this);
125 }
126
127 #region Anchor Callbacks
128
129 public void NotifyAttached(AnchorableBehaviour anchObj) {
130 _anchoredObjects.Add(anchObj);
131
132 if (_anchoredObjects.Count == 1) {
134 }
135 }
136
137 public void NotifyDetached(AnchorableBehaviour anchObj) {
138 _anchoredObjects.Remove(anchObj);
139
140 if (_anchoredObjects.Count == 0) {
142 }
143 }
144
145 private void updateAnchorCallbacks() {
148 }
149
151 _preferringAnchorables.Add(anchObj);
152
153 if (_preferringAnchorables.Count == 1) {
155 }
156 }
157
159 _preferringAnchorables.Remove(anchObj);
160
161 if (_preferringAnchorables.Count == 0) {
163 }
164 }
165
166 #endregion
167
168 #region Gizmos
169
170 public static Color AnchorGizmoColor = new Color(0.6F, 0.2F, 0.8F);
171
172 void OnDrawGizmosSelected() {
173 Matrix4x4 origMatrix = Gizmos.matrix;
174 Gizmos.matrix = this.transform.localToWorldMatrix;
175 Gizmos.color = AnchorGizmoColor;
176 float radius = 0.015F;
177
178 drawWireSphereGizmo(Vector3.zero, radius);
179
180 drawSphereCirclesGizmo(5, Vector3.zero, radius, Vector3.forward);
181
182 Gizmos.matrix = origMatrix;
183 }
184
185 private static Vector3[] worldDirs = new Vector3[] { Vector3.right, Vector3.up, Vector3.forward };
186
187 private void drawWireSphereGizmo(Vector3 pos, float radius) {
188 foreach (var dir in worldDirs) {
189 if (dir == Vector3.forward) continue;
190 Utils.DrawCircle(pos, dir, radius, AnchorGizmoColor, quality: 24, depthTest: true);
191 }
192 }
193
194 private void drawSphereCirclesGizmo(int numCircles, Vector3 pos, float radius, Vector3 poleDir) {
195 float dTheta = 180F / numCircles;
196 float halfTheta = dTheta / 2F;
197
198 for (int i = 0; i < numCircles; i++) {
199 float curTheta = (dTheta * i) + halfTheta;
200 Utils.DrawCircle(pos + poleDir * Mathf.Cos(curTheta * Mathf.Deg2Rad) * radius, poleDir, Mathf.Sin(curTheta * Mathf.Deg2Rad) * radius, AnchorGizmoColor, quality: 16, depthTest: true);
201 }
202 }
203
204 #endregion
205
206 #region Unity Events (Internal)
207
208 [SerializeField]
209 private EnumEventTable _eventTable = null;
210
211 public enum EventType {
212 OnAnchorPreferred = 100,
218 }
219
220 private void initUnityEvents() {
221 setupCallback(ref OnAnchorPreferred, EventType.OnAnchorPreferred);
222 setupCallback(ref OnAnchorNotPreferred, EventType.OnAnchorNotPreferred);
223 setupCallback(ref WhileAnchorPreferred, EventType.WhileAnchorPreferred);
224 setupCallback(ref OnAnchorablesAttached, EventType.OnAnchorablesAttached);
225 setupCallback(ref OnNoAnchorablesAttached, EventType.OnNoAnchorablesAttached);
226 setupCallback(ref WhileAnchorablesAttached, EventType.WhileAnchorablesAttached);
227 }
228
229 private void setupCallback(ref Action action, EventType type) {
230 action += () => _eventTable.Invoke((int)type);
231 }
232
233 #endregion
234
235 }
236
237}
UnityEngine.Color Color
Definition: TestScript.cs:32
void NotifyAttached(AnchorableBehaviour anchObj)
Definition: Anchor.cs:129
HashSet< AnchorableBehaviour > anchoredObjects
Gets the set of AnchorableBehaviours currently attached to this anchor.
Definition: Anchor.cs:50
HashSet< AnchorGroup > groups
Definition: Anchor.cs:42
Action OnNoAnchorablesAttached
Called when there are no anchorables attached to this anchor.
Definition: Anchor.cs:82
static Color AnchorGizmoColor
Definition: Anchor.cs:170
Action OnAnchorNotPreferred
Called when no anchorable objects prefer this anchor any more.
Definition: Anchor.cs:67
Action OnAnchorablesAttached
Called as soon as any anchorables become attached to this anchor.
Definition: Anchor.cs:77
Action WhileAnchorPreferred
Called every Update() that an AnchorableBehaviour prefers this anchor.
Definition: Anchor.cs:72
Action OnAnchorPreferred
Called as soon as any anchorable objects prefer this anchor if they were to try to attach to an ancho...
Definition: Anchor.cs:62
bool matchActiveStateWithAttachedObjects
Definition: Anchor.cs:39
static HashSet< Anchor > allAnchors
Definition: Anchor.cs:22
void NotifyAnchorPreference(AnchorableBehaviour anchObj)
Definition: Anchor.cs:150
void NotifyEndAnchorPreference(AnchorableBehaviour anchObj)
Definition: Anchor.cs:158
void NotifyDetached(AnchorableBehaviour anchObj)
Definition: Anchor.cs:137
Action WhileAnchorablesAttached
Called every Update() that one or more AnchorableBehaviours is attached to this anchor.
Definition: Anchor.cs:87
AnchorableBehaviours mix well with InteractionBehaviours you'd like to be able to pick up and place i...