chore: sync workspace state
This commit is contained in:
283
参考/TransformGizmo/Scripts/DirectController.cs
Normal file
283
参考/TransformGizmo/Scripts/DirectController.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class DirectController
|
||||
{
|
||||
private RuntimeTranslateGizmo translateGizmo;
|
||||
private RuntimeRotateGizmo rotateGizmo;
|
||||
private SelectDetector selectDetector;
|
||||
private GameObject targetObject;
|
||||
|
||||
private Material outlineMaterial;
|
||||
private Color orangeOutline = new Color(1, 0.5f, 0, 1);
|
||||
private Color blueOutline = new Color(0, 0, 1, 1);
|
||||
|
||||
private enum GizmoState { TRANSLATE, ROTATE }
|
||||
private GizmoState gizmoState = GizmoState.TRANSLATE;
|
||||
|
||||
|
||||
public void Initialize(SelectDetector selectDetector)
|
||||
{
|
||||
//OutLine Shader Initialize
|
||||
Shader outlineShader = Shader.Find("Custom/Outline");
|
||||
outlineMaterial = new Material(outlineShader);
|
||||
|
||||
//SelectDetector Initialize
|
||||
this.selectDetector = selectDetector;
|
||||
}
|
||||
|
||||
public void InitializeGizmo()
|
||||
{
|
||||
//Gizmo Initialize
|
||||
translateGizmo = new RuntimeTranslateGizmo();
|
||||
rotateGizmo = new RuntimeRotateGizmo();
|
||||
translateGizmo.Initialize();
|
||||
rotateGizmo.Initialize();
|
||||
selectDetector.AddGizmos(translateGizmo.gizmo);
|
||||
selectDetector.AddGizmos(rotateGizmo.gizmo);
|
||||
}
|
||||
|
||||
|
||||
public void Update()
|
||||
{
|
||||
//Object Select Update
|
||||
//Select by cursor when the cursor is not on ui panels.
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
SelectUpdateByCursor(selectDetector.detectedObject);
|
||||
}
|
||||
|
||||
|
||||
//Gizmo Select Update
|
||||
if (targetObject)
|
||||
{
|
||||
GizmoSelectUpdate();
|
||||
}
|
||||
|
||||
//Gizmo Update
|
||||
translateGizmo.Update();
|
||||
rotateGizmo.Update();
|
||||
}
|
||||
|
||||
private void SelectUpdateByCursor(GameObject selectedObject)
|
||||
{
|
||||
//Select
|
||||
if (selectedObject != null)
|
||||
{
|
||||
//The First Select
|
||||
if (targetObject == null)
|
||||
{
|
||||
//Select the TopMost Parent GameObject
|
||||
targetObject = GetTopmostParent(selectedObject);
|
||||
AddOutlines(targetObject, blueOutline);
|
||||
EnableTargetGizmo();
|
||||
}
|
||||
//The Second Select
|
||||
else
|
||||
{
|
||||
if(selectedObject != targetObject)
|
||||
{
|
||||
GameObject parent = GetTopmostParent(selectedObject);
|
||||
if (parent == targetObject)
|
||||
{
|
||||
//Select Child of the TopMost Parent GameObject(Selected the TopMost Parent GameObject before)
|
||||
RemoveOutlines(targetObject);
|
||||
targetObject = selectedObject;
|
||||
AddOutLine(targetObject, orangeOutline);
|
||||
EnableTargetGizmo();
|
||||
}
|
||||
else if (parent == GetTopmostParent(targetObject))
|
||||
{
|
||||
//Select Other Child of the TopMost Parent GameObject(Selected one child of the TopMost Parent GameObject before)
|
||||
RemoveOutLine(targetObject);
|
||||
targetObject = selectedObject;
|
||||
AddOutLine(targetObject, orangeOutline);
|
||||
EnableTargetGizmo();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Select Other TopMost Parent GameObject
|
||||
RemoveOutlines(targetObject);
|
||||
targetObject = parent;
|
||||
AddOutlines(targetObject, blueOutline);
|
||||
EnableTargetGizmo();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveOutlines(targetObject);
|
||||
AddOutLine(targetObject, orangeOutline);
|
||||
}
|
||||
}
|
||||
}
|
||||
//UnSelect
|
||||
else if (selectedObject == null && selectDetector.detectedGizmo == null)
|
||||
{
|
||||
if (targetObject)
|
||||
{
|
||||
RemoveOutlines(targetObject);
|
||||
targetObject = null;
|
||||
}
|
||||
if (translateGizmo.enabled)
|
||||
{
|
||||
translateGizmo.DisableGizmo();
|
||||
}
|
||||
if (rotateGizmo.enabled)
|
||||
{
|
||||
rotateGizmo.DisableGizmo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void GizmoSelectUpdate()
|
||||
{
|
||||
//Translate
|
||||
if (Input.GetKeyDown(KeyCode.W))
|
||||
{
|
||||
ChangeGizmoToTranslate();
|
||||
}
|
||||
if (translateGizmo.enabled)
|
||||
{
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
GameObject selectedGizmo = selectDetector.detectedGizmo;
|
||||
if (selectedGizmo != null)
|
||||
{
|
||||
translateGizmo.OnSelect(selectedGizmo.name);
|
||||
}
|
||||
}
|
||||
else if (Input.GetMouseButtonUp(0))
|
||||
{
|
||||
translateGizmo.OnUnSelect();
|
||||
}
|
||||
}
|
||||
|
||||
//Rotate
|
||||
if (Input.GetKeyDown(KeyCode.E))
|
||||
{
|
||||
ChangeGizmoToRotate();
|
||||
}
|
||||
if (rotateGizmo.enabled)
|
||||
{
|
||||
GameObject selectedGizmo = selectDetector.detectedGizmo;
|
||||
if (selectedGizmo != null)
|
||||
{
|
||||
rotateGizmo.SphereRenderUpdate(selectedGizmo.name);
|
||||
if (Input.GetMouseButtonDown(0))
|
||||
{
|
||||
rotateGizmo.OnSelect(selectedGizmo.name);
|
||||
}
|
||||
}
|
||||
else { rotateGizmo.SphereRenderUpdate(""); }
|
||||
if (Input.GetMouseButtonUp(0))
|
||||
{
|
||||
rotateGizmo.OnUnSelect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnableTargetGizmo()
|
||||
{
|
||||
if (targetObject == null) { return; }
|
||||
switch (gizmoState)
|
||||
{
|
||||
case GizmoState.TRANSLATE:
|
||||
translateGizmo.EnableGizmo(targetObject);
|
||||
break;
|
||||
case GizmoState.ROTATE:
|
||||
rotateGizmo.EnableGizmo(targetObject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private GameObject GetTopmostParent(GameObject gameObject)
|
||||
{
|
||||
GameObject current = gameObject;
|
||||
while (current.transform.parent != null && !current.transform.parent.gameObject.name.Equals("Factory"))
|
||||
{
|
||||
current = current.transform.parent.gameObject;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
private void AddOutLine(GameObject gameObject, Color color)
|
||||
{
|
||||
Renderer renderer = gameObject.GetComponent<Renderer>();
|
||||
if (renderer != null)
|
||||
{
|
||||
outlineMaterial.SetColor("_OutlineColor", color);
|
||||
List<Material> materials = renderer.materials.ToList<Material>();
|
||||
if(!materials.Contains(outlineMaterial))
|
||||
{
|
||||
materials.Add(outlineMaterial);
|
||||
renderer.materials = materials.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveOutLine(GameObject gameObject)
|
||||
{
|
||||
Renderer renderer = gameObject.GetComponent<Renderer>();
|
||||
if (renderer != null)
|
||||
{
|
||||
List<Material> materials = renderer.materials.ToList<Material>();
|
||||
foreach (var material in materials)
|
||||
{
|
||||
if (material.shader.name == outlineMaterial.shader.name)
|
||||
{
|
||||
materials.Remove(material);
|
||||
break;
|
||||
}
|
||||
}
|
||||
renderer.materials = materials.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddOutlines(GameObject gameObject, Color color)
|
||||
{
|
||||
foreach (Transform child_transform in gameObject.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
AddOutLine(child, color);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveOutlines(GameObject gameObject)
|
||||
{
|
||||
foreach (Transform child_transform in gameObject.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
RemoveOutLine(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ChangeGizmoToTranslate()
|
||||
{
|
||||
gizmoState = GizmoState.TRANSLATE;
|
||||
if (!translateGizmo.enabled)
|
||||
{
|
||||
EnableTargetGizmo();
|
||||
}
|
||||
if (rotateGizmo.enabled)
|
||||
{
|
||||
rotateGizmo.DisableGizmo();
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeGizmoToRotate()
|
||||
{
|
||||
gizmoState = GizmoState.ROTATE;
|
||||
if (!rotateGizmo.enabled)
|
||||
{
|
||||
EnableTargetGizmo();
|
||||
}
|
||||
if (translateGizmo.enabled)
|
||||
{
|
||||
translateGizmo.DisableGizmo();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
参考/TransformGizmo/Scripts/DirectController.cs.meta
Normal file
11
参考/TransformGizmo/Scripts/DirectController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 019a98c1111d28a42ab5ebc611903c4f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62
参考/TransformGizmo/Scripts/RuntimeGizmo.cs
Normal file
62
参考/TransformGizmo/Scripts/RuntimeGizmo.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class RuntimeGizmo
|
||||
{
|
||||
public GameObject gizmo;
|
||||
protected GameObject prefab;
|
||||
public bool enabled = false;
|
||||
|
||||
protected GameObject target;
|
||||
|
||||
protected List<string> handleNames;
|
||||
|
||||
protected float scaleRate = 1.0f;
|
||||
|
||||
public virtual void Initialize() { }
|
||||
|
||||
public virtual List<GameObject> RegisterObjectsToSelectDetector() { return null; } //这样可以让Gizmo的指定组件可以使用TransformGizmo的操纵
|
||||
|
||||
public virtual void Update() { }
|
||||
|
||||
protected virtual void RenderUpdate()
|
||||
{
|
||||
//Gizmo Scale Update
|
||||
Vector3 cameraPosition = Camera.main.transform.position;
|
||||
Vector3 gizmoPosition = gizmo.transform.position;
|
||||
float distance = (cameraPosition - gizmoPosition).magnitude;
|
||||
gizmo.GetComponent<Transform>().localScale = new Vector3(distance, distance, distance);
|
||||
}
|
||||
|
||||
protected virtual void FollowUpdate() { }
|
||||
|
||||
protected void HideBeindCamera()
|
||||
{
|
||||
if (gizmo.activeSelf) { gizmo.SetActive(false); }
|
||||
gizmo.GetComponent<Transform>().position = Camera.main.transform.position - Camera.main.transform.forward * 10;
|
||||
}
|
||||
|
||||
public virtual void EnableGizmo(GameObject target)
|
||||
{
|
||||
enabled = true;
|
||||
this.target = target;
|
||||
if (!gizmo.activeSelf) { gizmo.SetActive(true); }
|
||||
gizmo.GetComponent<Transform>().position = target.transform.position;
|
||||
gizmo.GetComponent<Transform>().rotation = target.transform.rotation;
|
||||
}
|
||||
|
||||
public virtual void DisableGizmo()
|
||||
{
|
||||
enabled = false;
|
||||
this.target = null;
|
||||
HideBeindCamera();
|
||||
}
|
||||
public virtual void OnSelect(string handleName) { }
|
||||
|
||||
public virtual void OnUnSelect() { }
|
||||
protected virtual void OnSelecting() { }
|
||||
|
||||
protected virtual void ChangeRenderOnSelect() { }
|
||||
protected virtual void ChangeRenderOnUnSelect() { }
|
||||
}
|
||||
11
参考/TransformGizmo/Scripts/RuntimeGizmo.cs.meta
Normal file
11
参考/TransformGizmo/Scripts/RuntimeGizmo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5457f7831add57d4c931055617ae1e43
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
284
参考/TransformGizmo/Scripts/RuntimeRotateGizmo.cs
Normal file
284
参考/TransformGizmo/Scripts/RuntimeRotateGizmo.cs
Normal file
@@ -0,0 +1,284 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class RuntimeRotateGizmo : RuntimeTransformGizmo
|
||||
{
|
||||
private string prefabPath = "Prefabs/RotateGizmo";
|
||||
|
||||
private GameObject rotatePlane;
|
||||
private GameObject rotatePlaneHandle;
|
||||
private GameObject rotateXYZ;
|
||||
private GameObject rotateX;
|
||||
private GameObject rotateY;
|
||||
private GameObject rotateZ;
|
||||
private GameObject rotateSphere;
|
||||
enum RotateSelectState { X, Y, Z, Plane, Sphere, UnSelected }
|
||||
RotateSelectState rotateSelectState;
|
||||
|
||||
//Offset
|
||||
private float XYZOffsetOnSelect;
|
||||
private Vector2 sphereOffsetOnSelect;
|
||||
|
||||
//Rate
|
||||
private float XYZRotateRate = 0.1f;
|
||||
private float planeRotateRate = 0.1f;
|
||||
private float sphereRotateRate = 0.1f;
|
||||
|
||||
private Quaternion rotationOnSelect;
|
||||
private Vector3 viewLocalDirectionX;
|
||||
private Vector3 viewLocalDirectionY;
|
||||
private Vector3 viewLocalDirectionZ;
|
||||
|
||||
private Quaternion lastTargetRotation;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
//Base Initialize
|
||||
base.Initialize();
|
||||
|
||||
//Material Initialize
|
||||
redMaterial = Resources.Load<Material>("Materials/RotateRed");
|
||||
greenMaterial = Resources.Load<Material>("Materials/RotateGreen");
|
||||
blueMaterial = Resources.Load<Material>("Materials/RotateBlue");
|
||||
|
||||
////Prefab Initialize
|
||||
prefab = Resources.Load<GameObject>(prefabPath);
|
||||
if (prefab != null)
|
||||
{
|
||||
gizmo = Object.Instantiate(prefab) as GameObject;
|
||||
}
|
||||
HideBeindCamera();
|
||||
|
||||
//Component Initialize
|
||||
rotatePlane = gizmo.GetComponent<Transform>().Find("RotatePlane").gameObject;
|
||||
rotatePlaneHandle = rotatePlane.GetComponent<Transform>().Find("RotatePlaneHandle").gameObject;
|
||||
rotateXYZ = gizmo.GetComponent<Transform>().Find("RotateXYZ").gameObject;
|
||||
rotateX = rotateXYZ.GetComponent<Transform>().Find("RotateX").gameObject;
|
||||
rotateY = rotateXYZ.GetComponent<Transform>().Find("RotateY").gameObject;
|
||||
rotateZ = rotateXYZ.GetComponent<Transform>().Find("RotateZ").gameObject;
|
||||
rotateSphere = gizmo.GetComponent<Transform>().Find("RotateSphere").gameObject;
|
||||
|
||||
//Other Initialzie
|
||||
rotateSelectState = RotateSelectState.UnSelected;
|
||||
rotateSphere.GetComponent<MeshRenderer>().material.SetFloat("_AlphaScale", 0.2f);
|
||||
scaleRate = 160.0f;
|
||||
handleNames = new List<string> { "RotatePlaneHandle", "RotatePlaneDetect", "RotateXDetect", "RotateX", "RotateYDetect", "RotateY", "RotateZDetect", "RotateZ", "RotateSphere" };
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
//hide
|
||||
if(enabled)
|
||||
{
|
||||
//Render Update
|
||||
RenderUpdate();
|
||||
//Follow Update
|
||||
FollowUpdate();
|
||||
//Interaction Update
|
||||
if (rotateSelectState != RotateSelectState.UnSelected)
|
||||
{
|
||||
OnSelecting();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HideBeindCamera();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void RenderUpdate()
|
||||
{
|
||||
//Base Update
|
||||
base.RenderUpdate();
|
||||
gizmo.GetComponent<Transform>().localScale /= scaleRate;
|
||||
|
||||
//Rotate Plane Update
|
||||
Vector3 viewDirection = -Camera.main.transform.forward;
|
||||
Quaternion rotatePlaneRotation = Quaternion.LookRotation(viewDirection, Vector3.up);
|
||||
rotatePlane.GetComponent<Transform>().rotation = rotatePlaneRotation;
|
||||
|
||||
//Clip Plane Update
|
||||
Vector3 normalizedNormal = viewDirection.normalized;
|
||||
Vector3 targetPosition = gizmo.GetComponent<Transform>().position;
|
||||
float D = -Vector3.Dot(targetPosition, normalizedNormal);
|
||||
Vector4 clipPlane = new Vector4(normalizedNormal.x, normalizedNormal.y, normalizedNormal.z, D);
|
||||
redMaterial.SetVector("_ClipPlane", clipPlane);
|
||||
greenMaterial.SetVector("_ClipPlane", clipPlane);
|
||||
blueMaterial.SetVector("_ClipPlane", clipPlane);
|
||||
}
|
||||
|
||||
public override void EnableGizmo(GameObject target)
|
||||
{
|
||||
base.EnableGizmo(target);
|
||||
lastTargetRotation = target.GetComponent<Transform>().rotation;
|
||||
}
|
||||
|
||||
protected override void FollowUpdate()
|
||||
{
|
||||
if (target == null) { return; }
|
||||
//Position Follow
|
||||
gizmo.GetComponent<Transform>().position = target.GetComponent<Transform>().position;
|
||||
target.GetComponent<Transform>().rotation = gizmo.GetComponent<Transform>().rotation;
|
||||
|
||||
//Rotation Follow
|
||||
Quaternion targetRotation = target.GetComponent<Transform>().rotation;
|
||||
if (targetRotation != lastTargetRotation)
|
||||
{
|
||||
gizmo.GetComponent<Transform>().rotation = targetRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
target.GetComponent<Transform>().rotation = gizmo.GetComponent<Transform>().rotation;
|
||||
}
|
||||
lastTargetRotation = targetRotation;
|
||||
}
|
||||
|
||||
public override void OnSelect(string handleName)
|
||||
{
|
||||
if (!handleNames.Contains(handleName)) { return; }
|
||||
rotationOnSelect = gizmo.GetComponent<Transform>().rotation;
|
||||
Vector3 gizmoPosition = gizmo.GetComponent<Transform>().position;
|
||||
Vector2 mousePositionOnSelect = Input.mousePosition;
|
||||
gizmoXYZScreenStart = Camera.main.WorldToScreenPoint(gizmoPosition);
|
||||
if (handleName.Contains("X") || handleName.Contains("Y") || handleName.Contains("Z")) //RotateX RotateY RotateZ
|
||||
{
|
||||
Vector3 gizmoEndPosition = new Vector3();
|
||||
switch (handleName)
|
||||
{
|
||||
case "RotateX":
|
||||
case "RotateXDetect":
|
||||
rotateSelectState = RotateSelectState.X;
|
||||
gizmoEndPosition = gizmoPosition + gizmo.GetComponent<Transform>().right;
|
||||
break;
|
||||
case "RotateY":
|
||||
case "RotateYDetect":
|
||||
rotateSelectState = RotateSelectState.Y;
|
||||
gizmoEndPosition = gizmoPosition + gizmo.GetComponent<Transform>().up;
|
||||
break;
|
||||
case "RotateZ":
|
||||
case "RotateZDetect":
|
||||
rotateSelectState = RotateSelectState.Z;
|
||||
gizmoEndPosition = gizmoPosition + gizmo.GetComponent<Transform>().forward;
|
||||
break;
|
||||
}
|
||||
Vector2 gizmoXYZScreenEnd = Camera.main.WorldToScreenPoint(gizmoEndPosition);
|
||||
gizmoXYZScreenDirection = (gizmoXYZScreenEnd - gizmoXYZScreenStart).normalized;
|
||||
Vector2 gizmoXYZXcreenVerticalDirection = new Vector2(gizmoXYZScreenDirection.y, -gizmoXYZScreenDirection.x);
|
||||
Vector2 mouseVector = mousePositionOnSelect - gizmoXYZScreenStart;
|
||||
XYZOffsetOnSelect = Vector2.Dot(mouseVector, gizmoXYZXcreenVerticalDirection);
|
||||
}
|
||||
else if (handleName == "RotatePlaneDetect" || handleName == "RotatePlaneHandle")
|
||||
{
|
||||
rotateSelectState = RotateSelectState.Plane;
|
||||
gizmoXYZScreenDirection = (mousePositionOnSelect - gizmoXYZScreenStart).normalized;
|
||||
XYZOffsetOnSelect = 0.0f;
|
||||
Vector3 viewDirectionZ = Camera.main.transform.forward;
|
||||
viewLocalDirectionZ = (gizmo.GetComponent<Transform>().worldToLocalMatrix * viewDirectionZ).normalized;
|
||||
}
|
||||
else if(handleName == "RotateSphere")
|
||||
{
|
||||
rotateSelectState = RotateSelectState.Sphere;
|
||||
sphereOffsetOnSelect = mousePositionOnSelect - gizmoXYZScreenStart;
|
||||
Vector3 viewDirectionX = Camera.main.transform.right;
|
||||
viewLocalDirectionX = (gizmo.GetComponent<Transform>().worldToLocalMatrix * viewDirectionX).normalized;
|
||||
Vector3 viewDirectionY = Camera.main.transform.up;
|
||||
viewLocalDirectionY = (gizmo.GetComponent<Transform>().worldToLocalMatrix * viewDirectionY).normalized;
|
||||
}
|
||||
ChangeRenderOnSelect();
|
||||
}
|
||||
|
||||
public override void OnUnSelect()
|
||||
{
|
||||
if (rotateSelectState == RotateSelectState.UnSelected) { return; }
|
||||
rotateSelectState = RotateSelectState.UnSelected;
|
||||
//Render
|
||||
ChangeRenderOnUnSelect();
|
||||
}
|
||||
|
||||
protected override void OnSelecting()
|
||||
{
|
||||
Vector3 gizmoPosition = gizmo.GetComponent<Transform>().position;
|
||||
Vector2 mousePosition = Input.mousePosition;
|
||||
Vector2 mouseVector = mousePosition - gizmoXYZScreenStart;
|
||||
if (rotateSelectState <= RotateSelectState.Plane)
|
||||
{
|
||||
//Rotate 90 degrees clockwise
|
||||
Vector2 gizmoXYZScreenVerticalDirection = new Vector2(gizmoXYZScreenDirection.y, -gizmoXYZScreenDirection.x);
|
||||
float dragDistance = Vector2.Dot(mouseVector, gizmoXYZScreenVerticalDirection) - XYZOffsetOnSelect;
|
||||
switch (rotateSelectState)
|
||||
{
|
||||
case RotateSelectState.X:
|
||||
gizmo.GetComponent<Transform>().rotation = rotationOnSelect * Quaternion.Euler(-Vector3.right * dragDistance * XYZRotateRate);
|
||||
break;
|
||||
case RotateSelectState.Y:
|
||||
gizmo.GetComponent<Transform>().rotation = rotationOnSelect * Quaternion.Euler(-Vector3.up * dragDistance * XYZRotateRate);
|
||||
break;
|
||||
case RotateSelectState.Z:
|
||||
gizmo.GetComponent<Transform>().rotation = rotationOnSelect * Quaternion.Euler(-Vector3.forward * dragDistance * XYZRotateRate);
|
||||
break;
|
||||
case RotateSelectState.Plane:
|
||||
gizmo.GetComponent<Transform>().rotation = rotationOnSelect * Quaternion.Euler(-viewLocalDirectionZ * dragDistance * planeRotateRate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (rotateSelectState == RotateSelectState.Sphere)
|
||||
{
|
||||
Vector2 dragVector = mouseVector - sphereOffsetOnSelect;
|
||||
gizmo.GetComponent<Transform>().rotation = rotationOnSelect * Quaternion.Euler(-viewLocalDirectionY * dragVector.x * sphereRotateRate);
|
||||
gizmo.GetComponent<Transform>().rotation = gizmo.transform.rotation * Quaternion.Euler(viewLocalDirectionX * dragVector.y * sphereRotateRate);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeRenderOnSelect()
|
||||
{
|
||||
switch (rotateSelectState)
|
||||
{
|
||||
case RotateSelectState.X:
|
||||
rotatePlaneHandle.SetActive(false);
|
||||
rotateX.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
break;
|
||||
case RotateSelectState.Y:
|
||||
rotatePlaneHandle.SetActive(false);
|
||||
rotateY.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
break;
|
||||
case RotateSelectState.Z:
|
||||
rotatePlaneHandle.SetActive(false);
|
||||
rotateZ.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
break;
|
||||
case RotateSelectState.Plane:
|
||||
rotateX.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
rotateY.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
rotateZ.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
rotatePlaneHandle.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
break;
|
||||
case RotateSelectState.Sphere:
|
||||
rotateSphere.GetComponent<MeshRenderer>().material.SetFloat("_AlphaScale", 0.4f);
|
||||
rotateSphere.SetActive(true);
|
||||
rotatePlaneHandle.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeRenderOnUnSelect()
|
||||
{
|
||||
rotatePlaneHandle.SetActive(true);
|
||||
rotateX.SetActive(true);
|
||||
rotateY.SetActive(true);
|
||||
rotateZ.SetActive(true);
|
||||
rotatePlaneHandle.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
rotateX.GetComponent<MeshRenderer>().material = redMaterial;
|
||||
rotateY.GetComponent<MeshRenderer>().material = greenMaterial;
|
||||
rotateZ.GetComponent<MeshRenderer>().material = blueMaterial;
|
||||
rotateSphere.GetComponent<MeshRenderer>().material.SetFloat("_AlphaScale", 0.2f);
|
||||
}
|
||||
|
||||
public void SphereRenderUpdate(string handleName)
|
||||
{
|
||||
if (rotateSelectState != RotateSelectState.UnSelected) { return; }
|
||||
rotateSphere.SetActive(handleName.Equals("RotateSphere"));
|
||||
}
|
||||
}
|
||||
11
参考/TransformGizmo/Scripts/RuntimeRotateGizmo.cs.meta
Normal file
11
参考/TransformGizmo/Scripts/RuntimeRotateGizmo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df5ef9b135776ed44bdf6f431703cc5d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
109
参考/TransformGizmo/Scripts/RuntimeTransformGizmo.cs
Normal file
109
参考/TransformGizmo/Scripts/RuntimeTransformGizmo.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
public class RuntimeTransformGizmo : RuntimeGizmo
|
||||
{
|
||||
protected Material redMaterial;
|
||||
protected Material greenMaterial;
|
||||
protected Material blueMaterial;
|
||||
protected Material yellowMaterial;
|
||||
protected Material whiteMaterial;
|
||||
|
||||
//the vector projected by Gizmo XYZ axis on the screen
|
||||
protected Vector2 gizmoXYZScreenStart;
|
||||
protected Vector2 gizmoXYZScreenDirection;
|
||||
|
||||
protected enum Axis { X, Y, Z }
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
//Material Initialize
|
||||
yellowMaterial = Resources.Load<Material>("Materials/Yellow");
|
||||
whiteMaterial = Resources.Load<Material>("Materials/White");
|
||||
}
|
||||
public override void Update() { }
|
||||
|
||||
protected override void RenderUpdate()
|
||||
{
|
||||
base.RenderUpdate();
|
||||
}
|
||||
|
||||
protected override void FollowUpdate() { }
|
||||
|
||||
public override void EnableGizmo(GameObject target)
|
||||
{
|
||||
base.EnableGizmo(target);
|
||||
}
|
||||
|
||||
public override void DisableGizmo()
|
||||
{
|
||||
base.DisableGizmo();
|
||||
}
|
||||
public override void OnSelect(string handleName) { }
|
||||
|
||||
public override void OnUnSelect() { }
|
||||
protected override void OnSelecting() { }
|
||||
|
||||
protected override void ChangeRenderOnSelect() { }
|
||||
protected override void ChangeRenderOnUnSelect() { }
|
||||
|
||||
|
||||
protected Vector3? GetIntersectionPlaneAndLine(Axis axis, Vector3 lineStart, Vector3 lineDirection)
|
||||
{
|
||||
Vector4 plane = GetPlane(axis);
|
||||
Vector3 planeNormal = new Vector3(plane.x, plane.y, plane.z);
|
||||
Vector3? intersectionPoint = GetIntersectionPlaneAndLine(planeNormal, plane.w, lineStart, lineDirection);
|
||||
return intersectionPoint;
|
||||
}
|
||||
|
||||
protected Vector3? GetIntersectionPlaneAndLine(Vector3 planeNormal, float d, Vector3 lineStart, Vector3 lineDirection)
|
||||
{
|
||||
// Plane: Ax + By + Cz + D = 0
|
||||
// Line: P(t) = P0 + tD
|
||||
|
||||
float a = planeNormal.x;
|
||||
float b = planeNormal.y;
|
||||
float c = planeNormal.z;
|
||||
|
||||
float dx = lineDirection.x;
|
||||
float dy = lineDirection.y;
|
||||
float dz = lineDirection.z;
|
||||
|
||||
float denominator = a * dx + b * dy + c * dz;
|
||||
|
||||
if (Math.Abs(denominator) < 0.0001f) return null;
|
||||
|
||||
float t = -(a * lineStart.x + b * lineStart.y + c * lineStart.z + d) / denominator;
|
||||
|
||||
Vector3 intersectionPoint = lineStart + t * lineDirection;
|
||||
return intersectionPoint;
|
||||
}
|
||||
|
||||
protected Vector4 GetPlane(Axis axis)
|
||||
{
|
||||
Vector4 plane = new Vector4();
|
||||
Vector3 normal = new Vector3();
|
||||
switch (axis)
|
||||
{
|
||||
case Axis.X:
|
||||
normal = gizmo.GetComponent<Transform>().right;
|
||||
break;
|
||||
case Axis.Y:
|
||||
normal = gizmo.GetComponent<Transform>().up;
|
||||
break;
|
||||
case Axis.Z:
|
||||
normal = gizmo.GetComponent<Transform>().forward;
|
||||
break;
|
||||
}
|
||||
plane.x = normal.x;
|
||||
plane.y = normal.y;
|
||||
plane.z = normal.z;
|
||||
Vector3 position = gizmo.GetComponent<Transform>().position;
|
||||
plane.w = -Vector3.Dot(position,normal);
|
||||
return plane;
|
||||
}
|
||||
}
|
||||
11
参考/TransformGizmo/Scripts/RuntimeTransformGizmo.cs.meta
Normal file
11
参考/TransformGizmo/Scripts/RuntimeTransformGizmo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f10630399e8d77e46960c12087ee2b69
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
336
参考/TransformGizmo/Scripts/RuntimeTranslateGizmo.cs
Normal file
336
参考/TransformGizmo/Scripts/RuntimeTranslateGizmo.cs
Normal file
@@ -0,0 +1,336 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class RuntimeTranslateGizmo : RuntimeTransformGizmo
|
||||
{
|
||||
private string prefabPath = "Prefabs/TranslateGizmo";
|
||||
|
||||
private GameObject translateX;
|
||||
private GameObject translateY;
|
||||
private GameObject translateZ;
|
||||
private GameObject translatePlaneX;
|
||||
private GameObject translatePlaneY;
|
||||
private GameObject translatePlaneZ;
|
||||
private float translatePlaneOffset = 0.15f;
|
||||
private Vector3 screenCenterPosition;
|
||||
|
||||
enum TranslateSelectState { X, Y, Z, PlaneX, PlaneY, PlaneZ, UnSelected }
|
||||
TranslateSelectState translateSelectState;
|
||||
|
||||
private float XYZOffsetOnSelect;
|
||||
private Vector2 gizmoPlaneOffset;
|
||||
|
||||
private Vector3 lastTargetPosition;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
//Base Initialize
|
||||
base.Initialize();
|
||||
|
||||
//Material Initialize
|
||||
redMaterial = Resources.Load<Material>("Materials/Red");
|
||||
greenMaterial = Resources.Load<Material>("Materials/Green");
|
||||
blueMaterial = Resources.Load<Material>("Materials/Blue");
|
||||
|
||||
|
||||
//Prefab Initialize
|
||||
prefab = Resources.Load<GameObject>(prefabPath);
|
||||
if (prefab != null)
|
||||
{
|
||||
gizmo = Object.Instantiate(prefab) as GameObject;
|
||||
}
|
||||
HideBeindCamera();
|
||||
|
||||
//Component Initialize
|
||||
translateX = gizmo.GetComponent<Transform>().Find("TranslateX").gameObject;
|
||||
translateY = gizmo.GetComponent<Transform>().Find("TranslateY").gameObject;
|
||||
translateZ = gizmo.GetComponent<Transform>().Find("TranslateZ").gameObject;
|
||||
translatePlaneX = gizmo.GetComponent<Transform>().Find("TranslatePlaneX").gameObject;
|
||||
translatePlaneY = gizmo.GetComponent<Transform>().Find("TranslatePlaneY").gameObject;
|
||||
translatePlaneZ = gizmo.GetComponent<Transform>().Find("TranslatePlaneZ").gameObject;
|
||||
|
||||
//Other Initialzie
|
||||
translateSelectState = TranslateSelectState.UnSelected;
|
||||
screenCenterPosition = new Vector3(Screen.width * 0.5f, Screen.height * 0.5f, 0);
|
||||
scaleRate = 6.0f;
|
||||
handleNames = new List<string> { "TranslateX", "TranslateY", "TranslateZ", "TranslatePlaneX", "TranslatePlaneY", "TranslatePlaneZ" };
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
//hide
|
||||
if (enabled && target)
|
||||
{
|
||||
//Render Update
|
||||
RenderUpdate();
|
||||
//Follow Update
|
||||
FollowUpdate();
|
||||
//Interaction Update
|
||||
if (translateSelectState != TranslateSelectState.UnSelected)
|
||||
{
|
||||
OnSelecting();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HideBeindCamera();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RenderUpdate()
|
||||
{
|
||||
//Base Update
|
||||
base.RenderUpdate();
|
||||
gizmo.GetComponent<Transform>().localScale /= scaleRate;
|
||||
|
||||
//Translate Plane Update
|
||||
Vector3 viewPosition = Camera.main.ScreenToWorldPoint(screenCenterPosition);
|
||||
Vector3 viewDirection = viewPosition - gizmo.GetComponent<Transform>().position;
|
||||
Vector3 viewLocalDirection = gizmo.GetComponent<Transform>().worldToLocalMatrix.MultiplyVector(viewDirection);
|
||||
|
||||
int directionX = viewLocalDirection.x > 0 ? 1 : -1;
|
||||
int directionY = viewLocalDirection.y > 0 ? 1 : -1;
|
||||
int directionZ = viewLocalDirection.z > 0 ? 1 : -1;
|
||||
|
||||
|
||||
translatePlaneX.GetComponent<Transform>().localPosition = Vector3.zero;
|
||||
translatePlaneX.GetComponent<Transform>().localPosition += directionY * Vector3.up * translatePlaneOffset;
|
||||
translatePlaneX.GetComponent<Transform>().localPosition += directionZ * Vector3.forward * translatePlaneOffset;
|
||||
|
||||
translatePlaneY.GetComponent<Transform>().localPosition = Vector3.zero;
|
||||
translatePlaneY.GetComponent<Transform>().localPosition += directionX * Vector3.right * translatePlaneOffset;
|
||||
translatePlaneY.GetComponent<Transform>().localPosition += directionZ * Vector3.forward * translatePlaneOffset;
|
||||
|
||||
translatePlaneZ.GetComponent<Transform>().localPosition = Vector3.zero;
|
||||
translatePlaneZ.GetComponent<Transform>().localPosition += directionX * Vector3.right * translatePlaneOffset;
|
||||
translatePlaneZ.GetComponent<Transform>().localPosition += directionY * Vector3.up * translatePlaneOffset;
|
||||
}
|
||||
|
||||
protected override void FollowUpdate()
|
||||
{
|
||||
if (target == null) { return; }
|
||||
//Rotation Follow
|
||||
Vector3 targetPosition = target.GetComponent<Transform>().position;
|
||||
if (targetPosition != lastTargetPosition)
|
||||
{
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
target.GetComponent<Transform>().position = gizmo.GetComponent<Transform>().position;
|
||||
}
|
||||
lastTargetPosition = targetPosition;
|
||||
|
||||
//Rotation Follow
|
||||
gizmo.GetComponent<Transform>().rotation = target.GetComponent<Transform>().rotation;
|
||||
|
||||
}
|
||||
|
||||
public override void EnableGizmo(GameObject target)
|
||||
{
|
||||
base.EnableGizmo(target);
|
||||
lastTargetPosition = target.GetComponent<Transform>().position;
|
||||
}
|
||||
|
||||
|
||||
public override void OnSelect(string handleName)
|
||||
{
|
||||
if (!handleNames.Contains(handleName)) { return; }
|
||||
Vector3 gizmoPosition = gizmo.GetComponent<Transform>().position;
|
||||
Vector2 mousePositionOnSelect = Input.mousePosition;
|
||||
gizmoXYZScreenStart = Camera.main.WorldToScreenPoint(gizmoPosition);
|
||||
if (!handleName.Contains("Plane"))
|
||||
{
|
||||
Vector3 gizmoEndPosition = new Vector3();
|
||||
switch (handleName)
|
||||
{
|
||||
case "TranslateX":
|
||||
translateSelectState = TranslateSelectState.X;
|
||||
gizmoEndPosition = gizmoPosition + 10 * gizmo.GetComponent<Transform>().right;
|
||||
break;
|
||||
case "TranslateY":
|
||||
translateSelectState = TranslateSelectState.Y;
|
||||
gizmoEndPosition = gizmoPosition + 10 * gizmo.GetComponent<Transform>().up;
|
||||
break;
|
||||
case "TranslateZ":
|
||||
translateSelectState = TranslateSelectState.Z;
|
||||
gizmoEndPosition = gizmoPosition + 10 * gizmo.GetComponent<Transform>().forward;
|
||||
break;
|
||||
}
|
||||
Vector2 gizmoXYZScreenEnd = Camera.main.WorldToScreenPoint(gizmoEndPosition);
|
||||
gizmoXYZScreenDirection = (gizmoXYZScreenEnd - gizmoXYZScreenStart).normalized;
|
||||
XYZOffsetOnSelect = Vector2.Dot(mousePositionOnSelect - gizmoXYZScreenStart, gizmoXYZScreenDirection);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (handleName)
|
||||
{
|
||||
case "TranslatePlaneX":
|
||||
translateSelectState = TranslateSelectState.PlaneX;
|
||||
break;
|
||||
case "TranslatePlaneY":
|
||||
translateSelectState = TranslateSelectState.PlaneY;
|
||||
break;
|
||||
case "TranslatePlaneZ":
|
||||
translateSelectState = TranslateSelectState.PlaneZ;
|
||||
break;
|
||||
}
|
||||
gizmoPlaneOffset = new Vector2(mousePositionOnSelect.x - gizmoXYZScreenStart.x, mousePositionOnSelect.y - gizmoXYZScreenStart.y);
|
||||
}
|
||||
ChangeRenderOnSelect();
|
||||
}
|
||||
|
||||
public override void OnUnSelect()
|
||||
{
|
||||
if (translateSelectState == TranslateSelectState.UnSelected) { return; }
|
||||
translateSelectState = TranslateSelectState.UnSelected;
|
||||
//Render
|
||||
ChangeRenderOnUnSelect();
|
||||
}
|
||||
|
||||
protected override void OnSelecting()
|
||||
{
|
||||
Vector2 mousePosition = Input.mousePosition;
|
||||
Vector3 targetPosition = new Vector3();
|
||||
Vector3 gizmoPosition = gizmo.GetComponent<Transform>().position;
|
||||
Vector3 viewPosition = Camera.main.ScreenToWorldPoint(screenCenterPosition);
|
||||
//Translate XYZ Axis
|
||||
if (translateSelectState <= TranslateSelectState.Z)
|
||||
{
|
||||
float dragDistance = Vector2.Dot(mousePosition - gizmoXYZScreenStart, gizmoXYZScreenDirection) - XYZOffsetOnSelect;
|
||||
Vector2 dragScreenPosition = gizmoXYZScreenStart + gizmoXYZScreenDirection * dragDistance;
|
||||
Vector3 dragRayDirection = Camera.main.ScreenPointToRay(dragScreenPosition).direction;
|
||||
switch (translateSelectState)
|
||||
{
|
||||
case TranslateSelectState.X:
|
||||
Vector3? intersectionXY = GetIntersectionPlaneAndLine(Axis.Y, viewPosition, dragRayDirection);
|
||||
Vector3? intersectionXZ = GetIntersectionPlaneAndLine(Axis.Z, viewPosition, dragRayDirection);
|
||||
targetPosition = GetMediaPoint(intersectionXY, intersectionXZ).Value;
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
break;
|
||||
case TranslateSelectState.Y:
|
||||
Vector3? intersectionYX = GetIntersectionPlaneAndLine(Axis.X, viewPosition, dragRayDirection);
|
||||
Vector3? intersectionYZ = GetIntersectionPlaneAndLine(Axis.Z, viewPosition, dragRayDirection);
|
||||
targetPosition = GetMediaPoint(intersectionYX, intersectionYZ).Value;
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
break;
|
||||
case TranslateSelectState.Z:
|
||||
Vector3? intersectionZX = GetIntersectionPlaneAndLine(Axis.X, viewPosition, dragRayDirection);
|
||||
Vector3? intersectionZY = GetIntersectionPlaneAndLine(Axis.Y, viewPosition, dragRayDirection);
|
||||
targetPosition = GetMediaPoint(intersectionZX, intersectionZY).Value;
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Translate XYZ Plane
|
||||
else
|
||||
{
|
||||
Vector2 dragScreenPosition = mousePosition - gizmoPlaneOffset;
|
||||
Vector3 dragRayDirection = Camera.main.ScreenPointToRay(dragScreenPosition).direction;
|
||||
switch (translateSelectState)
|
||||
{
|
||||
case TranslateSelectState.PlaneX:
|
||||
targetPosition = GetIntersectionPlaneAndLine(Axis.X, viewPosition, dragRayDirection).Value;
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
break;
|
||||
case TranslateSelectState.PlaneY:
|
||||
targetPosition = GetIntersectionPlaneAndLine(Axis.Y, viewPosition, dragRayDirection).Value;
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
break;
|
||||
case TranslateSelectState.PlaneZ:
|
||||
targetPosition = GetIntersectionPlaneAndLine(Axis.Z, viewPosition, dragRayDirection).Value;
|
||||
gizmo.GetComponent<Transform>().position = targetPosition;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeRenderOnSelect()
|
||||
{
|
||||
switch(translateSelectState)
|
||||
{
|
||||
case TranslateSelectState.X:
|
||||
translateX.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translatePlaneX.SetActive(false);
|
||||
translatePlaneY.SetActive(false);
|
||||
translatePlaneZ.SetActive(false);
|
||||
break;
|
||||
case TranslateSelectState.Y:
|
||||
translateX.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translatePlaneX.SetActive(false);
|
||||
translatePlaneY.SetActive(false);
|
||||
translatePlaneZ.SetActive(false);
|
||||
break;
|
||||
case TranslateSelectState.Z:
|
||||
translateX.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translatePlaneX.SetActive(false);
|
||||
translatePlaneY.SetActive(false);
|
||||
translatePlaneZ.SetActive(false);
|
||||
break;
|
||||
case TranslateSelectState.PlaneX:
|
||||
translateX.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translatePlaneX.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translatePlaneY.SetActive(false);
|
||||
translatePlaneZ.SetActive(false);
|
||||
break;
|
||||
case TranslateSelectState.PlaneY:
|
||||
translateX.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translatePlaneX.SetActive(false);
|
||||
translatePlaneY.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translatePlaneZ.SetActive(false);
|
||||
break;
|
||||
case TranslateSelectState.PlaneZ:
|
||||
translateX.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = whiteMaterial;
|
||||
translatePlaneX.SetActive(false);
|
||||
translatePlaneY.SetActive(false);
|
||||
translatePlaneZ.GetComponent<MeshRenderer>().material = yellowMaterial;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ChangeRenderOnUnSelect()
|
||||
{
|
||||
translateX.SetActive(true);
|
||||
translateY.SetActive(true);
|
||||
translateZ.SetActive(true);
|
||||
translatePlaneX.SetActive(true);
|
||||
translatePlaneY.SetActive(true);
|
||||
translatePlaneZ.SetActive(true);
|
||||
translateX.GetComponent<MeshRenderer>().material = redMaterial;
|
||||
translateY.GetComponent<MeshRenderer>().material = greenMaterial;
|
||||
translateZ.GetComponent<MeshRenderer>().material = blueMaterial;
|
||||
translatePlaneX.GetComponent<MeshRenderer>().material = redMaterial;
|
||||
translatePlaneY.GetComponent<MeshRenderer>().material = greenMaterial;
|
||||
translatePlaneZ.GetComponent<MeshRenderer>().material = blueMaterial;
|
||||
}
|
||||
|
||||
private Vector3? GetMediaPoint(Vector3? point1, Vector3? point2)
|
||||
{
|
||||
if (point1 != null && point2 != null)
|
||||
{
|
||||
return (point1 + point2) / 2;
|
||||
}
|
||||
else if (point1 != null && point2 == null)
|
||||
{
|
||||
return point1;
|
||||
}
|
||||
else if (point2 != null && point1 == null)
|
||||
{
|
||||
return point2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
11
参考/TransformGizmo/Scripts/RuntimeTranslateGizmo.cs.meta
Normal file
11
参考/TransformGizmo/Scripts/RuntimeTranslateGizmo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcaa98f6cda37fd4b9e03e8b053b58dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
327
参考/TransformGizmo/Scripts/SelectDetector.cs
Normal file
327
参考/TransformGizmo/Scripts/SelectDetector.cs
Normal file
@@ -0,0 +1,327 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Security.Cryptography;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
|
||||
public class SelectDetector
|
||||
{
|
||||
//GameObject
|
||||
public GameObject detectedObject;
|
||||
private List<GameObject> objects;
|
||||
private List<int> objectIds;
|
||||
|
||||
private Shader objectEncodeShader;
|
||||
private Material objectEncodeMaterial;
|
||||
private Dictionary<int, Material> objectEncodeMaterials;
|
||||
|
||||
//Gizmo
|
||||
public GameObject detectedGizmo;
|
||||
private List<GameObject> gizmos;
|
||||
private List<int> gizmoIds;
|
||||
|
||||
private Shader gizmoEncodeShader;
|
||||
private Material gizmoEncodeMaterial;
|
||||
private Dictionary<int,Material> gizmoEncodeMaterials;
|
||||
|
||||
private CommandBuffer encodeCmdBuffer;
|
||||
|
||||
private Camera selectCamera;
|
||||
private GameObject cameraObject;
|
||||
|
||||
private Texture2D encodeTexture2d;
|
||||
private RenderTexture encodeTexture;
|
||||
|
||||
private bool isCursorOnPanels = false;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
//Encode CommandBuffer Initialize
|
||||
encodeCmdBuffer = new CommandBuffer();
|
||||
|
||||
//Object Encode Material Initialize
|
||||
objectEncodeShader = Shader.Find("Custom/ObjectSelectEncode");
|
||||
objectEncodeMaterial = new Material(objectEncodeShader);
|
||||
objectEncodeMaterial.SetColor("_ID", IntToRGBA(-1));
|
||||
|
||||
//Gizmo Encode Material Initialize
|
||||
gizmoEncodeShader = Shader.Find("Custom/GizmoSelectEncode");
|
||||
gizmoEncodeMaterial = new Material(gizmoEncodeShader);
|
||||
gizmoEncodeMaterial.SetColor("_ID", IntToRGBA(-1));
|
||||
|
||||
//Encode Texture Initialize
|
||||
encodeTexture = new RenderTexture(Screen.width, Screen.height, 24);
|
||||
encodeTexture2d = new Texture2D(1, 1, TextureFormat.ARGB32, false);
|
||||
|
||||
//Camera Initialize
|
||||
cameraObject = new GameObject();
|
||||
cameraObject.name = "SelectDetector";
|
||||
cameraObject.GetComponent<Transform>().parent = GameObject.Find("Main Camera").GetComponent<Transform>();
|
||||
cameraObject.GetComponent<Transform>().localPosition = Vector3.zero;
|
||||
cameraObject.GetComponent<Transform>().rotation = Quaternion.identity;
|
||||
selectCamera = cameraObject.AddComponent<Camera>();
|
||||
selectCamera.targetTexture = encodeTexture;
|
||||
selectCamera.GetComponent<Transform>().position = Camera.main.transform.position;
|
||||
selectCamera.GetComponent<Transform>().rotation = Camera.main.transform.rotation;
|
||||
|
||||
//List Initialize
|
||||
objects = new List<GameObject>();
|
||||
objectIds = new List<int>();
|
||||
objectEncodeMaterials = new Dictionary<int, Material>();
|
||||
gizmos = new List<GameObject>();
|
||||
gizmoIds = new List<int>();
|
||||
gizmoEncodeMaterials = new Dictionary<int, Material>();
|
||||
}
|
||||
|
||||
public void InitializeScene()
|
||||
{
|
||||
//Original GameObjects Initialize
|
||||
foreach (GameObject root in UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects())
|
||||
{
|
||||
foreach (Transform child_transform in root.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
objects.Add(child);
|
||||
objectIds.Add(child.GetInstanceID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (isCursorOnPanels) { return; }
|
||||
|
||||
//Select Camera Update
|
||||
//selectCamera.GetComponent<Transform>().position = Camera.main.transform.position;
|
||||
//selectCamera.GetComponent<Transform>().rotation = Camera.main.transform.rotation;
|
||||
selectCamera.RemoveAllCommandBuffers();
|
||||
|
||||
|
||||
//Encode CommandBuffer Update
|
||||
encodeCmdBuffer.Clear();
|
||||
encodeCmdBuffer.ClearRenderTarget(true, true, Color.white);
|
||||
|
||||
//Add Object Render Command
|
||||
for (int i = 0; i < objects.Count; i++)
|
||||
{
|
||||
GameObject tmpObject = objects[i];
|
||||
if (tmpObject == null) { continue; }
|
||||
if (tmpObject.activeSelf == false) { continue; }
|
||||
MeshRenderer tmpRenderer = tmpObject.GetComponent<MeshRenderer>();
|
||||
if (tmpRenderer != null)
|
||||
{
|
||||
int tmpId = tmpObject.GetInstanceID();
|
||||
Material tempMaterial = objectEncodeMaterials[tmpId];
|
||||
encodeCmdBuffer.DrawRenderer(tmpRenderer, tempMaterial);
|
||||
}
|
||||
}
|
||||
//Add Gizmo Render Command
|
||||
for (int i = 0; i < gizmos.Count; i++)
|
||||
{
|
||||
GameObject tmpGizmo = gizmos[i];
|
||||
MeshRenderer tmpRenderer = tmpGizmo.GetComponent<MeshRenderer>();
|
||||
if (tmpRenderer != null)
|
||||
{
|
||||
int tmpId = tmpGizmo.GetInstanceID();
|
||||
Material tmpMaterial = gizmoEncodeMaterials[tmpId];
|
||||
encodeCmdBuffer.DrawRenderer(tmpRenderer, tmpMaterial);
|
||||
}
|
||||
}
|
||||
selectCamera.AddCommandBuffer(CameraEvent.AfterEverything, encodeCmdBuffer);
|
||||
|
||||
|
||||
//Detected Object&Gizmo Update
|
||||
Vector2 input = Input.mousePosition;
|
||||
int inputX = (int)input.x;
|
||||
int inputY = (int)input.y;
|
||||
int clampInputX = Mathf.Clamp(inputX, 0, encodeTexture.width - 1);
|
||||
int clampInputY = Mathf.Clamp(inputY, 0, encodeTexture.height - 1);
|
||||
RenderTexture.active = encodeTexture;
|
||||
encodeTexture2d.ReadPixels(new Rect(clampInputX, clampInputY, 1, 1), 0, 0);
|
||||
encodeTexture2d.Apply();
|
||||
Color color = encodeTexture2d.GetPixel(0, 0);
|
||||
int id = RGBAToInt(color);
|
||||
detectedObject = FindObjectByID(id);
|
||||
detectedGizmo = FindGizmoByID(id);
|
||||
}
|
||||
|
||||
|
||||
//Object Add&Remove&Find
|
||||
public void AddObjects(GameObject root_object)
|
||||
{
|
||||
foreach (Transform child_transform in root_object.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
AddObject(child);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveObjects(GameObject root_object)
|
||||
{
|
||||
foreach (Transform child_transform in root_object.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
RemoveObject(child);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddObjects(List<GameObject> objects)
|
||||
{
|
||||
foreach(GameObject obj in objects)
|
||||
{
|
||||
AddObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveObjects(List<GameObject> objects)
|
||||
{
|
||||
foreach(GameObject obj in objects)
|
||||
{
|
||||
RemoveObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddObject(GameObject p_object)
|
||||
{
|
||||
if(p_object == null) { return; }
|
||||
objects.Add(p_object);
|
||||
int id = p_object.GetInstanceID();
|
||||
objectIds.Add(id);
|
||||
|
||||
//Encode Material
|
||||
Material encodeMaterial = new Material(objectEncodeMaterial);
|
||||
encodeMaterial.SetColor("_ID", IntToRGBA(id));
|
||||
objectEncodeMaterials.Add(id, encodeMaterial);
|
||||
}
|
||||
|
||||
public void RemoveObject(GameObject p_object)
|
||||
{
|
||||
if (p_object == null) { return; }
|
||||
if (!objects.Contains(p_object)) { return; }
|
||||
objects.Remove(p_object);
|
||||
int id = p_object.GetInstanceID();
|
||||
objectIds.Remove(id);
|
||||
objectEncodeMaterials.Remove(id);
|
||||
}
|
||||
|
||||
private GameObject FindObjectByID(int id)
|
||||
{
|
||||
for (int i = 0; i < objects.Count; i++)
|
||||
{
|
||||
if (objectIds[i] == id)
|
||||
{
|
||||
return objects[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
//Gizmo Add&Remove&Find
|
||||
public void AddGizmos(GameObject root_object)
|
||||
{
|
||||
foreach (Transform child_transform in root_object.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
AddGizmo(child);
|
||||
}
|
||||
}
|
||||
public void RemoveGizmos(GameObject root_object)
|
||||
{
|
||||
foreach (Transform child_transform in root_object.GetComponentsInChildren<Transform>(true))
|
||||
{
|
||||
GameObject child = child_transform.gameObject;
|
||||
RemoveGizmo(child);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddGizmos(List<GameObject> objects)
|
||||
{
|
||||
foreach(GameObject gameObject in objects)
|
||||
{
|
||||
AddGizmo(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveGizmos(List<GameObject> objects)
|
||||
{
|
||||
foreach(GameObject gameObject in objects)
|
||||
{
|
||||
RemoveGizmo(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddGizmo(GameObject p_gizmo)
|
||||
{
|
||||
if (p_gizmo == null) { return; }
|
||||
gizmos.Add(p_gizmo);
|
||||
int id = p_gizmo.GetInstanceID();
|
||||
gizmoIds.Add(id);
|
||||
|
||||
//Encode Material
|
||||
Material encodeMaterial = new Material(gizmoEncodeMaterial);
|
||||
encodeMaterial.SetColor("_ID", IntToRGBA(id));
|
||||
gizmoEncodeMaterials.Add(id, encodeMaterial);
|
||||
}
|
||||
|
||||
public void RemoveGizmo(GameObject p_gizmo)
|
||||
{
|
||||
if (p_gizmo == null) { return; }
|
||||
if (!gizmos.Contains(p_gizmo)) { return; }
|
||||
gizmos.Remove(p_gizmo);
|
||||
int id = p_gizmo.GetInstanceID();
|
||||
gizmoIds.Remove(id);
|
||||
gizmoEncodeMaterials.Remove(id);
|
||||
}
|
||||
|
||||
private GameObject FindGizmoByID(int id)
|
||||
{
|
||||
for (int i = 0; i < gizmos.Count; i++)
|
||||
{
|
||||
if (gizmoIds[i] == id)
|
||||
{
|
||||
return gizmos[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//Tool
|
||||
private Color IntToRGBA(int value)
|
||||
{
|
||||
byte red = (byte)((value >> 24) & 0xFF);
|
||||
|
||||
byte green = (byte)((value >> 16) & 0xFF);
|
||||
|
||||
byte blue = (byte)((value >> 8) & 0xFF);
|
||||
|
||||
byte alpha = (byte)(value & 0xFF);
|
||||
|
||||
return new Color32(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
private int RGBAToInt(Color32 color)
|
||||
{
|
||||
int result = (color.r << 24) |
|
||||
(color.g << 16) |
|
||||
(color.b << 8) |
|
||||
color.a;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int RGBAToInt(Color color)
|
||||
{
|
||||
Color32 color32 = new Color32((byte)(color.r * 255),
|
||||
(byte)(color.g * 255),
|
||||
(byte)(color.b * 255),
|
||||
(byte)(color.a * 255));
|
||||
return RGBAToInt(color32);
|
||||
}
|
||||
|
||||
}
|
||||
11
参考/TransformGizmo/Scripts/SelectDetector.cs.meta
Normal file
11
参考/TransformGizmo/Scripts/SelectDetector.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be973e2bc332fca4a9cb18ab3197b72b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user