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;
            };
        });
    }
Beispiel #12
0
 public void rotate(float degrees)
 {
     m_direction = Vector2Calc.rotateDirectionVector(m_direction, degrees);
 }
Beispiel #13
0
 public Line2D(Vector2 p_point, Vector2 p_direction)
 {
     m_point     = Vector2Calc.clone(p_point);
     m_direction = Vector2Calc.clone(p_direction);;
 }
Beispiel #14
0
                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;
        });
    }