Skip to content

Instantly share code, notes, and snippets.

@dimmduh
Created February 20, 2019 17:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dimmduh/0d8c0e697d57a330c8bfc78eb90d3d29 to your computer and use it in GitHub Desktop.
Save dimmduh/0d8c0e697d57a330c8bfc78eb90d3d29 to your computer and use it in GitHub Desktop.
Unity - Rotate around point tool - test 1
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class RotationHelper
{
private static bool enabled;
static RotationHelper()
{
EditorApplication.update += Update;
SceneView.onSceneGUIDelegate += OnSceneGUIDelegate;
}
private static int selectedAxis = 2;
private static Event lastEvent;
static void OnSceneGUIDelegate(SceneView sceneView)
{
var e = Event.current;
if (e == null)
return;
lastEvent = e;
var controlId = 0;
if (enabled)
{
controlId = GUIUtility.GetControlID(FocusType.Passive);
DrawUI();
}
switch (e.type)
{
case EventType.MouseDown:
if (e.button == 0 && enabled)
{
GUIUtility.hotControl = controlId;
Event.current.Use();
if (rotating)
{
}
else
{
rotating = true;
selectedPoint = lastSelectedPoint;
}
}
break;
case EventType.MouseDrag:
if (rotating && e.button == 0)
{
var axis = Vector3.up;
if (selectedAxis == 1)
axis = selectedGo.transform.right;
if (selectedAxis == 3)
axis = selectedGo.transform.forward;
selectedGo.transform.RotateAround(selectedPoint, axis, 20f * e.delta.x * Time.smoothDeltaTime);
}
break;
case EventType.KeyDown:
if (e.keyCode == KeyCode.J)
{
enabled = !enabled;
if (!enabled)
rotating = false;
}
if (e.keyCode == KeyCode.Alpha1)
selectedAxis = 1;
if (e.keyCode == KeyCode.Alpha2)
{
selectedAxis = 2;
GUIUtility.hotControl = controlId;
Event.current.Use();
}
if (e.keyCode == KeyCode.Alpha3)
selectedAxis = 3;
if (e.keyCode == KeyCode.Escape)
{
if (rotating)
rotating = false;
else
enabled = false;
}
break;
}
}
static void Update()
{
if (enabled)
HandleActiveMode();
}
private static bool rotating;
private static Vector3 selectedPoint;
private static Vector3 lastSelectedPoint;
private static GameObject selectedGo;
private static Camera camera;
private static void HandleActiveMode()
{
if (Selection.activeGameObject == null)
return;
if (Camera.current == null || lastEvent == null)
return;
camera = Camera.current;
selectedGo = Selection.activeGameObject;
var mousePos = new Vector3(lastEvent.mousePosition.x, camera.pixelHeight - lastEvent.mousePosition.y, 0);
if (!rotating)
{
var ray = HandleUtility.GUIPointToWorldRay(mousePos);
// Debug.DrawRay(ray.origin, ray.direction * 2000f, Color.red, 2f);
var ray2 = camera.ScreenPointToRay(mousePos);
// Debug.DrawRay(ray2.origin, ray2.direction * 2000f, Color.blue, 2f);
lastSelectedPoint = FindClosestPoint(selectedGo, ray2);
}
}
private static void DrawUI()
{
if (camera == null)
return;
Vector3 point;
if (rotating)
{
Handles.color = Color.red;
point = selectedPoint;
}
else
{
Handles.color = Color.blue;
point = lastSelectedPoint;
}
Handles.DrawSolidDisc(point, camera.transform.forward * -1f, 0.1f);
}
private static float DistanceToRay(Vector3 point, Ray ray)
{
var distance = Vector3.Distance(ray.origin, point);
var angle = Vector3.Angle(ray.direction, point - ray.origin);
return (distance * Mathf.Sin(angle * Mathf.Deg2Rad));
}
private static Vector3 FindClosestPoint(GameObject go, Ray ray)
{
//collect vertices
var meshFilters = go.GetComponentsInChildren<MeshFilter>();
var vertices = new List<Vector3>();
foreach (var meshFilter in meshFilters)
{
if (meshFilter.sharedMesh == null)
continue;
foreach (var vertex in meshFilter.sharedMesh.vertices)
{
vertices.Add(meshFilter.transform.TransformPoint(vertex));
}
}
//find
var closestVertex = Vector3.zero;
var minDistance = float.MaxValue;
foreach (var vertex in vertices)
{
var dist = DistanceToRay(vertex, ray);
// Debug.Log(vertexPos + " d = " + dist);
if (dist < minDistance)
{
closestVertex = vertex;
minDistance = dist;
}
}
return closestVertex;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment