Unity(Мировые координаты мыши)
(2D)Если камера стоит в координатах x>0,y0,y>0, есть небольшое смещение, с чем это связано?
#1
17:15, 9 авг 2015
Не воспроизводится. Камера перспективная или ортографическая? Небольшое смещение ― это сколько?
#2
2:15, 10 авг 2015
Ортографическая камера. Я попадаю мышкой в координату, которая должна в итоге округлится и затем поставить объект, но он появляется ниже. А если видимая область будет с отрицательным Y, то все работает точно. Смещение буквально несколько пикселей. Используется стандартная камера Unity на 2D проект с z = -10.
#3
2:22, 10 авг 2015
Округления бывают
— в отрицательную сторону,
— в положительную сторону,
— в сторону нуля,
— к ближайшему чётному целому.
У тебя, значит, выбран неподходящий к задаче тип округления. Если подходящий, то в любом случае проблема в коде после Camera.main.ScreenToWorldPoint().
#4
2:26, 10 авг 2015
В данном случае, я просто превращаю флоат в инт. Я так понимаю 1,99 превратятся в 1? Мне нужно узнать, в какой клетке произошел клик.
i = (int) pos.x;
j = (int) pos.y;
pos.x = i;
pos.y = j;
obj = Instantiate (Resources.Load (Item.itemName)) as GameObject;
obj.transform.position = pos;
Опять же по Х все ок, он положителен.
#5
2:35, 10 авг 2015
Приведение к целому типа просто отбрасывает дробную часть. Получается округление в сторону нуля.
+1,99 превратится в +1, т.е. уменьшится
–1,99 превратится в –1, т.е. увеличится
По идее, тебе нужно использовать один из дрвух вариантов:
Mathf.Ceil() — округляет вверх
Mathf.Floor() — округляет вниз
#6
2:42, 10 авг 2015

Я попробовал с этой функцией — никакого эффекта, по сути мне и нужно отбрасывание дробной части. Не думаю, что дело с округление, так как смещение исключительно идет по оси Y в отрицательную часть.
Также если область будет в X0,Y
Центр = 0.
#7
2:50, 10 авг 2015
Ок. Предположим, есть четыре точки:
Какой должен быть результат после округления их координат?
#8
2:51, 10 авг 2015
#9
2:53, 10 авг 2015
И ещё ― у тебя центр координат попадает на границу между четырьмя клетками или в центр одной клетки?
#10
2:57, 10 авг 2015

Аналогично. Если брать в расчет отрицательные координаты, то в центр. Но в положительных — это начало сетки.
Так как я хочу использовать только положительные координаты, то в отрицательные мышь не сможет попасть.
#11
15:11, 10 авг 2015
lexaiko
> Смещение буквально несколько пикселей.
Сколько у тебя пикселей на экране в единице мировых координат?
#12
19:14, 10 авг 2015

Разное. Зависит от Size ортограф. камеры. Спрайты, которые я использую, равны 128*128 для 1 клетки в Юнити.
Кстати при положении камеры в Х0 смещение идет ровно в 1 клетку Юнити.
Х0 — кликаем в клетку 1, в любую ее часть, — объект появляется в клетке 2.
Х>0,Y И т.д. т.е при X>0,Y>0 — кликнули клетку 1, а объект будет клеткой ниже.
#13
19:23, 10 авг 2015
Я подобную проблему решал добавлением CellSize * 0.5 к координатам перед округлением.
#14
19:34, 10 авг 2015
Я подобную проблему решал добавлением CellSize * 0.5 к координатам перед округлением.
Удивительно, но таким образом действительно работает. Стоило переключить якорь спрайта в середину и стало работать точно при любых Х и У. Раньше же был якорь в левом верхнем углу, но это позволяло не изменять координаты. Почему же второй способ дает такое смещение?
Как отслеживать transform позицию курсора мыши в Unity2d?
Я делаю игру песочницу, в ней объекты создаются нажатием мыши. Но я не нашёл кода который выдавал бы transform позицию, Input.MousePosition выдаёт позицию в пикселях а использовать это в transform position слишком крупно для игры с размером камеры 0.5.
Отслеживать
задан 1 июн 2021 в 16:38
Фёдор Матвеев Фёдор Матвеев
3 2 2 бронзовых знака
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
ScreenToWorldPoint(Vector3 position);
где position x,y — экранная точка, а z — глубина на которой нужно разместить обьект на сцене.
Отслеживать
ответ дан 1 июн 2021 в 20:49
Andrew Stop_RU_war_in_UA Andrew Stop_RU_war_in_UA
19k 6 6 золотых знаков 35 35 серебряных знаков 98 98 бронзовых знаков
- c#
- unity3d
- transform
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
2д стрельба в сторону курсора мыши на Unity

Приветствую начинающих разработчиков. В данной статье мы научимся производить выстрелы, направленные в позицию курсора мыши. Для этого разобъём нашу статью на 2 части:
- В первой части данной статьи мы будем рассматривать простую реализацию стрельбу
- А во второй части, на основе простой стрельбы, мы сделаем так, чтобы стрельба происходило в направлении курсора мыши.
Так же хочется обратить Ваше внимание, что в одной из предыдущих статей мы рассматривали, как сделать простую реализацию стрельбы. Поэтому, чтобы не повторяться, первую часть данной статьи мы рассмотрим кратко, и в упрощённой форме.
Простая реализация стрельбы
Первым делом создадим префаб пули. Обязательно добавьте к нему компонент Rigidbody2d. А в поле Body Type данного компонента, укажите значение Kinematic — чтобы на пулю не дейстовала гравитация.

Теперь создаём для префаба нашей пули новый компонет(скрипт C#), и назовём его, например, Bullet. Данный скрипт должен производить полёт пули в указанное направление и с определённой скоростью, а так же уничтожать сам себя по истечении определённого времени, чтобы пуля не летела бесконечно долго.
Пропишем всё это в нашем скрипте:
using UnityEngine; public class Bullet : MonoBehaviour < public float timeDestroy = 3f; public float speed = 3f; public Rigidbody2D rb; void Start() < rb = GetComponent(); rb.velocity = transform.up * speed; Invoke("DestroyBullet", timeDestroy); > void DestroyBullet() < Destroy(this.gameObject); >>
Давайте разберём данный код:
- В строках #5-7 мы объявили три переменные: timeDestroy — для самоуничтожения пули; speed — для указании скорости пули; rb — которая будет хранить ссылку на компонент Rigidbody2D.
- В строках #11-13 мы сначала получили ссылку на компонент Rigidbody2D. Потом указали движение нашей пули вверх. А так же указали, что через 3 секунды запустится метод DestroyBullet, который уничтожит наш объект пули.
Наша пуля готова. Как только она появится в игровой сцене, она автоматически будет лететь вверх, и через 3 секунды пропадёт.
Теперь нам нужно сделать саму стрельбу персонажа, чтобы по клике мыши он создавал эту пулю. Для этого создадим скрипт C# для нашего персонажа. Скрипт назовём Player, и впишем в данный скрипт следующее содержимое:
using UnityEngine; public class Player : MonoBehaviour < public GameObject bullet; void Update() < if (Input.GetKeyDown(KeyCode.Mouse0)) < Instantiate(bullet, transform.position, Quaternion.identity); >> >
В строке #5 мы объявили переменную bullet, в которой будет хранится ссылка на наш префаб пули. Поэтому обязательно перетащите префаб пули в поле bullet в Инспекторе.
А в строке #11 с помощью метода Instantiate() мы создаём пулю на игровой сцене, из вашего префаба пули. И она сразу же будет осуществлять полёт вверх.
Стрельба в направление курсора мыши
Мы добрались до самого интересного. Для того, чтобы стрельба осуществлялась в направлении курсора мыши, первым делом нам необходимо определить, в какой же позиции игрового пространства располагается наша мышь, чтобы при появлении нашей пули, она летела не вверх, а в направлении курсора мыши. Поэтому и весь следующий код мы должны прописывать в скрипте Bullet, который находится на префабе нашей пули.
Пропишем следующую строчку:
Vector3 diference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
Если вкратце, то она находит векторные координаты курсора относительно объекта пули. А если более подробней, то рекоммендуем посетить нашу статью по определении позиции курсора мыши.
Далее нам нужно развернуть нашу пулю в сторону позиции курсора мыши, для это пропишем следующее:
float rotateZ = Mathf.Atan2(diference.y, diference.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0f, 0f, rotateZ);
Используя данные в переменной diference, с помощью метода Mathf.Atan2 мы получает угол в радианах. А потом с помощью константы Mathf.Rad2Deg, мы преобразовываем преобразовывает радиан в градусы.
Затем с помощью метода Quaternion.Euler мы получаем значение поворота, и присваиваем это значение нашему персонажу.
Готово! Теперь склеим всё что мы написали с кодом из персой части скрипта Bullet префаба пули. Весь код выглядит так:
using UnityEngine; public class Bullet : MonoBehaviour < public float timeDestroy = 3f; public float speed = 3f; public Rigidbody2D rb; void Start() < rb = GetComponent(); Vector3 diference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position; float rotateZ = Mathf.Atan2(diference.y, diference.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0f, 0f, rotateZ); rb.velocity = transform.up * speed; Invoke("DestroyBullet", timeDestroy); > void DestroyBullet() < Destroy(this.gameObject); >>
Поздравляем, теперь пуля сразу при появлении на сцене, единоразово сделает поворот в сторону пули, а потом запустит её туда.
Тема была сложная, но надеюсь у меня получилось объяснить данную тему. Но если остались вопросы, пишите в комментариях.
База знаний
Мы ведь не знаем, когда игрок кликнет мышью по экрану.
Поэтому всегда нужно проверять его клик.
Функция Update срабатывает каждый кадр (работает всегда), а значит писать код будем в ней.
«Если игрок кликнул». так и запрограммируем.
Начнем с программирования «Если» Для этого пишем конструкцию условия if () <>.
«Если» запрограммировали. Теперь программируем «игрок кликнул».
Клик ловится в Unity с помощью уже заранее написанного разработчиками Unity класса Input.
Класс — это такой же скрипт, как и мы с вами сейчас пишем, но разработчики Unity уже заранее его написали этот скрипт, который ловит все клики мыши, нажатия клавиш.
Собственно input в переводе с английского означает «ввод».
Мышь и клавиатура — устройства ввода информации в компьютер.
Вот и класс с названием Input ловит нажатия мыши и клавиатуры.
Я это к тому, что смотрите как называются классы и функции в Unity, а можем и во всем программировании и пробуйте перевести, тогда может будет понятней что делает этот код.
Короче пишем между скобочек Input. Получится вот так
Но нам не нужно ловить нажатия всех клавиш.
Только клик мыши.
В классе Input для этого есть функция GetMouseButtonDown().
Как переводится?)
«Получить Мышь Кнопка Нажата»)) С помощью нее можно поймать нажатие кнопки мыши.
Чтобы вызвать функцию у класса — надо поставить точку после класса и написать функцию, которую хотим вызвать.
В нашем случае получается такой код
Между скобочек GetMouseButtonDown() нужно ввести число.
От числа зависит нажатие какой кнопки мыши ловит функция — левой, правой или колесика?
В программировании «нужно ввести число между скобочек» звучало бы как «функция принимает параметр в виде числа».
Запоминайте, товарищи программисты:)
Сейчас я хочу поймать нажатие левой кнопкой мыши — поэтому ввожу туда 0.
Получится в итоге вот такой код
Сейчас расскажу, как я узнал про эту функцию.
Я ведь как и вы не знал что это так делается в Unity.
Я зашел на сайт Unity в раздел Scripting (раздел скриптов) и там нашел функцию как поймать клик мыши.
Вот ссылка — https://docs.unity3d.com/ScriptReference/30_search.html?q=GetMouseButtonDown
Сначала я просто гуглю в интернете типа «Unity как поймать клик мыши».
Там люди предлагают какие-то варианты по ссылкам, я оттуда беру функции. Захожу на сайт
— https://docs.unity3d.com/ScriptReference/index.html и смотрю, что на самом деле делают эти функции в игре.
Вы можете делать также и много чего нового можете узнать о том как программировать в Unity.
Узнавать про новые функции, потом приходить в клуб и удивлять своими знаниями всех и даже преподавателей).
Если будете там копаться, как минимум английский подтянете))
Возвращаемся в скрипт. У нас получился такой код
Мы запрограммировали «Если игрок кликнул левой кнопкой мыши».
А что произойдет, если он кликнул?
Это нужно программировать между <>.
Пусть, например, в консоль выводится текст.
Напомню консоль это вот это окно в Unity.
Выводить информацию в консоль поможет функция Debug.Log().
Между скобок пишем «Нажали». В кавычках, потому что это текст.
И получается Debug.Log(«Нажали»);
В общем получается такой код
if (Input.GetMouseButtonDown(0)) <
Debug.Log(«Нажали»);
>
Заходим в Unity.
Надеюсь вы подключили скрипт в объект на сцене, если нет — спросите кого-то как это сделать, иначе скрипт не заработает.
Кликаем по экрану.
Смотрим в консоль — Вау! Появляется текст!
И теперь мы умеем ловить клик мыши.
Узнаем позицию клика мыши
Есть у класса Input переменная mousePosition.
Чтобы её вызвать, пишем Input.mousePosition (заметьте вызываем переменную также, как функцию, через точку.
Но у переменной в конце нет скобочек)
Давайте в консоль выведем позицию мыши.
Вместо «Нажали» вызовем эту переменную.
Получится такой код
if (Input.GetMouseButtonDown(0)) <
Debug.Log(Input.mousePosition);
>
Запускаем игру.
Кликаем по сцене.
Видим в консоли позицию клика.
Посмотрите в консоль внимательно.
Мы видим там сразу три числа.
Так в unity хранится позиция объектов.
Это 3 координаты (x, y, z).
На гифке показываю, где X