2015-08-25 9 views
1

В настоящее время я работаю над стратегической игрой, и я хочу преформировать действия, используя GUI.Button на игровых объектах. Я использую ray cast и click для выбора объекта, однако, когда я нажимаю на GUI.Button, чтобы вынуть другое действие, кнопка исчезает. Я хочу использовать эту кнопку, чтобы открыть еще один GUI.Box, чтобы показать некоторые описания.Выберите игровой объект и выполните действия с помощью GUI.Button (EventTrigger)

Я знаю, почему кнопка исчезает, потому что я проецирую лучи на мои кнопки нажатием кнопки в функции обновления, но как я могу избежать этого? Я также знаю, что мне нужно использовать EventTrigger, но я не знаком с триггером javascript, я искал в Интернете, но я не мог найти полезный javascript.

Скриншоты:

enter image description here

enter image description here

Вот мой сценарий:

@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); 
    } 
} 
+0

вы можете попытайтесь объяснить еще раз, чего вы пытаетесь достичь? Вы хотите нажать кнопку, скрыть ее и показать другой элемент GUI? – Mad

+0

Да, это похоже на знаменитое игровое столкновение кланов. например, когда вы нажимаете кнопку «Обновить», открывается другая страница с описанием. Поскольку это функция обновления, raycast продолжает проверять столкновение с предоставленными тегами, поэтому, когда я нажимаю на кнопку одновременно, raycast снимается с камеры на кнопку, и поскольку кнопка не имеет никаких тегов, которые она обнаруживает ничего и ничего не показывает – Arsaceus

+0

Итак, не используйте raycast для обнаружения нажатия кнопки. Обычно вы можете использовать 'if (GUI.Button (...) {// делать вещи при нажатии кнопки}' – Mad

ответ

2

Если я понял, вы правы, проблема в том, что при нажатии на кнопку raycast является до щелчка кнопки, и вы выбираете другой объект или вообще нет объекта, а кнопка исчезает или появляется снова, но для что вам нужно сделать, это проверить, щелкнули ли вы на графическом интерфейсе, и если да, не проецируйте raycast, который выбирает объекты. Вот как вы это сделаете.

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#, поэтому я, возможно, допустил некоторые синтаксические ошибки, но логика правильная.

+0

Спасибо Neven Я вижу, что логика правильная, я думаю, что я выясню, что вызывает проблему. это заявление else, которое дает нам головную боль, когда еще что-то удалено, проблема решена наполовину. – Arsaceus

+0

Есть ли способ пометить элемент GUI, например, кнопки? – Arsaceus

+0

Конечно, у нас есть ссылка на конечный пользовательский интерфейс (EventSystem.current.currentSelectedGameObject), с помощью которого мы можем делать все, что захотим. Вы можете сделать некоторые тесты, например, если (selectedUI.name == "что-то) или выбраннымUI.tag или selectedUI.layer, или мы можем написать собственный скрипт и заставить его получить доступ к этому скрипту и проверить тип, у вас есть тысячи способов сделайте это, выберите то, что вам подходит. –

0

Я думаю, что самый простой способ - создать GameObject (блокиратор ввода), который не виден, но имеет коллайдер. Поместите его между камерой и объектами уровня и отключите ее. Когда вы выбираете GameObject с помощью Raycast, вы включаете этот блок-редактор GameObject и размещаете его вокруг области выбранного GameObject и GUI. Затем вы должны игнорировать выбор, если raycast сталкивается с Блокиром ввода. Когда вы снимите флажок геймобжекты затем деактивировать входной блокатор Вы должны также поддерживать текущее состояние игры, например:

enum State 
{ 
    NothingSelected = 0, 
    GameobjectSelected, 
    BigMenuOpen 
} 
State currentState; 

Итак, в соответствии с состоянием вы можете определить поведение при щелчке мыши. Например, если открыто полноэкранное меню, тогда raycast не срабатывает.

+0

Да, это похоже на хорошее исправление, однако оно не работает в некоторых сценариях, например, пользователь сначала выбирает игровой объект (House), затем появляется кнопка для этого игрового объекта (кнопка House), и мы блокируем raycast с помощью скрытого объекта gameObject теперь пользователь решает щелкнуть по другому объекту gameObject, а не щелкнуть по кнопке ... игра держится там, потому что у пользователя нет другого выбора, кроме как нажать кнопку. – Arsaceus

+0

Вот почему я упомянул, что вы будете блокировать только конкретная область вокруг выбранного GameObject не всех. –

2

Существует хороший трюк при использовании устаревшей GUI-системы, чтобы избежать raycast, когда мышь над элементами 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 
    } 
} 

Если вам нужно, чтобы избежать raycast когда отображается окно/панель «popUp», но вы не хотите использовать всплывающую подсказку, вы также можете использовать менеджер MouseOverGUI.

Это просто статический или синглтон, содержащий логическое значение, которое вы установите true, когда ваша мышь находится над некоторым прямоугольником, который вы не хотите наносить лучами, используя Rect.Contains (Event.current.mousePosition) и false при каждом запуске из этого прямоугольника.

Используйте этот BOOL с или без подсказки вара, чтобы raycast:

if(!MouseManager.MouseOverGUI) { 
    // raycast logic 
} 

Обратите внимание, что при создании вашего прямоугольника на каждом OnGUI цикла будет трудно поймать его и контролировать MouseOveGUI. Кроме того, это плохая практика для производительности, потому что OnGUI работает более одного раза за фрейм, поэтому я предлагаю вам сразу создать ваши исправления (пересчитать их по мере необходимости) и передать их вашим элементам GUI;)

+0

Этот ответ звучит многообещающе, я попробую его через час и дам вам знать результат. – Arsaceus