public class AntPopulationSystem:USystem { public override void Init () { base.Init (); this.AddRequestComponent (typeof(AntPopulationComponent)); } public override void Update (UEntity uEntity) { // Debug.Log ("UpdateAntSystem"); base.Update (uEntity); // InfluenceMap.getInstance ().Show (4); List<AntPopulation> tList = uEntity.GetComponent<AntPopulationComponent> ().mAntPopulationSet; for (int i = 0; i < AntPopulation.mNowListCount; i++) { if (tList [i].isStartFind) { UpdateAntPopulation (tList [i]); } } } private void UpdateAntPopulation(AntPopulation pAntPopulation) { // Debug.Log ("UpdateAntPopulation"); Ant[] tAnts = pAntPopulation.mAnts; for (int i = 0; i < tAnts.Length; i++) { tAnts [i].mPositionIndex = InfluenceMap.getInstance ().getTilefromPosition (new Vector2(tAnts[i].mAIRT.transform.position.x,tAnts[i].mAIRT.transform.position.z)); tAnts [i].Add (tAnts[i].mPositionIndex); if (tAnts [i].mInfoFood > 0.0f) tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.green; else if (tAnts [i].mInfoHome > 0.0f) tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.blue; else tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.red; if (tAnts [i].mNowTarget == NowTarget.FOOD) { OnFood (tAnts[i],pAntPopulation); } else if (tAnts [i].mNowTarget == NowTarget.HOME) { OnHome (tAnts[i],pAntPopulation); } } } private void OnFood(Ant pAnt,AntPopulation ap) { Vector2 v1 = new Vector2 (pAnt.mAIRT.transform.position.x,pAnt.mAIRT.transform.position.z); Vector2 v2 = new Vector2 (pAnt.mNowPositionTarget.x,pAnt.mNowPositionTarget.z); float dis = Vector2.Distance (v1,v2); if (pAnt.mNowPositionTarget == Vector3.zero || dis < 0.35f) { if(pAnt.mInfoHome>0.0f) UpdatePheromone (ap.mInfluenceHomeTag,pAnt.mInfoHome,ap.mRadiationRiaus,pAnt.mPositionIndex,1000,pAnt.mClosedArray.Count); GameObject g_target = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagDistination); GameObject g_home = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagHome); if(g_target != null) { pAnt.mInfoHome = -1.0f; pAnt.mInfoFood = 200.0f; pAnt.mNowTarget = NowTarget.HOME; pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap); pAnt.mClosedArray.Clear (); pAnt.mLastDir = Vector2.zero; return; } if (g_home != null) { pAnt.mInfoFood = -1.0f; pAnt.mInfoHome = 200.0f; } pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap); //Debug.Log (pAnt.mNowPositionTarget.ToString()); } else { Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position; offset.Normalize (); offset.y = 0; pAnt.mAIRT.transform.Translate (offset*Time.deltaTime*6); } } private void OnHome(Ant pAnt,AntPopulation ap) { Vector2 v1 = new Vector2 (pAnt.mAIRT.transform.position.x,pAnt.mAIRT.transform.position.z); Vector2 v2 = new Vector2 (pAnt.mNowPositionTarget.x,pAnt.mNowPositionTarget.z); float dis = Vector2.Distance (v1,v2); //Debug.Log ("OnHome"); if (pAnt.mNowPositionTarget == Vector3.zero || dis < 0.35f) { if(pAnt.mInfoFood>0.0f) UpdatePheromone (ap.mInfluenceDistinationTag,pAnt.mInfoFood,ap.mRadiationRiaus,pAnt.mPositionIndex,1000,pAnt.mClosedArray.Count); GameObject g_target = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagDistination); GameObject g_home = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagHome); if (g_home != null) { pAnt.mInfoFood = -1.0f; pAnt.mInfoHome = 200.0f; pAnt.mNowTarget = NowTarget.FOOD; pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap); pAnt.mClosedArray.Clear (); pAnt.mLastDir = Vector2.zero; return; } if (g_target != null) { pAnt.mInfoFood = 200.0f; pAnt.mInfoHome = -1.0f; } pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap); } else { Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position; offset.Normalize (); offset.y = 0; pAnt.mAIRT.transform.Translate (offset*Time.deltaTime*6); } } private GameObject FindTarget(Vector3 mCenter,float riaus,string code) { Collider[] tAllCollider = Physics.OverlapSphere (mCenter,riaus); GameObject tg = null; foreach (Collider c in tAllCollider) { if (c.tag == code) { tg = c.transform.gameObject; break; } } return tg; } private float Gauss(Vector2 v) { return Mathf.Exp(-(v.x*v.x/2.0f+v.y*v.y/2.0f)); } private void UpdatePheromone(string code,float f,int radioriaus,Vector2 center,float max,int pGoingTile) { int index = InfluenceMap.getInstance ().mDictionary [code]; int ti = Mathf.Clamp ((int)center.x,0,InfluenceMap.getInstance ().wtileCount-1); int tj = Mathf.Clamp ((int)center.y,0,InfluenceMap.getInstance ().htileCount-1); if(pGoingTile<radioriaus) InfluenceMap.getInstance ().IMData [index] [ti] [tj] += f * (1-(float)pGoingTile/(float)radioriaus); if (InfluenceMap.getInstance ().IMData [index] [ti] [tj] > max) InfluenceMap.getInstance ().IMData [index] [ti] [tj] = max; } private Vector3 ComputeDirction(Ant pAnt,AntPopulation ap) { Vector3 result = Vector3.zero; Vector2 resultNineGrid = Vector2.zero; int index = -1; if (pAnt.mNowTarget == NowTarget.FOOD) index = InfluenceMap.getInstance ().mDictionary [ap.mInfluenceDistinationTag]; else index = InfluenceMap.getInstance ().mDictionary [ap.mInfluenceHomeTag]; float tMax = InfluenceMap.getInstance ().getMax (pAnt.mPositionIndex,1,index); if (tMax > 0.0f) { //Debug.Log (pAnt.mNowTarget.ToString()+" "+tMax+" infoFood:"+pAnt.mInfoFood+" infoHome"+pAnt.mInfoHome); float minusRate = 0.02f; if (Random.Range (0.0f, 1.0f) < minusRate) { int RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length); resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex]; if (pAnt.mLastDir != Vector2.zero) resultNineGrid = pAnt.mLastDir; float minusRate_ = 0.2f; if (Random.Range (0.0f, 1.0f) < minusRate_) { RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length); resultNineGrid = resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex]; } int count = 0; while ((InfluenceMap.getInstance().isWall(resultNineGrid+pAnt.mPositionIndex)||pAnt.Contains(resultNineGrid+pAnt.mPositionIndex))&&count<10) { RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length); resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex]; count++; } } else { float sum = 0.0f; for (int i = 0; i < InfluenceMap.getInstance ().NineGrid.Length; i++) { Vector2 delta = InfluenceMap.getInstance ().NineGrid [i]; Vector2 real = pAnt.mPositionIndex + delta; if(real.x>=0&&real.x<InfluenceMap.getInstance().wtileCount&&real.y>=0&&real.y<InfluenceMap.getInstance().htileCount) sum += InfluenceMap.getInstance ().IMData [index] [(int)real.x] [(int)real.y]; } for (int i = 0; i < InfluenceMap.getInstance ().NineGrid.Length; i++) { Vector2 delta = InfluenceMap.getInstance ().NineGrid [i]; Vector2 real = pAnt.mPositionIndex + delta; float tRate = 0.0f; if(real.x>=0&&real.x<InfluenceMap.getInstance().wtileCount&&real.y>=0&&real.y<InfluenceMap.getInstance().htileCount) tRate = InfluenceMap.getInstance ().IMData [index] [(int)real.x] [(int)real.y] / sum; if (Random.Range (0.0f, 1.0f) < tRate&&!pAnt.Contains(delta+pAnt.mPositionIndex)&&!InfluenceMap.getInstance().isWall(delta+pAnt.mPositionIndex)) { resultNineGrid = new Vector2 (delta.x,delta.y); // Debug.Log (pAnt.Contains(delta+pAnt.mPositionIndex)); break; } } } } else { int RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length); resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex]; if (pAnt.mLastDir != Vector2.zero) resultNineGrid = pAnt.mLastDir; float minusRate_ = 0.2f; if (Random.Range (0.0f, 1.0f) < minusRate_) { RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length); resultNineGrid = resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex]; } int count = 0; while ((InfluenceMap.getInstance().isWall(resultNineGrid+pAnt.mPositionIndex)||pAnt.Contains(resultNineGrid+pAnt.mPositionIndex))&&count<10) { RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length); resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex]; count++; } //Debug.Log (pAnt.Contains(resultNineGrid+pAnt.mPositionIndex)); } pAnt.mLastDir = new Vector2 (resultNineGrid.x,resultNineGrid.y); float tx = pAnt.mPositionIndex.x + resultNineGrid.x; float ty = pAnt.mPositionIndex.y + resultNineGrid.y; tx = Mathf.Clamp (tx,0,InfluenceMap.getInstance().wtileCount-1); ty = Mathf.Clamp (ty,0,InfluenceMap.getInstance().htileCount-1); Vector2 tile = new Vector2 (tx,ty); // Debug.Log (pAnt.Contains(tile)); result = InfluenceMap.getInstance ().GetPositionByTile (tile); return result; } }
一开始的结果:
经过一段时间,开始往浅蓝和那个绿色箱子中间聚拢。
再过一段时间,已经是几乎所有都在一起聚拢。