Skip to content

Instantly share code, notes, and snippets.

@kyleweiner
Created November 14, 2012 09:01
Show Gist options
  • Save kyleweiner/4071089 to your computer and use it in GitHub Desktop.
Save kyleweiner/4071089 to your computer and use it in GitHub Desktop.
Unity: An editor script for Unity 3D that creates a custom plane.
// CreatePlane
// Credit: http://wiki.unity3d.com/index.php?title=CreatePlane
// 1. Using the inspector, create a new C# script.
// 2. Name the script "CreatePlane" and place it in a folder titled "Editor".
// 3. A new menu option titled "Custom Plane" will appear in "GameObject > Create Other".
using UnityEngine;
using UnityEditor;
using System.Collections;
public class CreatePlane : ScriptableWizard
{
public enum Orientation
{
Horizontal,
Vertical
}
public enum AnchorPoint
{
TopLeft,
TopHalf,
TopRight,
RightHalf,
BottomRight,
BottomHalf,
BottomLeft,
LeftHalf,
Center
}
public int widthSegments = 1;
public int lengthSegments = 1;
public float width = 1.0f;
public float length = 1.0f;
public Orientation orientation = Orientation.Horizontal;
public AnchorPoint anchor = AnchorPoint.Center;
public bool addCollider = false;
public bool createAtOrigin = true;
public string optionalName;
static Camera cam;
static Camera lastUsedCam;
[MenuItem("GameObject/Create Other/Custom Plane...")]
static void CreateWizard()
{
cam = Camera.current;
// Hack because camera.current doesn't return editor camera if scene view doesn't have focus
if (!cam)
cam = lastUsedCam;
else
lastUsedCam = cam;
ScriptableWizard.DisplayWizard("Create Plane",typeof(CreatePlane));
}
void OnWizardUpdate()
{
widthSegments = Mathf.Clamp(widthSegments, 1, 254);
lengthSegments = Mathf.Clamp(lengthSegments, 1, 254);
}
void OnWizardCreate()
{
GameObject plane = new GameObject();
if (!string.IsNullOrEmpty(optionalName))
plane.name = optionalName;
else
plane.name = "Plane";
if (!createAtOrigin && cam)
plane.transform.position = cam.transform.position + cam.transform.forward*5.0f;
else
plane.transform.position = Vector3.zero;
Vector2 anchorOffset;
string anchorId;
switch (anchor)
{
case AnchorPoint.TopLeft:
anchorOffset = new Vector2(-width/2.0f,length/2.0f);
anchorId = "TL";
break;
case AnchorPoint.TopHalf:
anchorOffset = new Vector2(0.0f,length/2.0f);
anchorId = "TH";
break;
case AnchorPoint.TopRight:
anchorOffset = new Vector2(width/2.0f,length/2.0f);
anchorId = "TR";
break;
case AnchorPoint.RightHalf:
anchorOffset = new Vector2(width/2.0f,0.0f);
anchorId = "RH";
break;
case AnchorPoint.BottomRight:
anchorOffset = new Vector2(width/2.0f,-length/2.0f);
anchorId = "BR";
break;
case AnchorPoint.BottomHalf:
anchorOffset = new Vector2(0.0f,-length/2.0f);
anchorId = "BH";
break;
case AnchorPoint.BottomLeft:
anchorOffset = new Vector2(-width/2.0f,-length/2.0f);
anchorId = "BL";
break;
case AnchorPoint.LeftHalf:
anchorOffset = new Vector2(-width/2.0f,0.0f);
anchorId = "LH";
break;
case AnchorPoint.Center:
default:
anchorOffset = Vector2.zero;
anchorId = "C";
break;
}
MeshFilter meshFilter = (MeshFilter)plane.AddComponent(typeof(MeshFilter));
plane.AddComponent(typeof(MeshRenderer));
string planeAssetName = plane.name + widthSegments + "x" + lengthSegments + "W" + width + "L" + length + (orientation == Orientation.Horizontal? "H" : "V") + anchorId + ".asset";
Mesh m = (Mesh)AssetDatabase.LoadAssetAtPath("Assets/Editor/" + planeAssetName,typeof(Mesh));
if (m == null)
{
m = new Mesh();
m.name = plane.name;
int hCount2 = widthSegments+1;
int vCount2 = lengthSegments+1;
int numTriangles = widthSegments * lengthSegments * 6;
int numVertices = hCount2 * vCount2;
Vector3[] vertices = new Vector3[numVertices];
Vector2[] uvs = new Vector2[numVertices];
int[] triangles = new int[numTriangles];
int index = 0;
float uvFactorX = 1.0f/widthSegments;
float uvFactorY = 1.0f/lengthSegments;
float scaleX = width/widthSegments;
float scaleY = length/lengthSegments;
for (float y = 0.0f; y < vCount2; y++)
{
for (float x = 0.0f; x < hCount2; x++)
{
if (orientation == Orientation.Horizontal)
{
vertices[index] = new Vector3(x*scaleX - width/2f - anchorOffset.x, 0.0f, y*scaleY - length/2f - anchorOffset.y);
}
else
{
vertices[index] = new Vector3(x*scaleX - width/2f - anchorOffset.x, y*scaleY - length/2f - anchorOffset.y, 0.0f);
}
uvs[index++] = new Vector2(x*uvFactorX, y*uvFactorY);
}
}
index = 0;
for (int y = 0; y < lengthSegments; y++)
{
for (int x = 0; x < widthSegments; x++)
{
triangles[index] = (y * hCount2) + x;
triangles[index+1] = ((y+1) * hCount2) + x;
triangles[index+2] = (y * hCount2) + x + 1;
triangles[index+3] = ((y+1) * hCount2) + x;
triangles[index+4] = ((y+1) * hCount2) + x + 1;
triangles[index+5] = (y * hCount2) + x + 1;
index += 6;
}
}
m.vertices = vertices;
m.uv = uvs;
m.triangles = triangles;
m.RecalculateNormals();
AssetDatabase.CreateAsset(m, "Assets/Editor/" + planeAssetName);
AssetDatabase.SaveAssets();
}
meshFilter.sharedMesh = m;
m.RecalculateBounds();
if (addCollider)
plane.AddComponent(typeof(BoxCollider));
Selection.activeObject = plane;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment