using UnityEngine;
public class TileTest : MonoBehaviour
{
public int Rows;
public int Columns;
public float TileWidth = 1;
public float TileHeight = 1;
[HideInInspector]
public Vector3 MarkerPosition;
private void OnDrawGizmosSelected()
{
var mapWidth = this.Columns * this.TileWidth;
var mapHeight = this.Rows * this.TileHeight;
var position = this.transform.position;
Gizmos.color = Color.white;
Gizmos.DrawLine(position, position + new Vector3(mapWidth, 0, 0));
Gizmos.DrawLine(position, position + new Vector3(0, mapHeight, 0));
Gizmos.DrawLine(position + new Vector3(mapWidth, 0, 0), position + new Vector3(mapWidth, mapHeight, 0));
Gizmos.DrawLine(position + new Vector3(0, mapHeight, 0), position + new Vector3(mapWidth, mapHeight, 0));
Gizmos.color = Color.grey;
for (float i = 1; i < this.Columns; i++)
{
Gizmos.DrawLine(position + new Vector3(i * this.TileWidth, 0, 0), position + new Vector3(i * this.TileWidth, mapHeight, 0));
}
for (float i = 1; i < this.Rows; i++)
{
Gizmos.DrawLine(position + new Vector3(0, i * this.TileHeight, 0), position + new Vector3(mapWidth, i * this.TileHeight, 0));
}
Gizmos.color = Color.red;
Gizmos.DrawWireCube(this.MarkerPosition, new Vector3(this.TileWidth, this.TileHeight, 1) * 1.1f);
}
public void GenerateNewMap()
{
}
public void DestroyMap()
{
var Tiles = GameObject.FindGameObjectsWithTag("Tile");
foreach (GameObject tile in Tiles)
{
DestroyImmediate(tile);
}
}
}
Затем редактор:
using System;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(TileTest))]
public class TileMapEditor : Editor
{
private Vector3 mouseHitPos;
public override void OnInspectorGUI()
{
TileTest Generate = (TileTest)target;
if (GUILayout.Button("Generate Map", GUILayout.Width(100), GUILayout.Height(30)))
{
Generate.GenerateNewMap();
}
DrawDefaultInspector();
if (GUILayout.Button("Destroy Map", GUILayout.Width(100), GUILayout.Height(30)))
{
Generate.DestroyMap();
}
}
private void OnSceneGUI()
{
if (this.UpdateHitPosition())
{
SceneView.RepaintAll();
}
this.RecalculateMarkerPosition();
Event current = Event.current;
if (this.IsMouseOnLayer())
{
if (current.type == EventType.MouseDown || current.type == EventType.MouseDrag)
{
if (current.button == 1)
{
this.Erase();
current.Use();
}
else if (current.button == 0)
{
this.Draw();
current.Use();
}
}
}
Handles.BeginGUI();
GUI.Label(new Rect(10, Screen.height - 90, 100, 100), "LMB: Draw");
GUI.Label(new Rect(10, Screen.height - 105, 100, 100), "RMB: Erase");
Handles.EndGUI();
}
private void OnEnable()
{
Tools.current = Tool.View;
Tools.viewTool = ViewTool.FPS;
}
private void Draw()
{
var map = (TileTest)this.target;
var tilePos = this.GetTilePositionFromMouseLocation();
var cube = GameObject.Find(string.Format("Tile_{0}_{1}", tilePos.x, tilePos.y));
if (cube != null && cube.transform.parent != map.transform)
{
return;
}
if (cube == null)
{
cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
}
var tilePositionInLocalSpace = new Vector3((tilePos.x * map.TileWidth) + (map.TileWidth / 2), (tilePos.y * map.TileHeight) + (map.TileHeight / 2));
cube.transform.position = map.transform.position + tilePositionInLocalSpace;
cube.transform.localScale = new Vector3(map.TileWidth, map.TileHeight, 1);
cube.transform.parent = map.transform;
cube.name = string.Format("Tile_{0}_{1}", tilePos.x, tilePos.y);
cube.tag = "Tile";
}
private void Erase()
{
var map = (TileTest)this.target;
var tilePos = this.GetTilePositionFromMouseLocation();
var cube = GameObject.Find(string.Format("Tile_{0}_{1}", tilePos.x, tilePos.y));
if (cube != null && cube.transform.parent == map.transform)
{
UnityEngine.Object.DestroyImmediate(cube);
}
}
private Vector2 GetTilePositionFromMouseLocation()
{
var map = (TileTest)this.target;
var pos = new Vector3(this.mouseHitPos.x / map.TileWidth, this.mouseHitPos.y / map.TileHeight, map.transform.position.z);
pos = new Vector3((int)Math.Round(pos.x, 5, MidpointRounding.ToEven), (int)Math.Round(pos.y, 5, MidpointRounding.ToEven), 0);
var col = (int)pos.x;
var row = (int)pos.y;
if (row < 0)
{
row = 0;
}
if (row > map.Rows - 1)
{
row = map.Rows - 1;
}
if (col < 0)
{
col = 0;
}
if (col > map.Columns - 1)
{
col = map.Columns - 1;
}
return new Vector2(col, row);
}
private bool IsMouseOnLayer()
{
var map = (TileTest)this.target;
return this.mouseHitPos.x > 0 && this.mouseHitPos.x < (map.Columns * map.TileWidth) &&
this.mouseHitPos.y > 0 && this.mouseHitPos.y < (map.Rows * map.TileHeight);
}
private void RecalculateMarkerPosition()
{
var map = (TileTest)this.target;
var tilepos = this.GetTilePositionFromMouseLocation();
var pos = new Vector3(tilepos.x * map.TileWidth, tilepos.y * map.TileHeight, 0);
map.MarkerPosition = map.transform.position + new Vector3(pos.x + (map.TileWidth / 2), pos.y + (map.TileHeight / 2), 0);
}
private bool UpdateHitPosition()
{
var map = (TileTest)this.target;
var p = new Plane(map.transform.TransformDirection(Vector3.forward), map.transform.position);
var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
var hit = new Vector3();
float dist;
if (p.Raycast(ray, out dist))
{
hit = ray.origin + (ray.direction.normalized * dist);
}
var value = map.transform.InverseTransformPoint(hit);
if (value != this.mouseHitPos)
{
this.mouseHitPos = value;
return true;
}
return false;
}
}
Затем в скрипте редактора я добавил внизу метод:
public void TerrainObjects(GameObject gameobject)
{
Terrain terrain = Terrain.activeTerrain;
var cube = GameObject.Find(string.Format("Terrain_{0}_{1}", gameobject.transform.position.x, gameobject.transform.position.y));
if (cube != null)
return;
if (cube == null)
{
cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
}
cube.transform.position = new Vector3(terrain.transform.position.x + gameobject.transform.position.x, 0, terrain.transform.position.z + gameobject.transform.position.y);
cube.transform.localScale = new Vector3(gameobject.transform.localScale.x, gameobject.transform.localScale.y, 1);
cube.transform.parent = GameObject.Find("Terrain Map").transform;
cube.name = string.Format("Terrain_{0}_{1}", gameobject.transform.position.x, gameobject.transform.position.y);
}
Этот метод создает кубики на местности в соответствии с позиции на карте мозаики сетки.
Например, предположим, что ландшафт находится в позиции 0,0,0, а объекты тайловой карты и карты ландшафта являются дочерними по отношению к ландшафту и расположены в 0,0,0
Скриншот местности на 0,0,0
Screenshot of the tile map child position 0,0,0
And screenshot of the terrain map child also at 0,0,0
Now I'm clicking with the mouse left button on the grid and create some cubes and it's creating also cubes on the terrain :
Now I moved the terrain to position 10,0,0
Both childs tile map and terrain map moved with the terrain and they are still at 0,0,0
Now I'm clicking with the mouse on the grid again to create cubes and this time it's creating the terrain cubes on the left side of the terrain and not on the terrain.
It's only creating the cubes on the terrain when the terrain is at position 0,0,0
Кубики должны быть созданы на местности, но они находятся на левой стороне ландшафта.
Как я могу сделать так, чтобы независимо от того, где находится ландшафт, в каком положении кубики, которые должны быть созданы на ландшафте, будут на нем, как если бы положение ландшафта было на 0,0,0 и не на стороне местности?