The main goal is when I click with the mouse on the tile map and generate a cube that it will generate another cube to the position that it should be on the 3d plane or terrain.
For example in the grid tilemap the top left cube will be position at 29,29 and now I want to convert this position to the top left position on a 3d plane or terrain and create a cube there too.
This is the mono script that draw gizmos and draw the tile map :
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()
{
}
}
And this is the editor script that use the mouse position to create cubes when clicking on a tile in the tilemap grid :
using System;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(TileTest))]
public class TileMapEditor : Editor
{
private Vector3 mouseHitPos;
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);
}
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;
}
}
Example of a tile map :
The plane is on the right of the grid.
I want that when I click on the grid map it will create at the same time also a cube/s on the plane.
So if on the grid top left position is 29,29 then how can I calculate the relative position on the plane ?
For example I just used a cube for testing and positioned it on the plane top left position and the position is :
The cube position is : 4.46 , 0.5 , -4.43
There might be some problems like if the tilemap grid is not the same size of the plane/terrain or hoe do I look on the plane/terrain from what direction. but maybe this can be decided as rules later. or maybe it’s not that matter how do I look on it for now.
The problem is how to convert/calculate the tile map coordinates to the plane/terrain coordinates.