// Event Handlers /// <summary> Fires when an object is picked up from the Sense Glove. Disconnect it from this SnapZone. </summary> /// <param name="source"></param> /// <param name="args"></param> private void Grabable_InteractionBegun(object source, SG_InteractArgs args) { SG_Grabable grabable = (SG_Grabable)source; grabable.InteractionBegun -= Grabable_InteractionBegun; //unsibscribe regardless. this.RemoveObject(grabable); }
/// <summary> Add a target object. </summary> /// <param name="obj"></param> public void AddTarget(SG_Grabable obj) { if (obj != null) { this.objectsToGet.Add(obj); } }
/// <summary> Fires when one of my ObjectsToGet is released. </summary> /// <remarks> Should only be subscribed to when </remarks> /// <param name="source"></param> /// <param name="args"></param> private void Grabable_InteractionEnded(object source, SG_InteractArgs args) { SG_Grabable grabable = (SG_Grabable)source; grabable.InteractionEnded -= Grabable_InteractionEnded; //unsubscribe from the method. this.AttachObject(grabable); }
/// <summary> Create a new instance of SnapProps, based on a singele Grabable's properties. </summary> /// <param name="grabable"></param> public SnapProps(SG_Grabable grabable) { this.wasInteractable = grabable.CanInteract(); this.wasKinematic = grabable.WasKinematic; this.usedGravity = grabable.UsedGravity; this.oldParent = grabable.OriginalParent; this.myJoint = null; }
/// <summary> Check if this SG_HapticGlove is one of the "goal" objects; </summary> /// <param name="obj"></param> /// <returns></returns> public bool IsTarget(SG_Grabable obj) { if (this.objectsToGet.Count > 0) { return(SG_DropZone.ListIndex(obj, this.objectsToGet) > -1); } return(true); //we can accept any kind of Object. }
/// <summary> Echeck if an exiting object belongs to one of the object we have. </summary> /// <param name="obj"></param> protected virtual void CheckObjectExit(GameObject obj) { SG_Grabable grabableScript = obj.GetComponent <SG_Grabable>(); if (grabableScript != null) { this.RemoveObject(grabableScript); //RemoveObject(Grabable) will check for indices etc. } }
/// <summary> Calls the ObjectRemoved event </summary> /// <param name="removedObject"></param> protected virtual void CallObjectRemoved(SG_Grabable removedObject) { //Debug.Log(this.name + ": " + removedObject.name + " Removed!"); if (this.ObjectRemoved != null) { this.ObjectRemoved(this, new DropZoneArgs(removedObject)); } this.OnObjectRemoved.Invoke(); }
/// <summary> Check if a newly incoming object belongs to our targets. </summary> /// <param name="obj"></param> protected virtual void CheckObjectEnter(GameObject obj) { SG_Grabable grabableScript = obj.GetComponent <SG_Grabable>(); if (grabableScript != null && this.IsTarget(grabableScript) && !this.IsDetected(grabableScript)) { this.AddObject(grabableScript); } }
/// <summary> Calls the ObjectDetected event </summary> /// <param name="detectedObject"></param> protected virtual void CallObjectDetect(SG_Grabable detectedObject) { //Debug.Log(this.name + ": " + detectedObject.name + " Detected!"); if (this.ObjectDetected != null) { this.ObjectDetected(this, new DropZoneArgs(detectedObject)); } this.OnObjectDetected.Invoke(); }
/// <summary> Removes a specific object from this SenseGlove_DropZone </summary> /// <param name="grabable"></param> public virtual void RemoveObject(SG_Grabable grabable) { int objIndex = SG_DropZone.ListIndex(grabable, this.objectsInside); if (objIndex > -1) { this.RemoveObject(objIndex); } }
// Class Methods /// <summary> Returns true if this particular object has been detected and snapped within the SnapZone. </summary> /// <param name="grabable"></param> /// <returns></returns> public bool IsSnapped(SG_Grabable grabable) { int index = ListIndex(grabable, this.objectsInside); if (index > -1) { return(this.snapProperties[index].isSnapped); } return(false); }
/// <summary> Adds an object to this SenseGlove_DropZone. Does not fire the eventTime. </summary> /// <param name="grabable"></param> public virtual void AddObject(SG_Grabable grabable) { this.objectsInside.Add(grabable); this.dropProperties.Add(new DropProps()); if (this.detectionTime == 0 && (!grabable.IsInteracting() || this.detectHeldObjects)) { this.dropProperties[this.dropProperties.Count - 1].detected = true; //mark that we have detected it! this.CallObjectDetect(grabable); } }
/// <summary> Fires when an object is reset. Disconnect it from this SnapZone.</summary> /// <param name="source"></param> /// <param name="args"></param> private void Grabable_ObjectReset(object source, System.EventArgs args) { Debug.Log("An object was reset!"); SG_Grabable grabable = (SG_Grabable)source; int index = ListIndex(grabable, this.objectsInside); if (index > -1) { this.snapProperties[index].BreakJoint(); } this.RemoveObject(grabable); }
// Detection Logic #region Detection /// <summary> Retrieve the index of a Grabable within a list of Grabables. </summary> /// <param name="obj"></param> /// <param name="grabables"></param> /// <returns> Returns -1 if obj does not exist in grabables. </returns> public static int ListIndex(SG_Grabable obj, List <SG_Grabable> grabables) { if (obj != null) { for (int i = 0; i < grabables.Count; i++) { if (GameObject.ReferenceEquals(obj.pickupReference.gameObject, grabables[i].pickupReference.gameObject)) { return(i); } } } return(-1); }
/// <summary> Restore properties back to their original state(s). </summary> /// <param name="grabable"></param> public void RestoreProperties(SG_Grabable grabable) { if (!grabable.IsInteracting()) { grabable.SetInteractable(this.wasInteractable); grabable.pickupReference.transform.parent = this.oldParent; if (grabable.physicsBody != null) { grabable.physicsBody.useGravity = this.usedGravity; grabable.physicsBody.isKinematic = this.wasKinematic; } } this.BreakJoint(); }
/// <summary> Create a Physics Joint between a grabable and a snapZone. </summary> /// <param name="grabable"></param> /// <param name="snapZoneBody"></param> /// <param name="breakForce"></param> public void CreateJoint(SG_Grabable grabable, Rigidbody snapZoneBody, float breakForce) { if (this.myJoint == null) { if (grabable.physicsBody != null) { this.myJoint = grabable.physicsBody.gameObject.AddComponent <FixedJoint>(); this.myJoint.connectedBody = snapZoneBody; this.myJoint.enableCollision = false; this.myJoint.breakForce = breakForce; } } else { SG_Debugger.LogError("Multiple Physics connections to my Properties. Wrong index!"); } }
/// <summary> Snaps an object to this Zone's snapPoint, based on the Grabable's grabType. </summary> /// <param name="grabable"></param> protected void AttachObject(SG_Grabable grabable) { grabable.SnapMeTo(this.snapPoint, true); grabable.InteractionBegun += Grabable_InteractionBegun; grabable.ObjectReset += Grabable_ObjectReset; int index = ListIndex(grabable, this.objectsInside); if (this.snapMethod == SnapMethod.FixedJoint || (this.snapMethod == SnapMethod.ObjectDependent && grabable.pickupMethod == GrabType.FixedJoint)) { if (grabable.physicsBody != null) { grabable.physicsBody.useGravity = true; if (index > -1) { this.snapProperties[index].CreateJoint(grabable, this.physicsBody, SG_Grabable.defaultBreakForce); this.snapProperties[index].isSnapped = true; } } else { SG_Debugger.LogWarning(grabable.name + " does not have a RigidBody to attach to " + this.name + " via PhysicsJoint."); } } else //any other way we snap it using the parent method. { grabable.pickupReference.parent = this.snapPoint; if (grabable.physicsBody != null) { grabable.physicsBody.useGravity = false; grabable.physicsBody.isKinematic = true; } if (index > -1) { this.snapProperties[index].isSnapped = true; } } }
/// <summary> Called when an Object is detected and its event is called. End interation if needed, then snap it </summary> /// <param name="detectedObject"></param> protected override void CallObjectDetect(SG_Grabable detectedObject) { if (this.disablesInteraction) { detectedObject.SetInteractable(false); } if (this.takesFromHand) { detectedObject.EndInteraction(); } if (!detectedObject.IsInteracting()) { this.AttachObject(detectedObject); } else //we still are interacting, meaning we did not disable nor take from the hand. { detectedObject.InteractionEnded += Grabable_InteractionEnded; //not subscribed to untill this object is released. } base.CallObjectDetect(detectedObject); }
/// <summary> Check if this Object has already been detected. </summary> /// <param name="obj"></param> /// <returns></returns> public bool IsDetected(SG_Grabable obj) { return(SG_DropZone.ListIndex(obj, this.objectsInside) > -1); }
/// <summary> Release a specific object from the zone. </summary> /// <param name="grabable"></param> public void ReleaseObject(SG_Grabable grabable) { this.ReleaseObject(ListIndex(grabable, this.objectsInside)); }
/// <summary> Create a new instance of the DropZoneArgs. </summary> /// <param name="obj"></param> public DropZoneArgs(SG_Grabable obj) { this.grabable = obj; }
/// <summary> Fires when an object first enters the zone. Record its snap-properties. </summary> /// <param name="grabable"></param> public override void AddObject(SG_Grabable grabable) { this.snapProperties.Add(new SnapProps(grabable)); //empty base.AddObject(grabable); //if time==0, then CallObjectDetect is also coaaled. }