Created
January 9, 2020 22:59
-
-
Save lowteq/db30c1641c290ffe8f522fe38ac34310 to your computer and use it in GitHub Desktop.
UnityEditorWindow上で外枠のパスを入力し立体物に変換するスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using System.Collections.Generic; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
public class BroochEditor : EditorWindow | |
{ | |
private class PathTool | |
{ | |
int selectindex = -1; | |
DrawTexture2D drawTexture2d = new DrawTexture2D(); | |
Texture2D texture; | |
bool closed = false; | |
List<Vector2> veclist; | |
float r; | |
int canvasSize; | |
public PathTool(int canvassize,float radius){ | |
r = radius; | |
canvasSize = canvassize; | |
veclist = new List<Vector2>(); | |
texture = new Texture2D(canvasSize,canvasSize); | |
drawTexture2d = new DrawTexture2D(); | |
} | |
public Texture2D canvas(){ | |
drawTexture2d.Begin(texture); | |
drawTexture2d.Clear(new Color(0.0f, 0.0f, 0.0f)); | |
var c = new Color(0.5f, 0.5f, 0.5f); | |
if (veclist.Count == 0){ | |
drawTexture2d.End(); | |
return texture; | |
}else{ | |
drawTexture2d.DrawCircle((int)veclist[0].x, (int)veclist[0].y, (int)r, c); | |
for(var i=1;i<veclist.Count;i++){ | |
var v1 = veclist[i-1]; | |
var v2 = veclist[i]; | |
drawTexture2d.DrawLine((int)v1.x,(int)v1.y,(int)v2.x,(int)v2.y,c); | |
drawTexture2d.DrawCircle((int)v2.x,(int)v2.y,(int)r,c); | |
} | |
} | |
if(closed){ | |
drawTexture2d.DrawLine((int)veclist[0].x,(int)veclist[0].y,(int)veclist[veclist.Count-1].x,(int)veclist[veclist.Count-1].y,c); | |
} | |
drawTexture2d.End(); | |
return texture; | |
} | |
public void Clear(){ | |
veclist = new List<Vector2>(); | |
texture = new Texture2D(canvasSize, canvasSize); | |
drawTexture2d = new DrawTexture2D(); | |
veclist.Clear(); | |
closed = false; | |
} | |
public void ReleaseSelect(){ | |
selectindex = -1; | |
} | |
public void Move(Vector2 vec) | |
{ | |
if(selectindex == -1) return; | |
veclist[selectindex] = vec; | |
} | |
public bool Select(Vector2 vec){ | |
selectindex = -1; | |
for(var i=0;i<veclist.Count;i++){ | |
if(circleIn(vec,veclist[i],r)){ | |
selectindex = i; | |
return true; | |
} | |
} | |
return false; | |
} | |
public bool Add(Vector2 vec){ | |
bool ret = false; | |
for (var i = 0; i < veclist.Count; i++) | |
{ | |
if (circleIn(vec, veclist[i], r)) | |
{ | |
//もし追加しようとしてるvecがveclist内の点付近の場合は追加しない | |
//だたし閉じる処理のveclist[0]のクリックは調べない | |
if(closed) return false; | |
} | |
} | |
Debug.Log("Pass"); | |
if(closed){ | |
for (var i = 1; i < veclist.Count; i++) | |
{ | |
if(lineIn(vec,veclist[i-1],veclist[i],r)){ | |
veclist.Insert(i,vec); | |
Debug.Log("insert 1"); | |
ret = true; | |
break; | |
} | |
} | |
if (lineIn(vec, veclist[0], veclist[veclist.Count - 1], r)) | |
{ | |
veclist.Insert(0, vec); | |
Debug.Log("insert 2"); | |
ret = true; | |
} | |
}else{ | |
if (veclist.Count > 2) | |
{ | |
if (circleIn(veclist[0], vec, r)) | |
{ | |
//閉じるための処理 | |
closed = true; | |
} | |
else | |
{ | |
//追加する | |
veclist.Add(vec); | |
ret = true; | |
} | |
} | |
else | |
{ | |
veclist.Add(vec); | |
ret = true; | |
} | |
} | |
return ret; | |
} | |
public void Remove(Vector2 vec){ | |
if(veclist.Count <= 3){ | |
return; | |
} | |
for(var i=0;i<veclist.Count;i++){ | |
if (circleIn(veclist[i], vec, r)) | |
{ | |
veclist.RemoveAt(i); | |
break; | |
} | |
} | |
} | |
/// <summary> | |
/// 線分v1-v2上(太さ2*r)にpが存在するか | |
/// 点v1,v2付近ではfalseになる部分がある | |
/// </summary> | |
/// <param name="p"></param> | |
/// <param name="v1"></param> | |
/// <param name="v2"></param> | |
/// <param name="r"></param> | |
/// <returns></returns> | |
private static bool lineIn(Vector2 p,Vector2 v1,Vector2 v2,float r){ | |
float a = v2.x - v1.x; | |
float b = v2.y - v1.y; | |
float a2 = a * a; | |
float b2 = b * b; | |
float r2 = a2 + b2; | |
float tt = -(a*(v1.x-p.x)+b*(v1.y-p.y)); | |
float d2; | |
if(tt < 0){ | |
d2 = (v1.x-p.x)*(v1.x-p.x) + (v1.y-p.y)*(v1.y-p.y); | |
} | |
if(tt > r2){ | |
d2 = (v2.x-p.x)*(v2.x-p.x) + (v2.y-p.y)*(v2.y-p.y); | |
} | |
float f1 = a*(v1.y-p.y)-b*(v1.x-p.x); | |
d2 = (f1*f1)/r2; | |
Debug.Log(Math.Sqrt(d2)); | |
if (d2<=r && dist2(v1,p) < r2 && dist2(v2,p) < r2){ | |
return true; | |
}else{ | |
return false; | |
} | |
} | |
/// <summary> | |
/// 2点間の距離の2乗 | |
/// </summary> | |
/// <param name="p1"></param> | |
/// <param name="p2"></param> | |
/// <returns></returns> | |
private static float dist2(Vector2 p1,Vector2 p2){ | |
float c =(p2.x - p1.x); | |
float d =(p2.y - p1.y); | |
return c*c + d*d; | |
} | |
private static bool circleIn(Vector2 mousevec, Vector2 plotvec, float r) | |
{ | |
if (Math.Pow(mousevec.x - plotvec.x, 2) + Math.Pow(mousevec.y - plotvec.y, 2) <= r * r) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
} | |
Texture2D texture = null; | |
private int canvasOffsetX = 240; | |
private int canvasOffsetY = 20; | |
private int canvasSize = 500; | |
private int selGridInt = 0; | |
private PathTool pt; | |
enum ToolType{ | |
AddEdit = 0,Remove = 1 | |
} | |
private string[] selCaptions = new string[] { | |
"Add/Edit", | |
"Remove", | |
}; | |
[MenuItem("Window/BroochEditor")] | |
private static void Create() | |
{ | |
// 生成 | |
var window = GetWindow<BroochEditor>("Brooch Editor"); | |
window.minSize = new Vector2(320, 320); | |
window.Init(); | |
} | |
private void Init(){ | |
pt = new PathTool(canvasSize, 5); | |
} | |
void OnInspectorUpdate() | |
{ | |
if (EditorWindow.focusedWindow == this && | |
EditorWindow.mouseOverWindow == this) | |
{ | |
this.Repaint(); | |
} | |
} | |
public static void SetTextureImporterFormat(Texture2D texture, bool isReadable) | |
{ | |
if (texture.isReadable == isReadable){ | |
return; | |
} | |
string assetPath = AssetDatabase.GetAssetPath(texture); | |
var tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; | |
if (tImporter != null) | |
{ | |
//tImporter.textureType = TextureImporterType.Default; | |
tImporter.isReadable = isReadable; | |
AssetDatabase.ImportAsset(assetPath); | |
AssetDatabase.Refresh(); | |
} | |
} | |
void OnGUI() | |
{ | |
Event e = Event.current; | |
var cmp = new Vector2(e.mousePosition.x - canvasOffsetX,e.mousePosition.y - canvasOffsetY); | |
if(0< cmp.x && cmp.x < canvasSize && 0 < cmp.y && cmp.y < canvasSize){ | |
CanvasBehaviour(e,cmp); | |
} | |
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(200));{ | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUILayout.BeginVertical(GUI.skin.box); | |
{ | |
var mp = e.mousePosition; | |
EditorGUILayout.LabelField("x:" + mp.x + " y:" + mp.y + " type:" + e.type); | |
if (e.type == EventType.MouseDown){ | |
Debug.Log(mp); | |
} | |
} | |
EditorGUILayout.EndVertical(); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUI.BeginChangeCheck(); | |
texture = EditorGUILayout.ObjectField("Reference Texture:", texture, typeof(Texture), false) as Texture2D; | |
if(EditorGUI.EndChangeCheck()){ | |
Debug.Log("ChangeTexture"); | |
if (texture != null){ | |
SetTextureImporterFormat(texture,true); | |
} | |
} | |
}EditorGUILayout.EndVertical(); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
EditorGUILayout.LabelField("Tools",EditorStyles.boldLabel); | |
selGridInt = GUILayout.SelectionGrid(selGridInt, selCaptions, 1, EditorStyles.radioButton); | |
}EditorGUILayout.EndVertical(); | |
EditorGUILayout.BeginVertical(GUI.skin.box);{ | |
GUILayout.Label("Base Settings", EditorStyles.boldLabel); | |
// myString = EditorGUILayout.TextField("Text Field", myString); | |
}EditorGUILayout.EndVertical(); | |
}EditorGUILayout.EndVertical(); | |
} | |
if (texture != null) | |
{ | |
// Color[] pixels = texture.GetPixels(); | |
// Color[] change_pixels = new Color[pixels.Length]; | |
// for (int i = 0; i < pixels.Length; i++) | |
// { | |
// Color pixel = pixels[i]; | |
// // 書き換え用テクスチャのピクセル色を指定 | |
// Color change_pixel = new Color(1f, pixel.g, pixel.b, pixel.a); | |
// change_pixels.SetValue(change_pixel, i); | |
// } | |
// // 書き換え用テクスチャの生成 | |
// Texture2D change_texture = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false); | |
// change_texture.filterMode = FilterMode.Point; | |
// change_texture.SetPixels(change_pixels); | |
// change_texture.Apply(); | |
//EditorGUI.DrawPreviewTexture(new Rect(240,20, 500, 500),texture); | |
} | |
} | |
private void CanvasBehaviour(Event e,Vector2 canvasMousePosition){ | |
// if((ToolType)selGridInt==ToolType.Add){ | |
// switch(e.type){ | |
// case EventType.MouseDown: | |
// pt.Add(canvasMousePosition); | |
// break; | |
// } | |
// } | |
if((ToolType)selGridInt==ToolType.Remove){ | |
switch(e.type){ | |
case EventType.MouseDown: | |
pt.Remove(canvasMousePosition); | |
break; | |
} | |
}else if((ToolType)selGridInt==ToolType.AddEdit){ | |
switch(e.type){ | |
case EventType.MouseDown: | |
if(!pt.Add(canvasMousePosition)){ | |
pt.Select(canvasMousePosition); | |
} | |
break; | |
case EventType.MouseDrag: | |
pt.Move(canvasMousePosition); | |
break; | |
case EventType.MouseUp: | |
pt.ReleaseSelect(); | |
break; | |
} | |
} | |
var drawtex = pt.canvas(); | |
EditorGUI.DrawPreviewTexture(new Rect(240,20,500,500),drawtex); | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment