例如,我发现Unity插件“ Octave3d Level Design”具有此功能
由于Octave3d预制管理器不适合我的需求,所以我希望成为自己的预制管理器。所以问题是:当鼠标与“场景视图”重叠时,如何使鼠标抓住一个对象并将其放入“场景视图”中?
答案 0 :(得分:1)
编辑: 实际发现您需要使用SceneView.lastActiveSceneView.camera作为相机,并且可以使用Gizmos.DrawMesh()绘制网格而不是实例化。.
还有SceneView.OnSceneGUIDelegate可以帮助您访问场景视图。
这是一些有关如何进行设置的示例代码
void OnGUI() {
if (objectThatFollowsMouse != null) {
SceneView.onSceneGUIDelegate -= OnSceneGUI;
SceneView.onSceneGUIDelegate += OnSceneGUI;
}
else { SceneView.onSceneGUIDelegate -= OnSceneGUI; }
}
void OnSceneGUI(SceneView sceneView) {
...
}
通过一些其他编辑器脚本,您可以执行以下操作
Vector3 mousePoint = Camera.main.ViewportToWorldPoint(Input.mousePosition);
if (objectShouldFollowMouse) {
objectThatFollowsMouse.transform.position = mousePoint;
if (Event.current.type == EventType.MouseUp) {
objectShouldFollowMouse = false;
objectThatFollowsMouse = null;
}
}
if (prefabGotClicked) {
GameObject obj = Object.Instantiate(someObject,mousePoint,Quaternion.identity) as GameObject;
objectShouldFollowMouse = true;
objectThatFollowsMouse = obj;
}
答案 1 :(得分:0)
在Octave3d
中,他们通过以下方式实现了这个功能:
preview
游戏对象,预览游戏对象将跟随鼠标(通过其自定义光线投射检测)。预览游戏对象的父级是八度音程管理器或类似的东西。而且我认为这有点矫枉过正,像 Unity 自己的 DragAndDrop 这样的东西就足够了:预制件可以从自定义编辑器窗口拖动,然后放到场景视图、层次结构或对象字段上强>。而这个自定义拖放可以这样实现:
MouseDownEvent
以启动 DragAndDropDragUpdatedEvent
以移动拖动对象Dropping
,请在 ongui 回调中收听 DragPerform
和 DragExited
。代码在这里:
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class MyWindow : EditorWindow
{
[MenuItem("Window/MyWindow")]
private static void ShowWindow()
{
GetWindow<MyWindow>("MyWindow");
}
private GameObject prefab;
private bool m_IsDragPerformed = false;
private bool m_IsDragging = false;
private void OnEnable()
{
prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Cube.prefab");
var box = new VisualElement();
box.style.backgroundColor = Color.red;
box.style.flexGrow = 1f;
box.RegisterCallback<MouseDownEvent>(evt =>
{
DragAndDrop.PrepareStartDrag();
DragAndDrop.StartDrag("Dragging");
DragAndDrop.objectReferences = new Object[] { prefab };
Selection.activeGameObject = null;
m_IsDragPerformed = false;
m_IsDragging = true;
});
box.RegisterCallback<DragUpdatedEvent>(evt =>
{
DragAndDrop.visualMode = DragAndDropVisualMode.Move;
});
rootVisualElement.Add(box);
SceneView.duringSceneGui += sv => OnDragEnd();
EditorApplication.hierarchyWindowItemOnGUI += (id, rect) => OnDragEnd();
}
private void OnDragEnd()
{
if (Event.current.type == EventType.DragPerform)
{
m_IsDragPerformed = true;
}
if (Event.current.type == EventType.DragExited)
{
if (m_IsDragging && m_IsDragPerformed)
{
m_IsDragging = false;
m_IsDragPerformed = false;
var go = Selection.activeGameObject;
// Do your **OnDragEnd callback on go** here
}
}
}
private void OnDestroy()
{
SceneView.duringSceneGui -= sv => OnDragEnd();
EditorApplication.hierarchyWindowItemOnGUI -= (id, rect) => OnDragEnd();
}
}
参考在这里,这家伙是个天才:How to start DragAndDrop action so that SceneView and Hierarchy accept it like with prefabs