Exemple #1
0
    private static void ExpandNode(Node current, NVector2 to, ref PriorityQueue <Node> openlist, ref HashSet <Node> closedlist, int heurFactor = 1)
    {
        for (int i = 0; i < NeighborOffset.Length; ++i)
        {
            var offset = NeighborOffset[i];
            var child  = new Node(current.point + offset);
            child.parent = current;

            // check if point available
            if (!GridUtil.IsPassable(child.point))
            {
                continue;
            }

            if (closedlist.Contains(child))
            {
                continue;
            }
            child.distance = current.distance + 1;
            var heur = heurFactor * (int)currentHeuristicFunc(child.point, to);
            if (openlist.Contains(child, heur))
            {
                continue;
            }

            openlist.Enqueue(child, heur);
        }
    }
Exemple #2
0
    public static List <NVector2> Area(NVector2 from, int max_depth, bool includeStart = false)
    {
        Queue <Node>   openlist   = new Queue <Node>();
        HashSet <Node> closedlist = new HashSet <Node>();

        openlist.Enqueue(new Node(from));

        do
        {
            var current = openlist.Dequeue();

            closedlist.Add(current);

            if (current.distance >= max_depth)
            {
                closedlist.Remove(current);
                break;
            }
            ExpandNode(current, ref openlist, ref closedlist);
        } while (openlist.Count > 0);

        var outlist = closedlist.Select(n => n.point).ToList();

        outlist.Remove(from);
        return(outlist);
    }
Exemple #3
0
    public static List <NVector2> Path(NVector2 from, NVector2 to, int max_depth = 10, int distance = 0, int heurFactor = 1)
    {
        PriorityQueue <Node> openlist   = new PriorityQueue <Node>();
        HashSet <Node>       closedlist = new HashSet <Node>();

        openlist.Enqueue(new Node(from));

        distance = GridUtil.IsPassable(to) ? 0 : distance;

        do
        {
            var current = openlist.Dequeue();
            if (current.point == to || currentHeuristicFunc(current.point, to) <= distance)
            {
                List <NVector2> outlist = new List <NVector2>();
                outlist.Add(current.point);
                while (current.parent != null)
                {
                    current = current.parent;
                    outlist.Insert(0, current.point);
                }
                return(outlist);
            }
            closedlist.Add(current);

            if (current.distance >= max_depth)
            {
                break;
            }
            ExpandNode(current, to, ref openlist, ref closedlist, heurFactor: heurFactor);
        } while (!openlist.Empty);

        return(new List <NVector2>());
    }
Exemple #4
0
    void OnTriggerEnter(Collider other)
    {
        MonoBehaviour c = other.GetComponent <EnemyActor>();

        if (c != null)
        {
            roomEnemies.Add((EnemyActor)c);
            positions.Add(c.transform.position);

            Physics.IgnoreCollision(this.GetComponent <Collider>(), c.GetComponent <Collider>());

            if (GameTickManager.Instance.ActiveRoom == this)
            {
                c.gameObject.SetActive(false);
            }
            return;
        }
        c = other.GetComponent <PlayerActor>();
        if (c != null)
        {
            GameTickManager.Instance.ActiveRoom = this;
            playerEnterTile = ((PlayerActor)c).GridPosition;
            return;
        }
    }
Exemple #5
0
        private void OnSceneGUI()
        {
            var up_quat = Quaternion.Euler(90, 0, 0);

            var     points = serializedObject.FindProperty("waypoints").FindPropertyRelative("points");
            Vector3 p1 = Vector3.zero, p2 = Vector3.zero;

            Handles.color = Color.red;
            for (int i = 0; i < points.arraySize; ++i)
            {
                var point = points.GetArrayElementAtIndex(i);
                var x     = point.FindPropertyRelative("x").intValue;
                var y     = point.FindPropertyRelative("y").intValue;

                p2 = GridUtil.GridToWorld(new Vector2(x, y));
                if (i != 0)
                {
                    Handles.DrawLine(p1, p2);
                }
                p1 = p2;
                Handles.RectangleHandleCap(i, p1, up_quat, 0.2f, EventType.Repaint);
            }

            // --------------
            if (!visualmode)
            {
                return;
            }

            var plane = new Plane(Vector3.up, Vector3.zero);

            float enter;
            var   ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

            plane.Raycast(ray, out enter);
            var hitpoint = ray.GetPoint(enter);
            var tile     = GridUtil.WorldToGrid(hitpoint);

            Handles.color = new Color(1f, 0.45f, 0f);
            Handles.DrawDottedLine(p1, GridUtil.GridToWorld(tile), 5);

            if (Handles.Button(GridUtil.GridToWorld(tile) + Vector3.up * 0.1f, up_quat, 0.5f, 0.5f, Handles.RectangleHandleCap))
            {
                //active.Tiles[tile_y*active.TileMapWidth + tile_x] = selectedTile;
                //active.OnValidate();
                var selected_point = new NVector2(tile);
                var pat            = (target as PatrouilleBehaviour);
                if (pat.waypoints.points.Contains(selected_point))
                {
                    pat.waypoints.points.Remove(selected_point);
                }
                else
                {
                    pat.waypoints.points.Add(selected_point);
                }
                SceneView.RepaintAll();
                EditorUtility.SetDirty(target);
            }
        }
Exemple #6
0
        /// <returns>An A* Path to the Target, from the AI position, considering the Speed Attribute</returns>
        private List <NVector2> ClampedPathToTarget(NVector2 target)
        {
            var path = Astar.Path(actor.GridPosition, target, distance: 1);

            if (path.Count > actor.stats.currentStats.speed)
            {
                path = path.GetRange(0, actor.stats.currentStats.speed);
            }
            return(path);
        }
Exemple #7
0
        // public Vector2 currentWaypoint{ get { return waypoints.points[current];  } }

        void OnValidate()
        {
            var own_grid_pos = new NVector2(GridUtil.WorldToGrid(this.transform.position));

            if (waypoints.points.Count < 1)
            {
                waypoints.points.Add(own_grid_pos);
            }
            else
            {
                if (waypoints.points[0] != own_grid_pos)
                {
                    waypoints.points.Insert(0, own_grid_pos);
                }
            }
        }
Exemple #8
0
        public bool IsPlayerVisible()
        {
            if (visibleArea == null)
            {
                return(false);
            }

            var forward   = new NVector2(this.transform.forward.To2DXZ());
            var right     = new NVector2(forward.y, -forward.x);
            var pgrid_pos = PlayerActor.Instance.GridPosition - enemyActor.GridPosition;

            var dx = right.x * pgrid_pos.x + right.y * pgrid_pos.y + visibleArea.GetLength(0) / 2;
            var dy = forward.x * pgrid_pos.x + forward.y * pgrid_pos.y;

            return(visibleArea.GetLength(0) > dx && dx >= 0 &&
                   visibleArea.GetLength(1) > dy && dy >= 0 &&
                   visibleArea[dx, dy]);
        }
Exemple #9
0
        public override void Update(ActionSelectorSM self)
        {
            var mesh = self.selectionCircleMesh;

            var enemiesInRange = GameTickManager.Instance.activeEnemies.Where(
                e => Astar.CalculateHeuristic(e.GridPosition, PlayerActor.Instance.GridPosition)
                < PlayerActor.Instance.stats.currentStats.awareness).ToList();

            var   ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float enter;

            if (!plane.Raycast(ray, out enter))
            {
                return;
            }

            var field = new NVector2(GridUtil.WorldToGrid(ray.GetPoint(enter)));

            int?is_valid = null;

            for (var i = 0; i < enemiesInRange.Count; ++i)
            {
                if (enemiesInRange[i].GridPosition == field)
                {
                    is_valid = i;
                    Graphics.DrawMesh(mesh,
                                      Matrix4x4.Translate(enemiesInRange[i].transform.position), self.selectionCircleMaterial, 0, Camera.current, 0, activeCircle);
                }
                else
                {
                    Graphics.DrawMesh(mesh,
                                      Matrix4x4.Translate(enemiesInRange[i].transform.position), self.selectionCircleMaterial, 0, Camera.current, 0);
                }
            }

            if (Input.GetMouseButtonDown(0) && is_valid != null)
            {
                var enemy          = enemiesInRange[(int)is_valid];
                var selectedAction = new AttackAction(PlayerActor.Instance.gameObject, enemy.gameObject, enemy.attackPrefab, 1);
                onActionSelectedObservable.OnNext(selectedAction);
            }
        }
        public override void Update(ActionSelectorSM self)
        {
            if (mesh == null || meshMaterial == null)
            {
                return;
            }
            Graphics.DrawMesh(mesh, Matrix4x4.Translate(self.transform.position), meshMaterial, 0, Camera.current, 0, new MaterialPropertyBlock(), ShadowCastingMode.Off, receiveShadows: false);

            /* replace by input provider: */
            var   ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            float enter;

            if (plane.Raycast(ray, out enter))
            {
                var field = new NVector2(GridUtil.WorldToGrid(ray.GetPoint(enter)));

                fieldSelector.transform.position =
                    Vector3.MoveTowards(fieldSelector.transform.position,
                                        GridUtil.GridToWorld(field),
                                        32 * Time.deltaTime);

                var sel = new NVector2(GridUtil.WorldToGrid(fieldSelector.transform.position));

                if (Math.Abs(sel.x - field.x + sel.y - field.y) > 0)
                {
                    return;
                }

                var is_valid = walkableTiles.Contains(sel);
                fieldSelector.SetActive(is_valid);

                if (Input.GetMouseButtonDown(0) && is_valid)
                {
                    var path = Astar.Path(PlayerActor.Instance.GridPosition, sel, heurFactor: 2);
                    selectedAction = new MoveAction(PlayerActor.Instance.gameObject, path);
                    onActionSelectedObservable.OnNext(selectedAction);
                }
            }
        }
Exemple #11
0
        private bool dirty = true; // quick hack

        private void Update()
        {
            NVector2 gridpos         = new NVector2(GridUtil.WorldToGrid(this.transform.position));
            Vector3  desiredWorldPos = GridUtil.GridToWorld(desiredPosition);

            animator.SetBool("walking", false);

            if (desiredWorldPos.Approx(transform.position, MOVEMENT_DEADZONE_SQR))
            {
                // reached field
                this.transform.position = GridUtil.GridToWorld(desiredPosition);

                if (dirty)
                {
                    onTileEnterAsObservable.OnNext(true);
                }
                dirty = false;

                if (nextPosition == null)
                {
                    return;
                }
                if (nextPosition == desiredPosition)
                {
                    onTileEnterAsObservable.OnNext(false);
                    return;
                }

                desiredPosition = (NVector2)nextPosition;
                nextPosition    = null;

                dirty = true;
                dir   = (desiredPosition - gridpos);

                var mg = (dir.x * dir.x + dir.y * dir.y);
                if (mg != 1)
                {
                    if (mg == 0)
                    {
                        return;         // standing still !?
                    }
                    throw new ArgumentException(this.name + ": Unknown direction: " + dir);
                }
            }

            // rotate towards dir:
            var desiredRotation = Quaternion.LookRotation(((Vector2)dir).To3DXZ(), Vector3.up);
            var desiredAngle    = Quaternion.Angle(transform.rotation, desiredRotation);

            if (desiredAngle > 5)
            {
                var rot = Quaternion.RotateTowards(transform.rotation, desiredRotation, 90 * rotationSpeedFactor * Time.deltaTime);
                transform.rotation   = rot;
                rotationSpeedFactor += 16 * Time.deltaTime;
            }
            else
            {
                animator.SetBool("walking", true);
                transform.rotation  = desiredRotation;
                rotationSpeedFactor = 1;

                //transform.position = transform.position + (((Vector2)dir) * Time.deltaTime * speed).To3DXZ();
                transform.position = Vector3.MoveTowards(transform.position, desiredWorldPos, Time.deltaTime * speed);
            }
        }
Exemple #12
0
 public void ResetDesiredPosition()
 {
     desiredPosition = new NVector2(GridUtil.WorldToGrid(this.transform.position));
 }
Exemple #13
0
        public static bool[,] CalculateVisibleArea(NVector2 position, int range, NVector2 forward, float viewAngle = 0)
        {
            var right = new NVector2(forward.y, -forward.x);

            // step 1: get opaque tiles in region
            bool[,] opaques = new bool[(range + 1) * 2 + 1, 1 + (range + 1) + 1];
            // pos_tile = [range+1, 1]
            for (int dx = -(range + 1); dx <= (range + 1); ++dx)
            {
                for (int dy = -1; dy <= (range + 1); ++dy)
                {
                    var pos = position + forward * dy + right * dx;
                    var b   = GridUtil.IsStaticObstacle(pos);
                    // Debug.Log(dx + ", " + dy + ": " + b);
                    opaques[(range + 1) + dx, dy + 1] = b;
                }
            }

            // step 2: get tile corners:
            // a corner is true if any of the 4 tiles that the corner belongs to are true
            // a corner is true if you cant look through it
            var range2 = range * range;

            bool[,] corners = new bool[opaques.GetLength(0) - 1, opaques.GetLength(1) - 1];
            for (int x = 0; x < corners.GetLength(0); ++x)
            {
                for (int y = 0; y < corners.GetLength(1); ++y)
                {
                    corners[x, y]  = opaques[x, y] | opaques[x + 1, y] | opaques[x, y + 1] | opaques[x + 1, y + 1];
                    corners[x, y] |= (range2 <= sqrt_vector_length(x - 0.5f - range, y - 0.5f));
                    // corners[x, y] |= Math.Abs((new Vector2(x - 0.5f - range, y - 0.5f).normalized).y) <= viewAngle;
                }
            }

/*            GameTickManager.Instance.Gizmos += () => {
 *
 *
 *              for (int x = 0; x < corners.GetLength(0); ++x) {
 *                  for (int y = 0; y < corners.GetLength(1); ++y) {
 *                      var wpos = GridUtil.GridToWorld((position + forward*y + right*(x-range)));
 *                      Gizmos.color = corners[x,y] ? Color.magenta : Color.cyan;
 *
 *                      if(corners[x,y] && (range2 <= sqrt_vector_length(x - 0.5f - range, y - 0.5f) ))
 *                          Gizmos.color = Color.red;
 *                      Gizmos.DrawCube(wpos + new Vector3(0.5f, 0, 0.5f), Vector3.one * 0.15f);
 *                  }
 *              }
 *
 *
 *              Debug.Break();
 *          };*/

            // step 3: visible tiles:
            bool[,] visibles = new bool[range * 2 + 1, range + 1];

            NVector2 pos_tile = new NVector2(range, 0);

            for (int x = 0; x < visibles.GetLength(0); ++x)
            {
                for (int y = 0; y < visibles.GetLength(1); ++y)
                {
                    if (opaques[x + 1, y + 1])
                    {
                        visibles[x, y] = false; continue;
                    }
                    if ((new Vector2(x - range, y).normalized).y <= viewAngle)
                    {
                        visibles[x, y] = false; continue;
                    }

                    if (CornersOfTile(x, y).All((xy) => corners[xy.x, xy.y]))
                    {
                        visibles[x, y] = false; continue;
                    }
                    var b = LineOfSight(pos_tile.x, pos_tile.y, x, y, ref corners);
                    visibles[x, y] = b;
                }
            }

/*
 *          GameTickManager.Instance.Gizmos += () => {
 *
 *              for (int x = 0; x < visibles.GetLength(0); ++x) {
 *                  for (int y = 0; y < visibles.GetLength(1); ++y) {
 *                      var wpos = GridUtil.GridToWorld((position + forward*y + right*(x-range)));
 *
 *                      if (opaques[x + 1, y + 1]) {
 *                          Gizmos.color = Color.black;
 *                          Gizmos.DrawWireCube(wpos , Vector3.one * 0.15f);
 *                          continue;
 *                      }
 *                      if (!visibles[x, y]) {
 *                          Gizmos.color = Color.red;
 *                          Gizmos.DrawWireCube(wpos , Vector3.one * 0.15f);
 *                          continue;
 *                      }
 *                      Gizmos.color = Color.cyan;
 *                      Gizmos.DrawWireCube(wpos , Vector3.one * 0.15f);
 *                      continue;
 *
 *                  }
 *              }
 *
 *              Debug.Break();
 *          };
 */

            return(visibles);
        }
Exemple #14
0
 public static float CalculateHeuristic(NVector2 from, NVector2 to)
 {
     //float schnellerAberUngenauer = 1f;
     //return Mathf.Abs(schnellerAberUngenauer * ((to.x - from.x) + (to.y - from.y)));
     return(Mathf.Abs(to.x - from.x) + Mathf.Abs(to.y - from.y));
 }
Exemple #15
0
 public Node(NVector2 point, int dis = 0)
 {
     this.point    = point;
     this.distance = dis;
 }
Exemple #16
0
    // Update is called once per frame
    void Update()
    {
        var activeEnemies = GameTickManager.Instance.activeEnemies;

        var   ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        float enter;

        if (plane.Raycast(ray, out enter))
        {
            var field = new NVector2(GridUtil.WorldToGrid(ray.GetPoint(enter)));

            var b = false;
            foreach (var enemy in activeEnemies)
            {
                if (field != enemy.GridPosition)
                {
                    continue;
                }
                var s = enemy.stats.currentStats;

                stats.text =
                    $@"<color=white>HP{"\t"}<color=red>{new string('/', s.hp)}
<color=white>Dmg{"\t"}<color=red>{new string('/', s.atk)}
<color=white>SPD{"\t"}<color=red>{new string('/', s.speed)}
";

                ((RectTransform)stats.transform.parent).position  = Camera.main.WorldToScreenPoint(enemy.transform.position);
                ((RectTransform)stats.transform.parent).position += Vector3.up * 50;
                b = true;
                break;
            }
            stats.transform.parent.gameObject.SetActive(b);
        }

        foreach (var key in indicators.Keys.Where(k => !activeEnemies.Contains(k)))
        {
            indicators[key].gameObject.SetActive(false);
        }

        foreach (var enemy in activeEnemies)
        {
            if (!indicators.ContainsKey(enemy))
            {
                var go = GameObject.Instantiate(prefab, parent: this.transform);
                indicators.Add(enemy, go.GetComponent <Image>());
            }



            if (enemy.State == AIState.Alterted)
            {
                int i = enemy.visibleArea.IsPlayerVisible() ? 2 : 1;
                indicators[enemy].gameObject.SetActive(true);
                indicators[enemy].sprite = AlertStates[i];
            }
            else
            {
                indicators[enemy].gameObject.SetActive(false);
            }

            var sp = Camera.main.WorldToScreenPoint(enemy.transform.position + Vector3.up * 2.5f);
            indicators[enemy].transform.position = sp;
        }
    }
Exemple #17
0
 public bool Equals(NVector2 other)
 {
     return(x == other.x && y == other.y);
 }