예제 #1
0
    public static void RequestPath(NodeSideInfo startInfo, NodeSideInfo endInfo, Action <NodeSideInfo[], bool> callback)
    {
        PathRequest newRequest = new PathRequest(startInfo, endInfo, callback);

        Instance._requestQueue.Enqueue(newRequest);
        Instance.TryProcessNext();
    }
예제 #2
0
    public NodeSideInfo GetClosesetNodeSideInfo(NodeSideInfo info, Node target)
    {
        if (info._node == target)
        {
            return(null);
        }

        int deltaX = target.X - info._node.X;
        int deltaY = target.Y - info._node.Y;
        int deltaZ = target.Z - info._node.Z;

        if (deltaX >= 2 || deltaY >= 2 || deltaZ >= 2)
        {
            return(null);
        }

        int   closest         = 0;
        float closestDistance = 999.0f;

        for (int i = 0; i < (int)Side.Count; ++i)
        {
            Vector3 targetSidePosition = target.GetWorldPositionBySide((Side)i);
            float   distance           = Vector3.Distance(targetSidePosition, info.GetWorldPosition());
            if (distance < closestDistance)
            {
                closestDistance = distance;
                closest         = i;
            }
        }

        return(_nodeSideInfos[Index3D(target.X, target.Y, target.Z), closest]);
    }
예제 #3
0
파일: BoardWalk.cs 프로젝트: Cesea/Sweeper
    public override void MoveTo(NodeSideInfo info)
    {
        if (_moving || (info._node == null))
        {
            return;
        }

        //갈 수 있는곳인지 없는곳 인지 판단
        if (info._side == Side.Top)
        {
            Node nodeRespecteSide = BoardManager.Instance.CurrentBoard.GetOffsetedNode(info._node, 0, 1, 0);
            //갈 수 없는 곳 이다.
            if (nodeRespecteSide.IsSolid)
            {
                return;
            }
        }

        _targetNodeInfo = info;
        _targetPosition = _targetNodeInfo._node.GetWorldPositionBySide(_targetNodeInfo._side);

        if (_targetPosition != _startPosition)
        {
            _moving = true;
            _movementManager.OnMovementStart();
        }
    }
예제 #4
0
        public void InstallObjectAtNode(NodeSideInfo info, int prefabIndex, Vector3 offset, Quaternion rotation)
        {
            if (prefabIndex > _installPrefabList.Count)
            {
                return;
            }

            if (!Object.ReferenceEquals(info, null))
            {
                if (info.InstalledObject != null)
                {
                    //설치하려는 자리에 이미 노드가 있다.... 어떻게 처리 할까??
                }
                else
                {
                    //오브젝트를 설치하고 노드의 속성을 업데이트 한다.
                    GameObject  go          = Instantiate(_installPrefabList[prefabIndex], info.GetWorldPosition() + offset, rotation);
                    LevelObject levelObject = go.GetComponent <LevelObject>();
                    levelObject.Offset       = offset;
                    levelObject.Rotation     = rotation;
                    levelObject._prefabIndex = prefabIndex;
                    info.InstalledObject     = go;
                }
            }
        }
예제 #5
0
    public virtual void UpdateNodeSideInfo(NodeSideInfo newInfo)
    {
        _startNodeInfo = newInfo;

        _targetPosition = _startNodeInfo.GetWorldPosition();
        _startPosition  = _startNodeInfo.GetWorldPosition();
    }
예제 #6
0
    public void OnMovementDone(NodeSideInfo info)
    {
        _sittingNodeInfo = info;
        _sittingNodeInfo.SittingObject = gameObject;

        _boardObject.UpdateNeighbourCells();

        //만약 플레이어가 죽거나 출구에 도착한다면 true를 반환한다
        if (_boardObject.CheckMovement(_sittingNodeInfo))
        {
            StopFindPath();
            return;
        }

        foreach (var movement in _availableMovements)
        {
            movement.UpdateNodeSideInfo(_sittingNodeInfo);
        }

        if (_boardObject.CheckAdjacentCells())
        {
            StopFindPath();
        }

        _boardObject.OnMovementDone();
    }
예제 #7
0
    public static Vector3 GetClosestEdge(NodeSideInfo a, NodeSideInfo b)
    {
        Vector3 result = Vector3.zero;
        Vector3 aPos   = a.GetWorldPosition();
        Vector3 bPos   = b.GetWorldPosition();

        if (a._side == b._side)
        {
            Vector3 diffHalf = (bPos - aPos) * 0.5f;
            result = aPos + diffHalf;
        }
        else if (a._node == b._node)
        {
            result = a._node.WorldPosition +
                     BoardManager.SideToVector3Offset(a._side) +
                     BoardManager.SideToVector3Offset(b._side);
        }
        else
        {
            Vector3 diff = (bPos - aPos);
            result = a._node.WorldPosition + diff;
        }

        return(result);
    }
예제 #8
0
    public override void MoveTo(NodeSideInfo info)
    {
        if (_moving || (info._node == null) ||
            ((info._side == _startNodeInfo._side) && (info._node != _startNodeInfo._node)) ||
            ((info._side == _startNodeInfo._side) && (info._node == _startNodeInfo._node)))
        {
            return;
        }

        if (info._node == _startNodeInfo._node)
        {
            Vector3 startPosition = _startNodeInfo.GetWorldPosition();
            Vector3 diff          = BoardManager.SideToVector3Offset(info._side);

            _cornerPosition = startPosition + diff;
        }
        else
        {
            _cornerPosition = NodeSideInfo.GetClosestEdge(_startNodeInfo, info);
        }

        _targetNodeInfo = info;
        _targetPosition = _targetNodeInfo._node.GetWorldPositionBySide(_targetNodeInfo._side);

        if (_targetPosition != _startPosition)
        {
            _moving = true;
            _movementManager.OnMovementStart();
        }
    }
예제 #9
0
파일: PathFinder.cs 프로젝트: Cesea/Sweeper
    private int GetDistanceCost(NodeSideInfo a, NodeSideInfo b)
    {
        int distX = Mathf.Abs(a._node.X - b._node.X);
        int distY = Mathf.Abs(a._node.Y - b._node.Y);
        int distZ = Mathf.Abs(a._node.Z - b._node.Z);

        return(distX * 10 + distY * 10 + distZ * 10);
    }
예제 #10
0
 private void CreateObjectsFromSaveData(LevelSaveData data)
 {
     foreach (var l in data._levelObjectDatas)
     {
         NodeSideInfo info = BoardManager.Instance.CurrentBoard.GetNodeInfoAt(l._boardX, l._boardY, l._boardZ, l._installedSide);
         LevelCreator.Instance.InstallObjectAtNode(info, l._prefabIndex, l._offset, l._rotation);
     }
 }
예제 #11
0
 public override void UpdateSelectingInfos(NodeSideInfo selecting, NodeSideInfo prev)
 {
     if (!_positioning)
     {
         _selectingInfo     = selecting;
         _prevSelectingInfo = prev;
     }
 }
예제 #12
0
파일: PathFinder.cs 프로젝트: Cesea/Sweeper
 public bool FindPathImmediate(NodeSideInfo startNode, NodeSideInfo endNode, ref NodeSideInfo[] outInfos)
 {
     if (CalculatePath(startNode, endNode))
     {
         outInfos = RetracePath(startNode, endNode);
         return(true);
     }
     return(false);
 }
예제 #13
0
 //레벨을 위함이 아니다...
 public GameObject CreateObjectAtNode(NodeSideInfo info, GameObject prefab, Vector3 offset, Quaternion rotation)
 {
     if (!Object.ReferenceEquals(info, null))
     {
         //오브젝트를 설치하고 노드의 속성을 업데이트 한다.
         GameObject go = Instantiate(prefab, info.GetWorldPosition() + offset, rotation);
         return(go);
     }
     return(null);
 }
예제 #14
0
 public void DestroyObjectAtNode(NodeSideInfo info)
 {
     if (!Object.ReferenceEquals(info, null) &&
         info.InstalledObject != null)
     {
         //LevelObject levelObject = info._node.GetInstalledObjectAt(info._side).GetComponent<LevelObject>();
         Destroy(info.InstalledObject);
         info.InstalledObject = null;
     }
 }
예제 #15
0
 public static Side GetRelativeSide(NodeSideInfo a, NodeSideInfo b)
 {
     if (a._node == b._node)
     {
         return(Side.Count);
     }
     else
     {
         return(Node.GetRelativeSide(a._node, b._node));
     }
 }
예제 #16
0
 public void StartFindPath(NodeSideInfo target, bool followImmediatly = true)
 {
     if (followImmediatly)
     {
         PathRequestManager.RequestPath(_sittingNodeInfo, target, OnPathFind);
     }
     else
     {
         PathRequestManager.RequestPath(_sittingNodeInfo, target, OnPathSave);
     }
 }
예제 #17
0
    public void SetSittingNode(int x, int y, int z, Side side)
    {
        if (!Object.ReferenceEquals(_sittingNodeInfo, null))
        {
            _sittingNodeInfo.SittingObject = null;
        }
        _sittingNodeInfo = BoardManager.Instance.CurrentBoard.GetNodeInfoAt(x, y, z, side);
        _sittingNodeInfo.SittingObject = gameObject;

        transform.position = _sittingNodeInfo.GetWorldPosition();
        OnMovementDone(_sittingNodeInfo);
    }
예제 #18
0
    public override bool CheckMovement(NodeSideInfo sittingNodeInfo)
    {
        bool result = false;

        if (sittingNodeInfo.IsHazard)
        {
            result = true;
            _health.ReceiveDamage(1);
        }

        return(result);
    }
예제 #19
0
    public override bool Equals(object obj)
    {
        NodeSideInfo info = obj as NodeSideInfo;

        if (Object.ReferenceEquals(obj, null))
        {
            return(false);
        }
        else
        {
            return((_node == info._node) && (_side == info._side));
        }
    }
예제 #20
0
파일: BoardWalk.cs 프로젝트: Cesea/Sweeper
    public override void MoveBy(int x, int y, int z)
    {
        if ((x == 0 && z == 0))
        {
            return;
        }

        NodeSideInfo targetNodeInfo = new NodeSideInfo();

        targetNodeInfo._node = BoardManager.Instance.CurrentBoard.GetOffsetedNode(_startNodeInfo._node, x, y, z);
        targetNodeInfo._side = _startNodeInfo._side;

        MoveTo(targetNodeInfo);
    }
예제 #21
0
    private IEnumerator CreateAndShowRadialMenu(NodeSideInfo info)
    {
        _rectTransform = _background.GetComponent <RectTransform>();

        yield return(StartCoroutine(CommandBuilder.BuildCommands(GameStateManager.Instance.Player, info, OnCommandBuildDone)));

        while (!_commandBuildDone)
        {
            yield return(null);
        }

        List <Command> commands = GameStateManager.Instance.Player.CommandBuffer;

        _elementAngleGap = 360.0f / commands.Count;

        for (int i = 0; i < commands.Count; ++i)
        {
            Command currentCommand = commands[i];

            GameObject go = Instantiate(_elementPrefab, _elementsParent.transform);

            RadialMenuElement element = go.GetComponent <RadialMenuElement>();
            element._assignedIndex = i;
            element._parent        = this;

            RectTransform rectTrans = element.GetComponent <RectTransform>();
            element.RotateTo(-_elementAngleGap * i + _globalAngleOffset, 0.3f * i);
            //rectTrans.localRotation = Quaternion.Euler(0, 0, -_elementAngleGap * i + _globalAngleOffset);

            Button currentButton = element._button;
            currentButton.GetComponent <Image>().fillAmount = (1.0f / (commands.Count));

            Text currentText = element._text;
            currentText.text = commands[i].ToString();

            float diffAngle = (270.0f - _elementAngleGap * i + _globalAngleOffset - (_elementAngleGap * 0.5f)) * Mathf.Deg2Rad;
            element.SetAngles(NormalizeAngle(diffAngle * Mathf.Rad2Deg), _elementAngleGap);

            diffAngle = (270.0f - _elementAngleGap / 2.0f) * Mathf.Deg2Rad;
            Vector3 offset = new Vector3(Mathf.Cos(diffAngle), Mathf.Sin(diffAngle), 0) * _rectTransform.rect.size.x * 0.4f;
            currentText.GetComponent <RectTransform>().position      = _rectTransform.position + offset;
            currentText.GetComponent <RectTransform>().localRotation = Quaternion.Euler(0, 0, (_elementAngleGap * i + _globalAngleOffset));

            int localI = i;
            currentButton.onClick.AddListener(() => CallCommand(localI));

            _elements.Add(element);
        }
        OnRadialElementBuildDone();
    }
예제 #22
0
파일: PathFinder.cs 프로젝트: Cesea/Sweeper
    NodeSideInfo[] RetracePath(NodeSideInfo start, NodeSideInfo end)
    {
        List <NodeSideInfo> path    = new List <NodeSideInfo>();
        NodeSideInfo        current = end;

        while (current != start)
        {
            path.Add(current);
            current = current.Parent;
        }
        path.Reverse();

        return(path.ToArray());
    }
예제 #23
0
    IEnumerator FollowPath()
    {
        NodeSideInfo currentNodeInfo = _path[0];

        if (_path.Length == 1)
        {
            BoardMoveBase toUseMovement = null;
            currentNodeInfo = _path[_targetIndex];
            if (_sittingNodeInfo._side != currentNodeInfo._side)
            {
                toUseMovement = _availableMovements[1];
            }
            else
            {
                toUseMovement = _availableMovements[0];
            }
            toUseMovement.MoveTo(currentNodeInfo);
        }
        else
        {
            while (true)
            {
                if (transform.position == _sittingNodeInfo.GetWorldPosition())
                {
                    BoardMoveBase toUseMovement = null;

                    currentNodeInfo = _path[_targetIndex];
                    if (_sittingNodeInfo._side != currentNodeInfo._side)
                    {
                        toUseMovement = _availableMovements[1];
                    }
                    else
                    {
                        toUseMovement = _availableMovements[0];
                    }
                    toUseMovement.MoveTo(currentNodeInfo);

                    _targetIndex++;
                    if (_targetIndex >= _path.Length)
                    {
                        _targetIndex = 0;
                        yield break;
                    }
                }
                yield return(null);
            }
        }

        _followingDone = true;
    }
예제 #24
0
    public static bool GetNodeSideInfoAtMouse(ref NodeSideInfo info)
    {
        bool       result = false;
        Ray        camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;

        if (Instance.CurrentBoard.CollisionObject.GetComponent <MeshCollider>().Raycast(camRay, out hitInfo, 1000.0f))
        {
            Vector3 roundedHitPos = hitInfo.point;
            GameStateManager.Instance.MouseNodeSidePosition = hitInfo.point;
            if (Mathf.Abs(hitInfo.point.x - Mathf.RoundToInt(hitInfo.point.x)) < EPSILON)
            {
                roundedHitPos.x = Mathf.RoundToInt(hitInfo.point.x);
            }
            if (Mathf.Abs(hitInfo.point.y - Mathf.RoundToInt(hitInfo.point.y)) < EPSILON)
            {
                roundedHitPos.y = Mathf.RoundToInt(hitInfo.point.y);
            }
            if (Mathf.Abs(hitInfo.point.z - Mathf.RoundToInt(hitInfo.point.z)) < EPSILON)
            {
                roundedHitPos.z = Mathf.RoundToInt(hitInfo.point.z);
            }

            Vector3Int tmp = BoardManager.WorldPosToBoardPos(roundedHitPos);

            if (hitInfo.normal.y > 0)
            {
                tmp.y -= 1;
            }
            else if (hitInfo.normal.x > 0)
            {
                tmp.x -= 1;
            }
            else if (hitInfo.normal.z > 0)
            {
                tmp.z -= 1;
            }
            NodeSideInfo tmpInfo = Instance.CurrentBoard.GetNodeInfoAt(tmp.x, tmp.y, tmp.z, NormalToSide(hitInfo.normal));
            if (!Object.ReferenceEquals(tmpInfo, null))
            {
                info   = tmpInfo;
                result = true;
            }
            else
            {
            }
        }
        return(result);
    }
예제 #25
0
파일: PathFinder.cs 프로젝트: Cesea/Sweeper
    IEnumerator FindPathRoutine(NodeSideInfo start, NodeSideInfo end)
    {
        bool findSuccess = CalculatePath(start, end);

        NodeSideInfo[] wayPoints = new NodeSideInfo[0];
        {
            yield return(null);

            if (findSuccess)
            {
                wayPoints = RetracePath(start, end);
            }
            _requestManager.FinishedProcessingPath(wayPoints, findSuccess);
        }
    }
예제 #26
0
    private void BuildLine()
    {
        List <Vector3> positionList = new List <Vector3>(_selectedInfoList.Count * 2);

        if (_selectedInfoList.Count > 0)
        {
            Vector3 closestEdge = Vector3.zero;

            Vector3 currentSideOffset = Vector3.zero;
            Vector3 nextSideOffset    = Vector3.zero;

            NodeSideInfo current = null;
            NodeSideInfo next    = null;

            if (_selectedInfoList.Count == 1)
            {
                current = _selectedInfoList[0];

                currentSideOffset = BoardManager.SideToOffset(current._side).ToVector3() * 0.1f;
                Vector3 currentMouseNodePos = GameStateManager.Instance.MouseNodeSidePosition;

                Vector3 diff = (currentMouseNodePos - currentSideOffset).normalized;
                positionList.Add(current.GetWorldPosition() + currentSideOffset);
                positionList.Add(current.GetWorldPosition() + (BoardManager.SideToVector3Offset(Side.Right) * 0.5f) + currentSideOffset);
            }
            else
            {
                for (int i = 0; i < _selectedInfoList.Count - 1; ++i)
                {
                    current = _selectedInfoList[i];
                    next    = _selectedInfoList[i + 1];

                    currentSideOffset = BoardManager.SideToOffset(current._side).ToVector3() * 0.1f;
                    nextSideOffset    = BoardManager.SideToOffset(next._side).ToVector3() * 0.1f;

                    closestEdge = NodeSideInfo.GetClosestEdge(current, next);
                    positionList.Add(current.GetWorldPosition() + currentSideOffset);
                    positionList.Add(closestEdge + nextSideOffset);
                }
                current           = _selectedInfoList[_selectedInfoList.Count - 1];
                currentSideOffset = BoardManager.SideToOffset(current._side).ToVector3() * 0.1f;
                positionList.Add(current.GetWorldPosition() + currentSideOffset);
            }

            _lineRenderer.positionCount = positionList.Count;
            _lineRenderer.SetPositions(positionList.ToArray());
        }
    }
예제 #27
0
    private void Update()
    {
        _selectingInfoChanged = false;
        _prevSelectingInfo    = _selectingInfo;

        _selectionValid = BoardManager.GetNodeSideInfoAtMouse(ref _selectingInfo);
        if (_selectionValid)
        {
            if (_selectingInfo != _prevSelectingInfo)
            {
                _selectingInfoChanged = true;
            }
        }

        _currentCursor.UpdateSelectingInfos(_selectingInfo, _prevSelectingInfo);
        _currentCursor.LocateCursor();
        _currentCursor.HandleInput();
    }
예제 #28
0
    public override bool CheckMovement(NodeSideInfo sittingNodeInfo)
    {
        bool result = false;

        if (sittingNodeInfo.IsHazard)
        {
            result = true;
            //ReceiveDamage가 true를 반환했다는건 데미지가 들어갔다는 이야기 이다
            if (_health.ReceiveDamage(1))
            {
                EventManager.Instance.TriggerEvent(new Events.PlayerHealthChanged(_health.CurrentHealth));
            }
        }
        else if (sittingNodeInfo._node.Type == Node.NodeType.Exit)
        {
            result = true;
            GameStateManager.Instance.IsGameOver    = true;
            GameStateManager.Instance.LevelFinished = true;
        }
        return(result);
    }
예제 #29
0
    public static IEnumerator BuildCommands(BoardObject subject, NodeSideInfo target, System.Action OnDoneMethod)
    {
        List <Command> buffer = subject.CommandBuffer;

        buffer.Add(new InspectCommand());

        BoardMovementManager movementManager   = subject.GetComponent <BoardMovementManager>();
        Vector3Int           deltaGridToPlayer = movementManager._sittingNodeInfo._node.BoardPosition - target._node.BoardPosition;

        if (movementManager != null)
        {
            PathRequestManager.RequestPath(subject.SittingNode, target, OnPathFound);
            while (!_pathDone)
            {
                yield return(null);
            }
            buffer.Add(new MoveCommand(_paths));
        }

        if (Mathf.Abs(deltaGridToPlayer.x) == 1 && deltaGridToPlayer.y == 0 && deltaGridToPlayer.z == 0 ||
            deltaGridToPlayer.x == 0 && Mathf.Abs(deltaGridToPlayer.y) == 0 && deltaGridToPlayer.z == 0 ||
            deltaGridToPlayer.x == 0 && deltaGridToPlayer.y == 0 && Mathf.Abs(deltaGridToPlayer.z) == 0)
        {
            if (target.InstalledObject != null)
            {
                buffer.Add(new DestroyObjectCommand(target));
            }
            else
            {
                buffer.Add(new InstallObjectCommand(target));
            }
        }

        _pathDone = false;

        OnDoneMethod();

        yield return(null);
    }
예제 #30
0
 public InstallObjectCommand(NodeSideInfo info)
 {
     _nodeInfo = info;
     _cost     = 2;
     Offset    = Vector3.zero;
 }