Jump to content

Все о Raycast.


photo

Recommended Posts

Привет.

Ray в разработке игр это один из основных инструментов, так что я собрал все что смог найти в одном месте. В Unigine этот функционал называется Intersections.

Перво-наперво конечно же смотрим туториал:

Spoiler

 

 

Скрипт из видео (что за дурацкая привычка не прикреплять УЖЕ написанный скрипт к видео?)

Spoiler
using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "Ваш ID скрипта")]
public class PlayerControl : Component
{
	Player player;
  WorldIntersection intersection = new WorldIntersection();
  Unigine.Object lastSelected = null;
  static vec4 lastSelectedColor;

  private void Init()
  {
    Unigine.Console.Run("console_onscreen 1");
    player = Game.Player;
  }

  private void Update()
  {
    if(Input.IsMouseButtonDown(Input.MOUSE_BUTTON.LEFT))
    {
      ivec2 mouse = Input.MouseCoord;
      vec3 p0 = player.WorldPosition;
      vec3 p1 = p0 + new vec3(player.GetDirectionFromScreen(mouse.x, mouse.y)) * 100;
      Unigine.Object obj = World.GetIntersection(p0, p1, 1, intersection);

      if(obj)
      {
        if(lastSelected)
          lastSelected.GetMaterial(0).SetParameterFloat4("albedo_color", lastSelectedColor);

        lastSelected = obj;
        lastSelectedColor = lastSelected.GetMaterial(0).GetParameterFloat4("albedo_color");

        obj.GetMaterial(0).SetParameterFloat4("albedo_color", vec4.WHITE);

        Log.Message(node.Name + ". Работа скрипта " + this + ". Изменили цвет объекту {0} \n", obj.Name);
      }
    }
  }
}

 

Покурив поиск я нашел следующее:

Документация (внимательно смотрим версию документации):

1) Intersections - общая информация

2) GetIntersection - ссылка на функционал World (нижу будет ссылка на пост где разработчики дают подробные комментарии по ее аналогам).

3) Самое важное, которое конечно же вы найдете через неделю активного поиска - Managing Intersections. Здесь даются сразу несколько примеров использования, включая пуск луча из центра экрана в курсор мыши (Внимание! Корректно работает на first_person_controller начиная с версии 2.12).

Так же, вы можете наткнуться на что-то типа getDirectionFromScreen, что может ввести вас в некоторое заблуждение.

Кроме того, еще можно найти - Migrating to Unigine from Unity

 

С форума, где разработчики дают некоторые пояснения:

1) 

2) 

 

 

 

Edited by nikolay.sykharev
Link to comment

Сборка из Managing Intersections:

Spoiler

//---------------- FINDING THE FIRST OBJECT INTERSECTED BY A RAY CAST FROM P0 to P1 --------------

			// initializing points of the ray from player's position in the direction pointed by the mouse cursor 
			ivec2 mouse = Input.MouseCoord;
			dvec3 p0 = player.WorldPosition;
			dvec3 p1 = p0 + new dvec3(player.GetDirectionFromScreen(mouse.x, mouse.y)) * 100;

			//creating a WorldIntersection object to store the information about the intersection
			WorldIntersection intersection = new WorldIntersection();

			// casting a ray from p0 to p1 to find the first intersected object
			Object obj = World.GetIntersection(p0, p1, 1, intersection);

			// print the name of the first intersected object and coordinates of intersection point if any
			if (obj)
			{
				dvec3 p = intersection.Point;
				Log.Message("The first object intersected by the ray at point ({0}) is: {1} \n ", p, obj.Name);
			}

 

не работает корректно с нативным FirstPersonController версии ниже 2.12. Так что если у вас по какой-то причине до сих пор версия ниже, то используйте либо свой FPS на основе например PlayerDummy, либо PlayerSpectator.

Edited by nikolay.sykharev
Link to comment

Привет.

Сейчас попробовал повторить пример с интерсекшеном для FirstPersonController. Для этого использовал прикрепленную компоненту MouseIntersection.cs. В качестве значения для player использовал Game.Player. При этом интерсекшен корректно отрабатывает для всех объектов. Можете проверить работоспособность данной компоненты в вашем примере?

MouseIntersection.cs

Link to comment
3 hours ago, karpych11 said:

Можете проверить работоспособность данной компоненты в вашем примере?

Для чистоты экперимента создал новый World, удалил PlayerSpectator, поставил FirstPersonController, закинул MouseIntersection в компонент и накидал примитивов. Тоже самое - луч постоянно возвращает землю. Условно он конечно работает - но только некорректно.

Обычно такое бывает когда идет рассинхрон с вызовами, так что я немного поэкспериментировал и собственно скорее всего так и есть. Если вызывать GetIntersection из других вызовов, то возвращаемые объекты будут идти от земли к текущему положению камеры.

Ну и в коде - собирается все в FirstPersonController в функции FlushTransform(), если закоментить строку camera.Modelview = GetModelview();, то камера будет смотреть в пол.

Получается камера изначально обращена в землю, а уже потом ее поворачивают в нормальное положение. Так и получается - пустили луч в землю пока камера еще не повернута - луч и вернул землю. Но это просто предварительно, так что не точно что проблема именно там.

Link to comment
9 hours ago, silent said:

А о какой версии движка идет речь? В 2.12.х уже камера вращается нормально в update().

Хм, значит я делал вот что. Сначала на версии 2.11 попробовал, затем обновил проект до версии 2.12. И да, только после того как создал новый проект 2.12, все стало корректно работать. Посмотрел код - уже 1700 строк кода против 1100 у первичного. Ну вы блин монстры. Стало быть у меня даже после обновления остался скрипт из версии 2.11. Честно говоря к такому жизнь меня не готовила.

Получается папки по-умолчанию не обновляются? Как же их обновлять тогда?

Link to comment

Мы не можем обновлять пользовательский код (в том числе компоненту игрока), т.к. там могут быть изменения котороые в случае обновления потеряются.

Возможно, стоит добавить проверку на изменение кода (если файл компоненты не менялся, то обновляем его, а если туда уже были сделаны изменения - пропускаем). Надо подумать как будет лучше.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment
5 hours ago, silent said:

Мы не можем обновлять пользовательский код (в том числе компоненту игрока), т.к. там могут быть изменения котороые в случае обновления потеряются.

Возможно, стоит добавить проверку на изменение кода (если файл компоненты не менялся, то обновляем его, а если туда уже были сделаны изменения - пропускаем). Надо подумать как будет лучше.

Ясно. Да, это проблема. Это пока кода из коробки не много.

Link to comment
×
×
  • Create New...