using UnityEngine; using System.Collections; using System.Collections.Generic; using System; namespace Wing.Gizmos { public delegate Vector3 GizmosValueChangedHandler(Vector3 before); public class GizmosBase : MonoBehaviour { public event Action AxisSelectedEvent; public GameObject _lastSelected; public float scale = 1.0f; private Vector3 _lastMousePt; private bool dirty = false; private float _distanceFactor = 1.0f; protected Dictionary _axisMap = new Dictionary(); // Use this for initialization void Awake() { transform.localScale = Vector3.zero; OnInit(); } protected void ConstructAxis(string axisRoot, EGizmosAxisType type) { Transform go = transform.Find(axisRoot); for (int i = 0; i < go.childCount; ++i) { GameObject obj = go.GetChild(i).gameObject; obj.AddComponent(); MeshRenderer r = obj.GetComponent(); SetColor(r.material, type, false); _axisMap[obj] = type; } } private void SetColor(Material mat, EGizmosAxisType type, bool highlight) { if (!highlight) { float lightness = 1.0f; if (type == EGizmosAxisType.X) { mat.color = new Color(lightness, 0.0f, 0.0f, 0.5f); } else if (type == EGizmosAxisType.Y) { mat.color = new Color(0.0f, lightness, 0.0f, 0.5f); } else if (type == EGizmosAxisType.Z) { mat.color = new Color(0.0f, 0.0f, lightness, 0.5f); } else if (type == EGizmosAxisType.LockX) { mat.color = new Color(lightness, 0.0f, 0.0f, 0.5f); } else if (type == EGizmosAxisType.LockY) { mat.color = new Color(0.0f, lightness, 0.0f, 0.5f); } else if (type == EGizmosAxisType.LockZ) { mat.color = new Color(0.0f, 0.0f, lightness, 0.5f); } else { mat.color = new Color(lightness, lightness, lightness, 1.0f); } } else { mat.color = new Color(1.0f, 1.0f, 0.0f, 1.0f); } } // Update is called once per frame void Update() { Vector3 diff = transform.position - Camera.main.transform.position; float d = diff.magnitude * scale * 0.05f; _distanceFactor = ComputeScaleFactor(d); transform.localScale = new Vector3(d, d, d); } protected virtual float ComputeScaleFactor(float d) { return d * 1.4f; } private void ChangeColor(GameObject go, bool highlight) { Transform root = go.transform.parent; for (int i = 0; i < root.childCount; ++i) { GameObject childGO = root.GetChild(i).gameObject; MeshRenderer r = childGO.GetComponent(); EGizmosAxisType type = _axisMap[childGO]; SetColor(r.material, type, highlight); } } public void OnMouseEnter(GameObject go) { if(_lastSelected != null) { ChangeColor(_lastSelected, false); } ChangeColor(go, true); //Debug.Log("OnMouseEnter"); _lastSelected = go; OnAxisSelected(_axisMap[go]); } public void OnMouseExit(GameObject go) { //ChangeColor(go, false); // Debug.Log("OnMouse Exit"); } public void OnMouseDown(GameObject go) { _lastMousePt = Input.mousePosition; // Debug.Log("OnMouseDown"); OnAxisSelected(_axisMap[go]); } public void OnMouseUp(GameObject go) { OnDragEnd(go); dirty = false; } public void OnMouseDrag(GameObject go) { Vector3 mousePt = Input.mousePosition; Vector3 diff = mousePt - _lastMousePt; if (diff.x + diff.y == 0) { return; } dirty = true; EGizmosAxisType type = _axisMap[go]; float dx = 0; float dy = 0; float dz = 0; float scensitivity = 0.02f; Vector3 ogrinPos = transform.position; Vector3 start = Camera.main.WorldToScreenPoint(ogrinPos); start.z = 0; if (type != EGizmosAxisType.CENTER) { Vector3 end = Camera.main.WorldToScreenPoint(ogrinPos + transform.right * 2); end.z = 0; Vector3 axisDir = end - start; axisDir.Normalize(); dx = (axisDir.x * diff.x + axisDir.y * diff.y) * scensitivity; end = Camera.main.WorldToScreenPoint(ogrinPos + transform.up * 2); end.z = 0; axisDir = end - start; axisDir.Normalize(); dy = (axisDir.x * diff.x + axisDir.y * diff.y) * scensitivity; end = Camera.main.WorldToScreenPoint(ogrinPos + transform.forward * 2); end.z = 0; axisDir = end - start; axisDir.Normalize(); dz = (axisDir.x * diff.x + axisDir.y * diff.y) * scensitivity; } else { Vector3 end = start + Vector3.one; end.z = 0; Vector3 axisDir = end - start; axisDir.Normalize(); dx = dy = dz = (axisDir.x * diff.x + axisDir.y * diff.y) * scensitivity; } Vector3 axisMask = Vector3.zero; switch (type) { case EGizmosAxisType.X: axisMask.x = 1; break; case EGizmosAxisType.Y: axisMask.y = 1; break; case EGizmosAxisType.Z: axisMask.z = 1; break; case EGizmosAxisType.LockX: axisMask.y = 1; axisMask.z = 1; break; case EGizmosAxisType.LockY: axisMask.x = 1; axisMask.z = 1; break; case EGizmosAxisType.LockZ: axisMask.x = 1; axisMask.y = 1; break; case EGizmosAxisType.CENTER: axisMask.x = 1; axisMask.y = 1; axisMask.z = 1; break; } dx = dx * axisMask.x * _distanceFactor; dy = dy * axisMask.y * _distanceFactor; dz = dz * axisMask.z * _distanceFactor; OnDragDelta(go, dx, dy, dz); _lastMousePt = mousePt; } protected virtual void OnInit() { } protected virtual void OnDragDelta(GameObject go,float dx, float dy, float dz) { } protected virtual void OnDragEnd(GameObject go) { } protected virtual void OnAxisSelected(EGizmosAxisType type) { if(AxisSelectedEvent != null) { AxisSelectedEvent(type); } } } }