Автор Тема: выстрел в направлении курсора мыши в 2d  (Прочитано 9804 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Январь 02, 2014, 17:42:35 pm
Прочитано 9804 раз

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
Добрый день. Не могу разобраться, как сделать выстрел в направлении курсоры мыши. Взял пример https://www.assetstore.unity3d.com/#/content/11228 с официального сайта. В данном проекте снаряд летит по координате X.
Вот кусок кода:
if(Input.GetButtonDown("Fire1"))
{
// ... set the animator Shoot trigger parameter and play the audioclip.
anim.SetTrigger("Shoot");
audio.Play();

// If the player is facing right...
if(playerCtrl.facingRight)
{
// ... instantiate the rocket facing right and set it's velocity to the right.
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(new Vector3(0,0,0))) as Rigidbody2D;
bulletInstance.velocity = new Vector2(speed, 0);

}
else
{
// Otherwise instantiate the rocket facing left and set it's velocity to the left.
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(new Vector3(0,0,180f))) as Rigidbody2D;
bulletInstance.velocity = new Vector2(-speed, 0);
}
}

т.е. по левому клику мышки, вылетает снаряд, в зависимости куда смотрит персонаж (влево или вправо)
bulletInstance.velocity = new Vector2(speed, 0);
где speed - движение по x со скоростью,
0 - координата Y.
Как направить снаряд в ту точку, где была нажата кнопка мыши?
Спасибо за ответ.

Январь 02, 2014, 18:38:31 pm
Ответ #1

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2454
  • Репутация:
    153
    • Просмотр профиля
ну в этом  же примере снаряд физикой движется. а тебе оно надо?
И вообще, нужно ли снаряд куда-то пускать? в реальности, ни снарядов ни пуль глазом не видно.
так что можно просто стрелять лучём рейкаста, и имитировать выстрел и попадание.

Январь 02, 2014, 22:05:03 pm
Ответ #2

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
ну в этом  же примере снаряд физикой движется. а тебе оно надо?
И вообще, нужно ли снаряд куда-то пускать? в реальности, ни снарядов ни пуль глазом не видно.
так что можно просто стрелять лучём рейкаста, и имитировать выстрел и попадание.
Мне надо, чтобы было видно как движется снаряд, в данном случае ракета, вот тут http://youtu.be/4qE8cuHI93c?t=10m30s видно, что ракета может лететь только по прямой, а мне надо сделать, чтобы ракета летела в то место, куда кликнули мышкой.

Январь 02, 2014, 22:27:17 pm
Ответ #3

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2454
  • Репутация:
    153
    • Просмотр профиля
ну вопервых, ракеты  обычно летят по параболической траектории.   а так,  преобразуешь с помощью рейкаста, координаты мышки в координаты 3D:

Ray ray = camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;   

//если попали мышкой в коллайдер, находим эту точку:
if(Physics.Raycast(ray, out hit, 1000f)){//Расстояние распознавания - не более 1000м. если нужнор бесконечность - Mathf.Infinity

    Debug.DrawLine (сamera.position, hit.point, Color.red, 0, false);//чертим красную линию, для отладки через Gizmo

    //наши действия

    //точка клика мышкой = hit.point;
}

И тебе остаётся всего лишь двигать ракету от пусковой установки, до найденой точки клика (её лучше запомнить в переменную цели для ракеты)
Параболу можно сделать, с помощью небольшого интегрированого отклонения вверх, либо с помощью алгебраических функций.
« Последнее редактирование: Январь 02, 2014, 22:31:01 pm от Mimi Neko »

Январь 03, 2014, 00:13:56 am
Ответ #4

Zylaks

  • Активный участник

  • Оффлайн
  • ****

  • 271
  • Репутация:
    2
    • Просмотр профиля
ну в этом  же примере снаряд физикой движется. а тебе оно надо?
И вообще, нужно ли снаряд куда-то пускать? в реальности, ни снарядов ни пуль глазом не видно.
так что можно просто стрелять лучом рейкаста, и имитировать выстрел и попадание.

Глазом не видно, но ведь есть же баллистика, патрон по любому когда-нибудь упадет или луч можно пустить по дуге?0_0

Январь 03, 2014, 00:17:59 am
Ответ #5

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2454
  • Репутация:
    153
    • Просмотр профиля
Цитировать
Глазом не видно, но ведь есть же баллистика, патрон по любому когда-нибудь упадет или луч можно пустить по дуге?0_0
ну и зачем это в игре? если хочешь изобразить падение снаряда  на  землю - просто отспавнь или поставь его в ту точку, на которую укажет рейкаст.  траектория может быть баллистической, но прицеливание идёт по прямой  линии обычно.

Январь 03, 2014, 13:39:18 pm
Ответ #6

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
Сделал так (заместо сamera поставил Camera.main):
Ray ray =  Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;   

//если попали мышкой в коллайдер, находим эту точку:
if(Physics.Raycast(ray, out hit, 1000f)){//Расстояние распознавания - не более 1000м. если нужнор бесконечность - Mathf.Infinity

Debug.DrawLine (Camera.main.position, hit.point, Color.red, 0, false);//чертим красную линию, для отладки через Gizmo

//наши действия

//точка клика мышкой = hit.point;
}
Теперь выдаются ошибки:
Assets/Scripts/Gun.cs(118,69): error CS1061: Type `UnityEngine.Camera' does not contain a definition for `position' and no extension method `position' of type `UnityEngine.Camera' could be found (are you missing a using directive or an assembly reference?)

Assets/Scripts/Gun.cs(118,47): error CS1502: The best overloaded method match for `UnityEngine.Debug.DrawLine(UnityEngine.Vector3, UnityEngine.Vector3, UnityEngine.Color, float, bool)' has some invalid arguments

Assets/Scripts/Gun.cs(118,47): error CS1503: Argument `#1' cannot convert `object' expression to type `UnityEngine.Vector3'



И еще такой вопрос, из кода выше, там комментарий, "если попали мышкой в коллайдер, находим эту точку:", так мы же в коллайдер не попадаем, моно кликать же в любую точку экрана, просто должен в ту точку будет лететь снаряд (ракета или еще что-нибудь).

Январь 03, 2014, 13:49:58 pm
Ответ #7

LiGuB

  • Пользователь

  • Оффлайн
  • **

  • 61
  • Репутация:
    5
    • Просмотр профиля

замени
Debug.DrawLine (Camera.main.position, hit.point, Color.red, 0, false)
на
Debug.DrawLine(ray.origin, hit.point, Color.red);

Январь 03, 2014, 14:43:14 pm
Ответ #8

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля

замени
Debug.DrawLine (Camera.main.position, hit.point, Color.red, 0, false)
на
Debug.DrawLine(ray.origin, hit.point, Color.red);
Заменил, ошибку не выдает, но условие if(Physics.Raycast(ray, out hit, 1000f) всегда false получается.

Январь 03, 2014, 14:45:50 pm
Ответ #9

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2454
  • Репутация:
    153
    • Просмотр профиля
если ты мышкой собираешся тыкать туда, гже вообще нет коллайдеров, то рейкаст тебе тут бесполезен.
А без него видимо, не получить точку клика мышкой, в  3D пространстве.

Январь 06, 2014, 14:16:40 pm
Ответ #10

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
Я могу определить где я кликнул мышкой (подсказали как сделать), вот код:
public Rigidbody2D rocket; // Prefab of the rocket.
public GameObject target; // пустышка

Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(new Vector3(0,0,0))) as Rigidbody2D;
float force = 1000f;
target.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
target.transform.position = new Vector3(target.transform.position.x, target.transform.position.y, 0);
rocket.transform.LookAt(target.transform, rocket.transform.up); //если нос ракеты направлен по оси x то rocket.transform.right
Vector3 forceVector = rocket.transform.TransformDirection(new Vector3(0, force, 0));//если нос ракеты направлен по оси x то new Vector3(force, 0, 0)
bulletInstance.rigidbody2D.AddForce(new Vector2(forceVector.x, forceVector.y));

Но ракета все равно летит не туда, на картинки 1 показано, где кликаю и куда летит ракета.
В какую бы точку экрана я бы не нажал, снаряд вылетает всегда верх и угол полета меняется незначительно, прикрепил картинку и указал область куда вылетают снаряды.



Январь 06, 2014, 16:10:25 pm
Ответ #11

Mimi Neko

  • Администратор
  • Старожил форума

  • Оффлайн
  • *****

  • 2454
  • Репутация:
    153
    • Просмотр профиля
Только щас заметил, в названии темы у тебя же написано, что 2D игра.
с 2D как-то иметь дело не приходилось в Юнити. Да и с физикой тоже...

Август 23, 2014, 17:16:02 pm
Ответ #12

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
Вопрос все еще актуален, буду очень благодарен за помощь.

Август 24, 2014, 14:33:55 pm
Ответ #13

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
Решил проблему, если кому надо:
float rocketSpeed = 2000;
Rigidbody2D bulletInstance = Instantiate(rocket, transform.position, Quaternion.Euler(new Vector3(0, 0, 0))) as Rigidbody2D;
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 dir = Input.mousePosition - pos;
bulletInstance.transform.LookAt(dir);
bulletInstance.rigidbody2D.AddForce(bulletInstance.transform.forward * rocketSpeed);

На картинке видно что снаряд летит в ту точку, которую надо.

Июнь 18, 2015, 11:13:07 am
Ответ #14

bserg

  • Новичок

  • Оффлайн
  • *

  • 8
  • Репутация:
    1
    • Просмотр профиля
С новыми версиями unity этот скрипт неправильно работает, вот рабочий код:
float speed = 500f;
Vector3 pos = Input.mousePosition;
pos.z = transform.position.z - Camera.main.transform.position.z;
pos = Camera.main.ScreenToWorldPoint(pos);
Quaternion q = Quaternion.FromToRotation(Vector3.up, pos - transform.position);
Rigidbody2D go = Instantiate(rocket, transform.position, q) as Rigidbody2D;
go.GetComponent<Rigidbody2D>().AddForce(go.transform.up * speed);