229 lines
8.4 KiB
C#
229 lines
8.4 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace RuntimeGizmos
|
|
{
|
|
//Currently doesnt really handle TransformType.All
|
|
public class TransformGizmoCustomGizmo : MonoBehaviour
|
|
{
|
|
public bool autoFindTransformGizmo = true;
|
|
public TransformGizmo transformGizmo;
|
|
|
|
public CustomTransformGizmos customTranslationGizmos = new CustomTransformGizmos();
|
|
public CustomTransformGizmos customRotationGizmos = new CustomTransformGizmos();
|
|
public CustomTransformGizmos customScaleGizmos = new CustomTransformGizmos();
|
|
|
|
public bool scaleBasedOnDistance = true;
|
|
public float scaleMultiplier = .4f;
|
|
|
|
public int gizmoLayer = 2; //2 is the ignoreRaycast layer. Set to whatever you want.
|
|
|
|
LayerMask mask;
|
|
|
|
void Awake()
|
|
{
|
|
if(transformGizmo == null && autoFindTransformGizmo)
|
|
{
|
|
transformGizmo = GameObject.FindObjectOfType<TransformGizmo>();
|
|
}
|
|
|
|
transformGizmo.manuallyHandleGizmo = true;
|
|
|
|
//Since we are using a mesh, rotating can get weird due to how the rotation method works,
|
|
//so we use a different rotation method that will let us rotate by acting like our custom rotation gizmo is a wheel.
|
|
//Can still give weird results depending on camera angle, but I think its more understanding for the user as to why its messing up.
|
|
transformGizmo.circularRotationMethod = true;
|
|
|
|
mask = LayerMask.GetMask(LayerMask.LayerToName(gizmoLayer));
|
|
|
|
customTranslationGizmos.Init(gizmoLayer);
|
|
customRotationGizmos.Init(gizmoLayer);
|
|
customScaleGizmos.Init(gizmoLayer);
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
transformGizmo.onCheckForSelectedAxis += CheckForSelectedAxis;
|
|
transformGizmo.onDrawCustomGizmo += OnDrawCustomGizmos;
|
|
}
|
|
void OnDisable()
|
|
{
|
|
transformGizmo.onCheckForSelectedAxis -= CheckForSelectedAxis;
|
|
transformGizmo.onDrawCustomGizmo -= OnDrawCustomGizmos;
|
|
}
|
|
|
|
void CheckForSelectedAxis()
|
|
{
|
|
ShowProperGizmoType();
|
|
|
|
if(Input.GetMouseButtonDown(0))
|
|
{
|
|
RaycastHit hitInfo;
|
|
if(Physics.Raycast(transformGizmo.myCamera.ScreenPointToRay(Input.mousePosition), out hitInfo, Mathf.Infinity, mask))
|
|
{
|
|
Axis selectedAxis = Axis.None;
|
|
TransformType type = transformGizmo.transformType;
|
|
|
|
if(selectedAxis == Axis.None && transformGizmo.TransformTypeContains(TransformType.Move))
|
|
{
|
|
selectedAxis = customTranslationGizmos.GetSelectedAxis(hitInfo.collider);
|
|
type = TransformType.Move;
|
|
}
|
|
if(selectedAxis == Axis.None && transformGizmo.TransformTypeContains(TransformType.Rotate))
|
|
{
|
|
selectedAxis = customRotationGizmos.GetSelectedAxis(hitInfo.collider);
|
|
type = TransformType.Rotate;
|
|
}
|
|
if(selectedAxis == Axis.None && transformGizmo.TransformTypeContains(TransformType.Scale))
|
|
{
|
|
selectedAxis = customScaleGizmos.GetSelectedAxis(hitInfo.collider);
|
|
type = TransformType.Scale;
|
|
}
|
|
|
|
transformGizmo.SetTranslatingAxis(type, selectedAxis);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OnDrawCustomGizmos()
|
|
{
|
|
if(transformGizmo.TranslatingTypeContains(TransformType.Move)) DrawCustomGizmo(customTranslationGizmos);
|
|
if(transformGizmo.TranslatingTypeContains(TransformType.Rotate)) DrawCustomGizmo(customRotationGizmos);
|
|
if(transformGizmo.TranslatingTypeContains(TransformType.Scale)) DrawCustomGizmo(customScaleGizmos);
|
|
}
|
|
|
|
void DrawCustomGizmo(CustomTransformGizmos customGizmo)
|
|
{
|
|
AxisInfo axisInfo = transformGizmo.GetAxisInfo();
|
|
customGizmo.SetAxis(axisInfo);
|
|
customGizmo.SetPosition(transformGizmo.pivotPoint);
|
|
|
|
Vector4 totalScaleMultiplier = Vector4.one;
|
|
if(scaleBasedOnDistance)
|
|
{
|
|
totalScaleMultiplier.w *= (scaleMultiplier * transformGizmo.GetDistanceMultiplier());
|
|
}
|
|
|
|
if(transformGizmo.transformingType == TransformType.Scale)
|
|
{
|
|
float totalScaleAmount = 1f + transformGizmo.totalScaleAmount;
|
|
if(transformGizmo.translatingAxis == Axis.Any) totalScaleMultiplier += (Vector4.one * totalScaleAmount);
|
|
else if(transformGizmo.translatingAxis == Axis.X) totalScaleMultiplier.x *= totalScaleAmount;
|
|
else if(transformGizmo.translatingAxis == Axis.Y) totalScaleMultiplier.y *= totalScaleAmount;
|
|
else if(transformGizmo.translatingAxis == Axis.Z) totalScaleMultiplier.z *= totalScaleAmount;
|
|
}
|
|
|
|
customGizmo.ScaleMultiply(totalScaleMultiplier);
|
|
}
|
|
|
|
void ShowProperGizmoType()
|
|
{
|
|
bool hasSelection = transformGizmo.mainTargetRoot != null;
|
|
customTranslationGizmos.SetEnable(hasSelection && transformGizmo.TranslatingTypeContains(TransformType.Move));
|
|
customRotationGizmos.SetEnable(hasSelection && transformGizmo.TranslatingTypeContains(TransformType.Rotate));
|
|
customScaleGizmos.SetEnable(hasSelection && transformGizmo.TranslatingTypeContains(TransformType.Scale));
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class CustomTransformGizmos
|
|
{
|
|
public Transform xAxisGizmo;
|
|
public Transform yAxisGizmo;
|
|
public Transform zAxisGizmo;
|
|
public Transform anyAxisGizmo;
|
|
|
|
Collider xAxisGizmoCollider;
|
|
Collider yAxisGizmoCollider;
|
|
Collider zAxisGizmoCollider;
|
|
Collider anyAxisGizmoCollider;
|
|
|
|
Vector3 originalXAxisScale;
|
|
Vector3 originalYAxisScale;
|
|
Vector3 originalZAxisScale;
|
|
Vector3 originalAnyAxisScale;
|
|
|
|
public void Init(int layer)
|
|
{
|
|
if(xAxisGizmo != null)
|
|
{
|
|
SetLayerRecursively(xAxisGizmo.gameObject, layer);
|
|
xAxisGizmoCollider = xAxisGizmo.GetComponentInChildren<Collider>();
|
|
originalXAxisScale = xAxisGizmo.localScale;
|
|
}
|
|
if(yAxisGizmo != null)
|
|
{
|
|
SetLayerRecursively(yAxisGizmo.gameObject, layer);
|
|
yAxisGizmoCollider = yAxisGizmo.GetComponentInChildren<Collider>();
|
|
originalYAxisScale = yAxisGizmo.localScale;
|
|
}
|
|
if(zAxisGizmo != null)
|
|
{
|
|
SetLayerRecursively(zAxisGizmo.gameObject, layer);
|
|
zAxisGizmoCollider = zAxisGizmo.GetComponentInChildren<Collider>();
|
|
originalZAxisScale = zAxisGizmo.localScale;
|
|
}
|
|
if(anyAxisGizmo != null)
|
|
{
|
|
SetLayerRecursively(anyAxisGizmo.gameObject, layer);
|
|
anyAxisGizmoCollider = anyAxisGizmo.GetComponentInChildren<Collider>();
|
|
originalAnyAxisScale = anyAxisGizmo.localScale;
|
|
}
|
|
}
|
|
|
|
public void SetEnable(bool enable)
|
|
{
|
|
if(xAxisGizmo != null && xAxisGizmo.gameObject.activeSelf != enable) xAxisGizmo.gameObject.SetActive(enable);
|
|
if(yAxisGizmo != null && yAxisGizmo.gameObject.activeSelf != enable) yAxisGizmo.gameObject.SetActive(enable);
|
|
if(zAxisGizmo != null && zAxisGizmo.gameObject.activeSelf != enable) zAxisGizmo.gameObject.SetActive(enable);
|
|
if(anyAxisGizmo != null && anyAxisGizmo.gameObject.activeSelf != enable) anyAxisGizmo.gameObject.SetActive(enable);
|
|
}
|
|
|
|
public void SetAxis(AxisInfo axisInfo)
|
|
{
|
|
Quaternion lookRotation = Quaternion.LookRotation(axisInfo.zDirection, axisInfo.yDirection);
|
|
|
|
if(xAxisGizmo != null) xAxisGizmo.rotation = lookRotation;
|
|
if(yAxisGizmo != null) yAxisGizmo.rotation = lookRotation;
|
|
if(zAxisGizmo != null) zAxisGizmo.rotation = lookRotation;
|
|
if(anyAxisGizmo != null) anyAxisGizmo.rotation = lookRotation;
|
|
}
|
|
|
|
public void SetPosition(Vector3 position)
|
|
{
|
|
if(xAxisGizmo != null) xAxisGizmo.position = position;
|
|
if(yAxisGizmo != null) yAxisGizmo.position = position;
|
|
if(zAxisGizmo != null) zAxisGizmo.position = position;
|
|
if(anyAxisGizmo != null) anyAxisGizmo.position = position;
|
|
}
|
|
|
|
public void ScaleMultiply(Vector4 scaleMultiplier)
|
|
{
|
|
if(xAxisGizmo != null) xAxisGizmo.localScale = Vector3.Scale(originalXAxisScale, new Vector3(scaleMultiplier.w + scaleMultiplier.x, scaleMultiplier.w, scaleMultiplier.w));
|
|
if(yAxisGizmo != null) yAxisGizmo.localScale = Vector3.Scale(originalYAxisScale, new Vector3(scaleMultiplier.w, scaleMultiplier.w + scaleMultiplier.y, scaleMultiplier.w));
|
|
if(zAxisGizmo != null) zAxisGizmo.localScale = Vector3.Scale(originalZAxisScale, new Vector3(scaleMultiplier.w, scaleMultiplier.w, scaleMultiplier.w + scaleMultiplier.z));
|
|
if(anyAxisGizmo != null) anyAxisGizmo.localScale = originalAnyAxisScale * scaleMultiplier.w;
|
|
}
|
|
|
|
public Axis GetSelectedAxis(Collider selectedCollider)
|
|
{
|
|
if(xAxisGizmoCollider != null && xAxisGizmoCollider == selectedCollider) return Axis.X;
|
|
if(yAxisGizmoCollider != null && yAxisGizmoCollider == selectedCollider) return Axis.Y;
|
|
if(zAxisGizmoCollider != null && zAxisGizmoCollider == selectedCollider) return Axis.Z;
|
|
if(anyAxisGizmoCollider != null && anyAxisGizmoCollider == selectedCollider) return Axis.Any;
|
|
|
|
return Axis.None;
|
|
}
|
|
|
|
void SetLayerRecursively(GameObject gameObject, int layer)
|
|
{
|
|
Transform[] selfAndChildren = gameObject.GetComponentsInChildren<Transform>(true);
|
|
|
|
for(int i = 0; i < selfAndChildren.Length; i++)
|
|
{
|
|
selfAndChildren[i].gameObject.layer = layer;
|
|
}
|
|
}
|
|
}
|
|
}
|