Разделы:
- Обработка нажатия мыши
- Создание курсора
- Получение первого пересеченного объекта
- Вывод информации об объекте при наведении
- Перемещение объектов
- Назначаем скрипты объектам
1. Обработка нажатия мыши
Создать компонент C# с название "MouseHandler". Функция возвращает название нажатой кнопки мыши.
public string IsMousePressed()
{
if (Input.IsMouseButtonPressed(Input.MOUSE_BUTTON.LEFT))
return "LeftPress";
if (Input.IsMouseButtonDown(Input.MOUSE_BUTTON.LEFT))
return "LeftDown";
if (Input.IsMouseButtonUp(Input.MOUSE_BUTTON.LEFT))
return "LeftUp";
return "None";
}
2. Создание курсора
Создать компонент C# с название "HUD".
public AssetLink crosshairImage = null;
public int crosshairSize = 16;
private WidgetSprite sprite = null;
private Gui screenGui = null;
private ivec2 prev_size = new ivec2(0, 0);
private void Init()
{
screenGui = Gui.GetCurrent();
sprite = new WidgetSprite(screenGui, crosshairImage.AbsolutePath);
sprite.Width = crosshairSize;
sprite.Height = crosshairSize;
screenGui.AddChild(sprite, Gui.ALIGN_CENTER | Gui.ALIGN_OVERLAP);
sprite.Lifetime = Widget.LIFETIME.WORLD;
}
private void Update()
{
ivec2 new_size = screenGui.Size;
if (prev_size != new_size)
{
screenGui.RemoveChild(sprite);
screenGui.AddChild(sprite, Gui.ALIGN_CENTER | Gui.ALIGN_OVERLAP);
}
prev_size = new_size;
}
Создадим NodeDummy и переместим в поле наш скрипт. В поле "Crosshair Image" поместим картинку курсора в .png, а в поле "Crosshair Size" выставим нужный нам размер.
3. Получение первого пересеченного объекта
Создаем компонент C# с названием "CameraCast". Этот скрипт предназначен для получения первого пересеченного объекта.
Добавим необходимые нам переменные.
public PlayerDummy shootingCamera = null;
[ParameterMask(MaskType = ParameterMaskAttribute.TYPE.INTERSECTION)]
public int mask = ~0;
private Unigine.dvec3 p0, p1;
Включим visualizer в функции init для управления настройками, связанными с визуализатором. В моем случае он необходим для выделения объектов.
Visualizer.Enabled = true;
Создаем функцию, которая пускает луч из камеры, находит первое пересечение с объектов и возвращает его.
public Unigine.Object GetObject()
{
p0 = shootingCamera.WorldPosition;
p1 = shootingCamera.WorldPosition + shootingCamera.GetWorldDirection() * 100;
WorldIntersectionNormal hitInfo = new WorldIntersectionNormal();
Unigine.Object hitObject = World.GetIntersection(p0, p1, mask, hitInfo);
return hitObject;
}
4. Вывод информации об объекте при наведении
Создать компонент C# с название "SelectObject".
Создадим необходимые переменные WidgetCanvas будем использовать для вывода названия объекта.
public CameraCast cameraCast = null;
private Unigine.Object selectedObject;
private WidgetCanvas textOfObject;
private Gui gui;
private int x, y;
В функцию Init напишем следующий код. Он созданию WidgetCanvas для будущей информации.
gui = Gui.GetCurrent();
textOfObject = new WidgetCanvas(gui);
textOfObject.Clear();
x = textOfObject.AddText(1);
vec4 color = new vec4(x, 1, 1, 0.5);
textOfObject.SetTextColor(x, color);
textOfObject.SetTextSize(x, 30);
textOfObject.SetTextPosition(x, new vec2(10, 10));
y = textOfObject.AddPolygon(0);
textOfObject.SetPolygonColor(y, new vec4(0, 0, 0, 0.5));
textOfObject.AddPolygonPoint(y, new vec3(0, 0, 0));
textOfObject.AddPolygonPoint(y, new vec3(600, 0, 0));
textOfObject.AddPolygonPoint(y, new vec3(600, 100, 0));
textOfObject.AddPolygonPoint(y, new vec3(0, 100, 0));
gui.AddChild(textOfObject, Gui.ALIGN_EXPAND);
textOfObject.Hidden = true;
В функцию Update напишем код, который получает пересеченный объект и вывод информацию об этом объекте. Причем вывод информации будет только у дочерних элементов элемента "Engine" (мой собственный объект). А также будет выделять этот объект с помощью visualizer.
selectedObject = cameraCast.GetObject();
if (selectedObject != null && selectedObject.RootNode.Name == "Engine")
{
Visualizer.RenderObjectSurfaceBoundBox(selectedObject, 0, vec4.BLUE, 0.05f);
textOfObject.Hidden = false;
string info = $"{selectedObject.Name}";
addText(info);
Visualizer.RenderMessage3D(selectedObject.WorldPosition + new vec3(0, 0, 0.05f), 0, info, vec4.GREEN, 0, 20,0);
}
Допишем функцию addText.
private void addText(string text)
{
textOfObject.SetTextText(x, text);
}
5. Перемещение объектов
Создадим скрипт, с помощью которого вы будет перемещать выбранные объекты. Назовем его "drugObject".
Создадим необходимые переменные.
public CameraCast cameraCast = null;
private Unigine.Object drugObject;
private Unigine.Object mainObject;
public MouseHandler mouseHandler = null;
private dmat4 transform;
private bool flag;
В функции Init поставим значение flag на false.
flag = false;
В функции Update напишем код, который при нажатие на левую кнопку будет перемещать объекты. При отпускании кнопки перемещение прекращается.
drugObject = cameraCast.GetObject();
if (flag)
mainObject.WorldTransform = cameraCast.shootingCamera.OldWorldTransform * transform;
string mouse = mouseHandler.IsMousePressed();
if (drugObject != null && drugObject.RootNode.Name == "Engine")
{
if (mouse == "LeftPress")
{
if (!flag && drugObject != null && drugObject.RootNode.Name == "Engine")
{
mainObject = drugObject;
transform = cameraCast.shootingCamera.IWorldTransform * drugObject.WorldTransform;
}
flag = true;
}
}
if (mouse == "LeftUp")
{
flag = false;
}
6. Назначаем скрипты объектам
Добавим основную камеру игрока PlayerDummy, от которой будем пускать луч для получения пересеченного объекта, назовем ее "player". Сделаем ее дочерней для "first_person_controller". Нажмем Edit у "first_person_controller" и изменить раздел "Camera". В "Camera Mode" выберем "USE_EXTERNAL", а в поле "Camera" перенесем камеру "player" из древа объектов.
Перенесем компоненты к объектам, согласно скринам ниже.
player_person_controller
player