/// <summary> Add a target object. </summary> /// <param name="obj"></param> public void AddTarget(SenseGlove_Grabable obj) { if (obj != null) { this.objectsToGet.Add(obj); } }
/// <summary> Remove an object from this dropzone and restore its original settings. </summary> /// <param name="objectIndex"></param> public void RemoveObject(int objectIndex) { //SenseGlove_Debugger.Log("The script wishes to remove " + objectIndex); if (objectIndex >= 0 && objectIndex < this.objectsInside.Count) { SenseGlove_Debugger.Log("removing " + this.objectsInside[objectIndex].name + " from the DropZone!"); SenseGlove_Grabable obj = this.objectsInside[objectIndex]; SenseGlove_Debugger.Log("RBProps.lengh = " + RBprops.Count); if (obj.GetComponent <Rigidbody>() != null && RBprops[objectIndex] != null) { //if it is currently picked up, we assign the previous properties to its grabscript, which will then apply them once it lets go. SenseGlove_Debugger.Log("It has a physicsBody"); if (obj.IsGrabbed()) { obj.SetOriginalParent(this.originalParent[objectIndex]); obj.SetRBProps(this.RBprops[objectIndex][0], this.RBprops[objectIndex][1]); } else { obj.transform.parent = this.originalParent[objectIndex]; obj.physicsBody.useGravity = this.RBprops[objectIndex][0]; obj.physicsBody.isKinematic = this.RBprops[objectIndex][1]; } } this.objectsInside.RemoveAt(objectIndex); SenseGlove_Debugger.Log("Removed it from ObjectsInside!"); this.RBprops.RemoveAt(objectIndex); this.originalParent.RemoveAt(objectIndex); obj.SetInteractable(true); //now the function can also be used to force removal of the object. this.OnObjectRemoved(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) { SenseGlove_Grabable grabable = (SenseGlove_Grabable)source; grabable.InteractionEnded -= Grabable_InteractionEnded; //unsubscribe from the method. this.AttachObject(grabable); }
// 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) { SenseGlove_Grabable grabable = (SenseGlove_Grabable)source; grabable.InteractionBegun -= Grabable_InteractionBegun; //unsibscribe regardless. this.RemoveObject(grabable); }
/// <summary> /// Set reference to instances /// </summary> private void Start() { additiveSceneManager = GameObject.FindGameObjectWithTag("AdditiveSceneManager").GetComponent <AdditiveSceneManager>(); defaultPos = this.transform.localPosition; defaultRot = this.transform.localRotation; grab = this.GetComponent <SenseGlove_Grabable>(); }
protected void OnObjectRemoved(SenseGlove_Grabable obj) { if (ObjectRemoved != null) { ObjectRemoved(this, new DropZoneArgs(obj)); } }
/// <summary> Check if this SenseGlove_Object is one of the "goal" objects; </summary> /// <param name="obj"></param> /// <returns></returns> public bool IsTarget(SenseGlove_Grabable obj) { if (this.objectsToGet.Count > 0) { return(SenseGlove_DropZone.ListIndex(obj, this.objectsToGet) > -1); } return(true); //we can accept any kind of Object. }
/// <summary> Create a new instance of SnapProps, based on a singele Grabable's properties. </summary> /// <param name="grabable"></param> public SnapProps(SenseGlove_Grabable grabable) { this.wasInteractable = grabable.CanInteract(); this.wasKinematic = grabable.WasKinematic; this.usedGravity = grabable.UsedGravity; this.oldParent = grabable.OriginalParent; this.myJoint = null; }
/// <summary> Removes a specific object from this SenseGlove_DropZone </summary> /// <param name="grabable"></param> public virtual void RemoveObject(SenseGlove_Grabable grabable) { int objIndex = SenseGlove_DropZone.ListIndex(grabable, this.objectsInside); if (objIndex > -1) { this.RemoveObject(objIndex); } }
/// <summary> Calls the ObjectRemoved event </summary> /// <param name="removedObject"></param> protected virtual void CallObjectRemoved(SenseGlove_Grabable removedObject) { //Debug.Log(this.name + ": " + removedObject.name + " Removed!"); if (this.ObjectRemoved != null) { this.ObjectRemoved(this, new DropZoneArgs(removedObject)); } this.OnObjectRemoved.Invoke(); }
protected virtual void CheckObjectExit(GameObject obj) { SenseGlove_Grabable grabableScript = obj.GetComponent <SenseGlove_Grabable>(); if (grabableScript != null) { this.RemoveObject(grabableScript); //RemoveObject(Grabable) will check for indices etc. } }
/// <summary> Check if a newly incoming object belongs to our targets. </summary> /// <param name="obj"></param> protected virtual void CheckObjectEnter(GameObject obj) { SenseGlove_Grabable grabableScript = obj.GetComponent <SenseGlove_Grabable>(); if (grabableScript != null && this.IsTarget(grabableScript) && !this.IsDetected(grabableScript)) { this.AddObject(grabableScript); } }
// 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(SenseGlove_Grabable grabable) { int index = ListIndex(grabable, this.objectsInside); if (index > -1) { return(this.snapProperties[index].isSnapped); } return(false); }
protected void CheckReset(Collider other) { SenseGlove_Grabable grabable = other.gameObject.GetComponent <SenseGlove_Grabable>(); if (other.tag.Contains(this.resetTag) && grabable != null && !grabable.IsInteracting()) { grabable.ResetObject(); //Debug.Log("Reset " + other.name); } }
/// <summary> Check if this SenseGlove_Object is one of the "goal" objects; </summary> /// <param name="obj"></param> /// <returns>The index of obj in the objectsToGet list. -1 if it does not exist inside this list.</returns> public bool IsTarget(SenseGlove_Grabable obj) { for (int i = 0; i < this.objectsToGet.Count; i++) { if (GameObject.ReferenceEquals(obj.gameObject, this.objectsToGet[i].gameObject)) { return(true); } } return(false); }
//A collider exits this dropZone void OnTriggerExit(Collider col) { SenseGlove_Grabable grabable = col.GetComponent <SenseGlove_Grabable>(); if (grabable) { int index = this.ListIndex(grabable); //SenseGlove_Debugger.Log("Object with index " + index + " is leaving this dropzone"); this.RemoveObject(index); } }
/// <summary> Adds an object to this SenseGlove_DropZone. Does not fire the eventTime. </summary> /// <param name="grabable"></param> public virtual void AddObject(SenseGlove_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); } }
//-------------------------------------------------------------------------------------------------------------------------- // Dropzone Logic #region DropzoneLogic /// <summary> Check if a SenseGlove_Grabable is (already) inside this dropzone. </summary> /// <param name="obj"></param> /// <returns>The index of obj in the objectsInside list. -1 if it does not exist inside this list.</returns> public int ListIndex(SenseGlove_Grabable obj) { for (int i = 0; i < this.objectsInside.Count; i++) { if (GameObject.ReferenceEquals(obj.gameObject, this.objectsInside[i].gameObject)) { return(i); } } return(-1); }
/// <summary> Add an object to this DropZone, and apply the desired settings. </summary> /// <param name="obj"></param> public void AddObject(SenseGlove_Grabable obj) { SenseGlove_Debugger.Log("Adding " + obj.name + " to the DropZone!"); // remember original parent if (obj.IsGrabbed()) { this.originalParent.Add(obj.GetOriginalParent()); } else { this.originalParent.Add(obj.transform.parent); } bool[] props = null; if (this.snapToMe && (this.takeFromHand || !obj.IsGrabbed())) { obj.EndInteraction(); Transform zoneParent = this.snapTarget; if (zoneParent == null) { zoneParent = this.gameObject.transform; } obj.gameObject.transform.parent = zoneParent; obj.gameObject.transform.localPosition = Vector3.zero; obj.gameObject.transform.localRotation = Quaternion.identity; Rigidbody RB = obj.physicsBody; if (RB != null) { if (obj.IsGrabbed()) { props = obj.GetRBProps(); } else { props = new bool[2] { RB.useGravity, RB.isKinematic }; } RB.useGravity = false; RB.isKinematic = true; } } this.RBprops.Add(props); this.objectsInside.Add(obj); obj.SetInteractable(!this.disableInteration); //enable / disable interactions. this.OnObjectDetected(obj); }
/// <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!"); SenseGlove_Grabable grabable = (SenseGlove_Grabable)source; int index = ListIndex(grabable, this.objectsInside); if (index > -1) { this.snapProperties[index].BreakJoint(); } this.RemoveObject(grabable); }
/// <summary> Restore properties back to their original state(s). </summary> /// <param name="grabable"></param> public void RestoreProperties(SenseGlove_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(); }
// 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(SenseGlove_Grabable obj, List <SenseGlove_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> 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(SenseGlove_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 { SenseGlove_Debugger.LogError("Multiple Physics connections to my Properties. Wrong index!"); } }
//a collider exists in the dropZone void OnTriggerStay(Collider col) { SenseGlove_Grabable grabable = col.GetComponent <SenseGlove_Grabable>(); if (grabable && (!grabable.IsGrabbed() || this.takeFromHand)) { int index = this.ListIndex(grabable); if (index < 0) { if (this.objectsToGet.Count <= 0 || this.IsTarget(grabable)) { //SenseGlove_Debugger.Log("A new object inside the dropZone!"); this.AddObject(grabable); } } } }
//A new collider enters this dropzone void OnTriggerEnter(Collider col) { SenseGlove_Grabable grabable = col.GetComponent <SenseGlove_Grabable>(); if (grabable && (!grabable.IsGrabbed() || this.takeFromHand)) { int index = this.ListIndex(grabable); //SenseGlove_Debugger.Log("Detected an Object with listIndex of " + index); if (index < 0) //its a new object, even if it has multiple colliders. { // SenseGlove_Debugger.Log("A new object!"); if (this.objectsToGet.Count <= 0 || this.IsTarget(grabable)) //either we require multiple objects or it is one of the goal objects. { this.AddObject(grabable); } } } }
/// <summary> Snaps an object to this Zone's snapPoint, based on the Grabable's grabType. </summary> /// <param name="grabable"></param> protected void AttachObject(SenseGlove_Grabable grabable) { grabable.SnapMeTo(this.snapPoint); 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, SenseGlove_Grabable.defaultBreakForce); this.snapProperties[index].isSnapped = true; } } else { SenseGlove_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(SenseGlove_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> Create a new instance of the DropZoneArgs. </summary> /// <param name="obj"></param> public DropZoneArgs(SenseGlove_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(SenseGlove_Grabable grabable) { this.snapProperties.Add(new SnapProps(grabable)); //empty base.AddObject(grabable); //if time==0, then CallObjectDetect is also coaaled. }
/// <summary> Release a specific object from the zone. </summary> /// <param name="grabable"></param> public void ReleaseObject(SenseGlove_Grabable grabable) { this.ReleaseObject(ListIndex(grabable, this.objectsInside)); }