using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEditor; using alexism.Floorplan.Core.Enums; using alexism.Floorplan.Core; using alexism.Floorplan.Core.Abstract; using System.Runtime.InteropServices; using UnityEditor.Experimental.GraphView; //Implement strategy pattern for drawing tools namespace alexism.Floorplan.Core.Abstract { public abstract class Tool { public abstract void MouseDown(Vector3 mousePos); public abstract void MouseDrag(Vector3 mousePos); public abstract void MouseUp(Vector3 mousePos, TileTypes tileType, GameObject tile,floorplan script, Material[] mat, List selected); public abstract void RenderPreview(); } } //Some classes that inherit Tool. I should probably put these into their own separate files. public class RectangleFilledStrat : alexism.Floorplan.Core.Abstract.Tool { float width; float height; Vector3 mouseStart; Vector3 mouseEnd; public void Render(GameObject tile, floorplan script, Material[] mats) { GameObject gO = new GameObject("Floor"); gO.transform.parent = script.geometry.transform; Vector3 topLeft = new Vector3(Mathf.Max(mouseStart.x, mouseEnd.x), mouseStart.y, Mathf.Max(mouseStart.z, mouseEnd.z)); for (int y = 0; y < Mathf.Abs(height); y += (int)script.tileSize) { for (int x = 0; x < Mathf.Abs(width); x += (int)script.tileSize) { GameObject floor = script.createInstance(tile, (topLeft - new Vector3(x, 0, y + script.tileSize)), Quaternion.identity); floor.GetComponent().materials = mats; floor.transform.parent.parent = gO.transform; } } Undo.RegisterCreatedObjectUndo(gO,"Undo floor creation"); } public override void MouseDown(Vector3 mousePos) { mouseStart = mousePos; } public override void MouseDrag(Vector3 mousePos) { width = -(mouseEnd.x - mouseStart.x); height = -(mouseEnd.z - mouseStart.z); mouseEnd = mousePos; } public override void MouseUp(Vector3 mousePos, TileTypes tileType, GameObject tile, floorplan script, Material[] mat, List selected) { Vector3[] points = new Vector3[] { mouseStart, mouseEnd, mouseStart-(new Vector3(width,0,0)), mouseEnd+(new Vector3(width,0,0)) }; List mats = new List(); selected.RemoveAll(o => o == -1); for (int i = 0; i < selected.Count; i++) { mats.Add(mat[selected[i]]); } //Should we even do this (manage which tiletypes a tool can create) inside tools? Should this be handled by something else? switch (tileType){ case TileTypes.Wall: Debug.LogWarning("Trying to draw type Wall with incorrect tool"); break; case TileTypes.Floor: Render(tile,script,mats.ToArray()); break; case TileTypes.Pillar: Debug.LogWarning("Trying to draw type Pillar with incorrect tool"); break; } mouseStart = Vector3.zero; mouseEnd = Vector3.zero; } public override void RenderPreview() { Handles.color = Color.red; Handles.DrawWireCube(mouseStart - new Vector3(width / 2, 0, height / 2), new Vector3(width, 2, height)); } } public class RectangleStrat : alexism.Floorplan.Core.Abstract.Tool { float width; float height; Vector3 mouseStart; Vector3 mouseEnd; GameObject depthText; GameObject widthText; bool replace; void Render(floorplan script, GameObject tile,Material[] mats) { GameObject pillar = script.getTilesFromType(TileTypes.Pillar)[0]; GameObject gO = new GameObject("Walls"); gO.transform.parent = script.geometry.transform; Vector3 topLeft = new Vector3(Mathf.Max(mouseStart.x, mouseEnd.x), mouseStart.y, Mathf.Max(mouseStart.z, mouseEnd.z)); Vector3 bottomLeft = new Vector3(Mathf.Min(mouseStart.x, mouseEnd.x), mouseStart.y, Mathf.Min(mouseStart.z, mouseEnd.z)); for (int x = 0; x < Mathf.Abs(width); x += (int)script.tileSize) { Vector3 offset = topLeft - new Vector3(x+script.tileSize/2, -.5f, 0); Vector3 offset2 = bottomLeft - new Vector3(-x-script.tileSize/2, -.5f, 0); GameObject wall = null; if (!Physics.CheckSphere(offset, .1f)) { wall = script.createInstance(tile, (topLeft - new Vector3(x + script.tileSize, 0, 0)), Quaternion.LookRotation(Vector3.right, Vector3.up)); wall.GetComponent().materials = mats; wall.transform.parent.parent = gO.transform; } if (!Physics.CheckSphere(offset2, .1f)) { wall = script.createInstance(tile, (bottomLeft - new Vector3(-x - script.tileSize, 0, 0)), Quaternion.LookRotation(-Vector3.right, Vector3.up)); wall.GetComponent().materials = mats; wall.transform.parent.parent = gO.transform; } } for (int z = 0; z < Mathf.Abs(height); z += (int)script.tileSize) { Vector3 offset = topLeft - new Vector3(0, -.5f, z+script.tileSize/2); Vector3 offset2 = bottomLeft - new Vector3(0,-.5f, -z-script.tileSize/2); GameObject wall = null; if (!Physics.CheckSphere(offset, .1f)) { wall = script.createInstance(tile, (topLeft - new Vector3(0, 0, z)), Quaternion.LookRotation(-Vector3.forward, Vector3.up)); wall.GetComponent().materials = mats; wall.transform.parent.parent = gO.transform; } if (!Physics.CheckSphere(offset2, .1f)) { wall = script.createInstance(tile, (bottomLeft - new Vector3(0, 0, -z)), Quaternion.identity); wall.GetComponent().materials = mats; wall.transform.parent.parent = gO.transform; } } //Create pillars. God all of the code in this place is awful. I'm sorry. GameObject pillarTopLeft = script.createInstance(pillar, bottomLeft, Quaternion.identity); GameObject pillarBottomLeft = script.createInstance(pillar, topLeft, Quaternion.identity); GameObject pillarTopRight = script.createInstance(pillar, topLeft + new Vector3(width, 0, 0), Quaternion.identity); GameObject pillarBottomRight = script.createInstance(pillar, bottomLeft + new Vector3(-width, 0, 0), Quaternion.identity); pillarTopLeft.GetComponent().materials = mats; pillarBottomLeft.GetComponent().materials = mats; pillarTopRight.GetComponent().materials = mats; pillarBottomRight.GetComponent().materials = mats; pillarTopLeft.transform.parent.parent = gO.transform; pillarBottomLeft.transform.parent.parent = gO.transform; pillarTopRight.transform.parent.parent = gO.transform; pillarBottomRight.transform.parent.parent = gO.transform; Undo.RegisterCreatedObjectUndo(gO, "Undo wall creation"); } public override void RenderPreview() { Handles.color = Color.red; Handles.DrawWireCube(mouseStart - new Vector3(width / 2, 0, height / 2), new Vector3(width, 2, height)); } public override void MouseDown(Vector3 mousePos) { mouseStart = mousePos; } public override void MouseDrag(Vector3 mousePos) { width = -(mouseEnd.x - mouseStart.x); height = -(mouseEnd.z - mouseStart.z); mouseEnd = mousePos; if (depthText == null) { //Initialize text. I could probably just use Handles.Label but this gives me more control over the look for text imo (and gives me way more awful code :D!) depthText = new GameObject(); TextMeshPro dText = depthText.AddComponent(); dText.enableAutoSizing = true; depthText.transform.rotation = Quaternion.LookRotation(-Vector3.up, -Vector3.right); dText.color = Color.black; dText.fontSizeMax = 8; widthText = new GameObject(); TextMeshPro wText = widthText.AddComponent(); wText.enableAutoSizing = true; widthText.transform.rotation = Quaternion.LookRotation(-Vector3.up, Vector3.up); widthText.transform.localScale = new Vector3(1, 1, -1); wText.color = Color.black; wText.fontSizeMax = 8; } else { TextMeshPro dText = depthText.GetComponent(); depthText.GetComponent().position = mouseStart - new Vector3(.5f, -1, (height / 2) + dText.textBounds.center.x); depthText.GetComponent().text = "Depth: "+Mathf.Abs((height / 2)).ToString(); TextMeshPro wText = widthText.GetComponent(); widthText.GetComponent().position = mouseStart - new Vector3((width/2)+wText.textBounds.center.x, -1, -.5f); widthText.GetComponent().text = "Width: "+Mathf.Abs((width / 2)).ToString(); } } public override void MouseUp(Vector3 mousePos, TileTypes tileType,GameObject tile,floorplan script, Material[] mat,List selected) { //Get the 4 corners of the rectangle Vector3[] points = new Vector3[] { mouseStart, mouseEnd, mouseStart-(new Vector3(width,0,0)), mouseEnd+(new Vector3(width,0,0)) }; List mats = new List(); selected.RemoveAll(o => o == -1); Debug.Log(selected.Count); for(int i=0; i