Есть ли способ определить заранее с какой сторони плитка от плеера?
Структура prefabs:
1:
LeftTile
Tile
LeftAttachPoint
TopAttachPoint
2:
TopTile
Tile
LeftAttachPoint
TopAttachPoint
Script:
public class TileManager : MonoBehaviour {
public GameObject [] prefabs;
public GameObject currentTile;
// Use this for initialization
void Start () {
for (int i = 0; i < 100; i++)
{
SpawnTile();
}
}
void SpawnTile()
{
int RandomIndex = Random.Range(0,2);
currentTile = (GameObject) Instantiate(prefabs[RandomIndex],currentTile.transform.GetChild(0).transform.GetChild(RandomIndex).position, Quaternion.identity);
}
}
Если координаты по Y центра плитки больше координат игрока, то плитка сверху, если меньше, то снизу. Если координаты плитки по Х больше координат X игрока, то плитка справа, если меньше, то слева.
Допустим, ты имеешь, скрипт прикрепленный к игроку, который устанавливает его позицию (grid position), здесь примерно похожая ситуация click. Только здесь проверка на плитки по диагонали, для твоего же игрока плитка с координатами (2,1) будет являться Tile Forward, а Tile Left - (1,0) соответственно. Здесь есть одна загвоздка, тайлы имеют собственные позиции в глобальной (мнимой) сетке и создан лист, в который занесены значения существующих позиций тайлов. Таким образом проверка включает в себя лишь условие на содержание в листе пойнта, который хочешь проверить на то, справа он или спереди от игрока, и, присваивание локальному массиву, состоящему из двух ячеек, проверяемые позиции (для дальнейшей работы с ними). Пример скриптов:
PlayerScript:
public class PlayerScript: MonoBehaviour{
public Point GridPosition { get; set; }
public void SetGridPosition(Point gridPos){
this.GridPosition = gridPos; //Этот метод нужен для установки новой позиции игрока при перемещении на тайл с такой-то позицией.
}
}
TileScript
При создании клонов тайлов из префаба в иерархии, мы можем им присвоить свои позиции относительно расположения в мнимой сетке и сделать ссылки на объекты путём добавления листа тайлов:
public class TileScript: MonoBehaviour{
public Point GridPosition { get; set; }
public void SetTileGridPosition (Point gridPos, GameObject Tile, Vector3 newTilePos){
this.GridPosition = gridPos;
Tile.transform.position = newTilePos;
GameManager.TilesArray.Add (Tile);
GameManager.AllTilesPoints.Add (gridPos);
}
}
GameManager
Теперь при создании тайлов мы можем обращаться к их скрипту и ставить им нужные позиции:
public static List<GameObject> TilesArray = new List<GameObject>();
public static List<Point> AllTilesPoints = new List<Point>();
[SerializeField]
private GameObject TilePrefab;
private float TileWidthOffset; //...переменная для рассчёта ширины тайла
private float TileHeightOffset;//...переменная для рассчёта высоты тайла
void Start(){
SetTileOffsets();
CreateTiles (TilePrefab);
}
private void CreateTiles(GameObject TilePrefab){
Vector3 TilesStart = new Vector3 (0f,0f,0f); //С какой позиции мы будем начинать спавнить тайлы
//Здесь возможен любой другой цикл for создания тайлов, это уже на усмотрения твоей задумки, сколько и как нужны расположить тайлы
//Пример создания сетки из пяти тайлов
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
GameObject Tile = Instantiate (TilePrefab);
Vector3 newTilePos = new Vector3(TilesStart.x + (TileWidthOffset * x), TilesStart.y+ (TileHeightOffset * y), 0f);
Tile.GetComponent<TileScript> ().SetTileGridPosition (new Point (x, y), Tile, newTilePos );
}
}
}
private void SetTileOffsets(){
//....Здесь твой метод, рассчитывающий высоту / ширину твоего тайла для тайл оффсета....
}
private void GoOverTilesArray(Point TileCheckPoint){
for (int i = 0; i < TilesArray.Count; i++) {
if (TileCheckPoint = TilesArray [i].GetComponent<TileScript> ().GridPosition) {
Debug.Log ("Это тайл с позицией: " + TileCheckPoint.X + ", " + TileCheckPoint.Y);
}
}
}
Как-то так. В дальнейшем мы можем создать метод проверки, например, добавив в скрипт игрока событие на OnMouseDown():
private void OnMouseDown(){
CheckTilesDirections ();
}
private void CheckTilesDirections(){
//Метод проверки направления тайла
Point PlayerPoint = Player.GetComponent<PlayerScript>().GridPosition;
float x = PlayerPoint.X;
float y = PlayerPoint.Y;
Point TileCheckPoint = new Point (x, y);
//Проверяем существование пойнта в листе и если он существует, то какой это тайл
//Допустим мы проверяем квадрат позиций вокруг игрока
for (y + 1; y >= (y - 1); y--) {
for (x - 1; x <= (x + 1); x++) {
TileCheckPoint = new Point (x, y);
if (GameManager.AllTilesPoints.Contains (TileCheckPoint)) {
GameManager.GoOverTilesArray (TileCheckPoint); //Здесь мы просто выводим позиции тайлов в квадрате позиций, окружающих игрока.
//Таким образом, пройдясь через массив тайлов и сопоставив их пойнт позиции в сетке с нужной нам для проверки позицией,
//мы выводим в консль информацию о позиции этого тайла. Дальше уже додумать код для проверки тайла справа и спереди игрока,
//я думаю не составит труда. Подкину мысль: if ((TileCheckPoint.X= PlayerPoint.X) && (TileCheckPoint.Y=PlayerPoint.Y+1)) - тайл слева в твоём случае
//if ((TileCheckPoint.X = PlayerPoint.X+1) && (TileCheckPoint.Y = PlayerPoint.Y)) - тайл впереди игрока
}
}
}
}
Конечно, здесь всё специфично, и подобрать вариант для работы с твоей задумкой можно по аналогии. Какое-то слишком подробное описание получилось, вплоть до методов инстанциирования с конкретными позициями, ну-с, дальше уже тебе решать как эту информацию применить. UPD: Point.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public struct Point
{
public int X {get; set;}
public int Y {get; set;}
public Point(int x, int y){
this.X = x;
this.Y = y;
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости