AR Design
UBC EML collab with UBC SALA - visualizing IoT data in AR
BaseGrabber.cs
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License. See LICENSE in the project root for license information.
3 
4 using System;
5 using System.Collections.Generic;
6 using UnityEngine;
7 
8 #if UNITY_WSA && UNITY_2017_2_OR_NEWER
9 using UnityEngine.XR.WSA.Input;
10 #endif
11 
12 namespace HoloToolkit.Unity.InputModule.Examples.Grabbables
13 {
18  public abstract class BaseGrabber : MonoBehaviour
19  {
20  public event Action<BaseGrabber> OnGrabStateChange;
21  public event Action<BaseGrabber> OnContactStateChange;
22 
23 #if UNITY_WSA && UNITY_2017_2_OR_NEWER
24  public InteractionSourceHandedness Handedness { get { return handedness; } set { handedness = value; } }
25 #endif
26 
27  public List<BaseGrabbable> GrabbedObjects { get { return new List<BaseGrabbable>(grabbedObjects); } }
28 
29 
30  public GrabStateEnum GrabState
31  {
32  get
33  {
34  if (grabbedObjects.Count > 1)
35  {
36  return GrabStateEnum.Multi;
37  }
38 
39  return grabbedObjects.Count > 0 ? GrabStateEnum.Single : GrabStateEnum.Inactive;
40  }
41  }
42 
43  public GrabStateEnum ContactState
44  {
45  get
46  {
47  if (contactObjects.Count > 1)
48  return GrabStateEnum.Multi;
49  else if (contactObjects.Count > 0)
50  return GrabStateEnum.Single;
51  else
52  return GrabStateEnum.Inactive;
53  }
54  }
55 
59  public Transform GrabHandle
60  {
61  get
62  {
63  return grabAttachSpot != null ? grabAttachSpot : transform;
64  }
65  }
66 
67  public float Strength { get { return strength; } }
68 
69  [SerializeField]
70  protected Transform grabAttachSpot;
71 
72  [SerializeField]
73  protected float strength = 1.0f;
74 
75  protected HashSet<BaseGrabbable> grabbedObjects = new HashSet<BaseGrabbable>();
76  protected List<BaseGrabbable> contactObjects = new List<BaseGrabbable>();
77 
78  protected float grabForgivenessRadius;
79 
80  private GrabStateEnum prevGrabState = GrabStateEnum.Inactive;
81  private GrabStateEnum prevContactState = GrabStateEnum.Inactive;
82 
83 #if UNITY_WSA && UNITY_2017_2_OR_NEWER
84  [SerializeField]
85  protected InteractionSourceHandedness handedness;
86 #endif
87 
88  public bool IsGrabbing(BaseGrabbable grabbable)
89  {
90  return grabbedObjects.Contains(grabbable);
91  }
92 
100  public virtual bool CanTransferOwnershipTo(BaseGrabbable ownerGrab, BaseGrabber otherGrabber)
101  {
102  Debug.Log("Transferring ownership of " + ownerGrab.name + " to grabber " + otherGrabber.name);
103  grabbedObjects.Remove(ownerGrab);
104  return true;
105  }
106 
110  protected virtual void GrabStart()
111  {
112  // Clean out the list of available objects list
113  for (int i = contactObjects.Count - 1; i >= 0; i--)
114  {
115  if ((contactObjects[i] == null || !contactObjects[i].isActiveAndEnabled) && !grabbedObjects.Contains(contactObjects[i]))
116  {
117  contactObjects.RemoveAt(i);
118  }
119  }
120 
121  // If there are any left after pruning
122  if (contactObjects.Count > 0)
123  {
124  // Sort by distance and try to grab the closest
125  SortAvailable();
126  BaseGrabbable closestAvailable = contactObjects[0];
127  if (closestAvailable.TryGrabWith(this))
128  {
129  grabbedObjects.Add(contactObjects[0]);
130  }
131  }
132  }
133 
138  protected virtual void GrabEnd()
139  {
140  grabbedObjects.Clear();
141  }
142 
143  protected virtual void OnEnable()
144  {
145  }
146 
147  protected virtual void OnDisable()
148  {
149  grabbedObjects.Clear();
150  }
151 
156  protected void AddContact(BaseGrabbable availableObject)
157  {
158  if (!contactObjects.Contains(availableObject))
159  {
160  contactObjects.Add(availableObject);
161  availableObject.AddContact(this);
162  }
163  }
164 
169 
170  protected void RemoveContact(BaseGrabbable availableObject)
171  {
172  contactObjects.Remove(availableObject);
173  availableObject.RemoveContact(this);
174 
175  if (contactObjects.Contains(availableObject))
176  {
177  // What's supposed to happen here?
178  }
179  }
180 
184  protected virtual void SortAvailable()
185  {
186  contactObjects.Sort(delegate (BaseGrabbable b1, BaseGrabbable b2)
187  {
188  return Vector3.Distance(b1.GrabPoint, GrabHandle.position).CompareTo(Vector3.Distance(b2.GrabPoint, GrabHandle.position));
189  });
190  }
191 
192  void Update()
193  {
194 #if UNITY_EDITOR
195  if (UnityEditor.Selection.activeGameObject == gameObject)
196  {
197  if (Input.GetKeyDown(KeyCode.G))
198  {
199  if (GrabState == GrabStateEnum.Inactive)
200  {
201  Debug.Log("Grab start");
202  GrabStart();
203  }
204  else
205  {
206  Debug.Log("Grab end");
207  GrabEnd();
208  }
209  }
210  }
211 #endif
212 
213  if (prevGrabState != GrabState && OnGrabStateChange != null)
214  {
215  Debug.Log("Calling on grab change in grabber");
216  OnGrabStateChange(this);
217  }
218 
219  if (prevContactState != ContactState && OnContactStateChange != null)
220  {
221  Debug.Log("Calling on contact change in grabber");
222  OnContactStateChange(this);
223  }
224 
225  prevGrabState = GrabState;
226  prevContactState = ContactState;
227  }
228  }
229 }
virtual bool CanTransferOwnershipTo(BaseGrabbable ownerGrab, BaseGrabber otherGrabber)
Attempts to transfer ownership of grabbable object to another grabber Can override to &#39;lock&#39; objects ...
Definition: BaseGrabber.cs:100
virtual void GrabStart()
If the correct grabbing button is pressed, we add to grabbedObjects.
Definition: BaseGrabber.cs:110
virtual void GrabEnd()
If the correct grabbing button is pressed, we set the GrabState. Grab behavior depends on the combina...
Definition: BaseGrabber.cs:138
void AddContact(BaseGrabbable availableObject)
Adds a grabbable object to the list of available objects
Definition: BaseGrabber.cs:156
Intended usage: scripts that inherit from this can be attached to the controller, or any object with ...
Definition: BaseGrabber.cs:18
void RemoveContact(BaseGrabber availableObject)
Removes a grabber object from the list of available grabbers
void RemoveContact(BaseGrabbable availableObject)
Removes a grabbable object from the list of available objects
Definition: BaseGrabber.cs:170
void AddContact(BaseGrabber availableObject)
Adds a grabber object to the list of available grabbers
//Intended Usage// Attach a "grabbable_x" script (a script that inherits from this) to any object tha...
virtual void SortAvailable()
Sorts by distance from grab point to grab handle by default
Definition: BaseGrabber.cs:184