예제 #1
0
        void Insert()
        {
            var p     = Prefabs[_r.NextInt(Prefabs.Length)];
            var scale = 1 - ScaleOffset + _r.NextFloat() * 2 * ScaleOffset;
            var rot   = _r.NextFloat(2 * math.PI);

            _points.Clear();
            foreach (var f in p.Vertices)
            {
                _points.Add(DemoMath.Rotate(scale * f, rot));
            }

            var min = new float2(float.MaxValue);
            var max = new float2(float.MinValue);

            for (var i = 0; i < _points.Count; i++)
            {
                min = math.min(_points[i], min);
                max = math.max(_points[i], max);
            }

            var size   = max - min;
            var range  = (float2)Plane.Size - size;
            var offset = _r.NextFloat2(range);

            for (var i = 0; i < _points.Count; i++)
            {
                _points[i] += (Vector2)(offset - min - (float2)Plane.Size / 2);
            }

            _ids.Add(Plane.InsertObstacle(_points));
        }
예제 #2
0
        void Insert()
        {
            var obstacle = ObstaclePrefabs[_r.NextInt(ObstaclePrefabs.Length)];
            var scale    = ObstacleMinScale + _r.NextFloat() * ObstacleScaleRange;
            var rot      = _r.NextFloat(2 * math.PI);
            var vertices = obstacle.Vertices.Select(f => DemoMath.Rotate(scale * f, rot)).ToList();

            var min = new float2(float.MaxValue);
            var max = new float2(float.MinValue);

            for (var i = 0; i < vertices.Count; i++)
            {
                min = math.min(vertices[i], min);
                max = math.max(vertices[i], max);
            }

            var size   = max - min;
            var range  = _size - new float2(0, 2 * SpawnRectHeight) - size;
            var offset = _r.NextFloat2(range) + new float2(0, SpawnRectHeight) - _size / 2;

            for (var i = 0; i < vertices.Count; i++)
            {
                vertices[i] += (Vector2)(offset - min);
            }

            Plane.InsertObstacle(vertices);
        }
예제 #3
0
        void ProcessInputAndUpdateUi()
        {
            if (Input.GetKeyDown(KeyCode.M))
            {
                SceneManager.LoadScene("menu");
                return;
            }

            if (Input.GetKeyDown(KeyCode.Escape))
            {
                _points.Clear();
                _points.Add(new List <Vector2>());
                _placingPrefab = -1;
            }

            var prev = _placingPrefab;

            if (Input.GetKeyDown(KeyCode.Alpha1))
            {
                _placingPrefab = 0;
            }
            if (Input.GetKeyDown(KeyCode.Alpha2))
            {
                _placingPrefab = 1;
            }
            if (Input.GetKeyDown(KeyCode.Alpha3))
            {
                _placingPrefab = 2;
            }
            if (Input.GetKeyDown(KeyCode.Alpha4))
            {
                _placingPrefab = 3;
            }
            if (Input.GetKeyDown(KeyCode.Alpha5))
            {
                _placingPrefab = 4;
            }

            var mousePosRaw = Input.mousePosition;

            mousePosRaw.z = _camera.nearClipPlane;
            var mousePos    = (Vector2)_camera.ScreenToWorldPoint(mousePosRaw).xz();
            var scrollDelta = Input.mouseScrollDelta.y;
            var mouseDelta  = mousePos - _previousMouse;

            _previousMouse = mousePos;

            if (_placingPrefab != -1)
            {
                if (prev != _placingPrefab)
                {
                    _prefabSize = _placingPrefab < 4
                        ? _cameraController.Zoom
                        : Mathf.Min(1, _cameraController.Zoom * 2);
                }

                if (scrollDelta != 0 && Input.GetKey(KeyCode.LeftShift))
                {
                    _prefabRotation += scrollDelta * PrefabRotationSpeed;
                }

                if (scrollDelta != 0 && Input.GetKey(KeyCode.LeftControl))
                {
                    _prefabSize = math.clamp(_prefabSize + scrollDelta * PrefabSizeSpeed * _prefabSize, PrefabMinSize, PrefabMaxSize);
                }


                _points.Clear();

                var start = _placingPrefab;
                var end   = _placingPrefab == 4 ? 14 : _placingPrefab + 1;

                for (int i = start; i < end; i++)
                {
                    var obstacle = Prefabs[i];
                    var verts    = obstacle.Vertices;
                    var points   = new List <Vector2>();
                    foreach (var vert in verts)
                    {
                        points.Add(DemoMath.Rotate(vert * _prefabSize, _prefabRotation) + mousePos);
                    }
                    _points.Add(points);
                }

                if (Input.GetMouseButtonDown(0))
                {
                    Insert();
                }
            }
            else
            {
                if (Input.GetMouseButtonDown(1) && _points[0].Count > 0)
                {
                    if (_points[0].Count > 1)
                    {
                        if ((Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) && _points[0].Count > 2)
                        {
                            _points[0].Add(_points[0][0]);
                        }
                        Insert();
                    }
                }

                if (Input.GetMouseButtonDown(0))
                {
                    var ray = _camera.ScreenPointToRay(Input.mousePosition);
                    if (Physics.Raycast(ray.origin, ray.direction * 10, out var hit))
                    {
                        _target = hit.collider.gameObject;
                    }
                    if (_target == null || _points[0].Count > 0)
                    {
                        _points[0].Add(mousePos);
                    }
                }

                if (Input.GetMouseButtonUp(0))
                {
                    _target = null;
                }

                if (scrollDelta != 0 && Input.GetKey(KeyCode.LeftControl))
                {
                    var size = _start.localScale.x;
                    size = math.clamp(size + scrollDelta * AgentSizeZoomSpeed * size, MinAgentSize, MaxAgentSize);
                    var s = new Vector3(size, size, size);
                    _start.localScale = s;
                    _goal.localScale  = s;
                    _agent.GetComponent <DotsNavAgent>().Radius = size / 2;
                }

                if (_target != null && Input.GetMouseButton(0) && !Input.GetMouseButtonDown(0) && mouseDelta != Vector2.zero)
                {
                    _target.transform.position += mouseDelta.ToXxY();
                }
            }

            if (Input.GetKeyDown(KeyCode.E))
            {
                _navmesh.DrawMode = _navmesh.DrawMode == DrawMode.Constrained ? DrawMode.Both : DrawMode.Constrained;
            }
            if (Input.GetKeyDown(KeyCode.H))
            {
                Help.gameObject.SetActive(!Help.gameObject.activeSelf);
            }

            if ((Input.GetKey(KeyCode.T) || Input.GetKeyDown(KeyCode.R)) && _obstacles.Count > 0)
            {
                Plane.RemoveObstacle(_obstacles.Last());
                _obstacles.RemoveAt(_obstacles.Count - 1);
            }

            if (Input.GetKeyDown(KeyCode.C))
            {
                _agent.DrawCorners = !_agent.DrawCorners;
            }

            foreach (var points in _points)
            {
                for (int i = 1; i < points.Count; i++)
                {
                    _lineDrawer.DrawLine(points[i - 1], points[i], Color.cyan);
                }
            }
            if (_placingPrefab == -1 && _points[0].Count > 0)
            {
                _lineDrawer.DrawLine(_points[0][_points[0].Count - 1], mousePos, Color.cyan);
            }
        }
예제 #4
0
        static unsafe void ClampObstacle(List <Vector2> vertices, Vector2 size)
        {
            var buffer = new List <Vector2>(vertices);

            vertices.Clear();
            var hs = size / 2;
            var br = new Vector2(hs.x, -hs.y);
            var tl = new Vector2(-hs.x, hs.y);
            var l  = stackalloc Vector2[2];

            for (var i = 0; i < buffer.Count; i++)
            {
                var f = buffer[i];

                if (DemoMath.Contains(f, -hs, hs))
                {
                    vertices.Add(f);
                }

                if (i < buffer.Count - 1)
                {
                    var next = buffer[i + 1];
                    var li   = 0;
                    if (DemoMath.IntersectSegSeg(f, next, -hs, br, out var r))
                    {
                        l[li++] = r;
                    }
                    if (DemoMath.IntersectSegSeg(f, next, br, hs, out r))
                    {
                        l[li++] = r;
                    }
                    if (DemoMath.IntersectSegSeg(f, next, hs, tl, out r))
                    {
                        l[li++] = r;
                    }
                    if (DemoMath.IntersectSegSeg(f, next, tl, -hs, out r))
                    {
                        l[li++] = r;
                    }

                    switch (li)
                    {
                    case 1:
                        AddCorner(l[0]);
                        vertices.Add(l[0]);
                        break;

                    case 2 when math.lengthsq(l[0] - f) < math.lengthsq(l[1] - f):
                        vertices.Add(l[0]);

                        vertices.Add(l[1]);
                        break;

                    case 2:
                        vertices.Add(l[1]);
                        vertices.Add(l[0]);
                        break;
                    }
                }
            }

            if (vertices.Count == 1)
            {
                vertices.Clear();
            }

            void AddCorner(Vector2 point)
            {
                Side a, b;

                if (vertices.Count == 0 || (a = GetSide(point)) == Side.None || (b = GetSide(vertices.Last())) == Side.None || a == b)
                {
                    return;
                }

                var aIsHor = a == Side.Bottom || a == Side.Top;

                switch (aIsHor ? a : b)
                {
                case Side.Top:
                    switch (aIsHor ? b : a)
                    {
                    case Side.Left:
                        vertices.Add(tl);
                        return;

                    case Side.Right:
                        vertices.Add(hs);
                        return;
                    }
                    break;

                case Side.Bottom:
                    switch (aIsHor ? b : a)
                    {
                    case Side.Left:
                        vertices.Add(-hs);
                        return;

                    case Side.Right:
                        vertices.Add(br);
                        return;
                    }
                    break;
                }
                throw new ArgumentOutOfRangeException();
            }

            Side GetSide(Vector2 p)
            {
                if (p.x == -hs.x)
                {
                    return(Side.Left);
                }
                if (p.x == hs.x)
                {
                    return(Side.Right);
                }
                if (p.y == -hs.y)
                {
                    return(Side.Bottom);
                }
                if (p.y == hs.y)
                {
                    return(Side.Top);
                }
                return(Side.None);
            }
        }