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(); }
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]); }
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(); } }
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; } } }
public virtual void UpdateNodeSideInfo(NodeSideInfo newInfo) { _startNodeInfo = newInfo; _targetPosition = _startNodeInfo.GetWorldPosition(); _startPosition = _startNodeInfo.GetWorldPosition(); }
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(); }
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); }
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(); } }
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); }
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); } }
public override void UpdateSelectingInfos(NodeSideInfo selecting, NodeSideInfo prev) { if (!_positioning) { _selectingInfo = selecting; _prevSelectingInfo = prev; } }
public bool FindPathImmediate(NodeSideInfo startNode, NodeSideInfo endNode, ref NodeSideInfo[] outInfos) { if (CalculatePath(startNode, endNode)) { outInfos = RetracePath(startNode, endNode); return(true); } return(false); }
//레벨을 위함이 아니다... 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); }
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; } }
public static Side GetRelativeSide(NodeSideInfo a, NodeSideInfo b) { if (a._node == b._node) { return(Side.Count); } else { return(Node.GetRelativeSide(a._node, b._node)); } }
public void StartFindPath(NodeSideInfo target, bool followImmediatly = true) { if (followImmediatly) { PathRequestManager.RequestPath(_sittingNodeInfo, target, OnPathFind); } else { PathRequestManager.RequestPath(_sittingNodeInfo, target, OnPathSave); } }
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); }
public override bool CheckMovement(NodeSideInfo sittingNodeInfo) { bool result = false; if (sittingNodeInfo.IsHazard) { result = true; _health.ReceiveDamage(1); } return(result); }
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)); } }
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); }
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(); }
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()); }
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; }
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); }
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); } }
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()); } }
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(); }
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); }
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); }
public InstallObjectCommand(NodeSideInfo info) { _nodeInfo = info; _cost = 2; Offset = Vector3.zero; }