c# - Unity编辑器捕获 "hold mouse down and move"事件

标签 c# unity3d

我正在统一创建一个简单的 tilemap 编辑器扩展,因为默认的扩展缺少我的项目需要的很多功能。我正在继承 EditorWindow。 当按住鼠标左键并拖动鼠标时,我想在场景中放置瓷砖(在编辑器模式下)。

下图说明了我想要的行为。

enter image description here :

我面临的问题是如何识别这个事件。这是我使用的处理鼠标输入的函数:

void HandleMouseInput() {
    Event e = Event.current;
    switch (e.type) {
    case EventType.MouseDown:
        if (e.button == 0) PlaceTile();
        break;
    case EventType.MouseMove:
        Debug.Log("Moving");
        Debug.Log(e.button); // <-- always show 0 (left click) even though mouse is not clicked.
        break;
    }
}

第一种情况(单个图 block 放置)按预期工作。但是我没能捕捉到“按住鼠标左键”的事件。我可以捕获鼠标移动事件 EventType.MouseMove 但我需要知道是否有左键单击。根据 unity 文档,e.button == 0 表示左键单击(在第一个开关案例中按预期工作)。但在第二种情况下,e.button 始终为 0,无论单击哪个鼠标按钮。还有一个 EventType.MouseDrag,但它似乎只在您在场景中选择一个游戏对象并拖动它时触发。

在 Unity 中,当按住鼠标左键并移动鼠标时,默认行为似乎是创建一个选择框:

enter image description here

或者如果选择了编辑器左上角的手形图标,则拖动整个场景。

本质上,我想捕获此事件并用我自己的功能覆盖结果。

编辑:我想我可以通过创建自定义工具来解决这个问题 https://docs.unity3d.com/ScriptReference/EditorTools.EditorTool.html

最佳答案

好吧,我没有继承 EditorWindow,而是创建了一个自定义工具 TileTool 并将所有逻辑放在其中。

在它的 OnToolGUI(等效于 OnGUI?)中,我可以禁用框选择:

HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));

然后自动正确捕获事件 EventType.MouseDrag,我达到了预期的效果。

整个脚本:

[EditorTool("Tile Tool")]
class TileTool : EditorTool
{
    // Serialize this value to set a default value in the Inspector.
    [SerializeField]
    Texture2D icon;



    public override GUIContent toolbarIcon =>
        new GUIContent() {
            image = icon,
            text = "Tile Tool",
            tooltip = "Tile Tool"
        };


    public override void OnToolGUI(EditorWindow window) {
        HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
        HandleMouse();
    }

    void HandleMouse() {
        Event e = Event.current;
        switch (e.type) {
            case EventType.MouseDown:
                if (e.button == 0) ApplyLeftClickTool();
                break;
            case EventType.MouseDrag:
                if (e.button == 0) ApplyLeftClickTool();
                break;
        }
    }



    void ApplyLeftClickTool() {
        switch (TilemapEditor.Instance().ActiveTool) {
        case TilemapEditor.TileTool.BRUSH:
                PlaceTile();
                break;
        case TilemapEditor.TileTool.ERASER:
                EraseTile();
                break;
        }
    }

    void PlaceTile() {
        GameObject prefab = TilemapEditor.Instance().Selected;
        GetTilemap().Place(prefab, MouseInWorld());
    }

    void EraseTile() {
        GetTilemap().Erase(MouseInWorld());
    }

    PrefabTilemap GetTilemap() {
        PrefabTilemap tilemap = FindObjectOfType<PrefabTilemap>();
        if (tilemap == null) {
            GameObject tilemapGO = new GameObject("Tilemap");
            tilemap = tilemapGO.AddComponent<PrefabTilemap>();
            tilemap.Init();
        }
        return tilemap;
    }

    Vector2 MouseInWorld() {
        return HandleUtility.GUIPointToWorldRay(Event.current.mousePosition).origin;
    }
}

关于c# - Unity编辑器捕获 "hold mouse down and move"事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63040319/

相关文章:

c# - 从 URL 获取 TIF 并将其移动到 C# 中的 Azure Blob 存储中

c# - 在 Unity 中访问场景之间的信息

c# - 在 Unity 应用启动时阅读 Android intent 额外数据

c# - Vector3.magnitude 和 vector3.normalized 解释

c# - C# 的异常层次结构

c# - Ninject——如何使用 Parallel.ForEach 循环中使用的类进行 IOC

android - Unity Gradle构建失败

unity3d - Unity 中缺少 GVRMain 文件

c# - Windows Phone 8.1 listview 点击更改页面

c# - 非严格的多接口(interface)类型参数约束?