var canvas = GetComponentInParent<Canvas>();
Camera cam = null;
switch (canvas.renderMode)
{
case RenderMode.ScreenSpaceOverlay:
break;
case RenderMode.ScreenSpaceCamera:
case RenderMode.WorldSpace:
cam = canvas.worldCamera;
break;
default:
break;
}
if (cam == null)
{
cam = Camera.main;
}
switch (canvas.renderMode)
{
case RenderMode.ScreenSpaceOverlay:
handle.transform.position = eventData.position;
break;
case RenderMode.ScreenSpaceCamera:
case RenderMode.WorldSpace:
Vector3 rectPos;
RectTransformUtility.ScreenPointToWorldPointInRectangle(GetComponent<RectTransform>(), eventData.position, cam, out rectPos);
handle.transform.position = rectPos;
break;
default:
break;
}
위에서 카메라만 가져올땐 약식으로 이거 써도 된다
public (Canvas, Camera) GetCanvasCamera()
{
var canvas = GetComponentInParent<Canvas>();
var camera = canvas.worldCamera;
if (camera == null)
{
camera = Camera.main;
}
return (canvas,camera);
}
특정 각도를 upVector삼아서 회전
(노란색 : 회전시킨 벡터)
(빨간색 : 기준각도)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VectorRotationTest : MonoBehaviour
{
void OnDrawGizmos()
{
//입력값
var axis = new Vector3(-2.85f, 1.4f, 3.4f);
var a = transform.rotation;
var b = Quaternion.Euler( 0, 0, (Time.time * 30) % 360);
//노란색원의 좌표계
var radius = Vector2.Distance(Vector2.zero, new Vector2(axis.x, axis.y));
var center = transform.position + a * Vector3.forward * axis.z;
UnityEngine.Debug.DrawLine(center, center + a * Vector3.up * radius, Color.blue);
UnityEngine.Debug.DrawLine(center, center + a * Vector3.right * radius, Color.green);
//노란색원
UnityEditor.Handles.color = Color.yellow;
UnityEditor.Handles.DrawWireDisc(center, a * Vector3.forward, radius);
UnityEditor.Handles.color = Color.white;
//흰색원과 좌표계
UnityEngine.Debug.DrawLine(transform.position, center, Color.red);
UnityEngine.Debug.DrawLine(transform.position, transform.position + a * Vector3.up, Color.blue);
UnityEngine.Debug.DrawLine(transform.position, transform.position + a * Vector3.right, Color.green);
UnityEditor.Handles.DrawWireDisc(transform.position, a * Vector3.forward, 1f);
var upRotation = a;
//핵심
UnityEngine.Debug.DrawLine(transform.position, transform.position + upRotation * b * axis, Color.yellow);
//검은색 선
UnityEngine.Debug.DrawLine(transform.position, transform.position + upRotation * b * Quaternion.Euler(0, 0, 90) * axis, Color.black);
UnityEngine.Debug.DrawLine(transform.position, transform.position + upRotation * b * Quaternion.Euler(0, 0, 180) * axis, Color.black);
UnityEngine.Debug.DrawLine(transform.position, transform.position + upRotation * b * Quaternion.Euler(0, 0, 270) * axis, Color.black);
}
}
벡터를 6방향으로 정규화
var axisNormal=vector;
if (Mathf.Abs(axisNormal.x) > Mathf.Abs(axisNormal.y))
{
axisNormal.y = 0;
}
if (Mathf.Abs(axisNormal.x) > Mathf.Abs(axisNormal.z))
{
axisNormal.z = 0;
}
else
{
axisNormal.x = 0;
}
axisNormal = axisNormal.normalized;
GPT가 짜준 패스에서 최단지점 구하는 함수
Vector3 ClosestPoint(Vector3 a, Vector3 b, Vector3 position)
{
Vector3 ab = b - a;
Vector3 ap = position - a;
float t = Vector3.Dot(ap, ab) / Vector3.Dot(ab, ab);
t = Mathf.Clamp01(t); // a와 b 사이의 지점만을 고려하려면 이 줄을 추가합니다.
return a + ab * t;
}
Vector3 ClosestPoint(Vector3 position)
{
var path = GetPath();
float minDistance = float.MaxValue;
Vector3 closestPoint = Vector3.zero;
for (int i = 0; i < path.Count - 1; i++)
{
Vector3 point = ClosestPoint(path[i], path[i + 1], position);
float distance = Vector3.Distance(point, position);
if (distance < minDistance)
{
minDistance = distance;
closestPoint = point;
}
}
return closestPoint;
}
List<Vector3> GetPath()
{
var childs = new List<Transform>();
for (int i = 0; i < tracksParent.childCount; i++)
{
childs.Add(tracksParent.GetChild(i));
}
var path = childs.ConvertAll(x => x.position);
return path;
}