private GameObject senseClosest(string p_type) { GameObject[] sensed = sense(p_type); if (sensed.Length == 0) { return(null); } GameObject closest = null; float closeness = float.PositiveInfinity; foreach (GameObject ob in sensed) { float prox = Vector2Calc.proximity(ob.transform.position, gameObject.transform.position); if (prox < closeness) { closest = ob; closeness = prox; } } return(closest); }
private GameObject[] sense(string p_type) { GameObject[] all_of_type = ObjectLogger.getByType(p_type); List <GameObject> in_arc = new List <GameObject>(); foreach (GameObject ob in all_of_type) { if (ob == null) { continue; } Vector3 diff = ob.transform.position - gameObject.transform.position; if (Vector2Calc.checkAngle(diff, m_forward, m_sense_angle) && diff.magnitude <= m_sense_proximity) { in_arc.Add(ob); } } // foreach(GameObject ob in in_arc){ // Debug.DrawLine(gameObject.transform.position, ob.transform.position, Color.cyan, 1f); // } return(in_arc.ToArray()); }
private void fitnessUpdate() { Vector3 creature_position = gameObject.transform.position; Task t = Task.Factory.StartNew(() => { Vector2 proj = Line2D.projection(creature_position, m_controller.GoalLine); //Prox to Line // float lineProx = (9.8f-((proj - Vector2Calc.fromVector3(creature_position)).magnitude)); // float fitness = Mathf.Sign(lineProx) > 0 ? Mathf.Pow( lineProx, 2 ) : -Mathf.Pow( lineProx, 2 ); //Prox to Line + Distance From Origin // float lineProx = (9.8f-((proj - Vector2Calc.fromVector3(creature_position)).magnitude)); // float originDist = (Vector2.zero - Vector2Calc.fromVector3(creature_position)).magnitude; // float fitness = Mathf.Sign(lineProx*originDist) > 0 ? Mathf.Pow( lineProx*originDist, 2 ) : -Mathf.Pow( lineProx*originDist, 2 ); //Distance from origin only if within prox of line // float counting = (proj - Vector2Calc.fromVector3(creature_position)).magnitude > 1f ? 0 : 1; // float originDist = (Vector2.zero - Vector2Calc.fromVector3(creature_position)).magnitude; // float fitness = counting * originDist; //Distance from origin only if within prox of line and only above x axis float counting = (proj - Vector2Calc.fromVector3(creature_position)).magnitude > 1f ? 0 : 1; float negative = creature_position.x >= 0 ? 1 : -1; float originDist = (Vector2.zero - Vector2Calc.fromVector3(creature_position)).magnitude; float fitness = counting * originDist * negative; fit_samples++; m_fit_color = fitness; m_fitness += fitness; }); // if(m_fit_color > 0){ // m_renderer.color = new Color(0,Mathf.Clamp(0.2f+0.8f*(m_fit_color/98),0,1),0,1); // } else { // m_renderer.color = new Color(Mathf.Clamp(0.2f+(-0.8f)*(m_fit_color/98), 0, 1),0,0,1); // } //COLOR: Distance from origin only if within prox of line if (m_fit_color > 0f) { m_renderer.color = new Color(0, Mathf.Clamp(0.2f + 0.8f * (m_fit_color / 16), 0, 1), 0, 1); } else if (m_fit_color < 0f) { m_renderer.color = new Color(Mathf.Clamp(0.2f + (-0.8f) * (m_fit_color / 16), 0, 1), 0, 0, 1); } else { m_renderer.color = new Color(0, 0, 0.5f, 1); } }
private void fitnessUpdate() { Vector3 creature_position = gameObject.transform.position; //Prox to Line float fitlineProx = (Vector2Calc.fromVector3(gameObject.transform.position) - Line2D.projection(creature_position, m_controller.FitnessLine)).magnitude; float healthlineProx = (Vector2Calc.fromVector3(gameObject.transform.position) - Line2D.projection(creature_position, m_controller.HealthLine)).magnitude; Task t = Task.Factory.StartNew(() => { if ((fitlineProx < healthlineProx) || (healthlineProx > 1)) { float fitness = 10 - (fitlineProx * 10); m_fit_color = fitness; m_fitness += fitness; } else { if (m_heal_time++ < 2000) { m_heal_amount = 3 - (3 * (healthlineProx)); m_health.add(m_heal_amount); m_fit_color = 0; } else { m_fit_color = -10f; } } fit_samples++; }); // if(m_fit_color > 0){ // m_renderer.color = new Color(0,Mathf.Clamp(0.2f+0.8f*(m_fit_color/98),0,1),0,1); // } else { // m_renderer.color = new Color(Mathf.Clamp(0.2f+(-0.8f)*(m_fit_color/98), 0, 1),0,0,1); // } if (m_fit_color > 0f) { m_renderer.color = new Color(0, 0, Mathf.Clamp(0.2f + 0.8f * (m_fit_color / 10), 0, 1), 1); } else if (m_fit_color < 0f) { m_renderer.color = new Color(Mathf.Clamp(0.2f - 0.8f * (m_fit_color / 10), 0, 1), 0, 0, 1); } else { m_renderer.color = new Color(0, Mathf.Clamp(0.2f + 0.8f * (m_heal_amount / 3), 0, 1), 0, 1); } }
private bool canGather() { GameObject[] obs = sense("RESOURCE"); foreach (GameObject o in obs) { if (Vector2Calc.proximity(gameObject.transform.position, o.transform.position) < 1f) { return(true); } } return(false); }
// Update is called once per frame // Using Fixed update because it's easy to speed up. When in real time, should probably split decision making into Update() from action activation in FixedUpdate() void FixedUpdate() { if (!m_is_initialized) { Debug.LogError("Creatures require initilization after Instantiation"); } //Tick Event Managers m_tm.tick(Time.fixedDeltaTime); m_im.tick(Time.fixedDeltaTime); //Set forward to correct forward vector m_forward = Vector2Calc.fromAngle(gameObject.transform.rotation.eulerAngles.z + 90); //Actiavte and flush the actions priority list m_actions.activate(); }
public static DOutput aim_at_nearest_creature(ResourceFightDNCreature p_cre) { return((float p_input) => { GameObject creature = p_cre.senseClosest("CREATURE"); if (creature) { float angle = Vector2Calc.getAngle(p_cre.m_forward, creature.transform.position - p_cre.transform.position); p_cre.m_actions.add("ROTATE", p_input, () => { p_cre.transform.Rotate(0, 0, -2 * Mathf.Sign(angle)); }); } else { return; } }); }
// Using Fixed update because it's easy to speed up. When in real time, should probably split decision making into Update() from action activation in FixedUpdate() void FixedUpdate() { if (!m_is_initialized) { Debug.LogError("Creatures require initilization after Instantiation"); } //Tick the timeout event manager m_tm.tick(Time.fixedDeltaTime); m_im.tick(Time.fixedDeltaTime); m_cooldowns.tickAll(Time.fixedDeltaTime); //Set forward to correct forward vector m_forward = Vector2Calc.fromAngle(gameObject.transform.rotation.eulerAngles.z + 90); if (!m_brain_stop) { if (m_decision_time) { m_actions.flush(); //Call fixed update of Controller to do one brain iteration setBehaviours(); m_decision_time = false; } //Actiavte and flush the actions priority list m_actions.activate(); } //Update fitness for this frame m_fitness += fitnessUpdate(); energyConsumer(Time.fixedDeltaTime * 0.2f); consumeMoveEnergy(Time.fixedDeltaTime); if (m_energy.isMin()) { m_renderer.color = Color.red; } else { m_renderer.color = Color.green; } }
public static DOutput search_resource(ResourceFightDNCreature p_cre) { return((float p_input) => { GameObject resource = p_cre.senseClosest("RESOURCE"); if (resource) { float angle = Vector2Calc.getAngle(p_cre.m_forward, resource.transform.position - p_cre.transform.position); p_cre.m_actions.add("ROTATE", p_input, () => { p_cre.transform.Rotate(0, 0, -2 * Mathf.Sign(angle)); }); if (angle < 10f) { p_cre.m_actions.add("MOVE", p_input, () => { p_cre.move(p_cre.m_forward); }); } } else { p_cre.m_actions.add("ROTATE", p_input, () => { p_cre.transform.Rotate(0, 0, 1); }); } }); }
//Dodging public static DInput bulletCollisionImminent(ResourceFightDNCreature p_cre) { DActivationFunction prox_activate = ActivationFactory.generateSigmoid(1.5f, 2, false, true, true); DActivationFunction angle_activate = ActivationFactory.generateSigmoid(10f, 2, false, true, true); DActivationFunction full_activate = ActivationFactory.generateSigmoid(1, 1, false, true, false); return(() => { GameObject[] bullets = p_cre.sense("BULLET"); List <GameObject> bullets_close_and_coming_towards = new List <GameObject>(); foreach (GameObject bul in bullets) { if (Vector2Calc.proximity(bul.transform.position, p_cre.transform.position) < 2 && Vector2Calc.checkAngle(p_cre.transform.position - bul.transform.position, bul.GetComponent <Rigidbody2D>().velocity, 10)) { bullets_close_and_coming_towards.Add(bul); } } float activation = 0; foreach (GameObject bul in bullets_close_and_coming_towards) { float bul_prox = prox_activate(Vector2Calc.proximity(bul.transform.position, p_cre.transform.position) - 0.5f); float bul_angle = angle_activate(Mathf.Abs(Vector2Calc.getAngle(p_cre.transform.position - bul.transform.position, bul.GetComponent <Rigidbody2D>().velocity))); float bul_active = full_activate(bul_prox * bul_angle); if (bul_active > activation) { activation = bul_active; } } //if(activation >0 ) Debug.Log(activation); return activation; }); }
public static DInputFactory <ResourceFightDNCreature> isInRangeFactory(string p_type, float p_range) { return((ResourceFightDNCreature p_cre) => { return () => { GameObject[] sensed = p_cre.sense(p_type); bool any_in_range = false; foreach (GameObject ob in sensed) { if (Vector2Calc.proximity(ob.transform.position, p_cre.transform.position) <= p_range) { any_in_range = true; break; } } // if (any_in_range) Debug.Log("InRange " + p_type); return any_in_range ? 1f : 0f; }; }); }
public void rotate(float degrees) { m_direction = Vector2Calc.rotateDirectionVector(m_direction, degrees); }
public Line2D(Vector2 p_point, Vector2 p_direction) { m_point = Vector2Calc.clone(p_point); m_direction = Vector2Calc.clone(p_direction);; }
public static Vector2 projection(Vector2 p_point, Line2D p_normal) { Vector2 norm_point = p_normal.Point; return(Vector2Calc.projection(p_point - norm_point, p_normal.Direction) + norm_point); }
private void gather() { //Get list of gatherable resources GameObject[] obs = sense("RESOURCE"); List <GameObject> resources = new List <GameObject>(); Vector3 this_position = gameObject.transform.position; foreach (GameObject o in obs) { if (Vector2Calc.proximity(this_position, o.transform.position) < 1f) { resources.Add(o); } } //If there are none, return if (resources.Count == 0) { return; } //Get the closest resource in gather arc float closeness = float.PositiveInfinity; GameObject to_harvest = null; foreach (GameObject o in resources) { float proximity = Vector2Calc.proximity(this_position, o.transform.position); if (!(proximity < closeness)) { continue; } closeness = proximity; to_harvest = o; } //Gather the resource m_brain_stop = true; m_rb.velocity = Vector3.zero; m_rb.angularVelocity = 0; m_actions.flush(); m_cooldowns.activate("GATHER", 0.5f); GameObject line = LineCreator.createLine(this_position + (Vector3Calc.fromVec2(m_forward) * 0.1f), to_harvest.transform.position, Color.green, 0.05f, 0.5f); Resource harvesting = to_harvest.GetComponent <Resource>(); DIntervalListener energy_suck = () => { float harvest_power = m_energy.Max - m_energy.Value; if (harvest_power > 10f) { harvest_power = 10f; } if (to_harvest != null) { m_energy.add(harvesting.collect(harvest_power)); } }; m_im.addListener(0.1f, energy_suck); m_tm.addTimeout(0.5f, () => { m_im.removeListener(0.1f, energy_suck); m_brain_stop = false; }); }