Quad Tree – Oct Tree – Hexa Tree
using System.Collections; using System.Collections.Generic; using UnityEngine; using ArgosTweenSpacePuppy; public class Spoke_Handler : MonoBehaviour { public bool setLastHeld = false; public bool isInFulgurite = false; public bool isBeingHeld = false; public float maxFJForce = 1000f; private Vector3 targetPos; private Quaternion targetRot; // +x,+y,+z,-x,-y,-z public List<Spoke_AllShape> spoke_AS = new List<Spoke_AllShape>(); public Rigidbody rb; private AF_Instance af_Instance; public SphereCollider sphereCollider; public AF_Network_Grabable netGrabbable; public Touch_Lighting_and_Sound tls; public Spoke_AllShape SAS1 { get; private set; } public Spoke_AllShape SAS2 { get; private set; } private GameObject AllShape_1; private GameObject AllShape_2; private GameObject objectToStay; private GameObject objectToMove; private Spoke_Handler spokeHandler_Object_to_Move; private Spoke_Handler spokeHandler_Object_to_Stay; private float tAccum_ST = 0f; private float tDurr_ST = 1.5f; private float tweenVAL = 0f; private Vector3[] axisFLIPPER = { new Vector3 { x = 1, y = 0, z = 0 }, new Vector3 { x = 0, y = 1, z = 0 }, new Vector3 { x = 0, y = 0, z = 1 }, new Vector3 { x = -1, y = 0, z = 0 }, new Vector3 { x = 0, y =-1, z = 0 }, new Vector3 { x = 0, y = 0, z = -1}, }; public void Awake() { af_Instance = AF_Instance.Instance; tls = GetComponent<Touch_Lighting_and_Sound>(); //TAG Spokes to access target transforms for (int i = 0; i<spoke_AS.Count; i++) { spoke_AS[i].SetParent_AllShape(this, i); tls.initializeColors_in_Spoke(spoke_AS[i]); } } void Start() { } public void Set_Target_Transform(Transform targ) { Vector3 center = (objectToMove.transform.position + objectToStay.transform.position) / 2f; int idx1 = spokeHandler_Object_to_Move.Closest_Fin(center); int idx2 = spokeHandler_Object_to_Stay.Closest_Fin(center); Vector3 vin = spokeHandler_Object_to_Stay.spoke_AS[idx2].trans_to.vIN[idx1]; Vector3 vup = spokeHandler_Object_to_Stay.spoke_AS[idx2].trans_to.vUP[idx1]; Vector3 vInTrans = objectToStay.transform.TransformDirection(vin); Vector3 vUpTrans = objectToStay.transform.TransformDirection(vup); targetPos = targ.position; targetRot = Quaternion.LookRotation(vInTrans, vUpTrans); //Flip it - for minimal rotation to bonding FIN if (Vector3.Dot(vUpTrans, objectToMove.transform.up) < 0 || Vector3.Dot(vInTrans, objectToMove.transform.forward) < 0) { Quaternion qRota = Quaternion.AngleAxis(180, axisFLIPPER[idx1]); targetRot *= qRota; } } public void SpokeTriggered(int idx, Spoke_AllShape sourceSpoke) { GameObject AS1 = spoke_AS[idx].myALL_SHAPE.gameObject; Transform targ1 = spoke_AS[idx].targTransform; GameObject AS2 = sourceSpoke.myALL_SHAPE.gameObject; Transform targ2 = sourceSpoke.targTransform; Determine_Target_Movement(AS1, targ1, AS2, targ2); } public void Determine_Target_Movement(GameObject AS1, Transform targ1, GameObject AS2, Transform targ2) { //Two calls - only take this one if (AS1 == af_Instance.last_Held_AllShape /*|| (AS1.GetComponent<Spoke_Handler>().isBeingHeld)*/) { objectToMove = AS1; objectToStay = AS2; spokeHandler_Object_to_Move = objectToMove.GetComponent<Spoke_Handler>(); spokeHandler_Object_to_Stay = objectToStay.GetComponent<Spoke_Handler>(); spokeHandler_Object_to_Move.netGrabbable.DropItem(null, true, true); spokeHandler_Object_to_Stay.netGrabbable.DropItem(null, true, true); Set_Target_Transform(targ2); tAccum_ST = 0.0f; Debug.Log("Start COROUTINE:" + Time.time.ToString("F3")); StartCoroutine(Move_to_Connect()); } } private IEnumerator Move_to_Connect() { spokeHandler_Object_to_Move.SetAllActive_Colliders(false, false); spokeHandler_Object_to_Stay.SetAllActive_Colliders(false, false); int i = 0; //Sanity check for infinite loops float linProg = tAccum_ST / tDurr_ST; while (i < 180 && linProg < 1) { tAccum_ST += Time.deltaTime; linProg = tAccum_ST / tDurr_ST; Mathf.Clamp(tAccum_ST, 0, tDurr_ST); tweenVAL = EaseMethods.ExpoEaseInOut(tAccum_ST, 0, 1, tDurr_ST); Move_AllShape_Into_Place(tweenVAL); yield return true; i++; } tAccum_ST = tDurr_ST; tweenVAL = 1; Move_AllShape_Into_Place(tweenVAL); Set_Occupied_These_Spokes(); FixedJoint fj = objectToStay.AddComponent<FixedJoint>(); fj.autoConfigureConnectedAnchor = true; fj.connectedBody = objectToMove.GetComponent<Rigidbody>(); spokeHandler_Object_to_Move.SetAllActive_Colliders(true, true); spokeHandler_Object_to_Stay.SetAllActive_Colliders(true, true); StopCoroutine("Move_to_Connect"); } private void Move_AllShape_Into_Place(float val) { objectToMove.transform.position = Vector3.Lerp(objectToMove.transform.position, targetPos, val); objectToMove.transform.rotation = Quaternion.Slerp(objectToMove.transform.rotation, targetRot, val); } private void Set_Occupied_These_Spokes() { Vector3 center = (objectToMove.transform.position + objectToStay.transform.position) / 2f; int idx1 = spokeHandler_Object_to_Move.Closest_Fin(center); int idx2 = spokeHandler_Object_to_Stay.Closest_Fin(center); spokeHandler_Object_to_Move.setOccupied(idx1, true, spokeHandler_Object_to_Stay.spoke_AS[idx2]); spokeHandler_Object_to_Stay.setOccupied(idx2, true, spokeHandler_Object_to_Move.spoke_AS[idx1]); } public void setOccupied(int spokeIDX, bool bOccupied, Spoke_AllShape connectedSpoke) { spoke_AS[spokeIDX].bOccupied = bOccupied; tls.Light_Occupied(spoke_AS[spokeIDX], bOccupied); spoke_AS[spokeIDX].connectedSpoke = connectedSpoke; } public void SetAllActive_Colliders(bool bOn, bool bSphereCollider) { sphereCollider.enabled = bSphereCollider; rb.isKinematic = false; //MORE CONSIDERATIONS HERE for (int i = 0; i < spoke_AS.Count; i++) { if (spoke_AS[i].bOccupied) { spoke_AS[i].enableCollider(false); } else { spoke_AS[i].enableCollider(bOn); } } } public int Closest_Fin(Vector3 testPos) { int idxMin = 0; float minDistance = 1000000f; float dist; for (int i = 0; i < spoke_AS.Count; i++) { dist = (spoke_AS[i].fin_LOC.position - testPos).sqrMagnitude; if(dist<minDistance) { idxMin = i; minDistance = dist; } } return idxMin; } public void SetAllColliders(bool bOn) { sphereCollider.enabled = bOn; rb.isKinematic = true; //MORE CONSIDERATIONS HERE for (int i = 0; i < spoke_AS.Count; i++) { spoke_AS[i].bOccupied = false; spoke_AS[i].enableCollider(bOn); } } public void Reset_Spokes_On_Grab() { for (int i = 0; i < spoke_AS.Count; i++) { if (spoke_AS[i].bOccupied) { spoke_AS[i].setOccupied(false); } } } void Update() { FixedJoint fj = GetComponent<FixedJoint>(); if(fj) { if(Vector3.Magnitude(fj.currentForce) > maxFJForce) { fj.connectedBody = null; Destroy(fj); } } if (setLastHeld) { af_Instance.last_Held_AllShape = this.gameObject; setLastHeld = false; } } }