/// <summary> Calls an ObjectReleased event. </summary> /// <param name="obj"></param> protected void OnReleasedObject(SG_Interactable obj) { if (ObjectReleased != null) { ObjectReleased(this, new SG_GrabEventArgs(obj)); } }
/// <summary> Attempt to release an Interactable in heldObjects. If succesful, fire the ObjectReleased event. </summary> /// <param name="index"></param> /// <returns></returns> protected virtual int ReleaseObjectAt(int index) //returns new index; { bool released = false; if (heldObjects[index] != null) { if (heldObjects[index].MustBeReleased() || (this.CanRelease(heldObjects[index]) && heldObjects[index].EndInteractAllowed())) { released = heldObjects[index].EndInteraction(this); } } else { released = true; } //the object is null, so remove it from the list anyway if (released) { SG_Interactable hObj = heldObjects[index]; //grab a ref brefore it is removed? heldObjects.RemoveAt(index); if (hObj != null) { this.OnReleasedObject(hObj); } //only fire if the object is not null } else { index++; } return(index); }
//---------------------------------------------------------------------------------- // Monobehaviour #region Monobehaviour protected virtual void Start() { //load grab options this.myInteractable = this.gameObject.GetComponent <SG_Interactable>(); if (myInteractable == null && this.mustBeGrabbed) { this.mustBeGrabbed = false; //we cannot require this material to be grabbed if it's not an interactable. } }
/// <summary> Return a list of GameObjects that this script is Currently Interacting with. </summary> /// <returns></returns> public virtual SG_Interactable[] HeldObjects() { SG_Interactable[] objects = new SG_Interactable[this.heldObjects.Count]; for (int i = 0; i < this.heldObjects.Count; i++) { objects[i] = this.heldObjects[i]; } return(objects); }
/// <summary> Check if a SG_Interactable is already connected to this GrabZone. </summary> /// <param name="obj"></param> /// <returns></returns> private int ConnectionIndex(SG_Interactable obj) { for (int i = 0; i < this.connectedTo.Count; i++) { if (GameObject.ReferenceEquals(this.connectedTo[i].gameObject, obj.gameObject)) { return(i); } } return(-1); }
/// <summary> Returns true if this GrabScript is grabbing a specific SG_Interactable. </summary> /// <param name="obj"></param> /// <returns></returns> public virtual bool IsGrabbing(SG_Interactable obj) { for (int i = 0; i < this.heldObjects.Count; i++) { if (GameObject.ReferenceEquals(obj.gameObject, heldObjects[i].gameObject)) { return(true); } } return(false); }
/// <summary> Forces this GrabScript to pick up a specific object. </summary> /// <param name="obj"></param> public virtual void GrabObject(SG_Interactable obj) { if (obj != null && !this.heldObjects.Contains(obj)) { bool grabbed = obj.BeginInteraction(this, true); if (grabbed) { this.heldObjects.Add(obj); } } }
/// <summary> Returns the index of an SG_Interactable in this script's touchedObjects. </summary> /// <param name="iScript"></param> /// <returns></returns> protected int ListIndex(SG_Interactable iScript) { for (int i = 0; i < interactablesTouched.Count; i++) { if (interactablesTouched[i].SameScript(iScript /*, this.name.Contains("Index")*/)) { return(i); } } return(-1); }
/// <summary> Returns true if this script is touching a specific SG_Interactable. </summary> /// <param name="interactable"></param> /// <returns></returns> public bool IsTouching(SG_Interactable interactable) { for (int i = 0; i < interactablesTouched.Count; i++) { if (interactablesTouched[i].SameScript(interactable /*, false*/)) { return(true); } } return(false); }
//---------------------------------------------------------------------------------------------- // PhysicsGrab Functions /// <summary> Returns true if an SG_Interactable is inside a list of other SG_Interactables </summary> /// <param name="heldObject"></param> /// <param name="objectsToGrab"></param> /// <returns></returns> public static bool IsInside(SG_Interactable heldObject, List <SG_Interactable> objectsToGrab) { for (int i = 0; i < objectsToGrab.Count; i++) { if (GameObject.ReferenceEquals(objectsToGrab[i].gameObject, heldObject.gameObject)) { return(true); } } return(false); }
/// <summary> Connect a new Interactable to this GrabZone. Returns true if succesful.</summary> /// <param name="obj"></param> /// <returns></returns> public bool ConnectTo(SG_Interactable obj) { if (obj != null) { int index = this.ConnectionIndex(obj); if (index < 0) { //new entry this.connectedTo.Add(obj); return(true); } } return(false); }
/// <summary> Returns true if this grabscript can release an object </summary> /// <param name="obj"></param> /// <returns></returns> protected override bool CanRelease(SG_Interactable obj) { if (obj.releaseMethod == ReleaseMethod.FunctionCall) { return(false); } else if (obj.releaseMethod == ReleaseMethod.MustOpenHand) { //Can only release if our fingers do not want to grab return(!(wantsGrab[1] || wantsGrab[2])); } return(base.CanRelease(obj)); }
/// <summary> Attempt to grab an Interactable. If succesful, fire the ObjectGrabbed event. </summary> /// <param name="obj"></param> protected virtual void TryGrabObject(SG_Interactable obj) { if (!obj.MustBeReleased() && !IsGrabbing(obj)) { bool grabbed = obj.BeginInteraction(this); if (grabbed) { //Debug.Log(this.name + " grabbed " + obj.name); this.heldObjects.Add(obj); this.OnGrabbedObject(obj); } } }
/// <summary> Remove a collider of a particular Interactable to our list. Remove the Interactable if we're no longer touching it. </summary> /// <param name="iScript"></param> public void RemoveCollider(SG_Interactable iScript, Collider col) { int index = ListIndex(iScript); if (index > -1) //this is an object in the list { interactablesTouched[index].RemoveCollider(col); if (!interactablesTouched[index].StillHovering) { this.interactablesTouched.RemoveAt(index); hoveredCount = this.interactablesTouched.Count; } } }
/// <summary> Add (another) collider of a particular Interactable to our list. </summary> /// <param name="iScript"></param> public void AddCollider(SG_Interactable iScript, Collider col) { int index = ListIndex(iScript); if (index > -1) //this is an object in the list { this.interactablesTouched[index].AddCollider(col); } else { this.interactablesTouched.Add(new DetectionArgs(iScript, col)); } hoveredCount = this.interactablesTouched.Count; }
/// <summary> Break the object: Hide the whole object, optionally show the broken one and play the particle effect(s) </summary> public virtual void Break() { if (this.IsBroken()) { return; } SG_Interactable senseScript = this.wholeObject.GetComponent <SG_Interactable>(); if (senseScript) { senseScript.EndInteraction(); } if (this.wholeDeform) { this.wholeDeform.ResetMesh(); } wholeMaterial.SetBroken(true); wholeObject.EndInteraction(); //end any interaction this.wholeObject.gameObject.SetActive(false); if (this.brokenObject) { this.brokenObject.transform.position = this.wholeObject.transform.position; this.brokenObject.transform.rotation = this.wholeObject.transform.rotation; this.brokenObject.gameObject.SetActive(true); } if (this.breakParticles) { this.breakParticles.gameObject.transform.position = this.wholeObject.transform.position; this.breakParticles.gameObject.transform.rotation = this.wholeObject.transform.rotation; this.breakParticles.Play(); } if (this.breakSound) { this.breakSound.Play(); } this.resetTime = 0; this.OnObjectBreaks(); }
/// <summary> If this grabscript is holding obj, end its interaction with it. </summary> /// <param name="obj"></param> /// <param name="callEvent">Call the EndInteraction on this object.</param> public virtual void EndInteraction(SG_Interactable obj, bool callObjectRelease = true) { if (obj != null) { for (int i = 0; i < this.heldObjects.Count; i++) { if (this.heldObjects[i].Equals(obj)) { //we have this object if (callObjectRelease) { //avoids a circular call to this function when coming from the object itself. this.heldObjects[i].EndInteraction(this, true); } this.heldObjects.RemoveAt(i); //remove refrences to this. break; } } } }
/// <summary> Retrieve a SG_Interactable object from a collider. Returns true if one is found. </summary> /// <param name="col"></param> /// <param name="interactable"></param> /// <param name="favourSpecific"></param> /// <returns></returns> public static bool GetInteractableScript(Collider col, out SG_Interactable interactable, bool favourSpecific = true) { SG_Interactable myScript = col.gameObject.GetComponent <SG_Interactable>(); if (myScript != null && favourSpecific) //we favour the 'specific' material over a global material. { interactable = myScript; return(true); } //myMat might exist, but we favour the connected one if possible. SG_Interactable connectedScript = col.attachedRigidbody != null? col.attachedRigidbody.gameObject.GetComponent <SG_Interactable>() : null; if (connectedScript == null) { interactable = myScript; } //the connected body does not have a material, so regardless we'll try the specific one. else { interactable = connectedScript; } return(interactable != null); }
/// <summary> Create a new instance of the DetectionArgs </summary> /// <param name="iScript"></param> /// <param name="collidersNowInside"></param> public DetectionArgs(SG_Interactable iScript) { Interactable = iScript; }
public SG_GrabEventArgs(SG_Interactable obj) { Interactable = obj; }
/// <summary> Check if this GrabScript is allowed to release an object, based on its release parameters. </summary> /// <param name="obj"></param> /// <returns></returns> protected virtual bool CanRelease(SG_Interactable obj) { return(true); }
public DetectionArgs(SG_Interactable iScript, Collider firstCollider) { Interactable = iScript; this.AddCollider(firstCollider); }
/// <summary> Returns true if our Interactable is the same as otherScript. </summary> /// <remarks> Placed in a separate function so we can optionally so some checks on a script level. </remarks> /// <param name="otherScript"></param> /// <returns></returns> public bool SameScript(SG_Interactable otherScript /*, bool debug*/) { //if (debug) // Debug.Log("Comparing " + Interactable.name + " to " + otherScript.name + ", result will be " + (this.Interactable == otherScript ? "TRUE" : "FALSE")); return(this.Interactable == otherScript); }