// Update is called once per frame void Update() { slowMotion = Mathf.Clamp(slowMotion, 0.01f, 1.0f); Time.timeScale = slowMotion; Time.fixedDeltaTime = 0.02f * slowMotion; if (Input.GetButtonDown("Fire1")) { Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); pos.z = transform.position.z; GameObject go = Instantiate(obj); go.transform.position = pos; go.transform.rotation = Quaternion.identity; quadtree.Add(go.GetComponent <QtAgent> ()); placedAgent = go.GetComponent <QtAgent>(); if (go.GetComponent <Rigidbody2D> () != null) { int cornerIndex = Random.Range(0, quadtree.Boundary.AllCorners.Length); Vector2 corner = quadtree.Boundary.AllCorners [cornerIndex]; Vector2 dir = (corner - placedAgent.GetCenter()).normalized * 3.0f; go.GetComponent <Rigidbody2D> ().AddForce(dir); } } if (Input.GetButtonDown("Fire2")) { Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); pos.z = transform.position.z; GameObject go = Instantiate(obj); go.transform.position = pos; go.GetComponent <SpriteRenderer> ().color = Color.black; quadtree.Add(go.GetComponent <QtAgent> ()); pickAgent = go.GetComponent <QtAgent>(); /* * //clear prvious agent contact status * foreach (IQuadtreeAgent a in queryAgents) * a.GetGameObject ().GetComponent<QtCircleAgent> ().contact = false; * * List<IQuadtreeAgent> retriveAgents = pickAgent.CurrentNode.FindElements(pickAgent); * foreach (IQuadtreeAgent agent in retriveAgents) { * * agent.GetGameObject ().GetComponent<QtCircleAgent> ().contact = true; * * queryAgents.Add (agent); * } */ } if (Input.GetButtonDown("Jump")) { QtAgent[] agents = GameObject.FindObjectsOfType <QtAgent> (); StartCoroutine(RemoveAgents(agents)); } if (Input.GetButton("Submit")) { Vector3 mPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); Vector2 pos = new Vector2(mPos.x, mPos.y); if (circleQuery == null) { circleQuery = new QtCircleQuery(pos, queryRadius); } if (rectQuery == null) { rectQuery = new QtRectangleQuery(pos, rectQuerySize); } ((ConvexCircle)circleQuery.GetShape()).Center = pos; ((ConvexCircle)circleQuery.GetShape()).Radius = queryRadius; ((ConvexRect)rectQuery.GetShape()).Center = pos; ((ConvexRect)rectQuery.GetShape()).Width = rectQuerySize.x; ((ConvexRect)rectQuery.GetShape()).Height = rectQuerySize.y; ((ConvexRect)rectQuery.GetShape()).Rotation = ((ConvexRect)rectQuery.GetShape()).Rotation + Time.deltaTime * 80.0f; //clear prvious agent contact status List <IQuadtreeAgent> .Enumerator er = queryAgents.GetEnumerator(); while (er.MoveNext()) { (er.Current as QtCircleAgent).contact = false; } queryAgents.Clear(); // quadtree query //er = quadtree.QueryRange (circleQuery).GetEnumerator(); er = quadtree.QueryRange(rectQuery).GetEnumerator(); while (er.MoveNext()) { (er.Current as QtCircleAgent).contact = true; queryAgents.Add(er.Current); Vector2 force = er.Current.GetCenter() - (circleQuery.GetShape() as ConvexCircle).Center; force = force.normalized * (100.0f * ((circleQuery.GetShape() as ConvexCircle).Radius - force.magnitude / (circleQuery.GetShape() as ConvexCircle).Radius)); if ((er.Current as QtAgent).agRigidbody2D) { (er.Current as QtAgent).agRigidbody2D.AddForce(force); } } drawQuery = true; } else { drawQuery = false; //clear prvious agent contact status /* * foreach (IQuadtreeAgent a in queryAgents){ * //a.GetGameObject ().GetComponent<QtCircleAgent> ().contact = false; * (a as QtCircleAgent).contact = false; * } */ List <IQuadtreeAgent> .Enumerator er = queryAgents.GetEnumerator(); while (er.MoveNext()) { (er.Current as QtCircleAgent).contact = false; } queryAgents.Clear(); } }
/** * Query elements within or contact with query shape * * You can create your own query with any kind of convex shape * * Return list of elements contact with or within query shape * * Param upwardSearch true query will find the node that query shape complete fit in in first * place then start search downward from that node. It is recommend to leave value as true for * more accurate result. **/ public List<IQuadtreeAgent> QueryRange(IQuadtreeQuery query, bool upwardSearch = true){ if (query == null) { #if DEBUG Debug.LogError("Can't query range, given query is null"); #endif return null; } /** * Upward search from this node * * This will go up until the node wihch query shape complete fit in **/ if (upwardSearch) { //If this is the node query shape complete fit in CollisionResult cResult = query.GetShape().IntersectWithShape(boundary); //we found the node then start query from this node if (cResult == CollisionResult.Fit) { //downward search from parent if there is parent node //the reason from parent node is that parent node's overlap element //might be contact query shape if (parentNode != null) { //from parent node we start downward search return parentNode.QueryRange (query, false); } } else {//continue search upward //If there is a parent node otherwsie this is root node and start from //here downward search if (parentNode != null) { //Continue finding upward until the node query shape can totally fit in return parentNode.QueryRange (query, true); } } } /** * Downward search from this node * * Downward search only search elements in child node include this node **/ List<IQuadtreeAgent> result = new List<IQuadtreeAgent> (); CollisionResult r = query.GetShape ().IntersectWithShape (boundary); //if not contact with query shape which is not in range if (r == CollisionResult.None) return result; //search child nodes if (nodes != null) { IEnumerator er = nodes.GetEnumerator (); while (er.MoveNext ()) { result.AddRange ((er.Current as QuadtreeNode).QueryRange (query, false)); } } //add this node's elements result.AddRange (elements); result.AddRange (overlapElements); //Check if any of element contact query shape List<IQuadtreeAgent> filterResult = new List<IQuadtreeAgent>(); List<IQuadtreeAgent>.Enumerator resultEr = result.GetEnumerator(); while(resultEr.MoveNext()){ if(resultEr.Current.GetShape().IntersectWithShape(query.GetShape()) != CollisionResult.None){ filterResult.Add(resultEr.Current); } } return filterResult; }