using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Test0517 : MonoBehaviour
{
public int row, col;
public int startX, startY;
public int targetX, targetY;
public Button btnNext;
public GameObject character;
private GameObject[] tilePrefabs;
private GameObject[,] tiles;
private GameObject motherNode;
private GameObject startNode;
private GameObject targetNode;
private List<GameObject> listTile;
private List<GameObject> openList;
private List<GameObject> closeList;
private List<GameObject> motherNodes;
private Vector2[,] coordinate;
void Start()
{
this.tilePrefabs = Resources.LoadAll<GameObject>("Tiles");
this.coordinate = new Vector2[this.row, this.col];
this.tiles = new GameObject[this.row, this.col];
this.listTile = new List<GameObject>();
this.openList = new List<GameObject>();
this.closeList = new List<GameObject>();
this.SetCorrdinate();
this.CreateTiles();
this.character.transform.position = this.startNode.transform.position;
this.SetMotherNode(this.tiles[startX, startY]);
//this.FindPath(this.tiles[targetX, targetY]);
this.FindPath_4(this.tiles[targetX, targetY]);
this.closeList.Add(this.motherNode);
this.btnNext.onClick.AddListener(() =>
{
//현재 박스 저장한 뒤
this.OpenTileSort(this.openList);
//Debug.LogFormat("{0} F : {1}", this.openList[0].GetComponent<TestTile>().textCoord.text, this.openList[0].GetComponent<TestTile>().f);
this.SetMotherNode(this.openList[0]);
this.ResetNodeVal(this.openList);
//this.openList.Clear();
this.openList = new List<GameObject>();
//this.FindPath(this.tiles[targetX, targetY]);
this.FindPath_4(this.tiles[targetX, targetY]);
this.closeList.Add(this.motherNode);
if (this.motherNode.GetComponent<TestTile>().x == targetX && this.motherNode.GetComponent<TestTile>().y == targetY)
{
Debug.Log("찾음!");
this.btnNext.gameObject.SetActive(false);
StartCoroutine(this.MoveCharacter());
}
});
}
private IEnumerator MoveCharacter()
{
//Debug.LogFormat("움직여라 닝겐 : {0}", this.closeList.Count);
for (int i = 0; i < this.closeList.Count; i++)
{
var dis = Vector2.Distance(this.closeList[i].transform.position, this.character.transform.position);
var dir = (this.closeList[i].transform.position - this.character.transform.position);
var dirX = Mathf.Round(dir.x);
var dirY = Mathf.Round(dir.y);
Debug.LogFormat("x : {0},y : {1}", dirX, dirY);
if (dirX > 0)
{
Debug.Log("오른");
this.character.GetComponent<Animator>().Play("Right");
}
else if (dirX < 0)
{
Debug.Log("왼");
this.character.GetComponent<Animator>().Play("Left");
}
else if (dirY > 0)
{
Debug.Log("위");
this.character.GetComponent<Animator>().Play("Up");
}
else if (dirY < 0)
{
Debug.Log("아래");
this.character.GetComponent<Animator>().Play("Down");
}
while (true)
{
if (dis <= 0)
{
break;
}
this.character.transform.position += dir * 1f * Time.deltaTime;
dis -= 1f * Time.deltaTime;
yield return null;
}
}
Debug.Log("도착!");
this.character.GetComponent<Animator>().Play("idle");
}
private void ResetNodeVal(List<GameObject> openList)
{
for (int i = 0; i < openList.Count; i++)
{
openList[i].GetComponent<TestTile>().textF.text = "F";
openList[i].GetComponent<TestTile>().textG.text = "G";
openList[i].GetComponent<TestTile>().textH.text = "H";
openList[i].GetComponent<TestTile>().Arrow.gameObject.SetActive(false);
}
}
private void OpenTileSort(List<GameObject> openList)
{
//Debug.Log("솔트시작");
int i = 0;
int j = 0;
int min = 0;
for (i = 0; i < openList.Count - 1; i++)//전체 훑기 Count-1 : 마지막칸은 자동으로 정렬되고 뒷칸이 없으므로 제외
{
min = i;//최소값을 들고 있을 제 3의 손//맨 처음엔 검사하는 첫배열을 들고있음
for (j = i + 1; j < openList.Count; j++)// 최소값을 탐색한다.
{
if (openList[j].GetComponent<TestTile>().f < openList[min].GetComponent<TestTile>().f)//초기값 or 최소값이 j보다 크면 j를 최소값에 넣는다.
{
min = j;
}
}
if (min != 0)//스왑 알고리즘
{
SwapList(i, min);
}
}
}
private void SwapList(int index1, int index2)
{
//값을 임시로 저장할 temp변수
var temp = openList[index2];
openList[index2] = openList[index1];
openList[index1] = temp;
}
private void FindPath(GameObject target)
{
this.FindNodes();
}
private void FindNodes()
{
var mother = this.motherNode.GetComponent<TestTile>();
var motherX = this.motherNode.GetComponent<TestTile>().x - 1;
var motherY = this.motherNode.GetComponent<TestTile>().y - 1;
var maxX = this.motherNode.GetComponent<TestTile>().x + 1;
var maxY = this.motherNode.GetComponent<TestTile>().y + 1;
if (motherX < 0)
{
motherX = 0;
}
if (motherY < 0)
{
motherY = 0;
}
for (int i = motherX; i <= maxX; i++)
{
for (int j = motherY; j <= maxY; j++)
{
if (this.tiles[i, j].GetComponent<TestTile>().tileType == 0)
{
this.listTile.Add(this.tiles[i, j]);
this.openList.Add(this.tiles[i, j]);
this.SetH(this.tiles[i, j]);
this.SetG(this.tiles[i, j]);
this.SetF(this.tiles[i, j]);
this.TurnArrow(this.tiles[i, j]);
var sprite = this.tiles[i, j].GetComponentInChildren<SpriteRenderer>();
sprite.color = Color.cyan;
}
else
{
this.tiles[i, j].GetComponent<TestTile>().closeNode = true;
}
}
}
}
private void FindPath_4(GameObject target)
{
this.FindNodes_4();
}
private void FindNodes_4()
{
var mother = this.motherNode.GetComponent<TestTile>();
var motherX = this.motherNode.GetComponent<TestTile>().x - 1;
var motherY = this.motherNode.GetComponent<TestTile>().y - 1;
var maxX = this.motherNode.GetComponent<TestTile>().x + 1;
var maxY = this.motherNode.GetComponent<TestTile>().y + 1;
if (motherX < 0)
{
motherX = 0;
}
if (motherY < 0)
{
motherY = 0;
}
if (this.tiles[motherX, mother.y].GetComponent<TestTile>().tileType == 0)
{
this.listTile.Add(this.tiles[motherX, mother.y]);
this.openList.Add(this.tiles[motherX, mother.y]);
this.SetH(this.tiles[motherX, mother.y]);
this.SetG(this.tiles[motherX, mother.y]);
this.SetF(this.tiles[motherX, mother.y]);
this.TurnArrow(this.tiles[motherX, mother.y]);
var sprite = this.tiles[motherX, mother.y].GetComponentInChildren<SpriteRenderer>();
sprite.color = Color.cyan;
}
if (this.tiles[maxX, mother.y].GetComponent<TestTile>().tileType == 0)
{
this.listTile.Add(this.tiles[maxX, mother.y]);
this.openList.Add(this.tiles[maxX, mother.y]);
this.SetH(this.tiles[maxX, mother.y]);
this.SetG(this.tiles[maxX, mother.y]);
this.SetF(this.tiles[maxX, mother.y]);
this.TurnArrow(this.tiles[maxX, mother.y]);
var sprite = this.tiles[maxX, mother.y].GetComponentInChildren<SpriteRenderer>();
sprite.color = Color.cyan;
}
if (this.tiles[mother.x, motherY].GetComponent<TestTile>().tileType == 0)
{
this.listTile.Add(this.tiles[mother.x, motherY]);
this.openList.Add(this.tiles[mother.x, motherY]);
this.SetH(this.tiles[mother.x, motherY]);
this.SetG(this.tiles[mother.x, motherY]);
this.SetF(this.tiles[mother.x, motherY]);
this.TurnArrow(this.tiles[mother.x, motherY]);
var sprite = this.tiles[mother.x, motherY].GetComponentInChildren<SpriteRenderer>();
sprite.color = Color.cyan;
}
if (this.tiles[mother.x, maxY].GetComponent<TestTile>().tileType == 0)
{
this.listTile.Add(this.tiles[mother.x, maxY]);
this.openList.Add(this.tiles[mother.x, maxY]);
this.SetH(this.tiles[mother.x, maxY]);
this.SetG(this.tiles[mother.x, maxY]);
this.SetF(this.tiles[mother.x, maxY]);
this.TurnArrow(this.tiles[mother.x, maxY]);
var sprite = this.tiles[mother.x, maxY].GetComponentInChildren<SpriteRenderer>();
sprite.color = Color.cyan;
}
}
private void TurnArrow(GameObject tile)
{
var script = tile.GetComponent<TestTile>();
var xPos = this.motherNode.transform.position.x - script.Arrow.transform.position.x;
var yPos = this.motherNode.transform.position.y - script.Arrow.transform.position.y;
var rad = Mathf.Atan2(yPos, xPos) * Mathf.Rad2Deg;
script.Arrow.transform.rotation = Quaternion.Euler(new Vector3(0, 0, rad + 270));
script.Arrow.SetActive(true);
}
private void SetMotherNode(GameObject mother)
{
this.motherNode = mother;
this.motherNode.GetComponent<TestTile>().tileType = 2;
this.motherNode.GetComponentInChildren<SpriteRenderer>().color = Color.gray;
}
private void SetCorrdinate()
{
for (int i = 0; i < this.row; i++)
{
for (int j = 0; j < this.col; j++)
{
this.coordinate[i, j] = new Vector2(i, j);
}
}
}
private void SetF(GameObject tile)
{
var tileScript = tile.GetComponent<TestTile>();
tileScript.f = tileScript.g + tileScript.h;
tileScript.textF.text = tileScript.f.ToString();
}
private void SetH(GameObject tile)
{
var tileScript = tile.GetComponent<TestTile>();
var targetScript = this.targetNode.GetComponent<TestTile>();
var dis = (int)(Vector2.Distance(tile.transform.position, this.targetNode.transform.position) * 10);
//Debug.Log(dis);
tileScript.textH.text = dis.ToString();
tileScript.h = dis;
}
private void SetG(GameObject tile)
{
var tileScript = tile.GetComponent<TestTile>();
var targetScript = this.targetNode.GetComponent<TestTile>();
var dis = (int)Mathf.Round(((Vector2.Distance(tile.transform.position, this.motherNode.transform.position)) * 10));
//Debug.LogFormat("G{0} : {1}", tile.transform.position, dis);
tileScript.textG.text = dis.ToString();
tileScript.g = dis;
}
private void CreateTiles()
{
for (int i = 0; i < this.row; i++)
{
for (int j = 0; j < this.col; j++)
{
var screenPos = Camera.main.ScreenToWorldPoint(new Vector2((j * 100) + 400, (i * -100) + 550));
screenPos.z = 0;
if (i == this.startX && j == this.startY)
{
var tile = GameObject.Instantiate(this.tilePrefabs[1]);
this.tiles[i, j] = tile;
this.startNode = tile;
var script = tile.GetComponent<TestTile>();
script.x = i;
script.y = j;
script.textCoord.text = script.x.ToString() + ", " + script.y.ToString();
tile.transform.position = screenPos;
}
else if (i == this.targetX && j == this.targetY)
{
var tile = GameObject.Instantiate(this.tilePrefabs[2]);
this.tiles[i, j] = tile;
this.targetNode = tile;
var script = tile.GetComponent<TestTile>();
script.x = i;
script.y = j;
script.textCoord.text = script.x.ToString() + ", " + script.y.ToString();
tile.transform.position = screenPos;
}
else if ((i >= 1 && i < 4) && j == 3)
{
var tile = GameObject.Instantiate(this.tilePrefabs[0]);
this.tiles[i, j] = tile;
var script = tile.GetComponent<TestTile>();
script.tileType = 1;
script.x = i;
script.y = j;
script.textCoord.text = script.x.ToString() + ", " + script.y.ToString();
tile.transform.position = screenPos;
}
else
{
var tile = GameObject.Instantiate(this.tilePrefabs[3]);
this.tiles[i, j] = tile;
var script = tile.GetComponent<TestTile>();
script.x = i;
script.y = j;
script.textCoord.text = script.x.ToString() + ", " + script.y.ToString();
tile.transform.position = screenPos;
}
}
}
}
}