I am Instantiating a lot of Rectangles of different sizes (ranging from 3 to 18 units) and they all have attached this script, which should cycle through all the GameObject List which contains them.
It should automatically avoid any overlap, but unfortunately sometimes it gets stuck with some rectangles that remain moving and all the others stop. When this occurs, my program can't continue and blocks in an infinite loop.
Here's the script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Cell : MonoBehaviour {
private float squareDistance;
float xShift = 0;
float yShift = 0;
//float globalStrength = 0;
public bool hasStopped = false;
private Vector2 oldPos = new Vector2();
//private Vector2 oldPos2 = new Vector2();
public Vector3 direction;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(Placer.work) {
float strength;
List<GameObject> cells = Placer.cells;
for (int i=0; i < cells.Count; i++) {
if(cells[i] != this.gameObject) {
if(isOverlapping(cells[i])) {
direction = transform.position - cells[i].transform.position;
strength = 1; //+ globalStrength;
/*if(globalStrength > 0) {
globalStrength = 0;
}*/
direction.Normalize();
xShift += strength * direction.x;
yShift += strength * direction.y;
}
}
}
transform.position = new Vector3(Mathf.Round(transform.position.x + xShift), Mathf.Round(transform.position.y + yShift), transform.position.z);
xShift = 0;
yShift = 0;
if (transform.position.x == oldPos.x && transform.position.y == oldPos.y) {
hasStopped = true;
} else {
hasStopped = false;
}
//oldPos2 = oldPos;
/*if(oldPos2.x == transform.position.x && oldPos2.y == transform.position.y) {
globalStrength = 2;
Debug.Log ("si2");
}*/
oldPos = new Vector2 (transform.position.x, transform.position.y);
/*if(oldPos2.x == oldPos.x && oldPos2.y == oldPos.y) {
globalStrength = 3;
Debug.Log ("Si");
}*/
}
}
private bool isOverlapping(GameObject obj) {
Vector2 size = new Vector2 (GetComponent<Renderer> ().bounds.size.x, GetComponent<Renderer> ().bounds.size.y);
if (pointInside (obj, new Vector2 (transform.position.x + 1 - size.x / 2, transform.position.y + 1 - size.y / 2))) {
return true;
}
if (pointInside (obj, new Vector2 (transform.position.x - 1 + size.x / 2, transform.position.y + 1 - size.y / 2))) {
return true;
}
if (pointInside (obj, new Vector2 (transform.position.x + 1 - size.x / 2, transform.position.y - 1 + size.y / 2))) {
return true;
}
if (pointInside (obj, new Vector2 (transform.position.x - 1 + size.x / 2, transform.position.y - 1 + size.y / 2))) {
return true;
}
return false;
}
/**
* With this method we verify if a Vector2 is inside a GameObject.
*/
private bool pointInside(GameObject obj, Vector2 point) {
Vector2 objSize = new Vector2 (obj.GetComponent<Renderer> ().bounds.size.x, obj.GetComponent<Renderer> ().bounds.size.y);
if ((point.x >= (obj.transform.position.x - objSize.x / 2)) &&
(point.x <= (obj.transform.position.x + objSize.x / 2)) &&
(point.y >= (obj.transform.position.y - objSize.y / 2)) &&
(point.y <= (obj.transform.position.y + objSize.y / 2))) {
return true;
}
return false;
}
public bool getHasStopped() {
return hasStopped;
}
}
I have tried with some workarounds, which you can see commented in the code; none of them fixes completely the problem.
What can I do to fix it?
hasStopped
which tells to the main script if they have stopped moving. The problem happens with lots of rectangles (150) and with fewer (30). \$\endgroup\$