Пример #1
0
        public void Update()
        {
            creature.Move(direction, 1f);
            elapsedTime += Time.deltaTime;
            var myCell = trace.GetCellPos(transform.position);

            float foodTrace;
            float dangerTrace;

            //update the danger signal
            var neighbors = creature.Sensor.SensePredators(creature);

            foreach (var neighbor in neighbors)
            {
                Debug.DrawLine(transform.position, neighbor.transform.position, Color.red);
            }
            dangerTrace = 2 * neighbors.Count;
            //update the food
            var        plants      = creature.Sensor.SensePlants(creature);
            GameObject closestFood = plants.Count == 0 ? null : plants[0];

            foreach (var food in plants)
            {
                Debug.DrawLine(food.transform.position, transform.position, Color.blue);
                if (Vector3.Distance(food.transform.position, transform.position) <= Vector3.Distance(transform.position, closestFood.transform.position))
                {
                    closestFood = food;
                }
                var foodCell = trace.GetCellPos(food.transform.position);
            }
            foodTrace = plants.Count;
            if (plants.Count == 0)
            {
                dangerTrace += 0.5f;
            }
            if (neighbors.Count != 0)
            {
                lastDanger = dangerTrace;
            }
            lastFood   = rememberanceFactor * lastFood + (1 - rememberanceFactor) * foodTrace;
            lastDanger = rememberanceFactor * lastDanger + (1 - rememberanceFactor) * dangerTrace;



            trace.AddFoodTrace(myCell.Item1, myCell.Item2, lastFood);
            trace.AddDangerTrace(myCell.Item1, myCell.Item2, lastDanger);



            // do we have a close piece of food ?
            if (closestFood != null)
            {
                //reach it depending on the associated danger
                var   foodCell = trace.GetCellPos(closestFood.transform.position);
                float risk     = trace.danger[foodCell.Item1, foodCell.Item2] / (trace.food[foodCell.Item1, foodCell.Item2] + trace.danger[foodCell.Item1, foodCell.Item2]);
                if (trace.danger[foodCell.Item1, foodCell.Item2] < 0.1f && trace.food[foodCell.Item1, foodCell.Item2] < 0.1f)
                {
                    risk = 0f;
                }
                if (UnityEngine.Random.Range(0f, 1f) > risk)// || creature.Energy<creature.EnergyManager.EatingReward(closestFood,creature.CreatureRegime))
                {
                    //go to the food and accept risk
                    direction = (closestFood.transform.position - transform.position);
                    return;
                }
                //if not choosing this risk, then go elsewhere (previous code)
            }

            if (elapsedTime < 1)
            {
                return;
            }
            elapsedTime = 0;

            // Go to the gravity center of attraction/repulsion
            Vector3 gCenter = Vector3.zero;
            int     count   = 0;
            bool    explore = UnityEngine.Random.Range(0f, 1f) < 0.05f;

            for (int i = -1; i < 2; i++)
            {
                for (int j = -1; j < 2; j++)
                {
                    int cellx = i + myCell.Item1;
                    int cellz = j + myCell.Item2;
                    if (cellx >= 0 && cellz >= 0 && cellx < trace.food.GetLength(0) && cellz < trace.food.GetLength(1))
                    {
                        Vector3 pos = trace.GetVectorPos(cellx, cellz);
                        if (explore && trace.food[cellx, cellz] < 0.1f && trace.danger[cellx, cellz] < 0.1f)
                        {
                            gCenter += (pos - transform.position).normalized;
                            count++;
                        }
                        else
                        {
                            gCenter += (pos - transform.position).normalized * (trace.food[cellx, cellz] - trace.danger[cellx, cellz]);
                            count++;
                        }
                    }
                }
            }
            direction = gCenter / count;
        }