C# 用户界面与统一立场

C# 用户界面与统一立场,c#,unity3d,C#,Unity3d,我有一个问题,我希望能够点击屏幕上的“磁贴”,然后在磁贴旁边显示一个弹出菜单。我可以点击瓷砖,然后弹出菜单出现,但不是我想要的地方 在图片上,我点击了左上角的一个 我放置图片的代码如下: using UnityEngine; using System.Collections; public class TowerMenu : MonoBehaviour { bool showMenu = false; float x; float y; GUIStyle my

我有一个问题,我希望能够点击屏幕上的“磁贴”,然后在磁贴旁边显示一个弹出菜单。我可以点击瓷砖,然后弹出菜单出现,但不是我想要的地方

在图片上,我点击了左上角的一个

我放置图片的代码如下:

using UnityEngine;
using System.Collections;

public class TowerMenu : MonoBehaviour 
{
    bool showMenu = false;
    float x;
    float y;
    GUIStyle myStyle;

    public Texture2D[] towers;

    void OnGUI()
    {
        if(showMenu)
        {
            //Bear tower
            GUI.Button(new Rect(x + 10, y - 25, 50, 50), towers[0]);
            //Seal tower
            GUI.Button(new Rect(x + 10, y + 25, 50, 50), towers[1]);
        }
    }

    public void ShowMenu(Vector2 pos)
    {
        showMenu = true;
        x = pos.x;
        y = pos.y;
    }
}

希望任何人都能帮助我:)

从外观上看,您的
ShowMenu
方法接收到的pos为(0,0),这就是为什么两个按钮分别位于(10,-25)和(10,25)的位置

在没有看到调用
ShowMenu
的代码的情况下,我无法确定您给出的位置,但我猜测这些分幅属于父对象,并且您传递的是本地位置而不是世界位置

如果您发布调用
ShowMenu
的代码,我可能会指出任何问题

编辑:

根据评论中提供的信息,问题在于位置需要在世界坐标和屏幕坐标之间转换:

void OnMouseDown()
        {
                if(state == State.water)
                {
                        errorHandler.sendError("You can't click on that");
                }

                if(state == State.ice)
                {
                        towerMenu.ShowMenu(camera.WorldToViewportPoint(this.transform.position));
                }
        }
并将ShowMenu更改为:

public void ShowMenu(Vector3 pos)
    {
        showMenu = true;
        x = pos.x;
        y = pos.y;
    }

从外观上看,您的
ShowMenu
方法接收到的pos为(0,0),这就是为什么两个按钮分别位于(10,-25)和(10,25)的位置

在没有看到调用
ShowMenu
的代码的情况下,我无法确定您给出的位置,但我猜测这些分幅属于父对象,并且您传递的是本地位置而不是世界位置

如果您发布调用
ShowMenu
的代码,我可能会指出任何问题

编辑:

根据评论中提供的信息,问题在于位置需要在世界坐标和屏幕坐标之间转换:

void OnMouseDown()
        {
                if(state == State.water)
                {
                        errorHandler.sendError("You can't click on that");
                }

                if(state == State.ice)
                {
                        towerMenu.ShowMenu(camera.WorldToViewportPoint(this.transform.position));
                }
        }
并将ShowMenu更改为:

public void ShowMenu(Vector3 pos)
    {
        showMenu = true;
        x = pos.x;
        y = pos.y;
    }

Sry,我不能评论,因为我没有足够的代表,这是对Steven Mills的评论,是对该帖子的回答和评论

第一个错误是因为您调用WorldToViewportPoint时,好像它是一个静态成员函数,而它不是(想象一下,如果您有两个摄像头,您必须指定您想要的摄像头,在这里读取静态成员的内容会很有帮助)。要解决此问题,您需要做的是获取MainCamera的引用并从该实例调用函数(最好的方法可能是使用公共变量并在编辑器中的脚本上拖动camera)

出现第二个错误是因为您试图为ShowMenu()指定一个矢量3,而ShowMenu()需要一个矢量2。第三个可能是编译器试图修复错误2的结果

这是一个逻辑错误,因为平铺是游戏对象,因此transform.position是3d空间中的位置。您真正想要的是主摄像头屏幕上的2d像素位置。要获取此信息,您需要调用WorldToViewportPoint而不是WorldToViewportPoint。不幸的是,正如你所注意到的,这里还有一个向量3,这不是你想要的,但是你可以把x和y坐标作为你的像素屏幕坐标。z坐标表示与摄影机的距离

希望它能把你弄清楚一点,而不是把你弄糊涂;D


欢迎再次提问,但也请尝试阅读Unity脚本参考资料,并尝试理解其中所写内容及其含义:)

Sry,我无法评论,因为我没有足够的代表,这是对Steven Mills的评论,请回答并评论该帖子

第一个错误是因为您调用WorldToViewportPoint时,好像它是一个静态成员函数,而它不是(想象一下,如果您有两个摄像头,您必须指定您想要的摄像头,在这里读取静态成员的内容会很有帮助)。要解决此问题,您需要做的是获取MainCamera的引用并从该实例调用函数(最好的方法可能是使用公共变量并在编辑器中的脚本上拖动camera)

出现第二个错误是因为您试图为ShowMenu()指定一个矢量3,而ShowMenu()需要一个矢量2。第三个可能是编译器试图修复错误2的结果

这是一个逻辑错误,因为平铺是游戏对象,因此transform.position是3d空间中的位置。您真正想要的是主摄像头屏幕上的2d像素位置。要获取此信息,您需要调用WorldToViewportPoint而不是WorldToViewportPoint。不幸的是,正如你所注意到的,这里还有一个向量3,这不是你想要的,但是你可以把x和y坐标作为你的像素屏幕坐标。z坐标表示与摄影机的距离

希望它能把你弄清楚一点,而不是把你弄糊涂;D


请尽管再问一次,但也请尝试阅读Unity脚本参考,并尝试理解其中所写的内容及其含义:)

我不清楚从您的图片中,什么表示“平铺”以及什么表示“弹出”。此外,您似乎正在通过X轴上的
10
偏移弹出位置,这可能与您的问题有关。unity标签是针对Microsoft unity的。请不要误用它。从您的图片中,我不清楚什么表示“平铺”和什么表示“弹出”。此外,您似乎正在通过X轴上的
10
偏移弹出窗口的位置,这可能与您的问题有关。unity标签是针对Microsoft unity的。请不要误用它。这是调用显示菜单的代码:瓷砖的工作方式是有两种状态,冰和水。当它是水时,你不允许点击它;当它是冰时,你可以点击它,然后弹出菜单。瓦片围棋是由3个东西组成的,一个空围棋和一个对撞机,还有两个小孩围棋和一个我可以切换的冰水精灵。当我点击冰砖时,我得到了空围棋的位置,出于某种原因,它的位置是从3到-3。就像你可以