void OnCollisionEnter2D(Collision2D col) { if (age < 1f) { return; // Если агент "младше" 1, он не может атаковать } if (attackSkill == 0) { return; // Если атака 0, так же не может атаковать } if (col.gameObject.name.Contains("bacterium")) { BacteriaAgent ai = col.gameObject.GetComponent <BacteriaAgent>(); if (ai.age < 1f) { return; } if (familyName.Equals(ai.familyName)) // Если встретил себе подобного - ничего не делать { return; } // Рассчёт урона (разница между силой атакующего и защитой обороняющегося) float damage = attackSkill - ai.defSkill; // Если атака оказалась больше if (damage >= 0) { Eat(ai.energy); // Хищник забирает энергию жертвы себе ai.energy = 0; // Энергия жертвы устанавливается в 0, т.е. смерть агента } } }
private void Eat(float food) { energy += food; if (energy > 16) { energy *= 0.5f; var bact = Resources.Load("bacteria", typeof(GameObject)); GameObject b = (GameObject)Object.Instantiate(bact, new Vector3(0, 0, 0), Quaternion.identity); b.transform.position = transform.position; b.name = "bacterium-" + familyName; Genome g = new Genome(genome); g.MutateWeights(0.5f); g.MutateSkills(allSkills); BacteriaAgent ai = b.GetComponent <BacteriaAgent>(); ai.Init(g); ai.energy = energy; ai.familyName = familyName; // Присваиваем род } }
void FixedUpdate() { float vision = 5f + attackSkill; float[] inputs = new float[inputsCount]; Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, vision); // количество соседних объектов float[] neighboursCount = new float[4]; // Вектора к центрам масс еды, красного, зеленого и синего Vector3[] vectors = new Vector3[4]; for (int i = 0; i < 4; i++) { neighboursCount[i] = 0; vectors[i] = new Vector3(0f, 0f, 0f); } for (int i = 0; i < colliders.Length; i++) { if (colliders[i].gameObject == gameObject) { continue; } if (colliders[i].gameObject.name == "food") { neighboursCount[0]++; vectors[0] += colliders[i].gameObject.transform.position - transform.position; } else if (colliders[i].gameObject.name.Contains("bacterium")) { BacteriaAgent ai = colliders[i].gameObject.GetComponent <BacteriaAgent>(); neighboursCount[1] += ai.attackSkill / 3f; vectors[1] += (colliders[i].gameObject.transform.position - transform.position) * ai.attackSkill; neighboursCount[2] += ai.foodSkill / 3f; vectors[2] += (colliders[i].gameObject.transform.position - transform.position) * ai.foodSkill; neighboursCount[3] += ai.defSkill / 3f; vectors[3] += (colliders[i].gameObject.transform.position - transform.position) * ai.defSkill; } } for (int i = 0; i < 4; i++) { if (neighboursCount[i] > 0) { vectors[i] /= neighboursCount[i] * vision; inputs[i] = vectors[i].magnitude; } else { inputs[i] = 0f; } } float[] outputs = nn.FeedForward(inputs); Vector2 target = new Vector2(0, 0); for (int i = 0; i < 4; i++) { if (neighboursCount[i] > 0) { Vector2 dir = new Vector2(vectors[i].x, vectors[i].y); dir.Normalize(); target += dir * outputs[i]; } } if (target.magnitude > 1f) { target.Normalize(); } Vector2 velocity = rb.velocity; velocity += target * (0.25f + attackSkill * 0.05f); velocity *= 0.98f; rb.velocity = velocity; energy -= (Time.deltaTime * 0.5f); allSkills = new int[] { foodSkill, attackSkill, defSkill }; if (energy < 0f) { Kill(); } }