Select 一个游戏对象并使用 GUI.Button (EventTrigger) 执行操作
Select a game object and perform actions using GUI.Button (EventTrigger)
我目前正在开发一款策略游戏,我想在游戏对象上使用 GUI.Button 执行动作。我正在使用光线投射和鼠标单击 select 对象,但是当我单击 GUI.Button 执行另一个操作时,按钮消失了。我想用那个按钮打开另一个 GUI.Box 来显示一些描述。
我知道为什么按钮消失了,这是因为我在更新功能中将光线投射到我的按钮点击上,但我该如何避免这种情况?我也知道我必须使用 EventTrigger 但是我不熟悉 javascript 事件触发器,我在网上搜索但找不到任何有用的 javascript.
截图:
这是我的脚本:
@HideInInspector
var isCalled:int = 0;
@HideInInspector
var scWidth:int = 0;
@HideInInspector
var scHeight:int = 0;
function Start () {
scWidth = Screen.width;
scHeight = Screen.height;
}
function Update () {
if (Input.GetMouseButtonDown(0)) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
}
function OnGUI(){
if(isCalled==1)
GUI.Button(Rect(scWidth/2,(scHeight/2)+(scHeight/4),120,120), name);
}
}
如果我没理解错的话,问题是当你点击按钮时,光线投射在按钮点击之前被触发,你 select 不同的对象或根本没有对象,按钮消失或重新出现,但另一个对象,您需要做的是检查您是否单击了 GUI,如果是,则不要投射 select 对象的光线投射。这是你要怎么做。
var selectedUI : GameObject = EventSystem.current.currentSelectedGameObject;
if (Input.GetMouseButtonDown(0) && selectedUI) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
我在 C# 工作,所以我可能犯了一些语法错误,但逻辑是正确的。
我认为最简单的方法是创建一个不可见但有碰撞器的游戏对象(输入拦截器)。将它放在相机和水平物体之间并停用它。当您 select 使用 Raycast 的 GameObject 时,您会启用该输入拦截器 GameObject 并将其放置在 selected GameObject 和 GUI 的区域周围。如果光线投射与输入拦截器发生碰撞,则您必须忽略 selection。当你 deselect 游戏对象时,你就停用了输入拦截器
您还应该维护游戏的当前状态,例如:
enum State
{
NothingSelected = 0,
GameobjectSelected,
BigMenuOpen
}
State currentState;
因此您可以根据状态定义鼠标单击时的行为。就像如果全屏菜单打开然后光线投射不会触发。
当鼠标悬停在 GUI 元素上时,使用旧版 GUI 系统时有一个很好的技巧可以避免光线投射。使用工具提示来控制你是否可以投射光线 =)
类似这样的事情(我也不在美国工作,所以我可能需要一些工作):
var hover : String;
function OnGUI(){
if(GUI.Button (Rect (10,10,100,20), "My Button"));
hover = GUI.tooltip;
function Update () {
if(hover != "") {
// raycast logic
}
}
如果您需要在 "popUp" window/panel 显示时避免光线投射,但又不想在其上显示工具提示,您也可以使用 MouseOverGUI 管理器。
它只是一个静态或单例,包含一个布尔值,当您的鼠标悬停在您不想使用 Rect.Contains(Event.current.mousePosition) 和每当它用完这个矩形时为假。
在有或没有工具提示变量的情况下使用此布尔值以允许光线投射:
if(!MouseManager.MouseOverGUI) {
// raycast logic
}
请注意,在每个 OnGUI 循环中创建您的矩形将很难捕获它并控制 MouseOveGUI。这对性能来说也是一种不好的做法,因为 OnGUI 每帧运行不止一次,所以我建议你只创建一次 rects(只在需要时重新计算)并将它传递给你的 GUI 元素 ;)
我目前正在开发一款策略游戏,我想在游戏对象上使用 GUI.Button 执行动作。我正在使用光线投射和鼠标单击 select 对象,但是当我单击 GUI.Button 执行另一个操作时,按钮消失了。我想用那个按钮打开另一个 GUI.Box 来显示一些描述。
我知道为什么按钮消失了,这是因为我在更新功能中将光线投射到我的按钮点击上,但我该如何避免这种情况?我也知道我必须使用 EventTrigger 但是我不熟悉 javascript 事件触发器,我在网上搜索但找不到任何有用的 javascript.
截图:
这是我的脚本:
@HideInInspector
var isCalled:int = 0;
@HideInInspector
var scWidth:int = 0;
@HideInInspector
var scHeight:int = 0;
function Start () {
scWidth = Screen.width;
scHeight = Screen.height;
}
function Update () {
if (Input.GetMouseButtonDown(0)) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
}
function OnGUI(){
if(isCalled==1)
GUI.Button(Rect(scWidth/2,(scHeight/2)+(scHeight/4),120,120), name);
}
}
如果我没理解错的话,问题是当你点击按钮时,光线投射在按钮点击之前被触发,你 select 不同的对象或根本没有对象,按钮消失或重新出现,但另一个对象,您需要做的是检查您是否单击了 GUI,如果是,则不要投射 select 对象的光线投射。这是你要怎么做。
var selectedUI : GameObject = EventSystem.current.currentSelectedGameObject;
if (Input.GetMouseButtonDown(0) && selectedUI) {
var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit)) {
if (hit.collider.tag == "House") {
isCalled = 1;
} else{
isCalled = 0;
}
}
}
我在 C# 工作,所以我可能犯了一些语法错误,但逻辑是正确的。
我认为最简单的方法是创建一个不可见但有碰撞器的游戏对象(输入拦截器)。将它放在相机和水平物体之间并停用它。当您 select 使用 Raycast 的 GameObject 时,您会启用该输入拦截器 GameObject 并将其放置在 selected GameObject 和 GUI 的区域周围。如果光线投射与输入拦截器发生碰撞,则您必须忽略 selection。当你 deselect 游戏对象时,你就停用了输入拦截器 您还应该维护游戏的当前状态,例如:
enum State
{
NothingSelected = 0,
GameobjectSelected,
BigMenuOpen
}
State currentState;
因此您可以根据状态定义鼠标单击时的行为。就像如果全屏菜单打开然后光线投射不会触发。
当鼠标悬停在 GUI 元素上时,使用旧版 GUI 系统时有一个很好的技巧可以避免光线投射。使用工具提示来控制你是否可以投射光线 =)
类似这样的事情(我也不在美国工作,所以我可能需要一些工作):
var hover : String;
function OnGUI(){
if(GUI.Button (Rect (10,10,100,20), "My Button"));
hover = GUI.tooltip;
function Update () {
if(hover != "") {
// raycast logic
}
}
如果您需要在 "popUp" window/panel 显示时避免光线投射,但又不想在其上显示工具提示,您也可以使用 MouseOverGUI 管理器。
它只是一个静态或单例,包含一个布尔值,当您的鼠标悬停在您不想使用 Rect.Contains(Event.current.mousePosition) 和每当它用完这个矩形时为假。
在有或没有工具提示变量的情况下使用此布尔值以允许光线投射:
if(!MouseManager.MouseOverGUI) {
// raycast logic
}
请注意,在每个 OnGUI 循环中创建您的矩形将很难捕获它并控制 MouseOveGUI。这对性能来说也是一种不好的做法,因为 OnGUI 每帧运行不止一次,所以我建议你只创建一次 rects(只在需要时重新计算)并将它传递给你的 GUI 元素 ;)