private void InitPoints(SensedObject obj) { float[,,] interpVals = obj.InterpolatedValues; int w = interpVals.GetLength(1); int h = interpVals.GetLength(0); int d = interpVals.GetLength(2); d = 1; // TODO remove if points have to be scatters in the whole volume //float xPos, yPos, zPos; points = new GameObject[h, w, d]; LoadPointGeometry(); float pointScale = obj.PanelGridStep / PointGeomPrefab.GetComponent <Renderer>().bounds.size.x; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { //for (int k = 0; k < d; k++) for (int k = 0; k < d; k++) { points[i, j, k] = Instantiate <GameObject>(PointGeomPrefab); //points[i, j, k] = GameObject.CreatePrimitive(PrimitiveType.Quad); points[i, j, k].transform.localScale = Vector3.one * pointScale; points[i, j, k].transform.position = obj.GetGridPosition(i, j, k); points[i, j, k].transform.parent = obj.ParentGO.transform; //points[i, j, k].SetActive(false); } } } }
private void DrawColoredParticles(SensedObject obj) { float[,,] interpVals = obj.InterpolatedValues; if (points == null) { InitPoints(obj); } int w = points.GetLength(1); int h = points.GetLength(0); int d = points.GetLength(2); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { for (int k = 0; k < d; k++) { //if (!points[i, j, k].activeSelf) // points[i, j, k].SetActive(true); points[i, j, k].GetComponent <Renderer>().material.color = Utilities.ThreeColorLerp(interpVals[i, j, k], Specs.MoistureLowerBound, Specs.MoistureUpperBound, new Color(0F, 0F, 1F), new Color(1F, 1F, 0F), new Color(1F, 0F, 0F)); } } } }
void DrawSizedParticles(SensedObject obj) { if (points == null) { InitPoints(obj); } int w = points.GetLength(1); int h = points.GetLength(0); int d = points.GetLength(2); float pointScale; //float tempWeight = 60F; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { for (int k = 0; k < d; k++) { pointScale = Utilities.Map(obj.InterpolatedValues[i, j, k], Specs.MoistureLowerBound, Specs.MoistureUpperBound, obj.PanelGridStep / PointGeomPrefab.GetComponent <Renderer>().bounds.size.x * 2.5F, 0); //pointScale = Mathf.Lerp(interpVals[i,j,k]/50, 0F, panelGridStep); //Debug.Log(pointScale); points[i, j, k].transform.parent = null; points[i, j, k].transform.localScale = Vector3.one * pointScale; points[i, j, k].transform.parent = obj.ParentGO.transform; points[i, j, k].GetComponent <Renderer>().material.color = Color.yellow; } } } }
public override IEnumerator Enter(Machine owner, Brain controller) { mainMachine = owner; myBrain = controller; Legs myLeg = myBrain.legs; //get sheep target sheepTarget = myBrain.memory.GetValue<SensedObject>("hasCommand"); sheepBrain = (Brain)sheepTarget.getObject().GetComponent("Brain"); sheepMemory = sheepBrain.memory; sheepMemory.SetValue("BeingEaten", true); arriveBehaviour = new Arrive(); arriveBehaviour.Init(myLeg); arriveBehaviour.setTarget(sheepTarget.getObject()); //speed is zero myBrain.legs.maxSpeed = 0f; Debug.Log("I'm eating:" + sheepTarget.getObject() + " HP: " + sheepMemory.GetValue<float>("HP")); yield return null; }
public void Forget(SensedObject target) { if (!SensedObjects.ContainsKey(target)) { return; } GameObject go = target.TargetObject; SensedObjects.Remove(target); if (null != go) { rememberedObjects.Remove(go); seenObjects.Remove(go); heardObjects.Remove(go); smelledObjects.Remove(go); implicitDetectedObjects.Remove(go); } if (NearestSensedObject == target) { var e = SensedObjects.GetEnumerator(); e.MoveNext(); NearestSensedObject = e.Current.Value; nearestSensedChanged?.Invoke(target, NearestSensedObject); } sensedObjectForgottenListener?.Invoke(target); }
public void Visualize(SensedObject obj, DateTime t) { obj.Interpolate(t); // TODO interpolates only if needed (not in the ) //obj.GO.GetComponent<Renderer>().enabled = false; if (LastVizMode != Specs.ThisVizMode) // change the visualization mode { DestroyOtherViz(Specs.ThisVizMode); } switch (Specs.ThisVizMode) { case Specs.VIZ_MODE.TEXTURE: case Specs.VIZ_MODE.TEXTURE_PAINT: SetTexture2D(obj, 0); obj.ObjectGO.GetComponent <Renderer>().material = Instantiate <Material>(Specs.TransparenMat); obj.ObjectGO.GetComponent <Renderer>().material.color = panelColor; //obj.GO.GetComponent<Renderer>().enabled = false; break; case Specs.VIZ_MODE.PARTICLE_COLOR: DrawColoredParticles(obj); obj.ObjectGO.GetComponent <Renderer>().material = Instantiate <Material>(Specs.TransparenMat); obj.ObjectGO.GetComponent <Renderer>().material.color = panelColor; break; case Specs.VIZ_MODE.PARTICLE_RADIUS: DrawSizedParticles(obj); obj.ObjectGO.GetComponent <Renderer>().material = Instantiate <Material>(Specs.TransparenMat); obj.ObjectGO.GetComponent <Renderer>().material.color = panelColor; //CreatParticles(obj.GO); break; case Specs.VIZ_MODE.TUBES: DrawTubes(obj); break; //case Specs.VIZ_MODE.PARTICLE_LOOSE: // Destroy(texGO); // DestroyPoints(); // CreatParticles(obj.GO); // obj.GO.GetComponent<Renderer>().material = Instantiate<Material>(Specs.TransparenMat); // obj.GO.GetComponent<Renderer>().material.color = panelColor; // break; } //DrawTubes(obj); //// write interpolated values to file (for debugging) //Utilities.WriteMatrix2File(Utilities.Slicer(obj.InterpolatedValues, 0), "interp/" + Time.frameCount + ".txt"); //// Setting the texture of the same geometry (wall) doesn't work due to irregular messhing //if (texGO.GetComponent<Renderer>().material.mainTexture == null) // texGO.GetComponent<Renderer>().material.SetTexture("_MainTex", Tex); //else // texGO.GetComponent<Renderer>().material.mainTexture = tex; //SetTexture2D((Texture2D)obj.GO.GetComponent<Renderer>().material.mainTexture, obj.InterpolatedValues, 0); }
void DrawTubes(SensedObject obj) { //int[] tIndx = obj.FindAllTimeStamps(t); //if (obj.TimeIndex != null) if (obj.DataAvailable) { if (tubes == null) { tubes = new GameObject[obj.Sensors.Length]; //for (int s = 0; s < obj.Sensors.Length; s++) //{ // // tubes[s] = new GameObject("TubeMesh"); // //tubes[s].AddComponent<MeshFilter>(); // //tubes[s].AddComponent<MeshRenderer>(); //} } //List<float> MCPerLayer = new List<float>(); float[] MCPerLayer = new float[obj.LayerCount]; for (int s = 0; s < obj.Sensors.Length; s++) { for (int i = 0; i < obj.LayerCount; i++) { MCPerLayer[i] = UnityEngine.Random.Range(0.4F * Specs.MoistureUpperBound, 0.8F * Specs.MoistureUpperBound); } //DrawOneTube(MCPerLayer.ToArray()); if (tubes[s] == null) { tubes[s] = new GameObject("TubeMesh"); tubes[s].AddComponent <MeshFilter>(); tubes[s].AddComponent <MeshRenderer>(); } DrawOneTube(tubes[s], MCPerLayer); tubes[s].transform.localRotation = Quaternion.Euler(-90, 0, 0); tubes[s].transform.position = new Vector3(obj.Sensors[s].Pos.x, obj.Sensors[s].Pos.y, obj.ParentGO.transform.position.z); //tubes[s].transform.localScale = Vector3.one * obj.ObjectGO.GetComponent<Renderer>().bounds.size.z; tubes[s].transform.localScale = Vector3.one * 0.003F; tubes[s].transform.SetParent(obj.Sensors[s].GO.transform); obj.Sensors[s].GO.GetComponent <Renderer>().enabled = false; //if (Vector3.Distance(obj.Sensors[0].Pos, obj.Sensors[s].Pos) < 0.1) //{ // MCPerLayer.Add(obj.Sensors[s].Values[obj.TimeIndex[s]]); //} } //Camera cam = Camera.main; //tubeGO.transform.rotation = Quaternion.LookRotation(cam.transform.right) * Quaternion.Euler(-90, 0, 0); //tubeGO.transform.position = cam.transform.position + cam.transform.forward * 1.1F + cam.transform.right * 0.75F; } }
private SensedObject RememberSensedObject(GameObject targetObject) { SensedObject sensedObject; if (!rememberedObjects.TryGetValue(targetObject, out sensedObject)) { sensedObject = new SensedObject(targetObject); if (null != sensedObject.sensableObject && !sensedObject.sensableObject.IsSensable) { sensedObject.sensableObject.onNoLongerSensableListener += () => { Forget(sensedObject); }; } rememberedObjects[targetObject] = sensedObject; } return(sensedObject); }
protected bool RememberSensedObject(GameObject targetObject, out SensedObject sensedObject) { if (!rememberedObjects.TryGetValue(targetObject, out sensedObject)) { sensedObject = new SensedObject(targetObject); if (null != sensedObject.sensableObject && !sensedObject.sensableObject.IsSensable) { var forgettable = sensedObject; sensedObject.sensableObject.onNoLongerSensableListener += () => { Forget(forgettable); }; } rememberedObjects[targetObject] = sensedObject; return(true); } return(false); }
void SetTexture2D(SensedObject obj, int depth) { float[,,] vals = obj.InterpolatedValues; int panelW = vals.GetLength(1); int panelH = vals.GetLength(0); int i, j; if (texGO == null) { InitTexture(obj); } Texture2D tex = (Texture2D)texGO.GetComponent <Renderer>().material.mainTexture; Color[] colorArray = new Color[tex.width * tex.height]; float alpha = (Specs.ThisVizMode == Specs.VIZ_MODE.TEXTURE_PAINT ? 0 : 1); for (int x = 0; x < tex.width; x++) { for (int y = 0; y < tex.height; y++) { j = (int)Math.Floor(Utilities.Map(x, 0, tex.width, 0, panelW)); i = (int)Math.Floor(Utilities.Map(y, 0, tex.height, 0, panelH)); //Color c = Color.Lerp(new Color(1F, 1F, 0F), new Color(0F, 1F, 0F), Utilities.Map(vals[i, j , depth], 0F, 30F, 0F, 1F)); Color c = Utilities.ThreeColorLerp(vals[i, j, depth], Specs.MoistureLowerBound, Specs.MoistureUpperBound, new Color(0F, 0F, 1F, alpha), new Color(1F, 1F, 0F, alpha), new Color(1F, 0F, 0F, alpha)); //c.a = (Specs.ThisVizMode == Specs.VIZ_MODE.TEXTURE_PAINT ? colorArray[x + (y * tex.width)].a : 1); colorArray[x + (y * tex.width)] = c; } } tex.SetPixels(colorArray); //if (Specs.ThisVizMode == Specs.VIZ_MODE.TEXTURE_PAINT) //{ // VertexPaint painter = texGO.GetComponent<VertexPaint>(); // if (painter == null) // painter = texGO.AddComponent<VertexPaint>(); // //painter.Paint(); //} //colorArray[0] = Color.black; //tex.SetPixels(colorArray); tex.Apply(); }
public SensedObject chooseTarget(List<SensedObject> seenSheep) { SensedObject target = null; foreach (SensedObject sheep in seenSheep) { Brain sheepBrain = sheep.getObject().GetComponent<Brain>(); Memory sheepMem = sheepBrain.memory; float sheepHP = sheepMem.GetValue<float>("HP"); float sheepDistanceWithSheperd = Vector2.Distance(sheepBrain.legs.getPosition(), ((Legs)GameObject.FindGameObjectWithTag("Player").GetComponent<Legs>()).getPosition()); float sheepChasedBy = sheepBrain.memory.GetValue<List<Brain>>("chasedBy").Count; float sheepCourage = sheepMem.GetValue<float>("cowardLevel"); if (sheepHP > sheepHPLimit) { if (sheepDistanceWithSheperd > sheepDistanceSheperdLimit) { target = sheep; break; } else { if (sheepChasedBy > sheepChasedByLimit) { if (sheepCourage <= sheepCourageLimit) { target = sheep; break; } } } } } return target; }
//void CreatParticlesInObject(GameObject go) //// There is a problem with setting the colors of points in the run time (bug?) when using material all particles have the same color, when using start color, color is not applied //{ // ParticleSystem prtclSys; // if (!(prtclSys = go.GetComponent<ParticleSystem>())) // { // prtclSys = go.AddComponent<ParticleSystem>(); // //go.GetComponent<ParticleSystemRenderer>().material = new Material(Shader.Find("Diffuse")); // } // var shp = prtclSys.shape; // shp.enabled = true; // shp.shapeType = ParticleSystemShapeType.Box; // shp.position = go.GetComponent<Renderer>().bounds.center - go.transform.position; // shp.scale = go.GetComponent<Renderer>().bounds.size; // var main = prtclSys.main; // main.startSpeed = 0F; // main.startSize = 0.05F; // main.startLifetime = 1F; // main.prewarm = true; // Material m = go.GetComponent<ParticleSystemRenderer>().material; // m.color = Color.red; // //main.startColor = Color.red; // //go.GetComponent<ParticleSystemRenderer>().material = null; // var emssn = prtclSys.emission; // emssn.rateOverTime = 200F; // //var rndr = prtclSys.GetComponent<Renderer>(); // int count = prtclSys.particleCount; // ParticleSystem.Particle[] prtcls = new ParticleSystem.Particle[count]; // count = prtclSys.GetParticles(prtcls); // main.startColor = new Color(0, 0, 1); // for (int i = 0; i < count; i++) // { // prtcls[i].startSize = 5 * prtcls[i].startSize; // } // //Debug.Log(go.transform.position - go.GetComponent<Renderer>().bounds.center); //} /// //void SetTexture3D(float[,,] vals) //{ // Color[] colorArray = new Color[Tex.width * Tex.height * Tex.depth]; // //Texture3D texture = new Texture3D(size, size, size, TextureFormat.RGBA32, true); // float r = 1.0f / (Tex.width - 1.0f); // for (int x = 0; x < Tex.width; x++) // { // for (int y = 0; y < Tex.height; y++) // { // for (int z = 0; z < Tex.depth; z++) // { // Color c = new Color(x * r, y * r, z * r, 1.0f); // colorArray[x + (y * Tex.width) + (z * Tex.width * Tex.height)] = c; // } // } // } // Tex.SetPixels(colorArray); // Tex.Apply(); // //return texture; //} public void InitTexture(SensedObject obj) { //texGO = GameObject.CreatePrimitive(PrimitiveType.Quad); //texGO = GameObject.CreatePrimitive(PrimitiveType.Plane); Bounds b = obj.ObjectGO.GetComponent <Renderer>().bounds; texGO = Utilities.CreatePlane(b.size.x, b.size.y, obj.InterpolatedValues.GetLength(2), obj.InterpolatedValues.GetLength(1), "TexturePlane"); //texGO = Utilities.CreatePlane(1,2 , 2, 6, "TexturePlane"); //texGO.name = "TexturePlane"; // Put the plane in front of wall (this only works with this iorientation of wall?) // TODO find a better way ? texGO.transform.position = b.center - obj.SurfaceNormal * b.extents.z; //texGO.transform.localScale = b.size; //texGO.transform.Rotate(new Vector3(0, 90, -90)); //texGO.GetComponent<Renderer>().bounds.SetMinMax(b.min, b.max); texGO.transform.SetParent(obj.ParentGO.transform); // make sure texture dimensions are power of 2 and close to dimensions of interpolated values int texW = (int)Mathf.Max(Mathf.Pow(2, Mathf.Round(Mathf.Log(obj.InterpolatedValues.GetLength(1), 2))), 4); int texH = (int)Mathf.Max(Mathf.Pow(2, Mathf.Round(Mathf.Log(obj.InterpolatedValues.GetLength(0), 2))), 4); texGO.GetComponent <Renderer>().material = Instantiate <Material>(Specs.TransparenMat); texGO.GetComponent <Renderer>().material.SetColor("_Color", Color.white); // Make sure the alpha is set to 1 texGO.GetComponent <Renderer>().material.SetTexture("_MainTex", new Texture2D(texW, texH)); if (Specs.ThisVizMode == Specs.VIZ_MODE.TEXTURE_PAINT) { texGO.AddComponent <VertexPaint>(); } //obj.GO.GetComponent<Renderer>().material = new Material(texGO.GetComponent<Renderer>().material); //obj.GO.GetComponent<Renderer>().material.SetTexture("_MainTex", new Texture2D(256,256)); // remove collider }
int Scariest(SensedObject wolf1, SensedObject wolf2) { Legs wolfLeg1 = wolf1.getObject().GetComponent<Brain>().legs; Vector2 sheepPos = myBrain.legs.getPosition(); Vector2 wolfPos1 = wolfLeg1.getPosition(); float distance1 = Vector2.Distance(sheepPos, wolfPos1); Vector2 wolfFacing1 = new Vector2(wolfLeg1.transform.forward.x, wolfLeg1.transform.forward.z); float relativeVelocity1 = Vector2.Dot(wolfFacing1, sheepPos - wolfPos1); float scariness1 = (1 / distance1) * (relativeVelocity1 + 1); Legs wolfLeg2 = wolf2.getObject().GetComponent<Brain>().legs; Vector2 wolfPos2 = wolfLeg2.getPosition(); float distance2 = Vector2.Distance(sheepPos, wolfPos2); Vector2 wolfFacing2 = new Vector2(wolfLeg2.transform.forward.x, wolfLeg2.transform.forward.z); float relativeVelocity2 = Vector2.Dot(wolfFacing2, sheepPos - wolfPos2); float scariness2 = (1 / distance2) * (relativeVelocity2 + 1); if(scariness1 > scariness2) { return 1; } if(scariness1 < scariness2) { return -1; } return 0; }
public override IEnumerator Enter(Machine owner, Brain controller) { mainMachine = owner; myBrain = controller; Legs myLeg = myBrain.legs; arriveBehaviour = new PathfindToPoint(); seekBehaviour = new Seek(); arriveBehaviour.Init(myLeg, myBrain.levelGrid); seekBehaviour.Init(myLeg); myLeg.addSteeringBehaviour(arriveBehaviour); myLeg.addSteeringBehaviour(seekBehaviour); myLeg.maxSpeed = 11f; time = 0f; ferocityRate = controller.memory.GetValue<float>("ferocity"); sheepTarget = myBrain.memory.GetValue<SensedObject>("hasCommand"); sheepMemory = sheepTarget.getMemory(); sheepBrain = (Brain)sheepTarget.getObject().GetComponent("Brain"); arriveBehaviour.setTarget(sheepTarget.getObject()); //for machine learning float panic = sheepBrain.memory.GetValue<float>("Panic"); float courage = sheepBrain.memory.GetValue<float>("cowardLevel"); float chasedBy = sheepBrain.memory.GetValue<List<Brain>>("chasedBy").Count; float distanceWithMe = Vector2.Distance(sheepBrain.legs.getPosition(), myBrain.legs.getPosition()); float distanceWithSheperd = Vector2.Distance(sheepBrain.legs.getPosition(), ((Legs)GameObject.FindGameObjectWithTag("Player").GetComponent<Legs>()).getPosition()); float hungry = myBrain.memory.GetValue<float>("hungryLevel"); float sheepHP = sheepBrain.memory.GetValue<float>("HP"); string sheep = panic + "," + courage + "," + chasedBy + "," + distanceWithMe + "," + distanceWithSheperd + "," + hungry + "," + sheepHP; myBrain.memory.SetValue("targeting", sheep); yield return null; }
/// <summary> /// The main method that you should override in your Agent subclass is AIUpdate(). /// </summary> /// <param name="inputs"></param> public override void AIUpdate(List <SensoryInput> inputs) { base.AIUpdate(inputs); // THE FIRST LINE OF YOUR AIUpdate() override MUST be: base.AIUpdate(inputs); // AIUpdate copies inputs into sensed if (!inited) { Init(); } // AIUpdate copies inputs into sensed SensedObject sawSomeone = null; toClosestEnemy = Vector3.one * 1000; closestEnemy = null; foreach (SensoryInput si in sensed) { switch (si.sense) { case SensoryInput.eSense.vision: if (si.type == eSensedObjectType.enemy) { sawSomeone = si.obj; // Check to see whether the Enemy is within the firing arc // The dot product of two vectors is the magnitude of A * the magnitude of B * cos(the angle between them) Vector3 toEnemy = si.pos - pos; if (toEnemy.magnitude < toClosestEnemy.magnitude) { toClosestEnemy = toEnemy; closestEnemy = si.obj as Agent; } // float dotProduct = Vector3.Dot(headTrans.forward, toEnemy.normalized); // float theta = Mathf.Acos(dotProduct) * Mathf.Rad2Deg; // if (theta <= ArenaManager.AGENT_SETTINGS.bulletAimVarianceDeg) { // if (ammo > 0) { // Fire(); // } // } } break; } // Regardless of the sense type, I want to know if it was a PickUp and what it was if (si.type == eSensedObjectType.item) { PickUp.eType puType = (si.obj as PickUp).puType; // Check the position of this item relative to the position of known item SpawnPoints if (MEM[PickUp.eType.none].Count > 0) { SpawnPoint foundSP = null; foreach (SpawnPoint sp in MEM[PickUp.eType.none]) { if ((sp.pos - si.obj.pos).magnitude < 0.1f) // We found it! { foundSP = sp; break; } } if (foundSP != null) { MEM[PickUp.eType.none].Remove(foundSP); if (!MEM.ContainsKey(puType)) { MEM.Add(puType, new List <SpawnPoint>()); } MEM[puType].Add(foundSP); } else { // No big deal, this just means that we already know about the SpawnPoint at that loc. } } } if (si.type == eSensedObjectType.enemy) { // tracker.Track(si); } } if (sawSomeone == null) { LookCenter(); // leadObj = null; } else { // Turn head to track enemies // How far is the enemy from current headTrans.forward float dotProdToClosest = Vector3.Dot(toClosestEnemy.normalized, headTrans.forward); // Account for the NaN errors that happen if Mathf.Acos(x) is called for x outside of -1 < x < 1 dotProdToClosest = Mathf.Clamp(dotProdToClosest, -1, 1); float angToClosest = Mathf.Acos(dotProdToClosest) * Mathf.Rad2Deg; // This shouldn't be needed because of the Clamp above // if (Mathf.Approximately(dotProdToClosest,1)) { // angToClosest = 0; // } else if (Mathf.Approximately(dotProdToClosest,-1)) { // angToClosest = 180; // } else { // angToClosest = Mathf.Acos( dotProdToClosest ) * Mathf.Rad2Deg; // } // // The following is here because the Acos of 1 is NaN. // if (float.IsNaN(angToClosest)) { // angToClosest = 0; // } // A dot product of toEnemy and transform.right will tell you whether to look left or right float posNeg = (Vector3.Dot(toClosestEnemy.normalized, headTrans.right) < 0) ? -1 : 1; angToClosest *= posNeg; // print("AngleToClosest: "+angToClosest); LookTheta(angToClosest); if (angToClosest <= ArenaManager.AGENT_SETTINGS.bulletAimVarianceDeg) { if (ammo > 0) { Fire(); } } } // Utility AI – Iterate through all the aiUtilRecs and find the one with the highest utility float maxUtil = -1; UtilRec uRecBest = null; foreach (UtilRec ur in aiUtilRecs) { if (ur.strat.Utility(this) > maxUtil) { uRecBest = ur; maxUtil = ur.u; } } aiU = maxUtil; aiStrat = uRecBest.stratType; if (uRecBest.dest != nmAgent.destination && health > 0) { nmAgent.SetDestination(uRecBest.dest); navMeshTargetLoc = uRecBest.dest; } // report on knowledge spawnPointKnowledge.x = MEM.ContainsKey(PickUp.eType.none) ? MEM[PickUp.eType.none].Count : 0; spawnPointKnowledge.y = MEM.ContainsKey(PickUp.eType.health) ? MEM[PickUp.eType.health].Count : 0; spawnPointKnowledge.z = MEM.ContainsKey(PickUp.eType.ammo) ? MEM[PickUp.eType.ammo].Count : 0; if (health > 0) { nmAgent.SetDestination(nmAgent.destination); } }
protected override void OnUpdateSenses() { if (!HasAdrenaline && frame++ < frequency) { return; } frame = 0; float nearest = float.MaxValue; Collider[] colliders = null; GameObject[] gameObjects = null; int possibleTargetCount; if (useSphereCast) { colliders = Physics.OverlapSphere(transform.position, maxSenseRange, targetMask); possibleTargetCount = colliders.Length; } else { gameObjects = SensableObject.Registry; possibleTargetCount = gameObjects.Length; } seenObjects.Clear(); heardObjects.Clear(); smelledObjects.Clear(); // TODO: We may want to think about creating a new set each frame. This was just updating // the set, but I was getting a concurrent modification exception from AnimalUtilityData since // it is operating in a coroutine instead of on the main thread. Let's discuss how to properly // optimize this. We could potentially go with a static list and create a copy for consumers // that request the list when they want it. We can also optimize consumers of the list to use // the OnNewObjectsSensed listener for updates var sensedObjects = new SortedSet <SensedObject>(); var newlySensedObjects = new HashSet <SensedObject>(); float detectionTime = Time.fixedTime; for (int i = 0; i < possibleTargetCount; i++) { GameObject targetObject = useSphereCast ? colliders[i].gameObject : gameObjects[i]; SensedObject sensedObject; float actualDistance = Vector3.Distance(targetObject.transform.position, transform.position); if (actualDistance > maxSenseRange) { continue; } if (targetObject == gameObject) { continue; } if (null != sensedObjectValidationListener && !sensedObjectValidationListener(targetObject)) { continue; } sensedObject = RememberSensedObject(targetObject); float sensedDistance = actualDistance; // Detection from least accurate to most. if (actualDistance < scentRange) { smelledObjects.Add(targetObject); if (sensedObject.actualPosition != targetObject.transform.position) { sensedObject.position = targetObject.transform.position + UnityEngine.Random.insideUnitSphere * scentAccuracyRadius; } sensedDistance = Vector3.Distance(targetObject.transform.position, transform.position); sensedObject.smelled = true; } if (CanSee(targetObject)) { seenObjects.Add(targetObject); sensedObject.position = targetObject.transform.position; sensedObject.seen = true; } if (actualDistance < implicitDetectionRange) { implicitDetectedObjects.Add(targetObject); sensedObject.position = targetObject.transform.position; sensedObject.implicitlyDetected = true; } sensedObject.actualPosition = targetObject.transform.position; sensedObject.distance = sensedDistance; if (lastSenseTime != sensedObject.lastDetection) { newlySensedObjects.Add(sensedObject); } sensedObject.lastDetection = detectionTime; SensedObjects[sensedObject] = sensedObject; while (SensedObjects.Count > nearbySenseCapacity) { SensedObjects.RemoveAt(nearbySenseCapacity); } } if (newlySensedObjects.Count > 0) { OnSensedNewObjects(newlySensedObjects); } lastSenseTime = detectionTime; SensedObject old = NearestSensedObject; NearestSensedObject = SensedObjects.Count > 0 ? SensedObjects.First().Value : null; if (null != NearestSensedObject && Time.fixedTime - NearestSensedObject.lastDetection > timeToRetainNearest) { NearestSensedObject = null; nearest = float.PositiveInfinity; nearestSensedChanged?.Invoke(old, null); } else if (old != NearestSensedObject) { nearestSensedChanged?.Invoke(old, null); } }
public override IEnumerator Run(Brain controller) { bool thereIsShepherd = false; float highestLeaderLevel = 0f; List<SensedObject> seenSheep = new List<SensedObject>(); List<SensedObject> seenWolf = new List<SensedObject>(); Transform playerTrans = null; foreach (SensedObject obj in controller.senses.GetSensedObjects()) { if (obj.getAgentType().Equals(AgentClassification.Sheep)) { seenSheep.Add(obj); } else if (obj.getAgentType().Equals(AgentClassification.Wolf)) { Memory wolfMemory = obj.getMemory(); if (highestLeaderLevel <= wolfMemory.GetValue<float>("leaderLevel")) { highestLeaderLevel = wolfMemory.GetValue<float>("leaderLevel"); } seenWolf.Add(obj); } else if(obj.getAgentType().Equals(AgentClassification.Shepherd)) { playerTrans = obj.getObject().transform; thereIsShepherd = true; } } //get current BeaconInfo if (controller.memory.GetValue<BeaconInfo>("LastBeacon") != null) { if (curBeacon != null) { if (curBeacon.GetTime() < controller.memory.GetValue<BeaconInfo>("LastBeacon").GetTime()) { curBeacon = controller.memory.GetValue<BeaconInfo>("LastBeacon"); } } else { curBeacon = controller.memory.GetValue<BeaconInfo>("LastBeacon"); } } if (curBeacon != null) { //delete curBeacon curBeacon = null; controller.memory.SetValue("LastBeacon", null); controller.memory.SetValue("shouldHide", 3f); } myBrain.memory.SetValue("caution", myBrain.memory.GetValue<float>("caution") - cautionLevelDecay * Time.deltaTime); if(thereIsShepherd) { UpdateCaution(playerTrans); } else { myBrain.memory.SetValue ("watched", myBrain.memory.GetValue<float>("watched") - watchedLevelDecay * Time.deltaTime); } myBrain.memory.SetValue("watched", Mathf.Clamp(myBrain.memory.GetValue<float>("watched"), 0, Mathf.Infinity)); if(myBrain.memory.GetValue<float>("watched") > 0) { //Debug.Log (myBrain.memory.GetValue<float>("watched")); } //check if this wolf has been given command to attack or not if (controller.memory.GetValue<SensedObject>("hasCommand") != null) { //decrease leaderLevel because it has been given command by others controller.memory.SetValue("leaderLevel", controller.memory.GetValue<float>("leaderLevel") - (decreaseLeaderLevel * Time.deltaTime)); //set the minimum leaderLevel for wolf if (controller.memory.GetValue<float>("leaderLevel") < 10f) { controller.memory.SetValue("leaderLevel", 10f); } //Change to hunting phase Debug.Log("I've received command. I'm hunting! Target: " + controller.memory.GetValue<SensedObject>("hasCommand").getObject()); } else { if (seenSheep.Count > 0) { //choose the target //if the wolf hasn't have his target, pick it target = chooseTarget(seenSheep); if (target != null) { //target is alive if (target.getObject().GetComponent<Brain>().memory.GetValue<float>("HP") > 0) { //set the target for this wolf controller.memory.SetValue("hasCommand", target); //calling sheep that it is being targeted Memory sheepMemory = target.getMemory(); //get a list of wolves that are chasing this sheep List<Brain> wolvesChasing = sheepMemory.GetValue<List<Brain>>("chasedBy"); //add itself in if (wolvesChasing != null) { wolvesChasing.Add(this.myBrain); sheepMemory.SetValue("chasedBy", wolvesChasing); } //send signal to other wolf in its sensing radius, tell them to change to hunting phase if (controller.memory.GetValue<float>("leaderLevel") >= highestLeaderLevel) { //increase its leaderLevel whenever it issue a decision to hunt if (controller.memory.GetValue<float>("leaderLevel") < 100f) { controller.memory.SetValue("leaderLevel", controller.memory.GetValue<float>("leaderLevel") + increaseLeaderLevel); } //set the maximum leaderLevel for wolf if (controller.memory.GetValue<float>("leaderLevel") > 100f) { controller.memory.SetValue("leaderLevel", 100f); } //call other to change to hunting phase foreach (SensedObject objWolf in seenWolf) { //give out command to attack the same target Memory wolfMemory = objWolf.getMemory(); wolfMemory.SetValue("hasCommand", target); Debug.Log("I'm the leader! I sent command!"); } } //Change to hunting phasemyBrain.memory.SetValue ("watched", myBrain.memory.GetValue<float>("watched") - watchedLevelDecay * Time.deltaTime); Debug.Log("I'm hunting. Target: " + controller.memory.GetValue<SensedObject>("hasCommand").getObject()); } } } } if (controller.memory.GetValue<SensedObject>("hasCommand") != null) { time = 0f; //decrease its hungryLevel when it change to hunting state //controller.memory.SetValue("hungryLevel", controller.memory.GetValue<float>("hungryLevel") - 4f); mainMachine.RequestStateTransition(hunting.GetTarget()); } else { if (time >= 20f) //wait for 20 sec { //decrease its leaderLevel if it can't find any sheep or cant issue and command if (controller.memory.GetValue<float>("leaderLevel") > 10f) { controller.memory.SetValue("leaderLevel", controller.memory.GetValue<float>("leaderLevel") - (decayLeaderLevel / myBrain.memory.GetValue<float>("ferocity"))); } if (controller.memory.GetValue<float>("hungryLevel") > 0f) { myBrain.memory.SetValue("hungryLevel", controller.memory.GetValue<float>("hungryLevel") - (decayHungryLevel * (myBrain.memory.GetValue<float>("ferocity") / 5))); } //set the minimum leaderLevel for wolf if (controller.memory.GetValue<float>("leaderLevel") < 10f) { controller.memory.SetValue("leaderLevel", 10f); } //set the minimum hungryLevel for wolf if (controller.memory.GetValue<float>("hungryLevel") < 0f) { controller.memory.SetValue("hungryLevel", 0f); Debug.Log("I died because I'm too hungry"); myBrain.getGameObject().SetActiveRecursively(false); controller.memory.GetValue<Genome>("Genome").manager.SpawnWolf(controller.memory.GetValue<Vector2>("StartPoint")); } } else { time += Time.deltaTime; } } yield return null; }
public override IEnumerator Enter(Machine owner, Brain controller) { mainMachine = owner; myBrain = controller; Legs myLeg = myBrain.legs; time = 0f; if (firstActivation) { target = null;//set leaderLevel for wolf myBrain.memory.SetValue("leaderLevel", Random.value * 100); myBrain.memory.SetValue("hasCommand", null); myBrain.memory.SetValue("hungryLevel", 60f); myBrain.memory.SetValue("damage", 20f); myBrain.memory.SetValue("caution", 10f); myBrain.memory.SetValue ("watched", 0f); myBrain.memory.SetValue<float>("ferocity", (float)myBrain.memory.GetValue<Genome>("Genome").getGene("Ferocity")); /* Removed ferocity override limit if (myBrain.memory.GetValue<float>("ferocity") < 0.8f) { myBrain.memory.SetValue("ferocity", 0.8f); }*/ myBrain.memory.SetValue ("shouldHide", 0f); firstActivation = false; } else { Debug.Log("I'm roaming"); //delete its target myBrain.memory.SetValue("hasCommand", null); myBrain.memory.SetValue("targeting", null); } myLeg.maxSpeed = 8.0f; generatedModel(); yield return null; }