Движение призрака за курсором

Общие вопросы о Unity3D

Движение призрака за курсором

Сообщение justDaemon 29 май 2017, 19:11

Доброго времени суток. Новичок в Unity, пытаюсь реализовать постройку объектов по алгоритму:
1) Игрок нажимает на кнопку "Постройка"
2) Появляется "призрак" постройки который двигается за курсором
3) По второму нажатию кнопки мыши постройка ставится на карте

Проблема в том что по нажатии на кнопку "Постройка", создаётся объект из префаба сразу на том месте где он находился при удалении из иерархии, вообщем на своих стандартных координатах. Ни как не могу понять в чём проблема. Буду благодарен за помощь. Заранее спасибо

Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BuildMenu : MonoBehaviour {
 public int width = 200;
    public int height = 35;
 
    public GameObject prefab;
   
    GameObject instance;
 
    void Update() {
 
        if (instance != null)
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                    {
                        if (hit.transform.name == "Ground")
                            {
                                instance.transform.position = hit.point;
                            }
                    }
           
                if (Input.GetMouseButton(0))
                    {
                        instance = null;
                    }
            }
 
    }
   
    void OnGUI() {
 
        GUILayout.BeginArea(new Rect(Screen.width/2 - width/2,
                                     Screen.height - height,
                                     width,
                                     height), "", "box");
       
        GUI.enabled = (instance == null);
        if (GUILayout.Button("Постройка"))
            {
                 instance = (GameObject)GameObject.Instantiate(prefab);
            }
        GUILayout.EndArea();
    }
}
justDaemon
UNец
 
Сообщения: 8
Зарегистрирован: 26 май 2017, 19:44

Re: Движение призрака за курсором

Сообщение Valentinus 29 май 2017, 19:22

Input.GetMouseButton(0) выдает не событие нажатия, а состояние нажатия кнопки.
когда вы жмете на кнопку "Постройка", то Input.GetMouseButton(0) выдает вам состояние еще не отпущенной левой клавиши мыши, и дом ставится на место.
другое мое творчество: samlib.ru/u/us_w/
Аватара пользователя
Valentinus
Старожил
 
Сообщения: 889
Зарегистрирован: 24 мар 2017, 18:33

Re: Движение призрака за курсором

Сообщение justDaemon 29 май 2017, 23:17

Valentinus писал(а):Input.GetMouseButton(0) выдает не событие нажатия, а состояние нажатия кнопки.
когда вы жмете на кнопку "Постройка", то Input.GetMouseButton(0) выдает вам состояние еще не отпущенной левой клавиши мыши, и дом ставится на место.


спасибо большое :ymhug:
justDaemon
UNец
 
Сообщения: 8
Зарегистрирован: 26 май 2017, 19:44

Re: Движение призрака за курсором

Сообщение justDaemon 30 май 2017, 19:00

Valentinus писал(а):Input.GetMouseButton(0) выдает не событие нажатия, а состояние нажатия кнопки.
когда вы жмете на кнопку "Постройка", то Input.GetMouseButton(0) выдает вам состояние еще не отпущенной левой клавиши мыши, и дом ставится на место.

а как будет записать более корректно и что бы работало?
justDaemon
UNец
 
Сообщения: 8
Зарегистрирован: 26 май 2017, 19:44

Re: Движение призрака за курсором

Сообщение samana 30 май 2017, 20:54

Наверно можно было бы переделать код, но сейчас голова не работает. Попробуйте поменять на НАжатие мыши Input.GetMouseButtonDown(0) или даже на ОТжатие Input.GetMouseButtonUp(0).
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Движение призрака за курсором

Сообщение Valentinus 30 май 2017, 21:32

samana писал(а):Наверно можно было бы переделать код, но сейчас голова не работает. Попробуйте поменять на НАжатие мыши Input.GetMouseButtonDown(0) или даже на ОТжатие Input.GetMouseButtonUp(0).

Можно, но несколько неудобно для пользователя.
Правильно завести переменную типа bool. При нажатии кнопки Построить устанавливать ее, при отжатии кнопки мыши - сбрасывать. А в условии нажатия (где строится дом) проверять чтоб переменная была сброшена (т.е. кнопка мыши была отжата перед этим). Сможете реализовать?
другое мое творчество: samlib.ru/u/us_w/
Аватара пользователя
Valentinus
Старожил
 
Сообщения: 889
Зарегистрирован: 24 мар 2017, 18:33

Re: Движение призрака за курсором

Сообщение justDaemon 31 май 2017, 05:26

Valentinus писал(а):Правильно завести переменную типа bool. При нажатии кнопки Построить устанавливать ее, при отжатии кнопки мыши - сбрасывать. А в условии нажатия (где строится дом) проверять чтоб переменная была сброшена (т.е. кнопка мыши была отжата перед этим). Сможете реализовать?


сразу извиняюсь если что то делаю не так, пока учусь)) Если я вас правильно понял то вы про это

Синтаксис:
Используется csharp
public bool building;

Синтаксис:
Используется csharp
        if (instance != null)
                        {
                                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                        RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                                        {
                                                if (hit.transform.name == "Ground")
                                                        {
                                        instance.transform.position = hit.point;
                                        }
                        }
           
                if (Input.GetMouseButtonDown(0))
                                        {
                                                if (building == false)
                                                        {
                                                                building = true;
                                                        }
                                                else{
                                                        Debug.Log("DOWN.");
                                        instance = null;
                                                }
                        }

                                if (Input.GetMouseButtonUp(0))
                                        {
                                                building = false;
                                                Debug.Log("UP.");
                                                instance = null;
                        }
                }
justDaemon
UNец
 
Сообщения: 8
Зарегистрирован: 26 май 2017, 19:44

Re: Движение призрака за курсором

Сообщение samana 31 май 2017, 05:59

Valentinus писал(а):Правильно завести переменную типа bool. При нажатии кнопки Построить устанавливать ее, при отжатии кнопки мыши - сбрасывать.

В данном случае роль такого флага у автора играет переменная instance.

Кстати, я скопировал код из первого топика, чтобы проверить и оказалось, что всё и так работает корректно. Да, объект появляется в центре, но стоит пошевелить мышь, чтобы луч ткнулся в ground и дом без проблем перемещается в это место, а после нажатия мыши устанавливается в месте клика. Ведь инстанс создаётся по клику на GUI кнопке (то-есть это срабатывает после mouseUp кнопки) и if (Input.GetMouseButton(0)) в Update никак не может сработать в этом же кадре, так как мышь уже отжата в этот момент. В общем я не знаю, почему ваш код у вас неправильно работает :-??

А Valentinus, имел ввиду сделать как-то так:
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BuildMenu : MonoBehaviour
{
    public int width = 200;
    public int height = 35;

    public GameObject prefab;

    GameObject instance;
    bool _isBuild;

    void Update()
    {

        if (_isBuild)
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                if (hit.transform.name == "Ground")
                {
                    instance.transform.position = hit.point;
                }
            }

            if (Input.GetMouseButtonDown(0))
            {
                _isBuild = false;
                instance = null;
            }
        }

    }

    void OnGUI()
    {

        GUILayout.BeginArea(new Rect(Screen.width / 2 - width / 2,
                                     Screen.height - height,
                                     width,
                                     height), "", "box");

        GUI.enabled = (instance == null);
        if (GUILayout.Button("Постройка"))
        {
            instance = (GameObject)GameObject.Instantiate(prefab);
            _isBuild = true;
        }
        GUILayout.EndArea();
    }
}
 


но это работает так же, как и первый ваш код, то-есть корректно.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Движение призрака за курсором

Сообщение Valentinus 31 май 2017, 08:29

justDaemon писал(а):
сразу извиняюсь если что то делаю не так, пока учусь)) Если я вас правильно понял то вы про это


не совсем, можно проще :
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class BuildMenu : MonoBehaviour {
 public int width = 200;
    public int height = 35;
    public GameObject prefab;
   
    GameObject instance;

bool mouse_btn0=false;

 
    void Update() {
 
        if (instance != null)
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                    {
                        if (hit.transform.name == "Ground")
                            {
                                instance.transform.position = hit.point;
                            }
                    }
           
                 if (Input.GetMouseButtonUp(0)) mouse_btn0=false;

                if (Input.GetMouseButton(0) && mouse_btn0==false)
                    {
                        instance = null;
                    }
            }
 
    }
   
    void OnGUI() {
 
        GUILayout.BeginArea(new Rect(Screen.width/2 - width/2,
                                     Screen.height - height,
                                     width,
                                     height), "", "box");
       
        GUI.enabled = (instance == null);
        if (GUILayout.Button("Постройка"))
            {
                 instance = (GameObject)GameObject.Instantiate(prefab);
mouse_btn0=true;
            }
        GUILayout.EndArea();
    }
}


samana писал(а):В данном случае роль такого флага у автора играет переменная instance.

нет, по ней не получится

samana писал(а):
Кстати, я скопировал код из первого топика, чтобы проверить и оказалось, что всё и так работает корректно. Да, объект появляется в центре, но стоит пошевелить мышь, чтобы луч ткнулся в ground и дом без проблем перемещается в это место, а после нажатия мыши устанавливается в месте клика. Ведь инстанс создаётся по клику на GUI кнопке (то-есть это срабатывает после mouseUp кнопки) и if (Input.GetMouseButton(0)) в Update никак не может сработать в этом же кадре, так как мышь уже отжата в этот момент. В общем я не знаю, почему ваш код у вас неправильно работает :-??


это смотря как сделать сцену.
если кнопка визуально поверх Ground , то движок сразу пропускает рейкаст через кнопку до Ground . по крайней мере в новом GUI (c канвасами) именно так, приходится отсекать рейкасты на UI вручную. думаю и в старом GUI тоже самое ( или может он начинает пропускать после GUI enable = false)
поэтому код может в некторых случаях работать, но лучше его написать нормально, с анализом отпускания кнопки мыши.

samana писал(а): вильно работает :-??

А Valentinus, имел ввиду сделать как-то так:

не тестировал, но имхо это работать не будет, т.к. после нажатия кнопки Построить сразу сработает if (_isBuild) и выполнение пройдет до
if (Input.GetMouseButtonDown(0))
Последний раз редактировалось Valentinus 31 май 2017, 13:51, всего редактировалось 4 раз(а).
другое мое творчество: samlib.ru/u/us_w/
Аватара пользователя
Valentinus
Старожил
 
Сообщения: 889
Зарегистрирован: 24 мар 2017, 18:33

Re: Движение призрака за курсором

Сообщение justDaemon 31 май 2017, 08:50

Кстати, я скопировал код из первого топика, чтобы проверить и оказалось, что всё и так работает корректно. Да, объект появляется в центре, но стоит пошевелить мышь, чтобы луч ткнулся в ground и дом без проблем перемещается в это место, а после нажатия мыши устанавливается в месте клика. Ведь инстанс создаётся по клику на GUI кнопке (то-есть это срабатывает после mouseUp кнопки) и if (Input.GetMouseButton(0)) в Update никак не может сработать в этом же кадре, так как мышь уже отжата в этот момент. В общем я не знаю, почему ваш код у вас неправильно работает :-??


Поправьте пожалуйста если не прав, у меня скрипт висит на камере, как я понимаю в данном случае не играет роли. Или нет?
justDaemon
UNец
 
Сообщения: 8
Зарегистрирован: 26 май 2017, 19:44

Re: Движение призрака за курсором

Сообщение Valentinus 31 май 2017, 09:09

justDaemon писал(а):
Поправьте пожалуйста если не прав, у меня скрипт висит на камере, как я понимаю в данном случае не играет роли. Или нет?

не играет роли.
выше я отписался почему у кого-то код может работать, а у кого-то - нет.
другое мое творчество: samlib.ru/u/us_w/
Аватара пользователя
Valentinus
Старожил
 
Сообщения: 889
Зарегистрирован: 24 мар 2017, 18:33

Re: Движение призрака за курсором

Сообщение samana 31 май 2017, 15:59

Valentinus писал(а):это смотря как сделать сцену.
если кнопка визуально поверх Ground , то движок сразу пропускает рейкаст через кнопку до Ground . по крайней мере в новом GUI (c канвасами) именно так, приходится отсекать рейкасты на UI вручную. думаю и в старом GUI тоже самое

Может в новом UI это и так, но у автора темы используется GUI. И повторюсь, что луч при нажатии на кнопку даже не пустится, так как instance или булева переменная-флаг получит значение только при клике по кнопке, то-есть в тот момент, когда кнопка будет отжата. Получается только в момент отжатия кнопки, разрешится доступ для пускания луча и ситуация с одновременным нажатием на кнопку и выполнение кода в Update c if (Input.GetMouseButt) просто невозможно.

Valentinus писал(а):не тестировал, но имхо это работать не будет, т.к. после нажатия кнопки Построить сразу сработает if (_isBuild) и выполнение пройдет до
if (Input.GetMouseButtonDown(0))

Нет, выполнение не дойдёт, я уже написал почему так) Так я же специально проверил в Unity тогда, поэтому работать будет. Хотя код автора у меня тоже работает правильно.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Движение призрака за курсором

Сообщение Valentinus 31 май 2017, 17:06

samana писал(а): луч при нажатии на кнопку даже не пустится, так как instance или булева переменная-флаг получит значение только при клике по кнопке, то-есть в тот момент, когда кнопка будет отжата. Получается только в момент отжатия кнопки, разрешится доступ для пускания луча и ситуация с одновременным нажатием на кнопку и выполнение кода в Update c if (Input.GetMouseButt) просто невозможно.

я с старым GUI почти не работал, поэтому не могу сказать когда GUILayout.Button начинает выдавать true, но готов поверить вам.

upd^ проверил, действительно GUILayout.Button выдает true только после отпускания кнопки. значит причина сбоя у автора в чем-то другом.
Последний раз редактировалось Valentinus 31 май 2017, 22:27, всего редактировалось 1 раз.
другое мое творчество: samlib.ru/u/us_w/
Аватара пользователя
Valentinus
Старожил
 
Сообщения: 889
Зарегистрирован: 24 мар 2017, 18:33

Re: Движение призрака за курсором

Сообщение samana 31 май 2017, 17:12

Valentinus писал(а):но готов поверить вам

Спасибо :)
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Движение призрака за курсором

Сообщение justDaemon 01 июн 2017, 14:39

Огромное спасибо всем за помощь! Понял в чём была ошибка. Названия не совпадали, в названии в инспекторе случайно пропустил букву и было Grond. x_x
так обидно что аж смешно. Извините за то что отнял время зря ^:)^
justDaemon
UNец
 
Сообщения: 8
Зарегистрирован: 26 май 2017, 19:44


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12