private int Hit(Vector2 pointer, Vector3[] vertices, Vector3[] normals) { float minMag = float.MaxValue; int index = -1; for (int i = 0; i < vertices.Length; ++i) { Vector3 normal = normals[i]; normal = HandlesTransform.MultiplyVector(normal); Vector3 vertex = vertices[i]; Vector3 vertexWorld = HandlesTransform.MultiplyPoint(vertices[i]); if (Mathf.Abs(Vector3.Dot((SceneCamera.transform.position - vertexWorld).normalized, normal.normalized)) > 0.999f) { continue; } if (!HitOverride(i, vertex, normal)) { continue; } Vector2 vertexScreen = SceneCamera.WorldToScreenPoint(vertexWorld); float distance = (vertexScreen - pointer).magnitude; if (distance < minMag && distance <= SelectionMargin) { minMag = distance; index = i; } } return(index); }
private bool HitSnapHandle() { Vector3 sp = SceneCamera.WorldToScreenPoint(HandlePosition); Vector3 mp = Input.mousePosition; const float pixelSize = 10; return(sp.x - pixelSize <= mp.x && mp.x <= sp.x + pixelSize && sp.y - pixelSize <= mp.y && mp.y <= sp.y + pixelSize); }
private bool HitAxis(Matrix4x4 transform, Matrix4x4 objToWorld, out float minDistance) { bool hit = false; minDistance = float.PositiveInfinity; const float radius = 1.0f; const int pointsPerCircle = 32; float angle = 0.0f; float z = 0.0f; Vector3 zeroCamPoint = transform.MultiplyPoint(Vector3.zero); zeroCamPoint = objToWorld.MultiplyPoint(zeroCamPoint); zeroCamPoint = SceneCamera.worldToCameraMatrix.MultiplyPoint(zeroCamPoint); Vector3 prevPoint = transform.MultiplyPoint(new Vector3(radius, 0, z)); prevPoint = objToWorld.MultiplyPoint(prevPoint); for (int i = 0; i < pointsPerCircle; i++) { angle += 2 * Mathf.PI / pointsPerCircle; float x = radius * Mathf.Cos(angle); float y = radius * Mathf.Sin(angle); Vector3 point = transform.MultiplyPoint(new Vector3(x, y, z)); point = objToWorld.MultiplyPoint(point); Vector3 camPoint = SceneCamera.worldToCameraMatrix.MultiplyPoint(point); if (camPoint.z > zeroCamPoint.z) { Vector3 screenVector = SceneCamera.WorldToScreenPoint(point) - SceneCamera.WorldToScreenPoint(prevPoint); float screenVectorMag = screenVector.magnitude; screenVector.Normalize(); if (screenVector != Vector3.zero) { float distance; if (HitScreenAxis(out distance, SceneCamera.WorldToScreenPoint(prevPoint), screenVector, screenVectorMag)) { if (distance < minDistance) { minDistance = distance; hit = true; } } } } prevPoint = point; } return(hit); }
private void GetMinPoint(ref float minDistance, ref Vector3 minPoint, ref bool minPointFound, Transform tr) { for (int j = 0; j < m_boundingBoxCorners.Length; ++j) { Vector3 worldPoint = tr.TransformPoint(m_boundingBoxCorners[j]); Vector3 screenPoint = SceneCamera.WorldToScreenPoint(worldPoint); screenPoint.z = 0; Vector3 mousePoint = Input.mousePosition; mousePoint.z = 0; float distance = (screenPoint - mousePoint).magnitude; if (distance < minDistance) { minPointFound = true; minDistance = distance; minPoint = worldPoint; } } }
protected override bool OnBeginDrag() { m_targetRotation = Target.rotation; m_targetInverseMatrix = Matrix4x4.TRS(Target.position, Target.rotation * StartingRotationInv, Vector3.one).inverse; SelectedAxis = Hit(); m_deltaX = 0.0f; m_deltaY = 0.0f; if (SelectedAxis == RuntimeHandleAxis.Screen) { Vector2 center = SceneCamera.WorldToScreenPoint(Target.position); Vector2 point = InputController._MousePosition; float angle = Mathf.Atan2(point.y - center.y, point.x - center.x); m_targetInverse = Quaternion.Inverse(Quaternion.AngleAxis(Mathf.Rad2Deg * angle, Vector3.forward)); m_targetInverseMatrix = Matrix4x4.TRS(Target.position, Target.rotation, Vector3.one).inverse; } else { if (SelectedAxis == RuntimeHandleAxis.X) { m_startingRotationAxis = (Target.rotation * Quaternion.Inverse(StartingRotation)) * Vector3.right; } else if (SelectedAxis == RuntimeHandleAxis.Y) { m_startingRotationAxis = (Target.rotation * Quaternion.Inverse(StartingRotation)) * Vector3.up; } else if (SelectedAxis == RuntimeHandleAxis.Z) { m_startingRotationAxis = (Target.rotation * Quaternion.Inverse(StartingRotation)) * Vector3.forward; } m_targetInverse = Quaternion.Inverse(Target.rotation); } return(SelectedAxis != RuntimeHandleAxis.None); }
private void GetMinPoint(Transform meshTransform, ref float minDistance, ref Vector3 minPoint, ref bool minPointFound, Mesh mesh) { if (mesh != null && mesh.isReadable) { Vector3[] vertices = mesh.vertices; for (int i = 0; i < vertices.Length; ++i) { Vector3 vert = vertices[i]; vert = meshTransform.TransformPoint(vert); Vector3 screenPoint = SceneCamera.WorldToScreenPoint(vert); screenPoint.z = 0; Vector3 mousePoint = Input.mousePosition; mousePoint.z = 0; float distance = (screenPoint - mousePoint).magnitude; if (distance < minDistance) { minPointFound = true; minDistance = distance; minPoint = vert; } } } }
protected override void UpdateOverride() { base.UpdateOverride(); if (RuntimeTools.IsPointerOverGameObject()) { return; } if (IsDragging) { if ((SnapToGround || InputController.GetKey(SnapToGroundKey)) && SelectedAxis != RuntimeHandleAxis.Y) { SnapActiveTargetsToGround(ActiveTargets, SceneCamera, true); transform.position = Targets[0].position; } } if (HightlightOnHover && !IsDragging) { SelectedAxis = Hit(); } if (InputController.GetKeyDown(SnappingKey)) { if (!LockObject.IsPositionLocked) { m_isInSnappingMode = true; if (InputController.GetKey(SnappingToggle)) { RuntimeTools.IsSnapping = !RuntimeTools.IsSnapping; } BeginSnap(); m_prevMousePosition = Input.mousePosition; } } else if (InputController.GetKeyUp(SnappingKey)) { SelectedAxis = RuntimeHandleAxis.None; m_isInSnappingMode = false; if (!IsInSnappingMode) { m_handleOffset = Vector3.zero; } } if (IsInSnappingMode) { Vector2 mousePosition = Input.mousePosition; if (RuntimeTools.SnappingMode == SnappingMode.BoundingBox) { if (IsDragging) { SelectedAxis = RuntimeHandleAxis.Snap; if (m_prevMousePosition != mousePosition) { m_prevMousePosition = mousePosition; float minDistance = float.MaxValue; Vector3 minPoint = Vector3.zero; bool minPointFound = false; for (int i = 0; i < m_allExposedToEditor.Length; ++i) { ExposeToEditor exposeToEditor = m_allExposedToEditor[i]; Bounds bounds = exposeToEditor.Bounds; m_boundingBoxCorners[0] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[1] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[2] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[3] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[4] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[5] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[6] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[7] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, -bounds.extents.z); GetMinPoint(ref minDistance, ref minPoint, ref minPointFound, exposeToEditor.BoundsObject.transform); } if (minPointFound) { HandlePosition = minPoint; } } } else { SelectedAxis = RuntimeHandleAxis.None; if (m_prevMousePosition != mousePosition) { m_prevMousePosition = mousePosition; float minDistance = float.MaxValue; Vector3 minPoint = Vector3.zero; bool minPointFound = false; for (int i = 0; i < m_snapTargets.Length; ++i) { Transform snapTarget = m_snapTargets[i]; Bounds bounds = m_snapTargetsBounds[i]; m_boundingBoxCorners[0] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[1] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[2] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[3] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[4] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[5] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[6] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[7] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, -bounds.extents.z); if (Targets[i] != null) { GetMinPoint(ref minDistance, ref minPoint, ref minPointFound, snapTarget); } } if (minPointFound) { m_handleOffset = minPoint - transform.position; } } } } else { if (IsDragging) { SelectedAxis = RuntimeHandleAxis.Snap; if (m_prevMousePosition != mousePosition) { m_prevMousePosition = mousePosition; Ray ray = SceneCamera.ScreenPointToRay(mousePosition); RaycastHit hitInfo; LayerMask layerMask = (1 << Physics.IgnoreRaycastLayer); layerMask = ~layerMask; for (int i = 0; i < m_snapTargets.Length; ++i) { m_targetLayers[i] = m_snapTargets[i].gameObject.layer; m_snapTargets[i].gameObject.layer = Physics.IgnoreRaycastLayer; } GameObject closestObject = null; if (Physics.Raycast(ray, out hitInfo, float.PositiveInfinity, layerMask)) { closestObject = hitInfo.collider.gameObject; } else { float minDistance = float.MaxValue; for (int i = 0; i < m_allExposedToEditor.Length; ++i) { ExposeToEditor exposedToEditor = m_allExposedToEditor[i]; Bounds bounds = exposedToEditor.Bounds; m_boundingBoxCorners[0] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[1] = bounds.center + new Vector3(bounds.extents.x, bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[2] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[3] = bounds.center + new Vector3(bounds.extents.x, -bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[4] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[5] = bounds.center + new Vector3(-bounds.extents.x, bounds.extents.y, -bounds.extents.z); m_boundingBoxCorners[6] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, bounds.extents.z); m_boundingBoxCorners[7] = bounds.center + new Vector3(-bounds.extents.x, -bounds.extents.y, -bounds.extents.z); for (int j = 0; j < m_boundingBoxCorners.Length; ++j) { Vector2 screenPoint = SceneCamera.WorldToScreenPoint(exposedToEditor.BoundsObject.transform.TransformPoint(m_boundingBoxCorners[j])); float distance = (screenPoint - mousePosition).magnitude; if (distance < minDistance) { closestObject = exposedToEditor.gameObject; minDistance = distance; } } } } if (closestObject != null) { float minDistance = float.MaxValue; Vector3 minPoint = Vector3.zero; bool minPointFound = false; Transform meshTransform; Mesh mesh = GetMesh(closestObject, out meshTransform); GetMinPoint(meshTransform, ref minDistance, ref minPoint, ref minPointFound, mesh); if (minPointFound) { HandlePosition = minPoint; } } for (int i = 0; i < m_snapTargets.Length; ++i) { m_snapTargets[i].gameObject.layer = m_targetLayers[i]; } } } else { SelectedAxis = RuntimeHandleAxis.None; if (m_prevMousePosition != mousePosition) { m_prevMousePosition = mousePosition; float minDistance = float.MaxValue; Vector3 minPoint = Vector3.zero; bool minPointFound = false; for (int i = 0; i < RealTargets.Length; ++i) { Transform snapTarget = RealTargets[i]; Transform meshTranform; Mesh mesh = GetMesh(snapTarget.gameObject, out meshTranform); GetMinPoint(meshTranform, ref minDistance, ref minPoint, ref minPointFound, mesh); } if (minPointFound) { m_handleOffset = minPoint - transform.position; } } } } } }
public void OnSceneGUI() { if (element == null) { element = (UISceneElement)target; } if (element == null || !element.enabled) { return; } if (element.isDeleteGameObject) { //销毁 EditorMemoryRecycle.RemoveMemory(element.gameObject); element.isDeleteGameObject = false; } base.OnSceneGUI(); //反算屏幕坐标 if (MoveFllowMouse) { //Debug.LogError("[MoveFllowMouse]"+MoveFllowMouse.ToString()); Vector3 mypos = element.transform.position; if (element.settingData.Type == SceneElementType.NPC) { mypos.y = 0; } else { mypos.y = element.transform.localScale.y / 2f; } element.transform.position = mypos; Vector3 ScenePos = SceneCamera.WorldToScreenPoint(element.transform.position); Vector3 mousePosition = Event.current.mousePosition; float height = SceneView.currentDrawingSceneView.position.height; mousePosition.y = height - mousePosition.y - 15f; mousePosition.z = ScenePos.z; Vector3 resultPos = SceneCamera.ScreenToWorldPoint(mousePosition); element.transform.position = resultPos; } //绘制文本框 Handles.Label(element.transform.position + Vector3.up * 3, element.transform.name + " : " + element.transform.position.ToString()); //开始绘制GUI Handles.BeginGUI(); //规定GUI显示区域 GUILayout.BeginArea(new Rect(100, 100, 200, 400)); //GUI绘制文本框 /*正在编辑*/ GUILayout.Label(EditorStringConfig.getString(10030) + ":" + element.gameObject.name); /*吸附到地图*/ element.isAtMap = GUILayout.Toggle(element.isAtMap, EditorStringConfig.getString(10031)); // /*鼠标跟随*/ // element.isSeletctedFllowMouse = GUILayout.Toggle(element.isSeletctedFllowMouse,EditorStringConfig.getString(10032)); // // if(element.isSeletctedFllowMouse) element.isAtMap = true; //自动吸附到地图 if (element.isAtMap) { element.AdsorptionToMap(); } else { /*种植*/ if (GUILayout.Button(EditorStringConfig.getString(10034), GUILayout.Width(100), GUILayout.Height(20))) { element.CorrectionPostion(); } } /*克隆*/ if (GUILayout.Button(EditorStringConfig.getString(10035), GUILayout.Width(100), GUILayout.Height(20))) { Object prefab = EditorUtility.GetPrefabParent(Selection.activeObject); GameObject cloneSource = Selection.activeObject as GameObject; GameObject cloneObject = null; if (prefab) { Vector3 oldpos = element.gameObject.transform.position; cloneObject = SceneEditorTools.CreatePlant(prefab, new Vector3(oldpos.x + 3f + element.transform.localScale.x, oldpos.y, oldpos.z), element.transform.localScale, element.settingData.Type, element.isAtMap, element.transform.rotation.eulerAngles); } //克隆代码 element.CloneScript(cloneSource, cloneObject); } /*销毁*/ if (GUILayout.Button(EditorStringConfig.getString(10033), GUILayout.Width(100), GUILayout.Height(20))) { element.isDeleteGameObject = true; } //GUILayout.BeginHorizontal(); element.isSetTransform = GUILayout.Toggle(element.isSetTransform, "Transform(World)", EditorStyles.foldout); //GUILayout.EndHorizontal(); Rect lastRect = GUILayoutUtility.GetLastRect(); if (element.isSetTransform) { ++EditorGUI.indentLevel; GUILayout.BeginHorizontal(); if (GUI.Button(new Rect(16, lastRect.yMax, 20, 18), "P")) { element.transform.position = Vector3.zero; } element.transform.position = EditorGUI.Vector3Field(new Rect(20, lastRect.yMax + 2, 150, 20), "", element.transform.position); GUILayout.EndHorizontal(); lastRect.yMax += 20f; GUILayout.BeginHorizontal(); if (GUI.Button(new Rect(16, lastRect.yMax, 20, 18), "R")) { element.transform.rotation = Quaternion.Euler(Vector3.zero); } element.transform.rotation = Quaternion.Euler(EditorGUI.Vector3Field(new Rect(20, lastRect.yMax + 2, 150, 20), "", element.transform.rotation.eulerAngles)); GUILayout.EndHorizontal(); lastRect.yMax += 20f; GUILayout.BeginHorizontal(); if (GUI.Button(new Rect(16, lastRect.yMax, 20, 18), "S")) { element.transform.localScale = Vector3.one; } element.transform.localScale = EditorGUI.Vector3Field(new Rect(20, lastRect.yMax + 2, 150, 20), "", element.transform.localScale); GUILayout.EndHorizontal(); --EditorGUI.indentLevel; } GUILayout.EndArea(); Handles.EndGUI(); }