예제 #1
0
 /// <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));
     }
 }
예제 #2
0
        /// <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);
        }
예제 #3
0
        //----------------------------------------------------------------------------------
        // 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.
            }
        }
예제 #4
0
 /// <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);
 }
예제 #5
0
 /// <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);
 }
예제 #6
0
 /// <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);
 }
예제 #7
0
 /// <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);
         }
     }
 }
예제 #8
0
 /// <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);
 }
예제 #9
0
 /// <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);
 }
예제 #10
0
        //----------------------------------------------------------------------------------------------
        // 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);
        }
예제 #11
0
 /// <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);
 }
예제 #12
0
 /// <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));
 }
예제 #13
0
 /// <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);
         }
     }
 }
예제 #14
0
        /// <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;
                }
            }
        }
예제 #15
0
        /// <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;
        }
예제 #16
0
        /// <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();
        }
예제 #17
0
 /// <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;
             }
         }
     }
 }
예제 #18
0
        /// <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);
        }
예제 #19
0
 /// <summary> Create a new instance of the DetectionArgs </summary>
 /// <param name="iScript"></param>
 /// <param name="collidersNowInside"></param>
 public DetectionArgs(SG_Interactable iScript)
 {
     Interactable = iScript;
 }
예제 #20
0
 public SG_GrabEventArgs(SG_Interactable obj)
 {
     Interactable = obj;
 }
예제 #21
0
 /// <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);
 }
예제 #22
0
 public DetectionArgs(SG_Interactable iScript, Collider firstCollider)
 {
     Interactable = iScript;
     this.AddCollider(firstCollider);
 }
예제 #23
0
 /// <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);
 }