public List <SpiderNode> FindNextNode(List <SpiderNode> nodes, Spider _monster) { List <SpiderNode> _connectNodeList = new List <SpiderNode>(); if (parentNode == this) { List <DirandRot> _canMoveVectors = _monster.FindCanMoveVectors(this); foreach (DirandRot _DR in _canMoveVectors) { if (_DR == null) { continue; } foreach (DirandRot _parentDR in _monster.FindCollisionVectors()) { if (_parentDR == null) { continue; } parentDR = _parentDR; Vector2 nextNodePosition = this.position; DirandRot downDR; if (parentDR.rot.eulerAngles.y == 0f) { downDR = new DirandRot(new Vector2(parentDR.dir.y, -parentDR.dir.x), Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f)); } else { downDR = new DirandRot(new Vector2(-parentDR.dir.y, parentDR.dir.x), Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f)); } DirandRot checkDR; checkDR = new DirandRot(new Vector2(-parentDR.dir.y, parentDR.dir.x), parentDR.rot.eulerAngles.y == 0f ? Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z + 90f) : Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f)); if (_DR == parentDR) // 직진할 경우 { bool isFloorExist = true; foreach (DirandRot d in _canMoveVectors) { if (d == null) { continue; } if (d == downDR) // 바닥이 없을 경우. { isFloorExist = false; break; } } if (isFloorExist) { nextNodePosition = this.position + _DR.dir; checkDR = parentDR; } } if (this.position == nextNodePosition && _DR == checkDR) //반시계 90도 회전. { bool canTurn = true; if (parentDR.rot.eulerAngles.y != 0f) { foreach (DirandRot d in _canMoveVectors) { if (d == null) { continue; } if (d == downDR) // 바닥이 없을 경우. { canTurn = false; break; } else if (d == parentDR) // 앞쪽 벽이 없을 경우. { canTurn = false; break; } } } if (canTurn) { nextNodePosition = this.position + checkDR.dir; } } else if (this.position == nextNodePosition) { // 시계 90도 회전. 아마도. checkDR = new DirandRot(new Vector2(parentDR.dir.y, -parentDR.dir.x), parentDR.rot.eulerAngles.y == 0f ? Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f) : Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z + 90f)); if (_DR == checkDR) //가는 경로 바닥에 타일 있는지 확인 조건 추가. { bool canTurn = true; if (parentDR.rot.eulerAngles.y == 0f) { foreach (DirandRot d in _canMoveVectors) { if (d == null) { continue; } if (d == downDR) // 바닥이 없을 경우. { canTurn = false; break; } else if (d == parentDR) // 앞쪽 벽이 없을 경우. { canTurn = false; break; } } } if (canTurn) { nextNodePosition = this.position + checkDR.dir; } } } if (nextNodePosition != this.position) { foreach (SpiderNode _node in nodes) { if (_node.position == nextNodePosition) { _node.parentDR = new DirandRot(checkDR.dir, checkDR.rot); _connectNodeList.Add(_node); break; } } } } } } else { foreach (DirandRot _DR in canMoveVectors) { if (_DR == null) { continue; } Vector2 nextNodePosition = this.position; DirandRot downDR; if (parentDR.rot.eulerAngles.y == 0f) { downDR = new DirandRot(new Vector2(parentDR.dir.y, -parentDR.dir.x), Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f)); } else { downDR = new DirandRot(new Vector2(-parentDR.dir.y, parentDR.dir.x), Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f)); } DirandRot checkDR; checkDR = new DirandRot(new Vector2(-parentDR.dir.y, parentDR.dir.x), parentDR.rot.eulerAngles.y == 0f ? Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z + 90f) : Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f)); if (_DR == parentDR) // 직진할 경우 { bool isFloorExist = true; foreach (DirandRot d in canMoveVectors) { if (d == null) { continue; } if (d == downDR) // 바닥이 없을 경우. { isFloorExist = false; break; } } if (isFloorExist) { nextNodePosition = this.position + _DR.dir; checkDR = parentDR; } } if (this.position == nextNodePosition && _DR == checkDR) //반시계 90도 회전. { bool canTurn = true; if (parentDR.rot.eulerAngles.y != 0f) { foreach (DirandRot d in canMoveVectors) { if (d == null) { continue; } if (d == downDR) // 바닥이 없을 경우. { canTurn = false; break; } else if (d == parentDR) // 앞쪽 벽이 없을 경우. { canTurn = false; break; } } } if (canTurn) { nextNodePosition = this.position + checkDR.dir; } } else if (this.position == nextNodePosition) { // 시계 90도 회전. 아마도. checkDR = new DirandRot(new Vector2(parentDR.dir.y, -parentDR.dir.x), parentDR.rot.eulerAngles.y == 0f ? Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z - 90f) : Quaternion.Euler(parentDR.rot.eulerAngles.x, parentDR.rot.eulerAngles.y, parentDR.rot.eulerAngles.z + 90f)); if (_DR == checkDR) //가는 경로 바닥에 타일 있는지 확인 조건 추가. { bool canTurn = true; if (parentDR.rot.eulerAngles.y == 0f) { foreach (DirandRot d in canMoveVectors) { if (d == null) { continue; } if (d == downDR) // 바닥이 없을 경우. { canTurn = false; break; } else if (d == parentDR) // 앞쪽 벽이 없을 경우. { canTurn = false; break; } } } if (canTurn) { nextNodePosition = this.position + checkDR.dir; } } } if (nextNodePosition != this.position) { foreach (SpiderNode _node in nodes) { if (_node.position == nextNodePosition) { _node.parentDR = new DirandRot(checkDR.dir, checkDR.rot); _connectNodeList.Add(_node); break; } } } } } if (_connectNodeList.Count == 0) { Debug.Log(this.position + " : this SpiderNode can't find connected Node!"); } return(_connectNodeList); }
public DirandRot GetNextNode(Spider _monster) { int loopcount = 0; List <SpiderNode> _nodes = new List <SpiderNode>(nodes); List <SpiderNode> nodeOpenList = new List <SpiderNode>(); List <SpiderNode> nodeClosedList = new List <SpiderNode>(); // 플레이어가 공중에 있을때 원래 있던 땅 자리를 목적지로 만드려는 것. Vector2 playerNodePosition = new Vector2(); int playerXindex = Mathf.FloorToInt(playerPosition.position.x + 0.5f + offsetX); int playerYindex = Mathf.FloorToInt(playerPosition.position.y + 0.5f + offsetY); for (int i = 0; i < (platformTiles[playerXindex].Count - playerYindex); i++) { if (platformTiles[playerXindex][playerYindex - i - 1].exist) { playerNodePosition = new Vector2(playerXindex - offsetX, playerYindex - i - offsetY); break; } else if (Mathf.Abs(playerXindex - offsetX - playerPosition.position.x) + playerColliderSizeX / 2 > 0.5f) { int _playerXindex = playerXindex + (playerXindex - offsetX - playerPosition.position.x > 0 ? -1 : 1); if (platformTiles[_playerXindex][playerYindex - i - 1].exist && !platformTiles[_playerXindex][playerYindex - i].exist) { playerNodePosition = new Vector2(_playerXindex - offsetX, playerYindex - i - offsetY); break; } } } SpiderNode goalNode = MakeNode((int)(playerNodePosition.x + offsetX), (int)(playerNodePosition.y + offsetY) , _nodes); //현재 길 찾고있는 Spider의 속한 그리드의 중심에 노드를 만들기 위함. 원래 그자리에 노드가 있으면 합침. SpiderNode selfNode = MakeNode((int)(_monster.GetPosition().x + offsetX), (int)(_monster.GetPosition().y + offsetY) , _nodes); if (selfNode == null || goalNode == null) //spider 주변에 벽이 없거나, 플레이어 아래 바닥이 끝까지 없을 때. { _monster.inGameObject.SendMessage("Fall"); return(new DirandRot(new Vector2(0, 0), Quaternion.Euler(0, 0, 0))); } selfNode.parentNode = selfNode; selfNode.SetGH(goalNode); nodeOpenList.Add(selfNode); SpiderNode nearestNode = null; while (loopcount < 100) { loopcount++; float minF = Mathf.Infinity; SpiderNode minFNode = null; foreach (SpiderNode _node in nodeOpenList) { float _currentF = _node.GetF(); if (minFNode == null || _currentF < minF && _node.H <= _monster.m_Script.spiderInfo.findRadius) { minF = _currentF; minFNode = _node; } else if (_currentF == minF) { if (Random.Range(0, 2) == 1) { minF = _currentF; minFNode = _node; } } } //Debug.Log(minFNode.position +" is 탐색됨. " + minFNode.FindNextNode(_nodes).Count); if (!nodeClosedList.Contains(minFNode)) { nodeClosedList.Add(minFNode); } nodeOpenList.Remove(minFNode); if (nearestNode == null || nearestNode.H > minFNode.H) { nearestNode = minFNode; } foreach (SpiderNode _node in minFNode.FindNextNode(_nodes, _monster)) { if (!nodeClosedList.Contains(_node)) { _node.parentNode = minFNode; if (_node == goalNode) { if (selfNode.position == goalNode.position) { return(new DirandRot(Vector2.zero, new Quaternion())); } SpiderNode getBackNode = _node; loopcount = 0; while (loopcount < 100) { loopcount++; if (getBackNode.parentNode == selfNode) { return(getBackNode.parentDR); } getBackNode = getBackNode.parentNode; } Debug.Log("Loop count over to Goal Node. " + goalNode.position); return(new DirandRot(Vector2.zero, new Quaternion())); } _node.SetGH(goalNode); if (!nodeOpenList.Contains(_node)) { nodeOpenList.Add(_node); } } } if (nodeOpenList.Count == 0) { Debug.Log(_monster.inGameObject.name + " can't find the path."); if (nearestNode.position == selfNode.position) { return(new DirandRot(Vector2.zero, new Quaternion())); } SpiderNode getBackNode = nearestNode; loopcount = 0; while (loopcount < 100) { loopcount++; if (getBackNode.parentNode == selfNode) { return(getBackNode.parentDR); } getBackNode = getBackNode.parentNode; } Debug.Log("Loop count over to Nearest Node."); return(new DirandRot(Vector2.zero, new Quaternion())); } } //Debug.Log("Loop count over in finding path. " + goalNode.position); if (nearestNode.position == selfNode.position) { return(new DirandRot(Vector2.zero, new Quaternion())); } SpiderNode _getBackNode = nearestNode; loopcount = 0; while (loopcount < 100) { loopcount++; if (_getBackNode.parentNode == selfNode) { return(_getBackNode.parentDR); } _getBackNode = _getBackNode.parentNode; } Debug.Log("Can't Find Anything with " + _monster.inGameObject.name); return(new DirandRot(Vector2.zero, new Quaternion())); }