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(); if (renderer != null) { outlineMaterial.SetColor("_OutlineColor", color); List materials = renderer.materials.ToList(); if(!materials.Contains(outlineMaterial)) { materials.Add(outlineMaterial); renderer.materials = materials.ToArray(); } } } private void RemoveOutLine(GameObject gameObject) { Renderer renderer = gameObject.GetComponent(); if (renderer != null) { List materials = renderer.materials.ToList(); 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(true)) { GameObject child = child_transform.gameObject; AddOutLine(child, color); } } private void RemoveOutlines(GameObject gameObject) { foreach (Transform child_transform in gameObject.GetComponentsInChildren(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(); } } }