版本: Unity3D 4.6.2f1
我有一个瓷砖网格(多维数据集GameObject
s附加Tile
脚本)。它们位于其索引位置[x][y] = (x, y, z=0) World Coordinates
。
我正在尝试实现类似于扫雷的行为:当释放左键时,除非右键单击,否则将显示释放鼠标的图块。下面,我尝试获取鼠标左键单击的图块坐标。
进入代码之前:
OnMouseDown()
- 当用户在GUIElement或Collider上方按下鼠标按钮时,会调用OnMouseDown。OnMouseUp()
- 当用户释放鼠标按钮时调用OnMouseUp。
基于这些定义,我假设(错误?)OnMouseUp()
将被其上方的对象调用,鼠标左键单击被释放。
在Tile
脚本上,我有以下内容:
public class Tile : MonoBehaviour
{
// variables
private Vector2 _gridPosition = Vector2.zero;
public Vector2 GridPosition
{
get { return _gridPosition; }
set { _gridPosition = value; }
}
// functions
string Vec2toText(Vector2 v)
{
return String.Format("(" + v.x + ", " + v.y + ")");
}
void OnMouseDown()
{
Debug.Log("TILE:: ON_MOUSE_DOWN:: " + Vec2toText(_gridPosition));
}
void OnMouseUp()
{
Debug.Log("TILE:: ON_MOUSE_UP:: " + Vec2toText(_gridPosition));
}
void OnMouseEnter()
{
Debug.Log("TILE:: MOUSE_ENTER: " + Vec2toText(_gridPosition));
}
void OnMouseExit()
{
Debug.Log("TILE:: MOUSE_EXIT: " + Vec2toText(_gridPosition));
}
}
here是输出:
TILE:: MOUSE_ENTER: (15, 15)
TILE:: MOUSE_DOWN: (15, 15)
TILE:: MOUSE_EXIT: (15, 15)
TILE:: MOUSE_ENTER: (14, 15)
TILE:: MOUSE_UP: (15, 15) %% This line
TILE:: MOUSE_EXIT: (14, 15)
如果我可以在(14,15)
函数上获得OnMouseUp()
,我会直接找到要显示的图块,但显然我不能。我认为我的目标的解决方法是保留static bool _isDragging
并在OnMouseEnter()
块的if
中使用它来指定要正确显示的磁贴。这是 - 由同一个对象调用两个函数,即使我按下左键单击某个对象并将其释放到其他对象上? - 打算?这种情况有更好的解决方法吗?
答案 0 :(得分:1)
OnMouseDown仅针对鼠标左键发出。所以你必须自己实施右击。
一个选项是按下按钮时检查光线投射。
void Update()
{
if (Input.GetMouseButtonDown(1))
{
var ray = camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo))
{
var myObject = hitInfo.collider.GetComponent<MyScriptOrSomething>();
// Do something here
}
}
}
另一个选项是使用OnMouseEnter来检查右键单击。类似的东西:
void OnMouseOver()
{
if (Input.GetMouseButtonDown(1))
{
// Do something here
}
}
修改强>
OnMouseUp调用您单击的磁贴的原因很简单。这种行为在大多数情况下是最安全和更预期的方式。将游戏对象的鼠标事件想象成&#34;用户点击我&#34;和&#34;用户在点击我之后发布了按钮&#34;。
因此,让我们说鼠标按钮释放时,光标下的对象会调用OnMouseUp。想象一下从鼠标点击开始的操作,并在鼠标按钮释放时完成(如拖放)。然后你会痛苦地发现,如果鼠标不再指向你最初点击的对象,就不会调用OnMouseUp。您无法完成操作。您必须自己捕捉鼠标释放事件。
在您的情况下,仅OnMouseUp和OnMouseDown就无法满足您的需求。您要做的事情对您的应用来说太具体了。不幸的是,Unity的输入系统默认不包括这种交互。幸运的是,Unity足够灵活,可以轻松实现这一点。
答案 1 :(得分:0)
作为更好的解决方法,请使用static bool _isDragging
函数,而不是使用void OnMouseOver()
:
void OnMouseOver()
{
if(Input.GetMouseButtonUp(0)) // left click released
RevealTile();
if(Input.GetMouseButtonUp(1)) // right click released
FlagTile();
}