This page has been translated automatically.
Видеоуроки
Интерфейс
Основы
Продвинутый уровень
Подсказки и советы
Основы
Программирование на C#
Рендеринг
Профессиональный уровень (SIM)
Принципы работы
Свойства (properties)
Компонентная Система
Рендер
Режимы вывода изображения
Физика
Браузер SDK 2
Лицензирование и типы лицензий
Дополнения (Add-Ons)
Демонстрационные проекты
API Samples
Редактор UnigineEditor
Обзор интерфейса
Работа с ассетами
Контроль версий
Настройки и предпочтения
Работа с проектами
Настройка параметров ноды
Setting Up Materials
Настройка свойств
Освещение
Sandworm
Использование инструментов редактора для конкретных задач
Расширение функционала редактора
Встроенные объекты
Ноды (Nodes)
Объекты (Objects)
Эффекты
Декали
Источники света
Geodetics
World-ноды
Звуковые объекты
Объекты поиска пути
Player-ноды
Программирование
Основы
Настройка среды разработки
Примеры использования
C++
C#
UnigineScript
Унифицированный язык шейдеров UUSL (Unified UNIGINE Shader Language)
Плагины
Форматы файлов
Материалы и шейдеры
Rebuilding the Engine Tools
Интерфейс пользователя (GUI)
Двойная точность координат
API
Animations-Related Classes
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
VR-Related Classes
Работа с контентом
Оптимизация контента
Материалы
Визуальный редактор материалов
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Учебные материалы

Переход на UNIGINE с Unity: программирование

Game logic in a Unity project is implemented via Script components. You got used to determine GameObject's behavior by writing event functions like Start(), Update(), etc.Игровая логика в проекте Unity реализована через компоненты Script . Вы привыкли определять поведение GameObject, записывая функции событий, такие как Start(), Update() и т.д.

UNIGINE has quite a similar concept, which can be easily adopted — C# Component System, which is safe and secure and ensures high performance. Logic is written in C# components that can be assigned to any node in the scene. Each component has a set of functions (Init(), Update(), etc.), that are called by the corresponding functions of the engine main loop.UNIGINE имеет довольно похожую концепцию, которая может быть легко адаптирована - Система компонентов C# , который безопасен и надежен и обеспечивает высокую производительность. Логика написана на компонентах C#, которые могут быть назначены любой ноде сцены. Каждый компонент имеет набор функций (Init(), Update() и т.д.), Которые вызываются соответствующими функциями основного цикла движка.

Programming in UNIGINE using C# is not much different from programming in Unity software. For example, let's compare how rotation is performed in Unity software:Программирование в UNIGINE с использованием C# мало чем отличается от программирования в программном обеспечении Unity. Например, сравним, как выполняется вращение в программе Unity:

Исходный код (C#)
using UnityEngine;

public class MyComponent : MonoBehaviour
{
    public float speed = 90.0f;

    void Update()
    {
        transform.Rotate(0, speed * Time.deltaTime, 0, Space.Self);
    }
}

and in UNIGINE:и в UNIGINE:

Исходный код (C#)
using Unigine;
/* .. */

public class MyComponent : Component
{

	public float speed = 90.0f;

	private void Update()
	{

		node.Rotate(0, 0, speed * Game.IFps);

	}

The Run button is available in the Editor to run an instance of the application in a separate window. Along with the button, there are settings available to fine-tune run options.Кнопка Run доступна в редакторе для запустить экземпляр приложения в отдельном окне. Наряду с кнопкой доступны настройки для точной настройки параметров запуска.

That's how we'll make the wheel rotate using C# Component System and run an instance to immediately check it:Вот как можно заставить колесо вращаться с помощью C# Component System и запустить из редактора приложение в отдельном окне, чтобы немедленно его проверить:

Moreover in UNIGINE, you can also implement Application Logic for the whole application by writing code in the AppWorldLogic.cs, AppSystemLogic.cs and AppEditorLogic.cs files stored in the source/ project folder.Кроме того, в UNIGINE вы также можете реализовать логику приложения для всего приложения путем написания кода в файлах AppWorldLogic.cs, AppSystemLogic.cs и AppEditorLogic.cs, хранящихся в папке проекта source/.

To learn more about the execution sequence and how to build components, follow the links below:Чтобы узнать больше о последовательности выполнения и о том, как создавать компоненты, перейдите по ссылкам ниже:

For those who prefer C++, UNIGINE allows creating C++ applications using C++ API and, if required, C++ Component System.Для тех, кто предпочитает C++, UNIGINE позволяет создавать C++ приложения с использованием C++ API и, при необходимости, Системы компонентов C++ .

Writing Gameplay Code
Написание игрового кода#

Printing to Console
Печать в консоль#

Unity software UNIGINE
Исходный код (C#)
Debug.Log("Text: " + text);
Debug.LogFormat("Formatted text: {0}", text);
Исходный код (C#)
Log.Message("Debug info:" + text + "\n");
Log.Message("Debug info: {0}\n", new vec3(1, 2, 3));

See Also
Смотрите также#

Accessing the GameObject / Node from Component
Доступ к GameObject / Node из компонента#

Unity software UNIGINE
Исходный код (C#)
GameObject this_go = gameObject;
string n = gameObject.name;
Исходный код (C#)
Node this_node = node;
string n = node.Name;

See Also
Смотрите также#

Working with Directions
Работа с маршрутами#

In Unity software to get a vector on a certain axis while also considering the rotation of a game object in world coordinates, you use the corresponding properties of the Transform component. The same vector in UNIGINE is got by using Node.GetWorldDirection() function:В программном обеспечении Unity для получения вектора на определенной оси с учетом вращения игрового объекта в мировых координатах используются соответствующие свойства компонента Transform. Тот же вектор в UNIGINE получается с помощью функции Node.GetWorldDirection():

Unity software UNIGINE
Исходный код (C#)
Vector3 forward = transform.forward;
Vector3 right = transform.right;
Vector3 up = transform.up;
transform.Translate(forward * speed * Time.deltaTime);
Исходный код (C#)
vec3 forward = node.GetWorldDirection(MathLib.AXIS.Y);
vec3 right = node.GetWorldDirection(MathLib.AXIS.X);
vec3 up = node.GetWorldDirection(MathLib.AXIS.Z);
node.Translate(forward * speed * Game.IFps);
Примечание
Intances of the Players-Related classes use different direction vectors and are to be treated correspondingly.Экземпляры Player-классов используют другие векторы направления и требуют соответствующего обращения .

See Also
Смотрите также#

Smoother Gameplay with DeltaTime / IFps
Более плавный игровой процесс с DeltaTime / IFps#

In Unity software to ensure that certain actions are performed at the same time periods regardless of the framerate (e.g. change something once per second etc) you use a scaling multiplier Time.deltaTime (the time in seconds it took to complete the last frame). The same thing in UNIGINE is called Game.IFps:В программном обеспечении Unity, чтобы гарантировать, что определенные действия выполняются в одни и те же периоды времени независимо от частоты кадров (например, изменение чего-либо один раз в секунду и т.д.), вы используете масштабный множитель Time.deltaTime (время в секундах, которое потребовалось для завершения последнего кадра). То же самое в UNIGINE называется Game.IFps:

Unity software UNIGINE
Исходный код (C#)
transform.Rotate(0, speed * Time.deltaTime, 0, Space.Self);
Исходный код (C#)
node.Rotate(0, 0, speed * Game.IFps);

Drawing Debug Data
Рисование отладочных данных#

Unity software:Unity программное обеспечение:

Исходный код (C#)
Debug.DrawLine(Vector3.zero, new Vector3(5, 0, 0), Color.white, 2.5f);

Vector3 forward = transform.TransformDirection(Vector3.forward) * 10;
Debug.DrawRay(transform.position, forward, Color.green);

UNIGINE:

Исходный код (C#)
Visualizer.Enabled = true;

/*..*/

Visualizer.RenderLine3D(vec3.ZERO, new vec3(5, 0, 0), vec4.ONE);
Visualizer.RenderVector(node.Position, node.GetDirection(MathLib.AXIS.Y) * 10, new vec4(1, 0, 0, 1));
Примечание
The visualizer can be toggled on and off via show_visualizer 1 console command as well.Визуализатор также можно включать и выключать с помощью консольной команды show_visualizer 1.

See Also
Смотрите также#

  • More types of visualizations in the Visualizer class API.Больше типов визуализаций в API класса Visualizer.

Loading a Scene
Загрузка сцены#

Unity software UNIGINE
Исходный код (C#)
SceneManager.LoadScene("YourSceneName",LoadSceneMode.Single);
Исходный код (C#)
World.LoadWorld("YourSceneName");

Accessing a Component from the GameObject / Node
Доступ к компоненту из GameObject / Node#

Unity software:Unity программное обеспечение:

Исходный код (C#)
MyComponent my_component = gameObject.GetComponent<MyComponent>();

UNIGINE:

Исходный код (C#)
MyComponent my_component = node.GetComponent<MyComponent>();

MyComponent my_component = GetComponent<MyComponent>(node);

Accessing Standard Components
Доступ к стандартным компонентам#

Unity software provides component-based workflow so such standard entities as MeshRenderer, Rigidbody, Collider, Transform and other are treated as usual components.Программное обеспечение Unity обеспечивает подход на основе компонентов, поэтому такие стандартные объекты, как MeshRenderer, Rigidbody, Collider, Transform и другие, рассматриваются как обычные компоненты.

In UNIGINE, analogs for these entities are accessed differently. For example, to access an entity of a type derived from the Node class (e.g. ObjectMeshStatic), you should downcast the instance to the corresponding class. Let's consider these most popular use cases:В UNIGINE доступ к аналогам этих сущностей осуществляется иначе. Например, для доступа к сущности типа, производного от класса Node (например, ObjectMeshStatic), вы должны преобразовать тип экземпляра к соответствующему классу. Давайте рассмотрим эти самые популярные варианты использования:

Unity software:Unity программное обеспечение:

Исходный код (C#)
// accessing the transform of the game object
Transform transform_1 = gameObject.GetComponent<Transform>();
Transform transform_2 = gameObject.transform;

// accessing the Mesh Renderer component
MeshRenderer mesh_renderer = gameObject.GetComponent<MeshRenderer>();

// accessing the Rigidbody component
Rigidbody rigidbody = gameObject.GetComponent<Rigidbody>();

// accessing a collider
Collider collider = gameObject.GetComponent<Collider>();
BoxCollider boxCollider = collider as BoxCollider;

UNIGINE:

Исходный код (C#)
// getting the transformation matrix of the node
dmat4 transform = node.WorldTransform;

// downcasting the node to the ObjectMeshStatic class
ObjectMeshStatic mesh_static = node as ObjectMeshStatic;

// accessing the rigid body assigned to the node
Body body = (node as Unigine.Object).Body;
BodyRigid rigid = body as BodyRigid;

// fetch all collision shapes of the ShapeBox type
for (int i = 0; i < body.NumShapes; i++)
{
	Shape shape = body.GetShape(i);
	if (shape is ShapeBox)
	{
		ShapeBox shape_box = shape as ShapeBox;
		/* some code */
	}
}

Finding GameObjects / Nodes
Поиск GameObject / Node#

Unity software:Unity программное обеспечение:

Исходный код (C#)
// Find a GameObject by name
GameObject myGameObj = GameObject.Find("My Game Object");

// Find the child named "ammo" of the gameobject "magazine" (magazine is a child of "gun").
Transform ammo_transform = gameObject.transform.Find("magazine/ammo");
GameObject ammo = ammo_transform.gameObject;

// Find GameObjects by the type of component assigned
MyComponent[] components = Object.FindObjectsOfType<MyComponent>();
foreach (MyComponent component in components)
{
        // ...
}

// Find GameObjects by tag
GameObject[] taggedGameObjects = GameObject.FindGameObjectsWithTag("MyTag");
foreach (GameObject gameObj in taggedGameObjects)
{
        // ...
}

UNIGINE:

Исходный код (C#)
// Find a Node by name
Node my_node = World.GetNodeByName("my_node");

// Find all nodes having this name
List<Node> nodes = new List<Node>();
World.GetNodesByName("my_node", nodes);

// Find the index of a direct child node
int index = node.FindChild("child_node");
Node direct_child = node.GetChild(index);

// Perform a recursive descend down the hierarchy to find a child Node by name
Node child = node.FindNode("child_node", 1);

// Find Nodes by the type of component assigned
MyComponent[] my_comps = FindComponentsInWorld<MyComponent>();
foreach(MyComponent comp in my_comps)
{
	Log.Message("{0}\n",comp.node.Name);
}

Casting From Type to Type
Приведение типов#

Downcasting (from a pointer-to-base to a pointer-to-derived) is performed similarly in both engines, by using the C# as native construction:Сужение типа или downcasting (от указателя на базовый класс к указателю на производный класс ) выполняется одинаково в обоих движках с использованием собственной конструкции C# as:

Unity software UNIGINE
Исходный код (C#)
Collider collider = gameObject.GetComponent<Collider>;
BoxCollider boxCollider = collider as BoxCollider;
Исходный код (C#)
Node node = World.GetNodeByName("my_mesh");
ObjectMeshStatic mesh = node as ObjectMeshStatic;

To perform Upcasting (from a pointer-to-derived to a pointer-to-base) you can simply use the instance itself:Чтобы выполнить расширение типа или upcasting (от указателя на производный класс к указателю на базовый класс ), вы можете просто использовать сам экземпляр:

Unity software UNIGINE
Исходный код (C#)
Collider collider = gameObject.GetComponent<Collider>;
BoxCollider boxCollider = collider as BoxCollider;
Collider coll = boxCollider;
Исходный код (C#)
Node node = World.GetNodeByName("my_mesh");
ObjectMeshStatic mesh = node as ObjectMeshStatic;
Unigine.Object obj = mesh;

Destroy GameObject/Node
Удаление GameObject / Node#

Unity software UNIGINE
Исходный код (C#)
Destroy(maGameObject);

// destroy the game object with 1 second delay
Destroy(maGameObject, 1);
Исходный код (C#)
node.DeleteLater(); // recommended option
//called between the current and the next frames

node.DeleteForce(); // called during the same frame but unsafe

To perform deferred removal of a node in UNIGINE, you can create a component that will be responsible for the timer and deletion.Чтобы выполнить отложенное удаление ноды в UNIGINE, вы можете создать компонент, который будет отвечать за таймер и удаление.

Исходный код (C#)
using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "AUTOGENERATED_GUID")] // <-- this line is generated automatically for a new component
public class LifeTimeController : Component
{
	public float lifetime = 5.0f;

	void Update()
	{
		lifetime = lifetime - Game.IFps;
		if (lifetime < 0)
		{
			// destroy current node with its properties and components
			node.DeleteLater();
		}
	}
}
Исходный код (C#)
public class MyComponent : Component
{

	private void Update()
	{

		if (/a reason to die/)

		{
			LifeTimeController lc = node.AddComponent<LifeTimeController>();
			lc.lifetime = 2.0f;
		}

	}
}

Instantiating Prefab / Node Reference
Создание экземпляра ссылки на префаб / ноду#

In Unity software, you instantiate a prefab using the Object.Instantiate function:В программном обеспечении Unity вы создаете экземпляр prefab с помощью функции Object.Instantiate:

Исходный код (C#)
using UnityEngine;

public class MyComponent : MonoBehaviour
{
public GameObject myPrefab;

void Start()
{
	Instantiate(myPrefab, new Vector3(0, 0, 0), Quaternion.identity);
}
}

Then, you should specify the prefab to be instantiated in the script component parameters:Затем вы должны указать prefab для создания экземпляра в параметрах компонента скрипта:

You can also use World.LoadNode to load a hierarchy of nodes from a .node asset manually by providing the virtual path to it:В UNIGINE вы должны использовать World.LoadNode для загрузки иерархии нод из ресурса .node. В этом случае в сцену будет добавлена иерархия нод, которая была сохранена как NodeReference. Вы можете ссылаться на ассет через компонентный параметр или вручную, предоставив виртуальный путь к нему:

Исходный код (C#)
public class MyComponent : Component
{

	public Node node_to_clone;
	public AssetLinkNode node_to_spawn;

	private void Init()
	{

		Node cloned = node_to_clone.Clone();

		Node spawned = node_to_spawn.Load(node.WorldPosition, quat.IDENTITY);

		Node spawned_manually = World.LoadNode("nodes/node_reference.node");

	}
}

В случае использования подхода компонентных параметров следует также указать ассет .node:

You can also spawn the node reference as a single node (without extracting the content) in the world:Вы также можете создать ссылку на Node Reference как единую ноду (без извлечения содержимого) в мире:

Исходный код (C#)
public class MyComponent : Component
{

	private void Init()
	{

		NodeReference nodeRef = new NodeReference("nodes/node_reference_0.node");

	}
}

Running Scripts in the Editor
Запуск скриптов в редакторе#

You are likely to be accustomed that Unity software enables you to extend the Editor using C# scripts. For this purpose you can use special attributes in your scripts:Вы, вероятно, уже привыкли, что программное обеспечение Unity позволяет расширять редактор с помощью сценариев C#. Для этого вы можете использовать в своих скриптах специальные атрибуты:

  • [ExecuteInEditMode] — to execute the script logic during Edit mode, while your application is not running.[ExecuteInEditMode] - для выполнения логики скрипта в режиме Edit, когда ваше приложение не запущено.
  • [ExecuteAlways] — to execute the script logic both as part of Play mode and when editing.[ExecuteAlways] - для выполнения логики скрипта как в составе режима Play, так и при редактировании.

For example, this is how you write a component that makes GameObject orient towards the certain point in the scene:Например, вот как вы пишете компонент, который заставляет GameObject повернуться к определенной точке сцены:

Исходный код (C#)
//C# Example (LookAtPoint.cs)
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
    public Vector3 lookAtPoint = Vector3.zero;

    void Update()
    {
        transform.LookAt(lookAtPoint);
    }
}

UNIGINE doesn't support executing C# logic inside the Editor. The most common way to extend functionality of UnigineEditor is C++ plugin.UNIGINE не поддерживает выполнение логики C# внутри редактора. Вместо этого вы можете написать логику в UnigineScript для оптимизации процесса создания проекта. UnigineScript доступен для любого подхода к программированию, который вы выбрали для своего проекта, включая C# .NET.

There are two methods to add a script to the project:Есть два способа добавить скрипт в проект :

  • By creating a World script. Perform the following steps:Создав скрипт World . Выполните следующие шаги:

    1. Create a .usc script asset.

      Создайте ресурс сценария .usc.

    2. Write logic inside this script file. If necessary, add a condition checking if the Editor is loaded:Напишите логику. При необходимости добавьте проверку условия, если редактор загружен:

      Исходный код (UnigineScript)
      #include <core/unigine.h>
      vec3 lookAtPoint = vec3_zero;
      Node node;
      int init() {
      	node = engine.world.getNodeByName("material_ball");
      	return 1;
      }
      
      int update() {
      	if(engine.editor.isLoaded())
      		node.worldLookAt(lookAtPoint);
      	return 1;
      }
    3. Select the current world and specify the world script for it. Click Apply and reload the world.Выберите текущий мир и укажите для него сценарий мира. Нажмите Apply и перезагрузите мир.

    4. Check the Console window for errors.Проверьте окно Console на наличие ошибок.

    After that the script logic will be executed in both Editor and application.После этого логика скрипта будет выполняться как в редакторе, так и в приложении.

  • By using WorldExpression. For the same purpose you can use a built-in WorldExpression node executing scripts when added to the world:Используя WorldExpression. С той же целью вы можете использовать встроенную ноду WorldExpression, выполняющий скрипты при добавлении в мир:

    1. Click Create -> Logic -> Expression and place the new WorldExpression node in the world.Щелкните Create -> Logic -> Expression и поместите новую ноду WorldExpression в мир.
    2. Write logic in UnigineScript in the Source field:Запишите логику в UnigineScript в поле Source:

      Исходный код (UnigineScript)
      {
      vec3 lookAtPoint = vec3_zero;
      Node node = engine.world.getNodeByName("my_node");
      node.worldLookAt(lookAtPoint);
      }
    3. Check the Console window for errors.Проверьте окно Console на наличие ошибок.
    4. The logic will be executed immediately.Логика будет выполнена немедленно.

Triggers
Триггеры#

In addition to collision detection, Unity Collider component is accountable for being a Trigger that is executed when one collider enters the space of another.В дополнение к обнаружению столкновений, компонент Unity Collider отвечает за то, что он является Trigger, который выполняется, когда один коллайдер входит в пространство другого.

Исходный код (C#)
public class MyComponent : MonoBehaviour
{
    void Start()
    {
        collider.isTrigger = true;
    }
    void OnTriggerEnter(Collider other)
    {
        // ...
    }
    void OnTriggerExit(Collider other)
    {
        // ...
    }
}

In UNIGINE, Trigger is a special built-in node that raises events in certain situations:В UNIGINE Trigger - это специальная встроенная нода, которая вызывает события в определенных ситуациях:

  • NodeTrigger is used to track events for a particluar node (to which the Trigger is attached as a child) - it executes event handlers when the Trigger node is enabled or the Trigger node position has changed.NodeTrigger используется для отслеживания событий для ноды Trigger — обработчики событий выполняются, когда нода Trigger включается или меняется ее положение.
  • WorldTrigger is used to track events for any node (collider or not) that gets inside or outside of it.WorldTrigger используется для отслеживания событий для любой ноды (коллайдер или нет), которая входит в объем триггера или же выходит из него.
  • PhysicalTrigger is used to track events for physical objects get inside or outside of it.PhysicalTrigger запускает события, когда физические объекты входят в объем триггера или же выходят из него.

    Примечание
    PhysicalTrigger does not handle collision events, for that purpose Bodies and Joints provide their own events.PhysicalTrigger не обрабатывает события столкновения, для этой цели у тел (bodies) и сочленений (joints) есть свои собственные события.

WorldTrigger is the most common type that can be used in gameplay. Here is an example on how to use it:WorldTrigger - наиболее распространенный тип, который можно использовать в игровом процессе. Вот пример того, как его использовать:

Исходный код (C#)
public class MyComponent : Component
{

	WorldTrigger trigger;

	void enter_event_handler(Node incomer)
	{
		Log.Message("\n{0} has entered the trigger space\n", incomer.Name);
	}

	private void Init()
	{

		trigger = node as WorldTrigger;
		if(trigger != null)
		{
			trigger.EventEnter.Connect(enter_event_handler);
			trigger.EventLeave.Connect( leaver => Log.Message("{0} has left the trigger space", leaver.Name));
		}

	}
}

Input
Ввод#

Unity Conventional Game Input:Unity Обычный игровой ввод:

Исходный код (C#)
public class MyPlayerController : MonoBehaviour
{
    void Update()
    {
        if (Input.GetButtonDown("Fire"))
        {
            // ...
        }
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
        // ...
    }
}

UNIGINE:

Исходный код (C#)
public class MyPlayerController : Component
{

	void Update()
	{

		if(Input.IsMouseButtonDown(Input.MOUSE_BUTTON.LEFT))
		{
			Log.Message("Left mouse button was clicked at {0}\n", Input.MousePosition);
		}

		if (Input.IsKeyDown(Input.KEY.Q) && !Unigine.Console.Active)
		{
			Log.Message("Q was pressed and the Console is not active.\n");
			Engine.Quit();
		}

	}
}

You can also use the ControlsApp class to handle control bindings. To configure the bindings, open the Controls settings:Вы также можете использовать класс ControlsApp для обработки привязок элементов управления. Чтобы настроить привязки, откройте настройки Controls:

Исходный код (C#)
public class MyPlayerController : Component
{

	private void Init()
	{

		// remapping states to keys and buttons
		ControlsApp.SetStateKey(Controls.STATE_FORWARD, Input.KEY.W);
		ControlsApp.SetStateKey(Controls.STATE_BACKWARD, Input.KEY.S);
		ControlsApp.SetStateKey(Controls.STATE_MOVE_LEFT, Input.KEY.A);
		ControlsApp.SetStateKey(Controls.STATE_MOVE_RIGHT, Input.KEY.D);
		ControlsApp.SetStateMouseButton(Controls.STATE_JUMP, Input.MOUSE_BUTTON.LEFT);

	}

	void Update()
	{

		if (ControlsApp.ClearState(Controls.STATE_FORWARD) != 0)
		{
			Log.Message("FORWARD key pressed\n");
		}
		else if (ControlsApp.ClearState(Controls.STATE_BACKWARD) != 0)
		{
			Log.Message("BACKWARD key pressed\n");
		}
		else if (ControlsApp.ClearState(Controls.STATE_MOVE_LEFT) != 0)
		{
			Log.Message("MOVE_LEFT key pressed\n");
		}
		else if (ControlsApp.ClearState(Controls.STATE_MOVE_RIGHT) != 0)
		{
			Log.Message("MOVE_RIGHT key pressed\n");
		}
		else if (ControlsApp.ClearState(Controls.STATE_JUMP) != 0)
		{
			Log.Message("JUMP button pressed\n");
		}

	}
}

Raycasting
Бросание лучей (raycasting)#

In Unity software, Physics.Raycast is used. GameObject should have a Collider component attached to take part in raycasting:В программном обеспечении Unity используется Physics.Raycast. GameObject должен иметь прикрепленный компонент Collider для участия в рейкастинге:

Исходный код (C#)
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
	public Camera camera;

    void Update()
    {
    	// ignore the 2nd layer
        int layerMask = 1 << 2;
        layerMask = ~layerMask;

        RaycastHit hit;
        Ray ray = camera.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
        {
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
            Debug.Log("Did Hit");
        }
        else
        {
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 1000, Color.white);
            Debug.Log("Did not Hit");
        }
    }
}

In UNIGINE the same is handled by Intersections:В UNIGINE то же самое реализовано с использованием пересечений (intersections) :

Исходный код (C#)
using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

#region Math Variables
#if UNIGINE_DOUBLE
using Scalar = System.Double;
using Vec3 = Unigine.dvec3;
#else
using Scalar = System.Single;
using Vec3 = Unigine.vec3;
#endif
#endregion

[Component(PropertyGuid = "AUTOGENERATED_GUID")] // <-- this line is generated automatically for a new component
public class IntersectionExample : Component
{
	void Init()
	{
		Visualizer.Enabled = true;
	}
	void Update()
	{
		ivec2 mouse = Input.MousePosition;
		float length = 100.0f;
		Vec3 start = Game.Player.WorldPosition;
		Vec3 end = start + new Vec3(Game.Player.GetDirectionFromMainWindow(mouse.x, mouse.y)) * length;

		// ignore surfaces that have certain bits of the Intersection mask enabled
		int mask = ~(1 << 2 | 1 << 4);

		WorldIntersectionNormal intersection = new WorldIntersectionNormal();

		Unigine.Object obj = World.GetIntersection(start, end, mask, intersection);

		if (obj)
		{
			Vec3 point = intersection.Point;
			vec3 normal = intersection.Normal;
			Visualizer.RenderVector(point, point + normal, vec4.ONE);
			Log.Message("Hit {0} at {1}\n", obj.Name, point);
		}
	}
}
Последнее обновление: 06.02.2024
Build: ()