add floorplan 2.0 package
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b60e70ac29709245a6762ce1b754786
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
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<int> 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<Renderer>().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<int> selected)
|
||||
{
|
||||
Vector3[] points = new Vector3[]
|
||||
{
|
||||
mouseStart,
|
||||
mouseEnd,
|
||||
mouseStart-(new Vector3(width,0,0)),
|
||||
mouseEnd+(new Vector3(width,0,0))
|
||||
};
|
||||
List<Material> mats = new List<Material>();
|
||||
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<Renderer>().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<Renderer>().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<Renderer>().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<Renderer>().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<Renderer>().materials = mats;
|
||||
pillarBottomLeft.GetComponent<Renderer>().materials = mats;
|
||||
pillarTopRight.GetComponent<Renderer>().materials = mats;
|
||||
pillarBottomRight.GetComponent<Renderer>().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<TextMeshPro>();
|
||||
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<TextMeshPro>();
|
||||
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<TextMeshPro>();
|
||||
depthText.GetComponent<RectTransform>().position = mouseStart - new Vector3(.5f, -1, (height / 2) + dText.textBounds.center.x);
|
||||
depthText.GetComponent<TextMeshPro>().text = "Depth: "+Mathf.Abs((height / 2)).ToString();
|
||||
TextMeshPro wText = widthText.GetComponent<TextMeshPro>();
|
||||
|
||||
widthText.GetComponent<RectTransform>().position = mouseStart - new Vector3((width/2)+wText.textBounds.center.x, -1, -.5f);
|
||||
widthText.GetComponent<TextMeshPro>().text = "Width: "+Mathf.Abs((width / 2)).ToString();
|
||||
|
||||
}
|
||||
}
|
||||
public override void MouseUp(Vector3 mousePos, TileTypes tileType,GameObject tile,floorplan script, Material[] mat,List<int> 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<Material> mats = new List<Material>();
|
||||
selected.RemoveAll(o => o == -1);
|
||||
Debug.Log(selected.Count);
|
||||
for(int i=0; i<selected.Count; i++)
|
||||
{
|
||||
mats.Add(mat[selected[i]]);
|
||||
}
|
||||
switch (tileType)
|
||||
{
|
||||
case TileTypes.Wall:
|
||||
Render(script, tile,mats.ToArray());
|
||||
break;
|
||||
case TileTypes.Floor:
|
||||
Debug.LogWarning("Trying to draw type Floor with incorrect tool");
|
||||
break;
|
||||
}
|
||||
Editor.DestroyImmediate(depthText);
|
||||
Editor.DestroyImmediate(widthText);
|
||||
mouseStart = Vector3.zero;
|
||||
mouseEnd = Vector3.zero;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dabceb884080c5f449b5db43a41bee48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
// DrawGizmoGrid.cs
|
||||
// draws a useful reference grid in the editor in Unity.
|
||||
// 09/01/15 - Hayden Scott-Baron
|
||||
// twitter.com/docky
|
||||
// no attribution needed, but please tell me if you like it ^_^
|
||||
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(Grid))]
|
||||
public class DrawGizmoGrid : MonoBehaviour
|
||||
{
|
||||
// universal grid scale
|
||||
public float gridScale = 1f;
|
||||
|
||||
// extents of the grid
|
||||
public int minX = -15;
|
||||
public int minY = -15;
|
||||
public int maxX = 15;
|
||||
public int maxY = 15;
|
||||
|
||||
// nudges the whole grid rel
|
||||
public Vector3 gridOffset = Vector3.zero;
|
||||
|
||||
// is this an XY or an XZ grid?
|
||||
public bool topDownGrid = true;
|
||||
|
||||
// choose a colour for the gizmos
|
||||
public int gizmoMajorLines = 5;
|
||||
public Color gizmoLineColor = new Color(0.4f, 0.4f, 0.3f, 1f);
|
||||
|
||||
Grid grid;
|
||||
|
||||
// rename + centre the gameobject upon first time dragging the script into the editor.
|
||||
void Reset()
|
||||
{
|
||||
if (name == "GameObject")
|
||||
name = "~~ GIZMO GRID ~~";
|
||||
|
||||
transform.position = Vector3.zero;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
grid = GetComponent<Grid>();
|
||||
gridScale = grid.cellSize.x/10;
|
||||
}
|
||||
// draw the grid :)
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
|
||||
// orient to the gameobject, so you can rotate the grid independently if desired
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
|
||||
// set colours
|
||||
Color dimColor = new Color(gizmoLineColor.r, gizmoLineColor.g, gizmoLineColor.b, 0.25f * gizmoLineColor.a);
|
||||
Color brightColor = Color.Lerp(Color.white, gizmoLineColor, 0.75f);
|
||||
|
||||
// draw the horizontal lines
|
||||
for (int x = minX; x < maxX + 1; x++)
|
||||
{
|
||||
// find major lines
|
||||
Gizmos.color = (x % gizmoMajorLines == 0 ? gizmoLineColor : dimColor);
|
||||
if (x == 0)
|
||||
Gizmos.color = brightColor;
|
||||
|
||||
Vector3 pos1 = new Vector3(x, minY, 0) * gridScale;
|
||||
Vector3 pos2 = new Vector3(x, maxY, 0) * gridScale;
|
||||
|
||||
// convert to topdown/overhead units if necessary
|
||||
if (topDownGrid)
|
||||
{
|
||||
pos1 = new Vector3(pos1.x, 0, pos1.y);
|
||||
pos2 = new Vector3(pos2.x, 0, pos2.y);
|
||||
}
|
||||
|
||||
Gizmos.DrawLine((gridOffset + pos1), (gridOffset + pos2));
|
||||
}
|
||||
|
||||
// draw the vertical lines
|
||||
for (int y = minY; y < maxY + 1; y++)
|
||||
{
|
||||
// find major lines
|
||||
Gizmos.color = (y % gizmoMajorLines == 0 ? gizmoLineColor : dimColor);
|
||||
if (y == 0)
|
||||
Gizmos.color = brightColor;
|
||||
|
||||
Vector3 pos1 = new Vector3(minX, y, 0) * gridScale;
|
||||
Vector3 pos2 = new Vector3(maxX, y, 0) * gridScale;
|
||||
|
||||
// convert to topdown/overhead units if necessary
|
||||
if (topDownGrid)
|
||||
{
|
||||
pos1 = new Vector3(pos1.x, 0, pos1.y);
|
||||
pos2 = new Vector3(pos2.x, 0, pos2.y);
|
||||
}
|
||||
|
||||
Gizmos.DrawLine((gridOffset + pos1), (gridOffset + pos2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86e1e5e2582bb564fa54cb6dc6cde247
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d6771a18eba00443b669d8971816238
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace alexism.Floorplan.Core.Enums
|
||||
{
|
||||
public enum TileTypes
|
||||
{
|
||||
Wall,
|
||||
Pillar,
|
||||
Floor,
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b75a3cb37a7c18844bf12d735e9683b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace alexism.Floorplan.Core.Enums
|
||||
{
|
||||
public enum ToolTypes
|
||||
{
|
||||
Rectangle,
|
||||
RectangleFilled
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 43e3308c14f4ea248a1f49a0ec902c80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+547
@@ -0,0 +1,547 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Linq;
|
||||
|
||||
static public class MeshColliderTools
|
||||
{
|
||||
|
||||
public static void SnapToGrid(this Mesh mesh, float gridDelta)
|
||||
{
|
||||
if (gridDelta < 1e-5f)
|
||||
return;
|
||||
float inverse = 1f / gridDelta;
|
||||
var verts = mesh.vertices;
|
||||
for (int i = 0; i < verts.Length; i++)
|
||||
{
|
||||
verts[i].x = Mathf.RoundToInt(verts[i].x * inverse) / inverse;
|
||||
verts[i].y = Mathf.RoundToInt(verts[i].y * inverse) / inverse;
|
||||
verts[i].z = Mathf.RoundToInt(verts[i].z * inverse) / inverse;
|
||||
}
|
||||
mesh.vertices = verts;
|
||||
}
|
||||
|
||||
public static void Weld(this Mesh mesh, float threshold, float bucketStep)
|
||||
{
|
||||
Vector3[] oldVertices = mesh.vertices;
|
||||
Vector3[] newVertices = new Vector3[oldVertices.Length];
|
||||
int[] old2new = new int[oldVertices.Length];
|
||||
Vector2[] oldUVs = mesh.uv;
|
||||
|
||||
int newSize = 0;
|
||||
|
||||
// Find AABB
|
||||
Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
|
||||
Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
|
||||
for (int i = 0; i < oldVertices.Length; i++)
|
||||
{
|
||||
if (oldVertices[i].x < min.x) min.x = oldVertices[i].x;
|
||||
if (oldVertices[i].y < min.y) min.y = oldVertices[i].y;
|
||||
if (oldVertices[i].z < min.z) min.z = oldVertices[i].z;
|
||||
if (oldVertices[i].x > max.x) max.x = oldVertices[i].x;
|
||||
if (oldVertices[i].y > max.y) max.y = oldVertices[i].y;
|
||||
if (oldVertices[i].z > max.z) max.z = oldVertices[i].z;
|
||||
}
|
||||
min -= Vector3.one * 0.111111f;
|
||||
max += Vector3.one * 0.899999f;
|
||||
|
||||
// Make cubic buckets, each with dimensions "bucketStep"
|
||||
int bucketSizeX = Mathf.FloorToInt((max.x - min.x) / bucketStep) + 1;
|
||||
int bucketSizeY = Mathf.FloorToInt((max.y - min.y) / bucketStep) + 1;
|
||||
int bucketSizeZ = Mathf.FloorToInt((max.z - min.z) / bucketStep) + 1;
|
||||
List<int>[,,] buckets = new List<int>[bucketSizeX, bucketSizeY, bucketSizeZ];
|
||||
|
||||
// Make new vertices
|
||||
for (int i = 0; i < oldVertices.Length; i++)
|
||||
{
|
||||
// Determine which bucket it belongs to
|
||||
int x = Mathf.FloorToInt((oldVertices[i].x - min.x) / bucketStep);
|
||||
int y = Mathf.FloorToInt((oldVertices[i].y - min.y) / bucketStep);
|
||||
int z = Mathf.FloorToInt((oldVertices[i].z - min.z) / bucketStep);
|
||||
|
||||
// Check to see if it's already been added
|
||||
if (buckets[x, y, z] == null)
|
||||
buckets[x, y, z] = new List<int>(); // Make buckets lazily
|
||||
|
||||
for (int j = 0; j < buckets[x, y, z].Count; j++)
|
||||
{
|
||||
Vector3 to = newVertices[buckets[x, y, z][j]] - oldVertices[i];
|
||||
if (Vector3.SqrMagnitude(to) < 0.001f)
|
||||
{
|
||||
old2new[i] = buckets[x, y, z][j];
|
||||
goto skip; // Skip to next old vertex if this one is already there
|
||||
}
|
||||
}
|
||||
|
||||
// Add new vertex
|
||||
newVertices[newSize] = oldVertices[i];
|
||||
buckets[x, y, z].Add(newSize);
|
||||
old2new[i] = newSize;
|
||||
newSize++;
|
||||
|
||||
skip:;
|
||||
}
|
||||
|
||||
// Make new triangles
|
||||
int[] oldTris = mesh.triangles;
|
||||
int[] newTris = new int[oldTris.Length];
|
||||
for (int i = 0; i < oldTris.Length; i++)
|
||||
{
|
||||
newTris[i] = old2new[oldTris[i]];
|
||||
}
|
||||
|
||||
Vector3[] finalVertices = new Vector3[newSize];
|
||||
for (int i = 0; i < newSize; i++)
|
||||
finalVertices[i] = newVertices[i];
|
||||
|
||||
mesh.Clear();
|
||||
mesh.vertices = finalVertices;
|
||||
mesh.triangles = newTris;
|
||||
Vector2[] newUVs = new Vector2[mesh.vertices.Length];
|
||||
for(int i=0; i<newUVs.Length; i++)
|
||||
{
|
||||
newUVs[i] = oldUVs[i];
|
||||
}
|
||||
mesh.SetUVs(0, newUVs);
|
||||
mesh.RecalculateNormals();
|
||||
mesh.RecalculateTangents();
|
||||
// Debug.LogFormat("Weld vert count: {0} vs. {1}", newSize, oldVertices.Length);
|
||||
}
|
||||
|
||||
|
||||
public static void Simplify(this MeshCollider meshCollider) { meshCollider.sharedMesh.Simplify(); }
|
||||
public static void Simplify(this Mesh mesh)
|
||||
{
|
||||
var verts = mesh.vertices;
|
||||
var uvs = mesh.uv;
|
||||
var origNumVerts = verts.Length;
|
||||
var origNormals = mesh.normals;
|
||||
|
||||
var workingSet = new List<Vertice>(origNumVerts);
|
||||
for (int i = 0; i < origNumVerts; i++)
|
||||
{
|
||||
var r = new Vertice();
|
||||
r.position = verts[i];
|
||||
workingSet.Add(r);
|
||||
}
|
||||
|
||||
var tris = mesh.triangles;
|
||||
var triLength = tris.Length;
|
||||
for (int i = 0; i < triLength; i += 3)
|
||||
Face.AddFace(workingSet, tris, i);
|
||||
|
||||
for (int i = 0; i < origNumVerts; i++)
|
||||
workingSet[i].AssignLinearPosition();
|
||||
|
||||
|
||||
/*********************************
|
||||
* *
|
||||
* Simplify mesh! *
|
||||
* *
|
||||
********************************/
|
||||
|
||||
HashSet<Vertice> candidates;
|
||||
HashSet<Vertice> nextCandidates = new HashSet<Vertice>();
|
||||
|
||||
foreach (Vertice v in workingSet) if (!v.IsStatic)
|
||||
nextCandidates.Add(v);
|
||||
|
||||
while (nextCandidates.Count != 0)
|
||||
{
|
||||
candidates = nextCandidates;
|
||||
nextCandidates = new HashSet<Vertice>();
|
||||
foreach (Vertice a in candidates)
|
||||
{
|
||||
if (a.edges != null) foreach (Edge ac in a.edges)
|
||||
{
|
||||
Vertice c;
|
||||
if (a.CanFollow(ac, out c))
|
||||
{
|
||||
foreach (Face f in ac.faces)
|
||||
Edge.Collapse(f.GetOpposite(c), f.GetOpposite(a), f);
|
||||
foreach (Edge edge_of_a in a.edges)
|
||||
{
|
||||
if (edge_of_a != ac)
|
||||
{
|
||||
var o = edge_of_a.GetOpposite(a);
|
||||
if (!o.IsStatic) nextCandidates.Add(o);
|
||||
edge_of_a.Reconnect(a, c);
|
||||
}
|
||||
}
|
||||
if (!c.IsStatic) nextCandidates.Add(c);
|
||||
|
||||
c.DisconnectFrom(ac);
|
||||
a.Disconnect();
|
||||
ac.DisconnectIncludingFaces();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var simplifiedVerts = new List<Vertice>();
|
||||
foreach (Vertice v in workingSet) if (v.edges != null)
|
||||
simplifiedVerts.Add(v);
|
||||
|
||||
var simplifiedNumVerts = simplifiedVerts.Count;
|
||||
var newPositions = new Vector3[simplifiedNumVerts];
|
||||
//var resultColors = new Color[simplifiedNumVerts];
|
||||
for (int i = 0; i < simplifiedNumVerts; i++)
|
||||
{
|
||||
simplifiedVerts[i].finalIndex = i;
|
||||
newPositions[i] = simplifiedVerts[i].position;
|
||||
}
|
||||
|
||||
var resultTris = new List<int>();
|
||||
var triSet = new HashSet<Face>();
|
||||
foreach (Vertice v in simplifiedVerts)
|
||||
{
|
||||
foreach (Edge e in v.edges)
|
||||
{
|
||||
foreach (Face f in e.faces) if (!triSet.Contains(f))
|
||||
{
|
||||
triSet.Add(f);
|
||||
f.GetIndexes(resultTris);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mesh.Clear();
|
||||
mesh.vertices = newPositions;
|
||||
mesh.triangles = resultTris.ToArray();
|
||||
Array.Clear(mesh.uv, 0, mesh.uv.Length);
|
||||
|
||||
Vector3[] oldVerts = mesh.vertices;
|
||||
int[] triangles = mesh.triangles;
|
||||
Vector3[] vertices = new Vector3[triangles.Length];
|
||||
for (int i = 0; i < triangles.Length; i++)
|
||||
{
|
||||
vertices[i] = oldVerts[triangles[i]];
|
||||
triangles[i] = i;
|
||||
}
|
||||
|
||||
|
||||
mesh.vertices = vertices;
|
||||
mesh.triangles = triangles;
|
||||
mesh.RecalculateBounds();
|
||||
mesh.RecalculateNormals();
|
||||
mesh.Optimize();
|
||||
|
||||
Debug.LogFormat("Simplify vert count: {0} vs. {1}", simplifiedNumVerts, origNumVerts);
|
||||
}
|
||||
|
||||
private class Vertice
|
||||
{
|
||||
public List<Edge> edges = new List<Edge>();
|
||||
public Vector3 position;
|
||||
|
||||
/// <summary>A cache used for identifying a vertice during mesh reconstruction.
|
||||
public int finalIndex;
|
||||
|
||||
/// <summary>
|
||||
/// - Null if vertice is internal in a plane
|
||||
/// - A non-zero vector if vertice is internal in a line
|
||||
/// - Vector3.zero otherwise.
|
||||
/// </summary>
|
||||
public Vector3? linearPosition;
|
||||
|
||||
public void AssignLinearPosition()
|
||||
{
|
||||
for (int i = 0; i < edges.Count; i++)
|
||||
{
|
||||
var edge = edges[i];
|
||||
if (!edge.HasEqualPlanes())
|
||||
{
|
||||
if (linearPosition == null)
|
||||
linearPosition = edge.vertices[1].position - edge.vertices[0].position;
|
||||
else if (!edge.IsParallel(linearPosition))
|
||||
{
|
||||
linearPosition = Vector3.zero;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsStatic {
|
||||
get {
|
||||
return linearPosition == Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
public Edge GetExistingConnectingEdge(Vertice v)
|
||||
{
|
||||
foreach (Edge e in edges)
|
||||
{
|
||||
if (e.vertices[0] == this && e.vertices[1] == v) return e;
|
||||
if (e.vertices[1] == this && e.vertices[0] == v) return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Edge GetConnectingEdge(Vertice v)
|
||||
{
|
||||
Edge result = GetExistingConnectingEdge(v);
|
||||
if (result == null)
|
||||
{
|
||||
result = new Edge(this, v);
|
||||
edges.Add(result);
|
||||
v.edges.Add(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>When collapsing an edge a->c, the linear space must
|
||||
/// be respected, and all faces, not connected with a->c,
|
||||
/// must not flip.
|
||||
/// </summary>
|
||||
public bool CanFollow(Edge transportEdge, out Vertice opposite)
|
||||
{
|
||||
if (IsStatic) { opposite = default(Vertice); return false; }
|
||||
if (linearPosition != null && !transportEdge.IsParallel(linearPosition)) { opposite = default(Vertice); return false; }
|
||||
|
||||
var localTris = new HashSet<Face>();
|
||||
foreach (Edge e in edges) foreach (Face f in e.faces)
|
||||
localTris.Add(f);
|
||||
|
||||
localTris.ExceptWith(transportEdge.faces);
|
||||
|
||||
opposite = transportEdge.GetOpposite(this);
|
||||
var targetPos = opposite.position;
|
||||
var lTriEnum = localTris.GetEnumerator();
|
||||
try
|
||||
{
|
||||
while (lTriEnum.MoveNext())
|
||||
if (lTriEnum.Current.MoveWouldFlip(this, targetPos))
|
||||
return false;
|
||||
}
|
||||
finally { lTriEnum.Dispose(); }
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DisconnectFrom(Edge e)
|
||||
{
|
||||
edges.Remove(e);
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
edges.Clear();
|
||||
edges = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class Edge
|
||||
{
|
||||
public List<Vertice> vertices;
|
||||
public List<Face> faces;
|
||||
|
||||
public static void Collapse(Edge moved, Edge target, Face f)
|
||||
{
|
||||
Face faceOutsideMoved;
|
||||
try { faceOutsideMoved = moved.GetOpposite(f); }
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception(e.Message + "\n" + moved.vertices[0].position.ToString() + " <--> " + moved.vertices[1].position.ToString());
|
||||
}
|
||||
faceOutsideMoved.Replace(moved, target);
|
||||
target.Replace(f, faceOutsideMoved);
|
||||
foreach (Vertice v in moved.vertices)
|
||||
{
|
||||
v.edges.Remove(moved);
|
||||
}
|
||||
}
|
||||
|
||||
public Edge(Vertice v0, Vertice v1)
|
||||
{
|
||||
vertices = new List<Vertice>(2);
|
||||
vertices.Add(v0);
|
||||
vertices.Add(v1);
|
||||
faces = new List<Face>(2);
|
||||
}
|
||||
|
||||
public Vertice GetOpposite(Vertice v)
|
||||
{
|
||||
var v0 = vertices[0];
|
||||
return v != v0 ? v0 : vertices[1];
|
||||
}
|
||||
|
||||
public Face GetOpposite(Face v)
|
||||
{
|
||||
if (faces.Count != 2) throw new Exception("Collapsing an edge with only 1 face into another. This is not supported.");
|
||||
var face0 = faces[0];
|
||||
return face0 == v ? faces[1] : face0;
|
||||
}
|
||||
|
||||
public bool HasEqualPlanes()
|
||||
{
|
||||
if (faces.Count != 2) return false;
|
||||
var f0 = faces[0];
|
||||
var f0e0 = faces[0].edges[0];
|
||||
|
||||
var f1 = faces[1];
|
||||
var f1e0 = faces[1].edges[0];
|
||||
|
||||
var e0 = f0e0 != this ? f0e0 : f0.edges[1];
|
||||
var e1 = f1e0 != this ? f1e0 : f1.edges[1];
|
||||
|
||||
var v0 = vertices[1].position - vertices[0].position;
|
||||
var v1 = e0.vertices[1].position - e0.vertices[0].position;
|
||||
var v2 = e1.vertices[1].position - e1.vertices[0].position;
|
||||
|
||||
var n0 = Vector3.Cross(v0, v1);
|
||||
|
||||
var dot = Vector3.Dot(n0, v2);
|
||||
return -5e-3 < dot && dot < 5e-3;
|
||||
}
|
||||
|
||||
public void Replace(Face oldFace, Face newFace)
|
||||
{
|
||||
for (int j = 0; j < faces.Count; j++)
|
||||
{
|
||||
if (faces[j] == oldFace)
|
||||
{
|
||||
faces[j] = newFace;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Reconnect(Vertice oldVertice, Vertice newVertice)
|
||||
{
|
||||
if (vertices[0] == oldVertice) vertices[0] = newVertice;
|
||||
else vertices[1] = newVertice;
|
||||
newVertice.edges.Add(this);
|
||||
}
|
||||
|
||||
public bool Contains(Vertice v)
|
||||
{
|
||||
return v == vertices[0] || v == vertices[1];
|
||||
}
|
||||
|
||||
public bool IsParallel(Vector3? nv)
|
||||
{
|
||||
var v0 = vertices[0].position;
|
||||
var v1 = vertices[1].position;
|
||||
float cross = Vector3.Cross(v1 - v0, nv.Value).sqrMagnitude;
|
||||
return -5e-6f < cross && cross < 5e-6f;
|
||||
}
|
||||
|
||||
public void DisconnectIncludingFaces()
|
||||
{
|
||||
vertices.Clear();
|
||||
vertices = null;
|
||||
foreach (Face f in faces)
|
||||
f.Disconnect();
|
||||
faces.Clear();
|
||||
faces = null;
|
||||
}
|
||||
}
|
||||
|
||||
private class Face
|
||||
{
|
||||
public Edge[] edges;
|
||||
|
||||
/*
|
||||
* <paramref name="e0">Edge between v0 and v1</paramref>
|
||||
* <paramref name="e1">Edge between v0 and v2</paramref>
|
||||
* <paramref name="e2">Edge between v1 and v2</paramref>
|
||||
*/
|
||||
private Face(Edge e0, Edge e1, Edge e2)
|
||||
{
|
||||
edges = new Edge[] { e0, e1, e2 };
|
||||
}
|
||||
|
||||
/*
|
||||
* <paramref name="allVertices">List of vertices, in the same order as 'verts' from the mesh.</paramref>
|
||||
* <paramref name="tris">The tris array from the mesh.</paramref>
|
||||
* <paramref name="triIndex">The index of the first vertex in this triangle.</paramref>
|
||||
*/
|
||||
public static void AddFace(List<Vertice> allVertices, int[] tris, int triIndex)
|
||||
{
|
||||
var v0 = allVertices[tris[triIndex + 0]];
|
||||
var v1 = allVertices[tris[triIndex + 1]];
|
||||
var v2 = allVertices[tris[triIndex + 2]];
|
||||
|
||||
var e0 = v0.GetConnectingEdge(v1);
|
||||
var e1 = v0.GetConnectingEdge(v2);
|
||||
var e2 = v1.GetConnectingEdge(v2);
|
||||
|
||||
var face = new Face(e0, e1, e2);
|
||||
|
||||
e0.faces.Add(face);
|
||||
e1.faces.Add(face);
|
||||
e2.faces.Add(face);
|
||||
}
|
||||
|
||||
public Edge GetOpposite(Vertice v)
|
||||
{
|
||||
Edge e0, e1;
|
||||
if (!(e0 = edges[0]).Contains(v)) return e0;
|
||||
if (!(e1 = edges[1]).Contains(v)) return e1;
|
||||
return edges[2];
|
||||
}
|
||||
|
||||
public Vertice GetOpposite(Edge o)
|
||||
{
|
||||
var o0 = o.vertices[0];
|
||||
var o1 = o.vertices[1];
|
||||
for (int i = 0; i < 3; i++)
|
||||
{ // Will never reach 3 because there will be an unequal vertice before the third edge
|
||||
Edge e = edges[i];
|
||||
Vertice e0 = e.vertices[0];
|
||||
if (e0 != o0 && e0 != o1) return e0;
|
||||
Vertice e1 = e.vertices[1];
|
||||
if (e1 != o0 && e1 != o1) return e1;
|
||||
}
|
||||
throw new Exception("A face seems to have three edges that all share a vertice with a given edge.");
|
||||
}
|
||||
|
||||
public void Replace(Edge oldEdge, Edge newEdge)
|
||||
{
|
||||
if (edges[0] == oldEdge) edges[0] = newEdge;
|
||||
else if (edges[1] == oldEdge) edges[1] = newEdge;
|
||||
else edges[2] = newEdge;
|
||||
}
|
||||
|
||||
public bool MoveWouldFlip(Vertice v, Vector3 p)
|
||||
{
|
||||
Edge oppositeEdge = GetOpposite(v);
|
||||
var ov0 = oppositeEdge.vertices[0].position;
|
||||
var ov = oppositeEdge.vertices[1].position - ov0;
|
||||
var ot = p - ov0;
|
||||
var ct = v.position - ov0;
|
||||
|
||||
var cross0 = Vector3.Cross(ot, ov);
|
||||
var c0SqrMagnitude = cross0.sqrMagnitude;
|
||||
if (c0SqrMagnitude < 0.0001f) return true;
|
||||
|
||||
var cross1 = Vector3.Cross(ct, ov);
|
||||
var c1SqrMagnitude = cross1.sqrMagnitude;
|
||||
if (c1SqrMagnitude < 0.0001f) return true;
|
||||
|
||||
if (Mathf.Sign(Vector3.Dot(cross0, cross1)) < 0f) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* <summary>Adds the finalIndex for the verts in order: v0, v1, v2.</summary>
|
||||
*/
|
||||
public void GetIndexes(List<int> results)
|
||||
{
|
||||
results.Add(GetOpposite(edges[2]).finalIndex);
|
||||
results.Add(GetOpposite(edges[1]).finalIndex);
|
||||
results.Add(GetOpposite(edges[0]).finalIndex);
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
edges = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb70efa811894a9439ee60d4e6cf4c6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.UI;
|
||||
|
||||
public class MeshCombiner : MonoBehaviour
|
||||
{
|
||||
GameObject wallMesh;
|
||||
GameObject floorMesh;
|
||||
public void Awake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
wallMesh = new GameObject("WallMesh", typeof(MeshFilter), typeof(Renderer));
|
||||
floorMesh = new GameObject("FloorMesh", typeof(MeshFilter), typeof(Renderer));
|
||||
print(transform.childCount);
|
||||
for (int i = transform.childCount - 1; i >= 0; --i)
|
||||
{
|
||||
Transform child = transform.GetChild(i);
|
||||
if (child.name == "Floor")
|
||||
child.SetParent(floorMesh.transform, true);
|
||||
else if (child.name == "Walls")
|
||||
child.SetParent(wallMesh.transform, true);
|
||||
}
|
||||
wallMesh.transform.parent = transform;
|
||||
floorMesh.transform.parent = transform;
|
||||
|
||||
CombineWalls();
|
||||
CombineFloor();
|
||||
ClearChildren(floorMesh.transform);
|
||||
ClearChildren(wallMesh.transform);
|
||||
SplitMesh(floorMesh.GetComponent<MeshFilter>());
|
||||
SplitMesh(wallMesh.GetComponent<MeshFilter>());
|
||||
|
||||
for (int i = 0; i < floorMesh.transform.childCount; i++)
|
||||
{
|
||||
Simplify(floorMesh.transform.GetChild(i).GetComponent<MeshFilter>());
|
||||
}
|
||||
for (int i = 0; i < wallMesh.transform.childCount; i++)
|
||||
{
|
||||
Simplify(wallMesh.transform.GetChild(i).GetComponent<MeshFilter>());
|
||||
}
|
||||
}
|
||||
|
||||
void ClearChildren(Transform t)
|
||||
{
|
||||
for(int i=0; i<t.childCount; i++)
|
||||
{
|
||||
Destroy(t.GetChild(i).gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void Simplify(MeshFilter mf)
|
||||
{
|
||||
if (mf != null)
|
||||
{
|
||||
mf.mesh.Weld(0.00000328f, 1f);
|
||||
mf.mesh.Simplify();
|
||||
}
|
||||
}
|
||||
|
||||
void SplitMesh(MeshFilter mf)
|
||||
{
|
||||
for (int i = 0; i < mf.mesh.subMeshCount; i++)
|
||||
{
|
||||
GameObject gO = new GameObject();
|
||||
gO.name = mf.gameObject.name + " submesh " + (i+1).ToString();
|
||||
gO.transform.parent = mf.gameObject.transform;
|
||||
MeshFilter filter = gO.AddComponent<MeshFilter>();
|
||||
filter.mesh=mf.mesh.GetSubmesh(i);
|
||||
Renderer r = gO.AddComponent<MeshRenderer>();
|
||||
r.material = mf.gameObject.GetComponent<Renderer>().materials[i];
|
||||
MeshCollider c = gO.AddComponent<MeshCollider>();
|
||||
c.sharedMesh = filter.mesh;
|
||||
}
|
||||
Destroy(mf.gameObject.GetComponent<Renderer>());
|
||||
Destroy(mf.gameObject.GetComponent<MeshCollider>());
|
||||
}
|
||||
|
||||
private void CombineWalls()
|
||||
{
|
||||
Vector3 basePosition = transform.position;
|
||||
Quaternion baseRotation = transform.rotation;
|
||||
transform.position = Vector3.zero;
|
||||
transform.rotation = Quaternion.identity;
|
||||
|
||||
|
||||
|
||||
ArrayList materials = new ArrayList();
|
||||
ArrayList combineInstanceArrays = new ArrayList();
|
||||
MeshFilter[] meshFilters = wallMesh.GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
//Linq solution to make sure we don't combine any of the doors(a door is easily identifiable by it's rigidbody component, so we look for that).
|
||||
meshFilters = meshFilters.Where((source, index) => !(source.transform.name == "FloorMesh" || source.transform.name == "WallMesh" || source.transform.GetComponent<Rigidbody>() || source.transform.GetComponentInParent<Rigidbody>())).ToArray();
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
MeshRenderer meshRenderer = meshFilter.GetComponent<MeshRenderer>();
|
||||
if (!meshRenderer ||
|
||||
!meshFilter.sharedMesh ||
|
||||
meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
|
||||
{
|
||||
print(meshFilter.gameObject.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
|
||||
{
|
||||
if (meshRenderer.sharedMaterials[s]){
|
||||
int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
|
||||
if (materialArrayIndex == -1)
|
||||
{
|
||||
materials.Add(meshRenderer.sharedMaterials[s]);
|
||||
materialArrayIndex = materials.Count - 1;
|
||||
}
|
||||
combineInstanceArrays.Add(new ArrayList());
|
||||
|
||||
CombineInstance combineInstance = new CombineInstance();
|
||||
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
|
||||
combineInstance.subMeshIndex = s;
|
||||
combineInstance.mesh = meshFilter.sharedMesh;
|
||||
(combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get / Create mesh filter & renderer
|
||||
MeshFilter meshFilterCombine = wallMesh.GetComponent<MeshFilter>();
|
||||
if (meshFilterCombine == null)
|
||||
{
|
||||
meshFilterCombine = wallMesh.AddComponent<MeshFilter>();
|
||||
}
|
||||
MeshRenderer meshRendererCombine = gameObject.GetComponent<MeshRenderer>();
|
||||
if (meshRendererCombine == null)
|
||||
{
|
||||
meshRendererCombine = wallMesh.AddComponent<MeshRenderer>();
|
||||
}
|
||||
|
||||
// Combine by material index into per-material meshes
|
||||
// also, Create CombineInstance array for next step
|
||||
Mesh[] meshes = new Mesh[materials.Count];
|
||||
CombineInstance[] combineInstances = new CombineInstance[materials.Count];
|
||||
|
||||
for (int m = 0; m < materials.Count; m++)
|
||||
{
|
||||
CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
|
||||
meshes[m] = new Mesh();
|
||||
meshes[m].CombineMeshes(combineInstanceArray, true, true);
|
||||
|
||||
combineInstances[m] = new CombineInstance();
|
||||
combineInstances[m].mesh = meshes[m];
|
||||
combineInstances[m].subMeshIndex = 0;
|
||||
|
||||
}
|
||||
|
||||
// Combine into one
|
||||
meshFilterCombine.sharedMesh = new Mesh();
|
||||
meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);
|
||||
|
||||
// Destroy other meshes
|
||||
foreach (Mesh oldMesh in meshes)
|
||||
{
|
||||
oldMesh.Clear();
|
||||
DestroyImmediate(oldMesh);
|
||||
}
|
||||
|
||||
// Assign materials
|
||||
Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
|
||||
meshRendererCombine.materials = materialsArray;
|
||||
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
|
||||
if (!meshFilter || meshFilter.transform.GetComponent<Rigidbody>() || meshFilter.transform.GetComponentInParent<Rigidbody>() || meshFilter.transform.GetComponentInChildren<Rigidbody>())
|
||||
continue;
|
||||
print(meshFilter.gameObject.transform.parent.name);
|
||||
DestroyImmediate(meshFilter.gameObject.transform.parent.gameObject);
|
||||
}
|
||||
wallMesh.transform.position = basePosition;
|
||||
wallMesh.transform.rotation = baseRotation;
|
||||
wallMesh.AddComponent<MeshCollider>().sharedMesh = wallMesh.GetComponent<MeshFilter>().sharedMesh;
|
||||
}
|
||||
private void CombineFloor()
|
||||
{
|
||||
Vector3 basePosition = transform.position;
|
||||
Quaternion baseRotation = transform.rotation;
|
||||
transform.position = Vector3.zero;
|
||||
transform.rotation = Quaternion.identity;
|
||||
|
||||
|
||||
|
||||
ArrayList materials = new ArrayList();
|
||||
ArrayList combineInstanceArrays = new ArrayList();
|
||||
MeshFilter[] meshFilters = floorMesh.GetComponentsInChildren<MeshFilter>();
|
||||
|
||||
//Linq solution to make sure we don't combine any of the doors(a door is easily identifiable by it's rigidbody component, so we look for that).
|
||||
meshFilters = meshFilters.Where((source, index) => !(source.transform.name=="FloorMesh" || source.transform.name=="WallMesh" || source.transform.GetComponent<Rigidbody>() || source.transform.GetComponentInParent<Rigidbody>())).ToArray();
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
MeshRenderer meshRenderer = meshFilter.GetComponent<MeshRenderer>();
|
||||
if (!meshRenderer ||
|
||||
!meshFilter.sharedMesh ||
|
||||
meshRenderer.sharedMaterials.Length != meshFilter.sharedMesh.subMeshCount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int s = 0; s < meshFilter.sharedMesh.subMeshCount; s++)
|
||||
{
|
||||
if (meshRenderer.sharedMaterials[s])
|
||||
{
|
||||
int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[s].name);
|
||||
if (materialArrayIndex == -1)
|
||||
{
|
||||
materials.Add(meshRenderer.sharedMaterials[s]);
|
||||
materialArrayIndex = materials.Count - 1;
|
||||
}
|
||||
combineInstanceArrays.Add(new ArrayList());
|
||||
|
||||
CombineInstance combineInstance = new CombineInstance();
|
||||
combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
|
||||
combineInstance.subMeshIndex = s;
|
||||
combineInstance.mesh = meshFilter.sharedMesh;
|
||||
(combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get / Create mesh filter & renderer
|
||||
MeshFilter meshFilterCombine = floorMesh.GetComponent<MeshFilter>();
|
||||
if (meshFilterCombine == null)
|
||||
{
|
||||
meshFilterCombine = floorMesh.AddComponent<MeshFilter>();
|
||||
}
|
||||
MeshRenderer meshRendererCombine = gameObject.GetComponent<MeshRenderer>();
|
||||
if (meshRendererCombine == null)
|
||||
{
|
||||
meshRendererCombine = floorMesh.AddComponent<MeshRenderer>();
|
||||
}
|
||||
|
||||
// Combine by material index into per-material meshes
|
||||
// also, Create CombineInstance array for next step
|
||||
Mesh[] meshes = new Mesh[materials.Count];
|
||||
CombineInstance[] combineInstances = new CombineInstance[materials.Count];
|
||||
|
||||
for (int m = 0; m < materials.Count; m++)
|
||||
{
|
||||
CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
|
||||
meshes[m] = new Mesh();
|
||||
meshes[m].CombineMeshes(combineInstanceArray, true, true);
|
||||
|
||||
combineInstances[m] = new CombineInstance();
|
||||
combineInstances[m].mesh = meshes[m];
|
||||
combineInstances[m].subMeshIndex = 0;
|
||||
}
|
||||
|
||||
// Combine into one
|
||||
meshFilterCombine.sharedMesh = new Mesh();
|
||||
meshFilterCombine.sharedMesh.CombineMeshes(combineInstances, false, false);
|
||||
|
||||
// Destroy other meshes
|
||||
foreach (Mesh oldMesh in meshes)
|
||||
{
|
||||
oldMesh.Clear();
|
||||
DestroyImmediate(oldMesh);
|
||||
}
|
||||
|
||||
// Assign materials
|
||||
Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
|
||||
meshRendererCombine.materials = materialsArray;
|
||||
|
||||
foreach (MeshFilter meshFilter in meshFilters)
|
||||
{
|
||||
|
||||
if (!meshFilter || meshFilter.transform.GetComponent<Rigidbody>() || meshFilter.transform.GetComponentInParent<Rigidbody>() || meshFilter.transform.GetComponentInChildren<Rigidbody>())
|
||||
continue;
|
||||
DestroyImmediate(meshFilter.gameObject.transform.parent.gameObject);
|
||||
}
|
||||
floorMesh.transform.position = basePosition;
|
||||
floorMesh.transform.rotation = baseRotation;
|
||||
floorMesh.AddComponent<MeshCollider>().sharedMesh = floorMesh.GetComponent<MeshFilter>().sharedMesh;
|
||||
}
|
||||
|
||||
private int Contains(ArrayList searchList, string searchName)
|
||||
{
|
||||
for (int i = 0; i < searchList.Count; i++)
|
||||
{
|
||||
if (((Material)searchList[i]).name == searchName)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d1dd59961254a34585afe7927f04a02
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class MeshExtension
|
||||
{
|
||||
private class Vertices
|
||||
{
|
||||
List<Vector3> verts = null;
|
||||
List<Vector2> uv1 = null;
|
||||
List<Vector2> uv2 = null;
|
||||
List<Vector2> uv3 = null;
|
||||
List<Vector2> uv4 = null;
|
||||
List<Vector3> normals = null;
|
||||
List<Vector4> tangents = null;
|
||||
List<Color32> colors = null;
|
||||
List<BoneWeight> boneWeights = null;
|
||||
|
||||
public Vertices()
|
||||
{
|
||||
verts = new List<Vector3>();
|
||||
}
|
||||
public Vertices(Mesh aMesh)
|
||||
{
|
||||
verts = CreateList(aMesh.vertices);
|
||||
uv1 = CreateList(aMesh.uv);
|
||||
uv2 = CreateList(aMesh.uv2);
|
||||
uv3 = CreateList(aMesh.uv3);
|
||||
uv4 = CreateList(aMesh.uv4);
|
||||
normals = CreateList(aMesh.normals);
|
||||
tangents = CreateList(aMesh.tangents);
|
||||
colors = CreateList(aMesh.colors32);
|
||||
boneWeights = CreateList(aMesh.boneWeights);
|
||||
}
|
||||
|
||||
private List<T> CreateList<T>(T[] aSource)
|
||||
{
|
||||
if (aSource == null || aSource.Length == 0)
|
||||
return null;
|
||||
return new List<T>(aSource);
|
||||
}
|
||||
private void Copy<T>(ref List<T> aDest, List<T> aSource, int aIndex)
|
||||
{
|
||||
if (aSource == null)
|
||||
return;
|
||||
if (aDest == null)
|
||||
aDest = new List<T>();
|
||||
aDest.Add(aSource[aIndex]);
|
||||
}
|
||||
public int Add(Vertices aOther, int aIndex)
|
||||
{
|
||||
int i = verts.Count;
|
||||
Copy(ref verts, aOther.verts, aIndex);
|
||||
Copy(ref uv1, aOther.uv1, aIndex);
|
||||
Copy(ref uv2, aOther.uv2, aIndex);
|
||||
Copy(ref uv3, aOther.uv3, aIndex);
|
||||
Copy(ref uv4, aOther.uv4, aIndex);
|
||||
Copy(ref normals, aOther.normals, aIndex);
|
||||
Copy(ref tangents, aOther.tangents, aIndex);
|
||||
Copy(ref colors, aOther.colors, aIndex);
|
||||
Copy(ref boneWeights, aOther.boneWeights, aIndex);
|
||||
return i;
|
||||
}
|
||||
public void AssignTo(Mesh aTarget)
|
||||
{
|
||||
if (verts.Count > 65535)
|
||||
aTarget.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
|
||||
aTarget.SetVertices(verts);
|
||||
if (uv1 != null) aTarget.SetUVs(0, uv1);
|
||||
if (uv2 != null) aTarget.SetUVs(1, uv2);
|
||||
if (uv3 != null) aTarget.SetUVs(2, uv3);
|
||||
if (uv4 != null) aTarget.SetUVs(3, uv4);
|
||||
if (normals != null) aTarget.SetNormals(normals);
|
||||
if (tangents != null) aTarget.SetTangents(tangents);
|
||||
if (colors != null) aTarget.SetColors(colors);
|
||||
if (boneWeights != null) aTarget.boneWeights = boneWeights.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static Mesh GetSubmesh(this Mesh aMesh, int aSubMeshIndex)
|
||||
{
|
||||
if (aSubMeshIndex < 0 || aSubMeshIndex >= aMesh.subMeshCount)
|
||||
return null;
|
||||
int[] indices = aMesh.GetTriangles(aSubMeshIndex);
|
||||
Vertices source = new Vertices(aMesh);
|
||||
Vertices dest = new Vertices();
|
||||
Dictionary<int, int> map = new Dictionary<int, int>();
|
||||
int[] newIndices = new int[indices.Length];
|
||||
for (int i = 0; i < indices.Length; i++)
|
||||
{
|
||||
int o = indices[i];
|
||||
int n;
|
||||
if (!map.TryGetValue(o, out n))
|
||||
{
|
||||
n = dest.Add(source, o);
|
||||
map.Add(o, n);
|
||||
}
|
||||
newIndices[i] = n;
|
||||
}
|
||||
Mesh m = new Mesh();
|
||||
dest.AssignTo(m);
|
||||
m.triangles = newIndices;
|
||||
return m;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cfee6f65c36c224ab66a34ea32ca686
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "com.alexism.floorplacom.alexism.floorplan",
|
||||
"references": [
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||
"GUID:3a9781db4804a9945b9883f3a7c46d45",
|
||||
"GUID:c4df6f69b1bd3d542a0bd5e003678751"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12d6d9ac7109b014bbe1f60624409612
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using alexism.Floorplan.Core.ScriptableObjects;
|
||||
using alexism.Floorplan.Core.Components;
|
||||
using alexism.Floorplan.Core.Enums;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace alexism.Floorplan.Core
|
||||
{
|
||||
[RequireComponent(typeof(Grid))]
|
||||
[ExecuteInEditMode]
|
||||
|
||||
public class floorplan : MonoBehaviour
|
||||
{
|
||||
|
||||
|
||||
public Bounds bounds;
|
||||
[HideInInspector]
|
||||
public GameObject geometry;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!geometry)
|
||||
geometry = new GameObject("FloorPlanGeometry");
|
||||
//geometry = GameObject.Find("New Floorplan Geometry");
|
||||
}
|
||||
|
||||
bool toolActive;
|
||||
[SerializeField]
|
||||
public floorplanTileset tileset;
|
||||
|
||||
public Material[] wallMaterials=new Material[100];
|
||||
|
||||
public List<int> selected = new List<int>(4) { -1,-1,-1,-1};
|
||||
|
||||
[Space(15)]
|
||||
Vector3 lastHandlePosition;
|
||||
Vector3 snapLastHandlePosition;
|
||||
Vector3 handlePosition;
|
||||
Vector3 lastTileDelta;
|
||||
Vector3 tileDelta;
|
||||
GameObject geometryRoot;
|
||||
[HideInInspector]
|
||||
public float tileSize = 2f;
|
||||
Color gizmoColor = Color.red;
|
||||
|
||||
public GameObject[] getTilesFromType(TileTypes type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TileTypes.Wall:
|
||||
return tileset.wallTiles;
|
||||
case TileTypes.Pillar:
|
||||
return tileset.pillarTiles;
|
||||
case TileTypes.Floor:
|
||||
return tileset.floorTiles;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TileTypes getTypeFromTile(GameObject tile)
|
||||
{
|
||||
TileTypes type = TileTypes.None;
|
||||
if (tileset.wallTiles.ToList().Find(x => x == tile))
|
||||
type = TileTypes.Wall;
|
||||
if (tileset.floorTiles.ToList().Find(x => x == tile))
|
||||
type = TileTypes.Floor;
|
||||
if (tileset.pillarTiles.ToList().Find(x => x == tile))
|
||||
type = TileTypes.Pillar;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
print("Selected: " + selected.Count);
|
||||
snapLastHandlePosition = transform.position;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
snapLastHandlePosition = transform.position;
|
||||
geometryRoot = geometry;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
}
|
||||
|
||||
public GameObject createInstance(GameObject instanceType, Vector3 spawnPosition, Quaternion spawnRotation)
|
||||
{
|
||||
GameObject instance = PrefabUtility.InstantiatePrefab(instanceType) as GameObject;
|
||||
instance.transform.position = spawnPosition;
|
||||
instance.transform.rotation = spawnRotation;
|
||||
instance.transform.parent = geometry.transform;
|
||||
instance.GetComponent<floorplanComponent>().tileset = tileset;
|
||||
instance.name = instanceType.name;
|
||||
return instance.transform.GetChild(0).gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9106951e7a6bcb4eae8310b1362189a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- tileset: {fileID: 11400000, guid: 04655de02232d0642ad32b971b2e2a91, type: 2}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,136 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using alexism.Floorplan.Core.ScriptableObjects;
|
||||
using alexism.Floorplan.Core.Enums;
|
||||
|
||||
namespace alexism.Floorplan.Core.Components
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[SelectionBase]
|
||||
|
||||
public class floorplanComponent : MonoBehaviour
|
||||
{
|
||||
public floorplanTileset tileset;
|
||||
public List<GameObject> stuff;
|
||||
Vector3 offset;
|
||||
public TileTypes tileType=TileTypes.Wall;
|
||||
void Start() {
|
||||
if (EditorApplication.isPlaying)
|
||||
return;
|
||||
Renderer r = transform.GetChild(0).GetComponent<Renderer>();
|
||||
offset = r.bounds.center - new Vector3(0, r.bounds.size.y / 2.4f);
|
||||
stuff = new List<GameObject>();
|
||||
#if UNITY_EDITOR
|
||||
if (Physics.CheckSphere(offset, .1f) && tileType==TileTypes.Floor)
|
||||
{
|
||||
|
||||
Collider[] overlaps = Physics.OverlapSphere(offset, .1f);
|
||||
foreach (Collider overlap in overlaps)
|
||||
{
|
||||
if (overlap.transform.root == transform.root && !isChild(overlap.transform, transform))
|
||||
{
|
||||
print("Destroyed overlap: " + overlap.transform.name);
|
||||
DestroyImmediate(overlap.transform.parent.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
//if (EditorApplication.isPlaying)
|
||||
// return;
|
||||
//if (Physics.CheckSphere(offset, .1f))
|
||||
//{
|
||||
|
||||
// Collider[] overlaps = Physics.OverlapSphere(offset, .1f);
|
||||
// foreach (Collider overlap in overlaps)
|
||||
// {
|
||||
// if (overlap.transform.root == transform.root && !isChild(overlap.transform, transform))
|
||||
// {
|
||||
// print("Destroyed overlap: " + overlap.transform.name);
|
||||
// overlap.transform.parent.position += new Vector3(0, 10, 0);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
bool isChild(Transform c,Transform p)
|
||||
{
|
||||
bool t = false;
|
||||
foreach(Transform child in p)
|
||||
{
|
||||
if (child == c)
|
||||
{
|
||||
t = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (child.childCount > 0)
|
||||
{
|
||||
t=isChild(c, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public GameObject[] getTilesFromType(TileTypes type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TileTypes.Wall:
|
||||
return tileset.wallTiles;
|
||||
case TileTypes.Pillar:
|
||||
return tileset.pillarTiles;
|
||||
case TileTypes.Floor:
|
||||
return tileset.floorTiles;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TileTypes getTypeFromTile(GameObject tile)
|
||||
{
|
||||
TileTypes type=TileTypes.None;
|
||||
if(tileset.wallTiles.ToList().Find(x => x==tile))
|
||||
type = TileTypes.Wall;
|
||||
if(tileset.floorTiles.ToList().Find(x => x==tile))
|
||||
type = TileTypes.Floor;
|
||||
if(tileset.pillarTiles.ToList().Find(x => x==tile))
|
||||
type = TileTypes.Pillar;
|
||||
return type;
|
||||
}
|
||||
|
||||
public void ChangeComponentType(GameObject newType)
|
||||
{
|
||||
|
||||
// GameObject newInstance = GameObject.Instantiate (newType, transform.position, transform.rotation);
|
||||
GameObject newInstance = PrefabUtility.InstantiatePrefab(newType) as GameObject;
|
||||
newInstance.transform.position = this.transform.position;
|
||||
newInstance.transform.rotation = this.transform.rotation;
|
||||
newInstance.transform.localScale = this.transform.localScale;
|
||||
newInstance.transform.parent = this.transform.parent;
|
||||
newInstance.GetComponent<floorplanComponent>().tileset = tileset;
|
||||
Renderer newRenderer = newInstance.transform.GetChild(0).GetComponent<Renderer>();
|
||||
Renderer oldRenderer = transform.GetChild(0).GetComponent<Renderer>();
|
||||
if (newRenderer.sharedMaterials.Length > 0)
|
||||
{
|
||||
newInstance.transform.GetChild(0).GetComponent<Renderer>().materials = transform.GetChild(0).GetComponent<Renderer>().sharedMaterials;
|
||||
}
|
||||
else
|
||||
{
|
||||
newInstance.transform.GetChild(0).GetComponent<Renderer>().material = transform.GetChild(0).GetComponent<Renderer>().sharedMaterial;
|
||||
}
|
||||
GameObject.DestroyImmediate(this.gameObject);
|
||||
|
||||
}
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d933d9bbd3e611d41a488afaa8ac3106
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using alexism.Floorplan.Core.Enums;
|
||||
|
||||
namespace alexism.Floorplan.Core.ScriptableObjects
|
||||
{
|
||||
[CreateAssetMenu(fileName = "New Floorplan Tileset", menuName = "Floorplan Tileset")]
|
||||
public class floorplanTileset : ScriptableObject
|
||||
{
|
||||
public GameObject[] floorTiles;
|
||||
public GameObject[] wallTiles;
|
||||
public GameObject[] pillarTiles;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8441b0125f23fb644b2d1fbd1835ee18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user