void Start() { //create a chaser and flock unit on each path for (int i = 0; i < paths.Count; ++i) { //first we create the chaser Vector3 startPos = paths[i].GetComponent <pathPoints>().points[25]; GameObject chaser = (GameObject)Instantiate(chaserPrefab, startPos, Quaternion.identity); //manually initialize the chaser's followPath component with the desired properties followPath fp = chaser.GetComponent <followPath>(); fp.path = paths[i]; fp.curPt = 25; fp.init(); //now we create as many flock units as desired for (int r = 0; r < numUnitsPerFlock; ++r) { GameObject flockUnit = (GameObject)Instantiate(flockUnitPrefab, startPos, Quaternion.identity); flockUnit.GetComponent <SpriteRenderer>().sprite = flockSprites[i]; //initialize the flock unit's followChaser component with the desired properties followChaser fc = flockUnit.GetComponent <followChaser>(); fc.leader = chaser; fc.init(); //ofset each flock unit by a different amount, so that they do not begin on top of each other Vector3 curPos = fc.transform.position; fc.transform.position = new Vector3(curPos.x + .4f * (numUnitsPerFlock / 2f + .5f - r), curPos.y, curPos.z); //give each flock unit a tag so we can poll through them for collisions flockUnit.tag = "flockUnit"; } } }
/** * perform a cone collision check against all specified objects, avoiding them if necessary * @param a: the object from which to perform a cone check * @param objs: the list of objects to check against */ public static void avoidConeCollisions(GameObject a, List <GameObject> objs) { //perform a cone check on each passed in object followChaser fc = a.GetComponent <followChaser>(); fc.coneHitsThisFrame = 0; foreach (GameObject o in objs) { if (coneCheck(a, o)) { //cone check returned a collision; turn at a rate inversely proportional to our distance from the object ++fc.coneHitsThisFrame; } } }
/** * use collision prediction to determine the nearest future collision between the input object and list of other objects * @param a: the object for which we wish to predict the nearesst collision * @param objs: the list of objects against which we should check for future collisions */ public static Vector3 predictNearestCollision(GameObject a, List <GameObject> objs) { followChaser afc = a.GetComponent <followChaser>(); float closestPredictedDistance = -1; afc.closestPredictedUnit = null; Vector3 closestPredictedLoc = Vector3.zero; //iterate over all passed in objects to find the one which will collide with us the soonest for (var i = 0; i < objs.Count; ++i) { GameObject b = objs[i]; followChaser bfc = b.GetComponent <followChaser>(); //calculate our collision prediction between a and b now Vector3 dp = b.transform.position - a.transform.position; Vector3 vt = bfc.spd * b.transform.up; Vector3 vc = afc.spd * a.transform.up; Vector3 dv = vt - vc; float tClosest = -(Vector3.Dot(dp, dv) / Mathf.Pow(Mathf.Abs(dv.magnitude), 2)); //ignore collisions in the past if (tClosest < 0) { continue; } Vector3 pcf = a.transform.position + vc * tClosest; Vector3 ptf = b.transform.position + vt * tClosest; float colDist = Vector3.Distance(pcf, ptf); if (colDist < (afc.radius + bfc.radius)) { //check if the distance at the time of collision will cause an intersection if (closestPredictedDistance == -1 || colDist < closestPredictedDistance) { closestPredictedDistance = colDist; afc.closestPredictedUnit = b; closestPredictedLoc = pcf; } } } return(closestPredictedLoc); }