static void GetHit(SceneView sceneView, out GameObject hitObject, out Vector3 hitPoint, out Vector3 hitNormal) { if (SceneQueryUtility.FindClickWorldIntersection(sceneView.camera, Event.current.mousePosition, out hitObject)) { var intersection = SceneQueryUtility.FindMeshIntersection(sceneView.camera, Event.current.mousePosition); hitPoint = intersection.worldIntersection; hitNormal = intersection.worldPlane.normal; } else { hitObject = HandleUtility.PickGameObject(Event.current.mousePosition, out int materialIndex); hitPoint = Vector3.zero; hitNormal = Vector3.zero; if (hitObject) { var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); var mf = hitObject.GetComponentInChildren <MeshFilter>(); if (mf) { EditorHandles_UnityInternal.IntersectRayMesh(ray, mf, out RaycastHit hit); hitPoint = hit.point; hitNormal = hit.normal; } } } }
public bool Raycast(out Vector3 pos, out Vector3 norm, out int face) { Ray mouseRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); bool hitSomething = false; norm = Vector2.zero; pos = Vector3.zero; face = -1; for (int i = 0; i < activeInstances.Length; i++) { RaycastHit hit; if (EditorHandles_UnityInternal.IntersectRayMesh(mouseRay, activeInstances[i].localMesh, activeInstances[i].transform.localToWorldMatrix, out hit)) { if (hitSomething) { if (Vector3.Distance(hit.point, mouseRay.origin) > Vector3.Distance(pos, mouseRay.origin)) { continue; } } norm = hit.normal.normalized; pos = hit.point; face = hit.triangleIndex; hitSomething = true; } } return(hitSomething); }
public void Handle(Asset asset) { if (asset.EnableWaypointEditing) { if (_snapToPlane && asset.SelectedWaypoint != null) { asset.SelectedWaypoint.Position.y = asset.HelperPlaneY; } switch (Event.current.type) { case EventType.Layout: break; case EventType.KeyDown: if (Event.current.keyCode == KeyCode.LeftControl) { _snapToPlane = true; } break; case EventType.KeyUp: if (Event.current.keyCode == KeyCode.C) { if (asset.WaypointState != WaypointState.CONNECT) { asset.WaypointState = WaypointState.CONNECT; } else { asset.WaypointState = WaypointState.NONE; } } if (Event.current.keyCode == KeyCode.R && asset.SelectedWaypoint != null) { if (asset.SelectedWaypoint == null) { break; } Waypoint.DeletePoint(asset, asset.SelectedWaypoint); } if (Event.current.keyCode == KeyCode.A) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); Vector3 hitPosition = Vector3.zero; EditorHandles_UnityInternal.SceneRaycastHit hit; if (EditorHandles_UnityInternal.IntersectRayGameObject(ray, asset.GameObject, out hit)) { hitPosition = hit.point; } else { Plane plane = new Plane(Vector3.up, new Vector3(0, asset.HelperPlaneY, 0)); float enter = 0; plane.Raycast(ray, out enter); hitPosition = ray.GetPoint(enter); } asset.SelectedWaypoint = Waypoint.addWaypoint(asset, hitPosition); } if (Event.current.keyCode == KeyCode.O && asset.SelectedWaypoint != null) { asset.SelectedWaypoint.IsOuter = !asset.SelectedWaypoint.IsOuter; } if (Event.current.keyCode == KeyCode.I && asset.SelectedWaypoint != null) { asset.SelectedWaypoint.IsRabbitHoleGoal = !asset.SelectedWaypoint.IsRabbitHoleGoal; } if (Event.current.keyCode == KeyCode.LeftControl) { _snapToPlane = false; } SceneView.RepaintAll(); HandleUtility.Repaint(); break; } //render helper plane Vector3 topLeft = new Vector3(-((float)asset.FootprintX) / 2.0f, 0, (float)asset.FootprintZ / 2.0f) + asset.GameObject.transform.position + new Vector3(0, asset.HelperPlaneY, 0); Vector3 topRight = new Vector3(((float)asset.FootprintX) / 2.0f, 0, (float)asset.FootprintZ / 2.0f) + asset.GameObject.transform.position + new Vector3(0, asset.HelperPlaneY, 0); Vector3 bottomLeft = new Vector3(-((float)asset.FootprintX) / 2.0f, 0, -(float)asset.FootprintZ / 2.0f) + asset.GameObject.transform.position + new Vector3(0, asset.HelperPlaneY, 0); Vector3 bottomRight = new Vector3(((float)asset.FootprintX) / 2.0f, 0, -(float)asset.FootprintZ / 2.0f) + asset.GameObject.transform.position + new Vector3(0, asset.HelperPlaneY, 0); Color fill = Color.white; fill.a = 0.1f; Handles.zTest = CompareFunction.LessEqual; Handles.color = Color.yellow; Handles.DrawSolidRectangleWithOutline(new[] { topLeft, topRight, bottomRight, bottomLeft }, fill, Color.black); Handles.zTest = CompareFunction.Always; } for (int x = 0; x < asset.Waypoints.Count; x++) { if (asset.EnableWaypointEditing && asset.Waypoints[x] == asset.SelectedWaypoint) { Handles.color = Color.red; } else if (asset.Waypoints[x].IsOuter) { Handles.color = Color.green; } else if (asset.Waypoints[x].IsRabbitHoleGoal) { Handles.color = Color.blue; } else { Handles.color = Color.yellow; } Vector3 worldPos = asset.Waypoints[x].Position + asset.GameObject.transform.position; Handles.zTest = CompareFunction.LessEqual; if (Handles.Button(worldPos, Quaternion.identity, HandleUtility.GetHandleSize(worldPos) * 0.2f, HandleUtility.GetHandleSize(worldPos) * 0.2f, Handles.SphereHandleCap)) { if (asset.EnableWaypointEditing) { handleClick(asset, asset.Waypoints[x]); } } Handles.color = Color.blue; foreach (int connectedIndex in asset.Waypoints[x].ConnectedTo) { Handles.DrawLine(worldPos, asset.Waypoints[connectedIndex].Position + asset.GameObject.transform.position); } Handles.color = Color.white; Handles.Label(worldPos, "#" + x); Handles.zTest = CompareFunction.Always; } if (asset.EnableWaypointEditing && asset.SelectedWaypoint != null) { Vector3 worldPos = asset.SelectedWaypoint.Position + asset.GameObject.transform.position; if (asset.WaypointState == WaypointState.CONNECT) { Handles.Label(worldPos, "\nConnecting..."); } else { asset.SelectedWaypoint.Position = asset.GameObject.transform.InverseTransformPoint( Handles.PositionHandle( asset.GameObject.transform.TransformPoint(asset.SelectedWaypoint.Position), Quaternion.identity)); Handles.Label(worldPos, "\n(A)dd\n(C)onnect\n(R)emove\n(O)uter\nRabb(i)t Hole"); } } }