Last active
July 19, 2025 06:07
-
-
Save seobyeongky/e92a7a52916ef47059fcbe17a2436ac7 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text.RegularExpressions; | |
using __; | |
using __.SceneViewEditing; | |
using Cysharp.Threading.Tasks; | |
using SolidUtilities; | |
using UnityEditor; | |
using UnityEngine; | |
[InitializeOnLoad] | |
public class ConsoleHelperStartup | |
{ | |
static ConsoleHelperStartup() | |
{ | |
ConsoleHelper.Begin(); | |
} | |
} | |
/* | |
* Line표시기능 | |
* [{id},{color},A] | |
* | |
* Labeling 기능 | |
* [P,Walk]-[UpJump]-[Rope]-[DashJump] (14.61, 23.11, 0.00)-(14.61, 23.11, -0.45)-(14.61, 23.11, -0.95)-(15.24, 23.54, -1.00)<WORLD> | |
* => 점 갯수면 점, 선 갯수면 선에 tag 적용 (Polygon의 경우 점 갯수와 선 갯수가 같기 때문에, 선으로 일단 하자. 점으로 하려면 VL을 붙이기) | |
* | |
* ex) [P,VI] (1,1)-(2,2)-(3,3) => polygon, vertex indexing | |
* [R:2](3,5) => 원점 (3,5) 기준 반지름 2의 원 | |
* [DEG]300.1 => 각도 300.1도 | |
* | |
* Item Tags | |
* P : polygon | |
* A : arrow | |
* VI : Vertex indexing | |
* LI : Line indexing | |
* VL : Vertex Labeling | |
* R:x : x크기의 반지름 원 | |
* DEG : 각도(degree) | |
* RAD : 각도(radian) | |
* X : 안나오게 | |
* V : 벡터(방향과 크기) | |
* | |
* | |
* Line Tags | |
* #n : ui 스케일 ex) #2는 2배 #0.5는 반 | |
* <WORLD> | |
* <MATRIX:(...)> | |
* | |
*/ | |
public class ConsoleHelper | |
{ | |
static ConsoleHelper instance; | |
EditorWindow wnd_; | |
EditorWindow gameviewWnd; | |
string cachedLog; | |
Func<string> GetSelectedLog; | |
ExposedList<PointItem> points = new (); | |
ExposedList<LineItem> lines = new(); | |
// List<(int, int)> lineChains = new(); | |
ExposedList<AngleItem> angles = new(); | |
// Regex vec3Regex; | |
// Regex vec2Regex; | |
Regex vecRegex; | |
Regex scaleRegex; | |
Regex commaRegex = new Regex("^ *, *$"); | |
Regex lineRegex = new Regex("^ *- *$"); | |
Regex rtagRegex = new Regex(@"\[([^\]]+)\] *$"); | |
Regex tagChainRegex = new Regex(@"(\[([^\]]+)\]-?)+"); // group[1]:[a,b,c] group[2]:a,b,c | |
Regex radiusRegex = new(@"R:([0-9.]+)"); | |
Regex matrixRegex = new(@"<MATRIX:([^\>]*)>"); | |
Regex numRegex; | |
// PointItemComparer comparer = new PointItemComparer(); | |
// LineItemComparer comparer2 = new LineItemComparer(); | |
Placing<int> placing = new(); | |
List<int> pointsRemove = new(); | |
Matrix4x4 curMat; | |
struct PointItem | |
{ | |
public int strIdx; | |
public Vector3 p; | |
public float scale; | |
public bool isWorldPoint; | |
// public int idx; | |
public bool hasTag; | |
public Tag tag; | |
} | |
struct LineItem | |
{ | |
public Vector3 p0; | |
public Vector3 p1; | |
public bool isWorldPoint; | |
// public int order; | |
// public int idx; | |
public bool hasTag; | |
public Tag tag; | |
public int linkFront; | |
public int linkBack; | |
/// <summary> p0의 string index </summary> | |
public int strIdx0; | |
/// <summary> p1의 string index </summary> | |
public int strIdx1; | |
public PolyBackLink polyBackLink; // 임시 polygon용 | |
} | |
struct PolyBackLink | |
{ | |
public bool hasTag; | |
public Tag tag; | |
} | |
struct AngleItem | |
{ | |
public bool isRad; | |
public float angle; | |
public Tag tag; | |
public bool hasLength; | |
public float length; | |
} | |
/// <summary> | |
/// 여러 chunk로 구성된 속성 | |
/// </summary> | |
struct Tag | |
{ | |
public bool hasColor; | |
public Color color; | |
public bool arrow; | |
public bool poly; | |
public bool vertexIndexing; | |
public bool lineIndexing; | |
public bool vertexLabeling; | |
public bool degree; | |
public bool radian; | |
public string label; | |
public float radius; | |
public bool no; | |
public bool vector; | |
} | |
class LineChain | |
{ | |
public int idxBegin; | |
/// <summary> inclusive </summary> | |
public int idxEnd; | |
public int LineCount => idxEnd - idxBegin + 1; | |
public int GetIndex(int i) => idxBegin + i; | |
} | |
// class PointItemComparer : IComparer<PointItem> | |
// { | |
// public int Compare(PointItem x, PointItem y) | |
// { | |
// return x.order.CompareTo(y.order); | |
// } | |
// } | |
// | |
// class LineItemComparer : IComparer<LineItem> | |
// { | |
// public int Compare(LineItem a, LineItem b) | |
// { | |
// return a.order.CompareTo(b.order); | |
// } | |
// } | |
public static void Begin() | |
{ | |
if (instance == null) | |
{ | |
instance = new ConsoleHelper(); | |
instance.Begin_(); | |
} | |
} | |
void Begin_() | |
{ | |
EditorApplication.update += OnUpdate; | |
SceneView.duringSceneGui += OnScene; | |
var bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; | |
var type = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.ConsoleWindow"); | |
var fieldInfo = type.GetField("m_ActiveText", bf); | |
GetSelectedLog = () => wnd == null ? null : (string)fieldInfo.GetValue(wnd); | |
var lb = Regex.Escape("("); | |
var rb = Regex.Escape(")"); | |
var dot = Regex.Escape("."); | |
var num = "[-+]?[0-9]*" + dot + "?[0-9]+"; | |
// var vec3Regex = new Regex(lb + $"({num}), ({num}), ({num})" + rb); | |
// var vec2Regex = new Regex(lb + $"({num}), ({num})" + rb); | |
vecRegex = new Regex(lb + $"({num}), ?({num})(, ?({num}))?" + rb); | |
scaleRegex = new Regex(Regex.Escape("#") + $"({num})$"); | |
numRegex = new Regex($"({num})"); | |
} | |
void OnUpdate() | |
{ | |
var nowLog = GetSelectedLog(); | |
if (nowLog != cachedLog) | |
{ | |
cachedLog = nowLog; | |
UpdatePoints(); | |
UpdateAngles(); | |
UpdateVectors(); | |
SceneView.RepaintAll(); | |
} | |
} | |
void UpdatePoints() | |
{ | |
points.Clear(); | |
lines.Clear(); | |
// lineChains.Clear(); | |
curMat = Matrix4x4.identity; | |
if (string.IsNullOrEmpty(cachedLog)) | |
return; | |
bool isWorldPoint = cachedLog.IndexOf("<WORLD>", StringComparison.Ordinal) != -1; | |
{ | |
var m = matrixRegex.Match(cachedLog); | |
if (m.Success) | |
{ | |
var nums = m.Groups[1].ToString(); | |
curMat = new Matrix4x4(); | |
int i = 0; | |
foreach (var num in nums.Split(',').Select((num_) => float.Parse(num_))) | |
{ | |
curMat[i++] = num; | |
} | |
} | |
} | |
float scale = 1f; | |
var logLines = cachedLog.Split('\n'); | |
if (logLines.Length > 0) | |
{ | |
var firstLine = logLines[0]; | |
var m = scaleRegex.Match(firstLine); | |
if (m.Length != 0) | |
{ | |
scale = float.Parse(m.Groups[1].Value); | |
} | |
} | |
var matches = vecRegex.Matches(cachedLog); | |
pointsRemove.Clear(); | |
{ | |
int pidx = points.Count; | |
foreach (Match m in matches) | |
{ | |
var x = float.Parse(m.Groups[1].Value); | |
var y = float.Parse(m.Groups[2].Value); | |
float z = 0; | |
if (m.Groups[3].Success) | |
z = float.Parse(m.Groups[4].Value); // 4번째가 실제 숫자임 | |
var p = new PointItem { strIdx = m.Index, p = new Vector3(x, y, z), scale = scale, isWorldPoint = isWorldPoint }; | |
var front = cachedLog.Substring(0, m.Index); | |
Match m2; | |
if ((m2 = rtagRegex.Match(front)).Success) | |
{ | |
var chunks = m2.Groups[1].Value.Split(','); | |
p.hasTag = true; | |
p.tag = GetTagFromChunks(chunks); | |
} | |
points.Add(p); | |
} | |
for (int i = 0; i < matches.Count - 1; i++) | |
{ | |
// (1,1)-(2,2) | |
// ^ | |
var lastIdx = matches[i].Index + matches[i].Length; | |
//" - " | |
var between = cachedLog.Substring(lastIdx, matches[i + 1].Index - lastIdx); | |
if (!lineRegex.IsMatch(between)) | |
{ | |
// CheckLineChain(false, -1, matches[i].Index); | |
} | |
else | |
{ | |
var l = new LineItem | |
{ | |
p0 = points._[pidx + i].p, p1 = points._[pidx + i + 1].p , isWorldPoint = isWorldPoint /*, order = points._[pidx + i].order*/ | |
, strIdx0 = matches[i].Index | |
, strIdx1 = matches[i+1].Index | |
, linkFront = -1 | |
, linkBack = -1 | |
}; | |
var lidx = lines.Count; | |
var front = cachedLog.Substring(0, matches[i].Index); | |
Match m; | |
if ((m = rtagRegex.Match(front)).Success) | |
{ | |
var chunks = m.Groups[1].Value.Split(','); | |
l.hasTag = true; | |
l.tag = GetTagFromChunks(chunks); | |
} | |
if (lidx > 0 && lines._[lidx - 1].strIdx1 == l.strIdx0) | |
{ | |
l.linkFront = lidx - 1; | |
lines._[lidx - 1].linkBack = lidx; | |
} | |
lines.Add(l); | |
if (!pointsRemove.Contains(pidx + i)) | |
pointsRemove.Add(pidx + i); | |
if (!pointsRemove.Contains(pidx + i + 1)) | |
pointsRemove.Add(pidx + i + 1); | |
} | |
} | |
} | |
DetectVertexLineIndexing(); | |
DetectTagChain(); | |
// Line을 구성하는 Point는 표시를 하지 않게 | |
for (int i = pointsRemove.Count - 1; i >=0; i--) | |
{ | |
// index가 망가지지 않기 위해 역순으로 지우기 | |
points.RemoveAt(pointsRemove[i]); | |
} | |
} | |
void UpdateAngles() | |
{ | |
angles.Clear(); | |
if (string.IsNullOrEmpty(cachedLog)) | |
return; | |
{ | |
var m = numRegex.Match(cachedLog); | |
while (m.Success) | |
{ | |
var num = float.Parse(m.Groups[1].Value); | |
var front = cachedLog.Substring(0, m.Index); | |
Match m2; | |
if ((m2 = rtagRegex.Match(front)).Success) | |
{ | |
var chunks = m2.Groups[1].Value.Split(','); | |
var tag = GetTagFromChunks(chunks); | |
if (tag.radian || tag.degree) | |
{ | |
var angleItem = new AngleItem { isRad = tag.radian, angle = num , tag = tag}; | |
angles.Add(angleItem); | |
} | |
} | |
m = m.NextMatch(); | |
} | |
} | |
} | |
void UpdateVectors() | |
{ | |
// UpdatePoints, UpdateVectors이후에 호출되야함 | |
// points 중에 vector tag가 있는 것들에 대해서 angle로 바꿔준다 | |
for (int i = points.Count - 1; i >= 0; i--) | |
{ | |
ref var p = ref points._[i]; | |
if (p.hasTag && p.tag.vector) | |
{ | |
var v = points._[i].p; | |
var angle = Mathf.Atan2(v.y, v.x); | |
var angleItem = new AngleItem { isRad = true, angle = angle, tag = p.tag, hasLength = true, length = v.magnitude }; | |
angles.Add(angleItem); | |
points.RemoveAt(i); | |
} | |
} | |
} | |
void DetectVertexLineIndexing() | |
{ | |
for (int i = 0; i < lines.Count; i++) | |
{ | |
ref var line = ref lines._[i]; | |
if (line.tag.vertexIndexing) | |
{ | |
var lineChain = GetLineChain(i); | |
int count = 0; | |
DoFor(count, line.strIdx0); | |
count++; | |
for (int j = lineChain.idxBegin; j <= lineChain.idxEnd; j++, count++) | |
{ | |
ref var seg = ref lines._[j]; | |
DoFor(count, seg.strIdx1); | |
} | |
void DoFor(int count, int strIdx) | |
{ | |
if (points.TryFindIndex((p) => p.strIdx == strIdx, out var pIdx)) | |
{ | |
pointsRemove.Remove(pIdx); | |
ref var p = ref points._[pIdx]; | |
p.hasTag = true; | |
if (string.IsNullOrEmpty(p.tag.label)) | |
p.tag.label = $"{count}"; | |
} | |
} | |
} | |
else if (line.tag.lineIndexing) | |
{ | |
var lineChain = GetLineChain(i); | |
int count = 0; | |
for (int j = lineChain.idxBegin; j <= lineChain.idxEnd; j++, count++) | |
{ | |
ref var seg = ref lines._[j]; | |
seg.hasTag = true; | |
if (string.IsNullOrEmpty(seg.tag.label)) | |
seg.tag.label = $"{count}"; | |
} | |
} | |
} | |
} | |
void DetectTagChain() | |
{ | |
foreach (Match m in tagChainRegex.Matches(cachedLog)) | |
{ | |
var endIdx = m.Index + m.Length; | |
for (int i = 0; i < lines.Count; i++) | |
{ | |
ref var line = ref lines._[i]; | |
if (endIdx <= line.strIdx0 | |
&& cachedLog.Substring(endIdx, line.strIdx0 - endIdx).Trim().Length == 0) // tag와 line chain 사이에 아무 글자도 없을 때 | |
{ | |
AssignTags(i); | |
break; | |
} | |
} | |
void AssignTags(int lidxBegin) | |
{ | |
var g = m.Groups[2]; //대괄호 안의 내용 | |
var chain = GetLineChain(lidxBegin); | |
var firstTag = GetTagFromChunks(g.Captures[0].Value.Split(',')); | |
bool isPoly = firstTag.poly; | |
bool isVertexLabeling = firstTag.vertexLabeling; | |
if (isVertexLabeling | |
|| (g.Captures.Count == chain.LineCount + 1 // 괄호 갯수가 line보다 많으면 vertex에 적용하겠거니 생각하는 것 (multi tag) | |
&& !isPoly)) // 예외처리 : polygon은 점 갯수와 선 갯수가 같다. 선 우선 처리 | |
{ | |
// 점 복구 | |
DoFor(g.Captures[0].Value, lines._[chain.GetIndex(0)].strIdx0); | |
for (int i = 0; i < chain.LineCount; i++) | |
{ | |
DoFor(g.Captures[i+1].Value, lines._[chain.GetIndex(i)].strIdx1); | |
} | |
{ | |
// 예외처리2 (polygon) | |
var lidx = chain.GetIndex(0); | |
lines._[lidx].hasTag = true; | |
lines._[lidx].tag = default; // 예외처리 (점이 가져가서 날려줘야됨) | |
lines._[lidx].tag.poly = isPoly; | |
} | |
void DoFor(string tags, int strIdx) | |
{ | |
if (points.TryFindIndex((p) => p.strIdx == strIdx, out var pIdx)) | |
{ | |
pointsRemove.Remove(pIdx); | |
var chunks = tags.Split(','); | |
points._[pIdx].hasTag = true; | |
points._[pIdx].tag = GetTagFromChunks(chunks); | |
} | |
} | |
} | |
else | |
{ | |
for (int i = 0; i < g.Captures.Count; i++) | |
{ | |
// Debug.Log($"{i} / {g.Captures.Count} / {chain.LineCount}"); | |
var capture = g.Captures[i]; | |
var tags = capture.Value; | |
var chunks = tags.Split(','); | |
if (i < chain.LineCount) | |
{ | |
var lidx = chain.GetIndex(i); | |
lines._[lidx].hasTag = true; | |
lines._[lidx].tag = GetTagFromChunks(chunks); | |
} | |
else if (i == chain.LineCount && isPoly) | |
{ | |
var lidx = chain.GetIndex(0); | |
lines._[lidx].polyBackLink = new PolyBackLink(){ hasTag = true, tag = GetTagFromChunks(chunks) }; | |
// Debug.Log($"set {lidx} backlink {lines._[lidx].polyBackLink.tag.ToStringSimple()}"); | |
} | |
} | |
} | |
// 색상 정보는 첫 번째 태그를 기준으로 전파시킨다. (단, 이미 색상이 있는 경우는 제외) | |
if (firstTag.hasColor) | |
{ | |
for (int i = 1; i < chain.LineCount; i++) | |
{ | |
var lidx = chain.GetIndex(i); | |
ref var l = ref lines._[lidx]; | |
if (l.hasTag && l.tag.hasColor) | |
continue; | |
l.hasTag = true; | |
l.tag.hasColor = true; | |
l.tag.color = firstTag.color; | |
} | |
if (isPoly) | |
{ | |
// polybackline 예외처리 => 이미 적용되는듯 => 적용안된다(마지막 선분까지 tag작성하지 않는 이상) | |
var lidx = chain.GetIndex(0); | |
ref var l = ref lines._[lidx]; | |
if (!l.polyBackLink.hasTag || !l.polyBackLink.tag.hasColor) | |
{ | |
l.polyBackLink.hasTag = true; | |
l.polyBackLink.tag.hasColor = true; | |
l.polyBackLink.tag.color = firstTag.color; | |
} | |
} | |
} | |
} | |
} | |
} | |
Tag GetTagFromChunks(IEnumerable<string> chunks) | |
{ | |
var tag = new Tag(); | |
Match m; | |
foreach (var chunk in chunks) | |
{ | |
if (chunk == "A") | |
tag.arrow = true; | |
else if (chunk == "P") | |
tag.poly = true; | |
else if (chunk == "VI") | |
tag.vertexIndexing = true; | |
else if (chunk == "LI") | |
tag.lineIndexing = true; | |
else if (chunk == "VL") | |
tag.vertexLabeling = true; | |
else if (chunk == "DEG") | |
tag.degree = true; | |
else if (chunk == "RAD") | |
tag.radian = true; | |
else if (chunk == "X") | |
tag.no = true; | |
else if (chunk == "V") | |
tag.vector = true; | |
else if (ColorUtils.colorByNameDict.TryGetValue(chunk, out var color)) | |
{ | |
tag.hasColor = true; | |
tag.color = color; | |
} | |
else if (ColorUtility.TryParseHtmlString(chunk, out color)) | |
{ | |
tag.hasColor = true; | |
tag.color = color; | |
} | |
else if ((m = radiusRegex.Match(chunk)).Success && float.TryParse(m.Groups[1].Value, out float radius)) | |
{ | |
tag.radius = radius; | |
} | |
else | |
{ | |
tag.label = chunk; | |
} | |
} | |
return tag; | |
} | |
LineChain GetLineChain(int idxBegin) | |
{ | |
var chain = new LineChain(); | |
chain.idxBegin = idxBegin; | |
int i = idxBegin; | |
while (i != -1) | |
{ | |
chain.idxEnd = i; | |
i = lines._[i].linkBack; | |
} | |
return chain; | |
} | |
GUIStyle miniLabelHasMargin; | |
void UpdatePlacing() | |
{ | |
placing.Clear(); | |
if (miniLabelHasMargin == null) | |
{ | |
miniLabelHasMargin = new GUIStyle(Styles.miniLabel); | |
miniLabelHasMargin.margin.left = 5; | |
miniLabelHasMargin.margin.top = 5; | |
} | |
for (int i = 0; i < points.Count; i++) | |
{ | |
ref var p = ref points._[i]; | |
var pos = p.p; | |
pos = curMat.MultiplyPoint3x4(pos); | |
if (p.isWorldPoint) | |
pos = pos.ViewPos(); | |
if (p.hasTag && !string.IsNullOrEmpty(p.tag.label)) | |
placing.AddLabelItem(i, pos, p.tag.label, miniLabelHasMargin); | |
} | |
for (int i = 0; i < lines.Count; i++) | |
{ | |
ref var l = ref lines._[i]; | |
var p0 = l.p0; | |
var p1 = l.p1; | |
p0 = curMat.MultiplyPoint3x4(p0); | |
p1 = curMat.MultiplyPoint3x4(p1); | |
if (l.isWorldPoint) | |
{ | |
p0 = p0.ViewPos(); | |
p1 = p1.ViewPos(); | |
} | |
if (l.hasTag && !string.IsNullOrEmpty(l.tag.label)) | |
placing.AddLabelItem(i+points.Count, 0.5f * (p0 + p1), l.tag.label, miniLabelHasMargin); | |
} | |
placing.Calc(); | |
} | |
// void AssignIndex() | |
// { | |
// for (int i = 0; i < points.Count; i++) | |
// { | |
// points._[i].idx = i; | |
// } | |
// | |
// for (int i = 0; i < lines.Count; i++) | |
// { | |
// lines._[i].idx = i; | |
// } | |
// } | |
static GUIStyle labelStyle; | |
void OnScene(SceneView sceneview) | |
{ | |
UpdatePlacing(); | |
var bgColor = sceneview.camera.backgroundColor; | |
if (labelStyle == null) | |
labelStyle = new GUIStyle(Styles.miniLabel); | |
Span<Color> pointColorUsed = stackalloc Color[points.Count]; | |
Span<Color> lineColorUsed = stackalloc Color[lines.Count]; | |
Span<Color> angleColorUsed = stackalloc Color[angles.Count]; | |
for (int i = 0; i < points.Count; i++) | |
{ | |
var item = points._[i]; | |
if (item.hasTag && item.tag.no) | |
continue; | |
var color = item.hasTag && item.tag.hasColor ? item.tag.color : IEnv.sceneViewColorManager.labelColor; | |
var s = item.scale; | |
var p = item.p; | |
p = curMat.MultiplyPoint3x4(p); | |
if (item.isWorldPoint) | |
p = p.ViewPos(); | |
if (item.hasTag && item.tag.label.Exists()) | |
s *= 0.5f; | |
pointColorUsed[i] = color; | |
Handles.color = color; | |
if (item.hasTag && item.tag.radius > 0) | |
{ | |
GizmoUtils.DrawCircleOutlineHandle(p, item.tag.radius); | |
continue; | |
} | |
var hs = HandleUtility.GetHandleSize(p); | |
// 십자가 그리기 | |
Handles.DrawLine(p + new Vector3(-0.05f, 0, 0) * s * hs, p + new Vector3(0.05f, 0, 0) * s * hs); | |
Handles.DrawLine(p + new Vector3(0, -0.05f, 0) * s * hs, p + new Vector3(0, 0.05f, 0) * s * hs); | |
if (item.hasTag && item.tag.label.Exists()) | |
continue; | |
Handles.color = new Color(color.r, color.g, color.b, 0.8f * s); | |
// outer원까지 | |
Handles.DrawWireDisc(p, new Vector3(0,0,-1), 0.15f * s * hs); | |
} | |
for (int i = 0; i < lines.Count; i++) | |
{ | |
var item = lines._[i]; | |
var p0 = item.p0; | |
var p1 = item.p1; | |
p0 = curMat.MultiplyPoint3x4(p0); | |
p1 = curMat.MultiplyPoint3x4(p1); | |
if (item.isWorldPoint) | |
{ | |
p0 = p0.ViewPos(); | |
p1 = p1.ViewPos(); | |
} | |
DrawLineWithTag(item.hasTag, item.tag, p0, p1, out Color c); | |
lineColorUsed[i] = c; | |
if (item.hasTag) | |
{ | |
if (item.tag.poly) | |
{ | |
var p2 = lines._[GetLineChain(i).idxEnd].p1; | |
p2 = curMat.MultiplyPoint3x4(p2); | |
if (item.isWorldPoint) | |
p2 = p2.ViewPos(); | |
// Debug.Log($"draw poly back link {p0} {p1} {p2}");; | |
DrawLineWithTag(item.polyBackLink.hasTag, item.polyBackLink.tag, p0, p2, out c); | |
} | |
} | |
} | |
void DrawLineWithTag(bool hasTag, Tag tag, Vector3 p0, Vector3 p1, out Color c) | |
{ | |
c = hasTag && tag.hasColor ? tag.color : IEnv.sceneViewColorManager.labelColor; | |
// c = Color.white; | |
// if (hasTag && tag.hasColor) | |
// c = tag.color; | |
if (hasTag && tag.no) | |
return; | |
Handles.color = c; | |
if (hasTag && tag.arrow) | |
{ | |
var arrowlen = 0.1f; | |
var plen = (p1 - p0).magnitude; | |
if (plen < 3 * arrowlen) | |
arrowlen = plen / 3f; | |
GizmoUtils.DrawArrow.ForHandle(p0, (p1 - p0), arrowlen); | |
return; | |
} | |
Handles.DrawLine(p0, p1); | |
} | |
// foreach (var lineChain in lineChains) | |
// { | |
// var item1 = lines._[lineChain.Item1]; | |
// var item2 = lines._[lineChain.Item2]; | |
// | |
// var p0 = item1.p0; | |
// var p1 = item2.p1; | |
// p0 = curMat.MultiplyPoint3x4(p0); | |
// p1 = curMat.MultiplyPoint3x4(p1); | |
// if (item1.isWorldPoint) | |
// p0 = p0.ViewPos(); | |
// if (item2.isWorldPoint) | |
// p1 = p1.ViewPos(); | |
// Handles.DrawLine(p0, p1); | |
// } | |
Lazy<Vector3> mousePos = new Lazy<Vector3>(() => HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin); | |
for (int i = 0; i < angles.Count; i++) | |
{ | |
var item = angles._[i]; | |
var angle = item.angle; | |
if (!item.isRad) | |
angle *= Mathf.Deg2Rad; | |
var p0 = new Vector3(0, 0, 0); | |
var p1 = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0); | |
p0 = mousePos.Value + p0; | |
p1 = mousePos.Value + p1; | |
var c = item.tag.hasColor ? item.tag.color : IEnv.sceneViewColorManager.labelColor; | |
Handles.color = c; | |
angleColorUsed[i] = c; | |
Handles.DrawLine(p0, p1); | |
} | |
Handles.BeginGUI(); | |
for (int i = 0; i < points.Count; i++) | |
{ | |
var item = points._[i]; | |
if (item.hasTag && item.tag.no) | |
continue; | |
var txt = $"{i}"; | |
var style = labelStyle; | |
style.normal.textColor = ColorUtils.GetDistinguishableColor2Slow(pointColorUsed[i], bgColor, secondWeight:2f, useCache:true); | |
if (item.hasTag) | |
{ | |
if (!string.IsNullOrEmpty(item.tag.label)) | |
txt = item.tag.label; | |
} | |
var p = item.p; | |
p = curMat.MultiplyPoint3x4(p); | |
if (item.isWorldPoint) | |
p = p.ViewPos(); | |
if (item.hasTag && !string.IsNullOrEmpty(item.tag.label)) | |
{ | |
var rt = placing.GetLabelRect(i, p, new GUIContent(txt), style); | |
GUI.Label(rt, txt, style); | |
} | |
} | |
for (int i = 0; i < lines.Count; i++) | |
{ | |
var item = lines._[i]; | |
var p0 = item.p0; | |
var p1 = item.p1; | |
p0 = curMat.MultiplyPoint3x4(p0); | |
p1 = curMat.MultiplyPoint3x4(p1); | |
if (item.isWorldPoint) | |
{ | |
p0 = p0.ViewPos(); | |
p1 = p1.ViewPos(); | |
} | |
var c = lineColorUsed[i]; | |
DrawLabelAt(item.hasTag, item.tag, i, c, 0.5f * (p0 + p1)); | |
if (item.tag.poly) | |
{ | |
var p2 = lines._[GetLineChain(i).idxEnd].p1; | |
p2 = curMat.MultiplyPoint3x4(p2); | |
if (item.isWorldPoint) | |
p2 = p2.ViewPos(); | |
// Debug.Log($"draw poly back link {p0} {p1} {p2}");; | |
DrawLabelAt(item.polyBackLink.hasTag, item.polyBackLink.tag, 9999 + i, c, 0.5f * (p0 + p2)); | |
} | |
} | |
for (int i = 0; i < angles.Count; i++) | |
{ | |
var item = angles._[i]; | |
var label = item.tag.label; | |
if (!label.Exists()) | |
continue; | |
var angle = item.angle; | |
if (!item.isRad) | |
angle *= Mathf.Deg2Rad; | |
// var p0 = new Vector3(0, 0, 0); | |
var dir = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)); | |
// p0 = mousePos.Value + p0; | |
// p1 = mousePos.Value + p1; | |
var length = item.hasLength ? item.length : 1; | |
var labelPos = mousePos.Value + (dir * (length + 0.5f)).xy0(); | |
DrawLabelAt(true, item.tag, 0, angleColorUsed[i], labelPos); | |
} | |
void DrawLabelAt(bool hasTag, Tag tag, int idx, Color evadeColor, Vector2 p) | |
{ | |
var style = labelStyle; | |
style.normal.textColor = ColorUtils.GetDistinguishableColor2Slow(evadeColor, bgColor, secondWeight:2, useCache:true); | |
if (hasTag) | |
{ | |
if (!string.IsNullOrEmpty(tag.label)) | |
{ | |
var rt = placing.GetLabelRect(idx+points.Count, p, new GUIContent(tag.label), style); | |
var bgColor = sceneview.camera.backgroundColor; | |
GUIUtils.LabelWithBackground(rt, tag.label, bgColor.WithAlpha(0.4f), style); | |
} | |
} | |
} | |
Handles.EndGUI(); | |
} | |
// Color GetColor(int i) | |
// { | |
// if (i == 0) | |
// return Color.red; | |
// else if (i == 1) | |
// return Color.green; | |
// else if (i == 2) | |
// return Color.blue; | |
// else | |
// return Color.black; | |
// } | |
static Type consoleWindowType; | |
double lastQueryTime; | |
EditorWindow wnd | |
{ | |
get | |
{ | |
if (!wnd_) | |
{ | |
// HOTFIX 최적화용 | |
// if (gameviewWnd == null) | |
// { | |
// gameviewWnd = EditorWindow.GetWindow(typeof(Editor).Assembly.GetType("UnityEditor.GameView"), false, "GameView", false); | |
// } | |
// gameviewWnd.Focus(); | |
// if (gameviewWnd != null && gameviewWnd.maximized) | |
// return null; | |
// wnd_ = EditorWindow.GetWindow(consoleWindowType, false); | |
var nowTime = EditorApplication.timeSinceStartup; | |
if (lastQueryTime + 1 < nowTime) | |
{ | |
lastQueryTime = nowTime; | |
var windows = Resources.FindObjectsOfTypeAll(consoleWindowType); | |
if (windows.Length == 0) | |
{ | |
// Debug.Log("콘솔창키라고"); | |
return null; | |
} | |
wnd_ = windows[0] as EditorWindow; | |
} | |
} | |
return wnd_; | |
} | |
} | |
[InitializeOnLoadMethod] | |
static void InitDomain() | |
{ | |
consoleWindowType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.ConsoleWindow"); | |
} | |
} | |
/* | |
* test문구들 | |
* | |
*QueryBulletGuarded raider_spear(-593914) (guardObjs:(none), hits:UnityEngine.RaycastHit2D,UnityEngine.RaycastHit2D, [bullet](-20.04, 23.52, -0.28), [virtualBullet](-20.23, 23.65), [dir,V](-0.82, 0.57)) | |
[P,targetHitBounds](-20.37, 23.95)-(-20.09, 23.95)-(-20.09, 23.07)-(-20.37, 23.07) | |
* | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment