Skip to content

Instantly share code, notes, and snippets.

@seobyeongky
Last active July 19, 2025 06:07
Show Gist options
  • Save seobyeongky/e92a7a52916ef47059fcbe17a2436ac7 to your computer and use it in GitHub Desktop.
Save seobyeongky/e92a7a52916ef47059fcbe17a2436ac7 to your computer and use it in GitHub Desktop.
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