Como colecionei física das rodas na Unigine

Dia bom.

Desta vez, falaremos sobre o mecanismo russo Unigine e sobre como montar uma máquina simples nele. O esquema não é ideal, já que não o descobri em algumas coisas, mas pelo menos vou compartilhar minha experiência.



Primeiro de tudo, para entender como é feita a física das rodas, vamos à documentação oficial e encontramos este exemplo .

A propósito, observe que este é um exemplo de junta de roda, mas por algum motivo está no endereço / car_suspension_joints /. Você também precisa garantir que a documentação não pule para as versões antigas (ou seja, que o DOCS (2.11) esteja aberto) e marque a caixa "C #" na parte superior do artigo.

Tendo estudado o exemplo, vemos que ele foi escrito por analogia com a solução C ++ inicial. Ou seja, tudo é criado através do código. Tanta coisa para programação visual, chegamos. Bem, nem tudo é tão triste, mas você pode ver como tudo isso é feito no código. E, ao rodar nos links, tenha uma idéia geral do dispositivo de articulação das rodas e das configurações físicas.
( ). , -, UnigineScript, . LOD'.
Obviamente, eu esperava um guia passo a passo pronto para montagem visual, a fim de fazer algo rolar, custando pouco sangue. Como resultado, eu ainda tinha que mergulhar nisso tudo com a cabeça para elaborar algum pipeline aproximado. Isso foi parcialmente bem-sucedido, mas estava longe de ser entendido em todos os pontos e as questões permanecem em aberto, por exemplo, se os nós da caixa e da roda devem ser construídos em uma determinada hierarquia, se os eixos dos pontos estão orientados corretamente e assim por diante.

Em geral, esta instrução o ajudará a entender o princípio básico, mas para entender os meandros das configurações, você ainda precisará estudar a documentação (ou talvez eles lhe digam algo útil nos comentários).

Montagem do quadro


1. Crie um novo projeto. Escolha a opção c #. Abra o projeto no editor.







2. Criamos a base da máquina.

Para fazer isso, clique com o botão direito do mouse na cena, escolhendo Criar > Primitivo > Caixa . O resultado é um objeto cubóide . Levante-o um pouco acima do "piso".



3. Criamos rodas.

Clique no mouse novamente e selecione Criar > Primitivo > Cilindro . Vai levar 4 peças.



Para não se confundir com a orientação, você pode girar a câmera para que -Y brilhe de cima no cubo (ou seja, agora olhamos para a futura máquina por trás) e coloque dois cilindros atrás do Cuboid, outros dois na frente. De alguma forma, girar e personalizá-los não é necessário. Por conveniência, cores diferentes podem ser atribuídas à traseira e à frente.

4. Adicione física com base.

Selecione Cubóide e, à esquerda, na janela Parâmetros da guia , alterne para Física . Na coluna Corpo, selecione o tipo Rígido . Depois disso, role para baixo e selecione o item Caixa na coluna Formas aberta .





Vemos o apareceu ShapeBox. Entraremos em suas configurações e definiremos imediatamente nossa base para a massa ( massa ) recomendada de 64 kg.



5. Adicione física às rodas.

Por sua vez, selecione os cilindros e também os coloque rígidos na guia Física.
Eles não precisam criar uma forma, porque as juntas das rodas funcionam em rakcasts.

6. Amarre as rodas na base.

Hora de atribuir juntas de roda. Para fazer isso, selecione Cuboid corretamente e role para baixo até a coluna Juntas na guia Física . Na lista, selecione Roda e, quando você clica no botão Adicionar , a janela Selecionar um Corpo é exibida.. Lá, você seleciona um cilindro, que é destacado com uma grade branca na cena e pressione Ok. Uma ligação WheelJoint aparecerá na lista . Aqui já é desejável renomeá-los (para isso, você precisa clicar na linha JointWheel e escrever um novo nome na coluna Nome).





Da mesma maneira, conecte os cilindros restantes ao Cuboid. De modo que no final de sua lista de pontos queimou 4 linhas.


Sem renomear, haveria quatro linhas de WheelJoint.Por

favor, note que você precisa vincular a partir do Cuboid, e não da guia Física dos próprios cilindros. Embora depois, se você selecionar um cilindro específico e for para a Física, a junta criada também será exibida lá e você poderá editar seus parâmetros.

7. Defina a configuração das ligações.

Mais uma vez, selecione Cuboid, encontre em Física uma lista de seus pontos e selecione um deles. Vemos que um canto branco com quadrados apareceu na cena dentro de Cuboid.
Nas configurações da junta, encontramos o gráfico do vetor Âncora 0 e ajustamos os valores de seus três campos para que esse canto seja deslocado ao longo do eixo X, fora de Cuboid e ligeiramente abaixado ao longo do eixo Z.





Em seguida, mudamos o canto ao longo do eixo Y, dependendo da ligação qual roda está atualmente selecionada.

Repetimos o procedimento com o restante dos pontos, definindo exatamente os mesmos turnos ao longo de Z e o mesmo, mas multidirecionais nos outros eixos.

Se você selecionar todos os pontos de uma vez, o design geral ficará visível. Você também pode ativar a exibição de juntas em auxiliares em um painel especial acima da cena: Auxiliares> Física > Articulações .


Vista traseira do quadro com os auxiliares incluídos

8. Vimos o que aconteceu.

No editor, há um botão para calcular a física. Se você ativá-lo, uma simulação de física é iniciada (os scripts não funcionam) e você pode verificar como nosso Frankenstein se comporta.
Antes de iniciar, verifique se as caixas de seleção ativadas para Intersecção de colisão e física estão marcadas nas configurações de "andar" . Caso contrário, nossa criação poderá falhar completamente embaixo do piso, inteiramente ou apenas com rodas.



Tenha cuidado, antes de ativar a simulação, é melhor salvar, e os parâmetros corrigidos durante sua operação retornarão aos seus valores após a desconexão.

Como vemos, as rodas são apanhadas nos lugares certos, mas a estrutura cai na superfície com as extremidades dos cilindros.



Você pode congelar o próprio Cuboid no local ativando primeiro a caixa de seleção Imóvel na guia Física na coluna Corpo.

9. Ajuste os eixos das rodas.

Desativar simulação física. Selecione Cuboid, vá para a guia Physics e edite os eixos 00 , Axis 10 e Axis 11 para cada junção . Observe que, na soma, os campos de cada vetor assumem valores de 0 a 1 e o editor tentará corrigir automaticamente os valores se você colocar 1 em um novo eixo pela primeira vez sem zerar o vetor.

Aparentemente, ainda não desenvolvi os vetores, os auxiliares mostram que as partes esquerda e direita estão olhando na mesma direção, mas não dão uma compreensão clara de qual eixo é onde, o que dificulta a sintonia.

De qualquer forma, esse layout funciona menos ou menos. Aqui, defino os vetores dos eixos da seguinte forma: Eixo 00 ( 0 , 0 , 1 ), Eixo 10 ( 1 , 0 , 0 ), Eixo 11 ( 0 , 0 , 1 ).



Se você iniciar uma simulação física agora, o design deve recair sobre os cilindros rotacionados corretamente, que posteriormente girarão ao longo do eixo correto.

10)Massa e comportamento das rodas, iterações físicas.

Muito provavelmente, a estrutura depois de cair no chão agora falha parcialmente.

Primeiro, vamos às configurações gerais da física. Clicamos na linha superior do editor. Windows > Configurações e na guia Configurações que se abre, encontramos a coluna Física (Runtime / World /). Definimos pelo menos 5 no campo Iterações . Mais uma vez, vamos para as configurações de cada junta. No topo da lista, todos têm um campo Iteração , definido como 8 . Restituição linear e restituição angular definida como 0,1 . Linear de






altere -0,15 , Linear para para 0,15 .
No fundo, afixamos uma massa de 25 kg no campo Massa da roda .

Quando a simulação começa, a "máquina" física ainda precisa falhar / falhar parcialmente.

Defina cada amortecimento linear para 50 . E defina Mola linear para 10 .
Agora, durante a simulação, a estrutura deve cair e saltar levemente no chão. Se isso não funcionar, experimente os valores de Amortecimento linear e Mola linear.
A documentação recomenda definir o amortecimento 400 e a mola 100, mas, pessoalmente, ao mesmo tempo, a "máquina" começa a girar como um helicóptero, salta e voa para longe.

11. A configuração final do quadro.

Salve e tente clicar em Reproduzir (o botão acima, ao lado da inclusão de simulação física) para percorrer a cena na primeira pessoa. Provavelmente a “máquina” pairou um pouco no ar, mas rola se for empurrada para dentro do cubo central.



Agora você pode ajustar a âncora 0 nos pontos para que fiquem aproximadamente equidistantes do centro (embora não seja necessário). Em seguida, inicie a simulação e altere a Mola Linear diretamente durante a mesma para encontrar o valor ideal em que cada roda normalmente toca o chão.

Depois de todas essas manipulações, você deve ter uma “máquina” caindo corretamente no chão, que rola levemente ao pressionar o modo de jogo, onde, por padrão, você roda em um controle separado com uma visão em primeira pessoa.



Escrevendo um script de controle



Temos um espaço em branco da "máquina de escrever", agora vamos escrever um código de controle para ele em C #.
Para fazer isso, clique com o botão direito do mouse na janela abaixo da cena e selecione Criar > Criar componente C # . Digite o nome do script na janela que aparece.





Clique duas vezes no arquivo de script exibido e o ambiente de desenvolvimento é iniciado.



Selecione as linhas preenchidas em azul na imagem, exclua-as e adicione o seguinte código ao qual eu vim editando o script proposto na documentação:

Snippet de script
	[ShowInEditor][Parameter(Tooltip = "Left Wheel")]
	private Node targetWheelL = null;
	[ShowInEditor][Parameter(Tooltip = "Right Wheel")]
	private Node targetWheelR = null;

	[ShowInEditor][Parameter(Tooltip = "Left Wheel F")]
	private Node targetFWL = null;
	[ShowInEditor][Parameter(Tooltip = "Right Wheel F")]
	private Node targetFWR = null;

	[ShowInEditor][Parameter(Tooltip = "theCar")]
	private Node targetCar = null;

    private JointWheel my_jointL;
    private JointWheel my_jointR;
    private JointWheel my_jointFL;
    private JointWheel my_jointFR;

	Controls controls = null;
	float angle = 0.0f;
	float velocity = 0.0f;
	float torque = 0.0f;

	private float ifps;

	private void Init()
	{
	my_jointL = targetWheelL.ObjectBodyRigid.GetJoint(0) as JointWheel;
	my_jointR = targetWheelR.ObjectBodyRigid.GetJoint(0) as JointWheel;
	my_jointFL = targetFWL.ObjectBodyRigid.GetJoint(0) as JointWheel;
	my_jointFR = targetFWR.ObjectBodyRigid.GetJoint(0) as JointWheel;

	PlayerPersecutor player = new PlayerPersecutor();
	controls = player.Controls;
	}
	
	private void Update()
	{
			ifps = Game.IFps;

			if ((controls.GetState(Controls.STATE_FORWARD) == 1) || (controls.GetState(Controls.STATE_TURN_UP) == 1))
			{
				velocity = MathLib.Max(velocity, 0.0f);
				velocity += ifps * 50.0f;
				torque = 5.0f;
			}
			else if ((controls.GetState(Controls.STATE_BACKWARD) == 1) || (controls.GetState(Controls.STATE_TURN_DOWN) == 1))
			{
				velocity = MathLib.Min(velocity, 0.0f);
				velocity -= ifps * 50.0f;
				torque = 5.0f;
			}
			else
			{
				velocity *= MathLib.Exp(-ifps);
			}
			velocity = MathLib.Clamp(velocity, -90.0f, 90.0f);

			if ((controls.GetState(Controls.STATE_MOVE_LEFT) == 1) || (controls.GetState(Controls.STATE_TURN_LEFT) == 1))
				angle += ifps * 100.0f;
			else if ((controls.GetState(Controls.STATE_MOVE_RIGHT) == 1) || (controls.GetState(Controls.STATE_TURN_RIGHT) == 1))
				angle -= ifps * 100.0f;
			else
			{
				if (MathLib.Abs(angle) < 0.25f) angle = 0.0f;
				else angle -= MathLib.Sign(angle) * ifps * 45.0f;
			}
	
			angle = MathLib.Clamp(angle, -10.0f, 10.0f);

			float base_a = 3.3f;
			float width = 3.0f;
			float angle_0 = angle;
			float angle_1 = angle;
			if (MathLib.Abs(angle) > MathLib.EPSILON)
			{
				float radius = base_a / MathLib.Tan(angle * MathLib.DEG2RAD);
				angle_0 = MathLib.Atan(base_a / (radius + width / 2.0f)) * MathLib.RAD2DEG;
				angle_1 = MathLib.Atan(base_a / (radius - width / 2.0f)) * MathLib.RAD2DEG;
			}

			my_jointFL.Axis10 = MathLib.RotateZ(angle_0).GetColumn3(0);
			my_jointFR.Axis10 = MathLib.RotateZ(angle_1).GetColumn3(0);

			if (controls.GetState(Controls.STATE_USE) == 1)
			{
				velocity = 0.0f;
					my_jointL.AngularDamping = 20000.0f;
					my_jointR.AngularDamping = 20000.0f;
					my_jointFL.AngularDamping = 20000.0f;
					my_jointFR.AngularDamping = 20000.0f;
			}
			else
			{
					my_jointL.AngularDamping = 0.0f;
					my_jointR.AngularDamping = 0.0f;
					my_jointFL.AngularDamping = 0.0f;
					my_jointFR.AngularDamping = 0.0f;
			}

			if (Input.IsKeyDown(Input.KEY.Q))
			{
				targetCar.ObjectBodyRigid.AddLinearImpulse(vec3.UP*1000f);
			}
			if (Input.IsKeyDown(Input.KEY.E))
			{
				targetCar.ObjectBodyRigid.AddLinearImpulse(vec3.DOWN*1000f);
			}

	}

		private void UpdatePhysics()
		{
			my_jointL.AngularVelocity = velocity;
			my_jointR.AngularVelocity = velocity;
			
			my_jointL.AngularTorque = torque;
			my_jointR.AngularTorque = torque;
		}



:

TheVehicle.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "ca695c8787d5703a22a6c2516a3c177cddf38cab")]
public class TheVehicle : Component
{

, , . , .

[ShowInEditor][Parameter(Tooltip = "Left Wheel")]
private Node targetWheelL = null;
[ShowInEditor][Parameter(Tooltip = "Right Wheel")]
private Node targetWheelR = null;

[ShowInEditor][Parameter(Tooltip = "Left Wheel F")]
private Node targetFWL = null;
[ShowInEditor][Parameter(Tooltip = "Right Wheel F")]
private Node targetFWR = null;

[ShowInEditor][Parameter(Tooltip = "theCar")]
private Node targetCar = null;

. tooltip , .

private JointWheel my_jointL;
private JointWheel my_jointR;
private JointWheel my_jointFL;
private JointWheel my_jointFR;

.

Controls controls = null;

float angle = 0.0f;
float velocity = 0.0f;
float torque = 0.0f;

private float ifps;

.

private void Init()
{
my_jointL = targetWheelL.ObjectBodyRigid.GetJoint(0) as JointWheel;
my_jointR = targetWheelR.ObjectBodyRigid.GetJoint(0) as JointWheel;
my_jointFL = targetFWL.ObjectBodyRigid.GetJoint(0) as JointWheel;
my_jointFR = targetFWR.ObjectBodyRigid.GetJoint(0) as JointWheel;

, JointWheel.
, , ( ).

			
// setting up player and controls
PlayerPersecutor player = new PlayerPersecutor();
controls = player.Controls;
}

, PlayerPresecutor, Controls player .

private void Update()
{
ifps = Game.IFps;

// forward and backward movement by setting joint motor's velocity and torque
			if ((controls.GetState(Controls.STATE_FORWARD) == 1) || (controls.GetState(Controls.STATE_TURN_UP) == 1))
			{
				velocity = MathLib.Max(velocity, 0.0f);
				velocity += ifps * 50.0f;
				torque = 5.0f;
			}//Input.IsKeyDown(Input.KEY.DOWN)
			else if ((controls.GetState(Controls.STATE_BACKWARD) == 1) || (controls.GetState(Controls.STATE_TURN_DOWN) == 1))
			{
				velocity = MathLib.Min(velocity, 0.0f);
				velocity -= ifps * 50.0f;
				torque = 5.0f;
			}
			else
			{
				velocity *= MathLib.Exp(-ifps);
			}
			velocity = MathLib.Clamp(velocity, -90.0f, 90.0f);

			// steering left and right by changing Axis01 for front wheel joints
			if ((controls.GetState(Controls.STATE_MOVE_LEFT) == 1) || (controls.GetState(Controls.STATE_TURN_LEFT) == 1))
				angle += ifps * 100.0f;
			else if ((controls.GetState(Controls.STATE_MOVE_RIGHT) == 1) || (controls.GetState(Controls.STATE_TURN_RIGHT) == 1))
				angle -= ifps * 100.0f;
			else
			{
				if (MathLib.Abs(angle) < 0.25f) angle = 0.0f;
				else angle -= MathLib.Sign(angle) * ifps * 45.0f;
			}

			angle = MathLib.Clamp(angle, -10.0f, 10.0f);//      30  (angle, -30.0f, 30.0f)

			// calculating steering angles for front joints (angle_0 and angle_1)
			float base_a = 3.3f;
			float width = 3.0f;
			float angle_0 = angle;
			float angle_1 = angle;
			if (MathLib.Abs(angle) > MathLib.EPSILON)
			{
				float radius = base_a / MathLib.Tan(angle * MathLib.DEG2RAD);
				angle_0 = MathLib.Atan(base_a / (radius + width / 2.0f)) * MathLib.RAD2DEG;
				angle_1 = MathLib.Atan(base_a / (radius - width / 2.0f)) * MathLib.RAD2DEG;
			}

Update, , .

my_jointFL.Axis10 = MathLib.RotateZ(angle_0).GetColumn3(0);
my_jointFR.Axis10 = MathLib.RotateZ(angle_1).GetColumn3(0);

// enabling or disabling a brake
if (controls.GetState(Controls.STATE_USE) == 1)
{
velocity = 0.0f;
my_jointL.AngularDamping = 20000.0f;
my_jointR.AngularDamping = 20000.0f;
my_jointFL.AngularDamping = 20000.0f;
my_jointFR.AngularDamping = 20000.0f;
}
else
{
my_jointL.AngularDamping = 0.0f;
my_jointR.AngularDamping = 0.0f;
my_jointFL.AngularDamping = 0.0f;
my_jointFR.AngularDamping = 0.0f;
}

, , . , 4 . , , 10 .

if (Input.IsKeyDown(Input.KEY.Q))
{
targetCar.ObjectBodyRigid.AddLinearImpulse(vec3.UP*1000f);
}

if (Input.IsKeyDown(Input.KEY.E))
{
targetCar.ObjectBodyRigid.AddLinearImpulse(vec3.DOWN*1000f);
}

}

Update , . , — «this.» .

private void UpdatePhysics()
{
// set angular velocity for rear joints
my_jointL.AngularVelocity = velocity;
my_jointR.AngularVelocity = velocity;

// set torque for rear joints
my_jointL.AngularTorque = torque;
my_jointR.AngularTorque = torque;

}

}

Update Physics , velocity torque.


Depois disso, salve o arquivo de script e retorne à janela do editor. O Unigine verificará se há erros no programa e, se estiver tudo bem, um retângulo verde deve aparecer no canto inferior direito com a notificação Construção do projeto bem-sucedida.

Agora selecione Cuboid, adicione o campo de componente a ele e arraste nosso script para lá. Aparecem alguns campos que precisam ser preenchidos. No campo Target Wheel L, arraste suavemente a roda traseira esquerda (ou seja, o Cilindro que a indica), Target Whell R - a roda traseira direita, Target FWL - a frente esquerda, Target FWR - a frente direita e o próprio Cuboid no campo Target Car.


Para adicionar um componente, encontramos esse campo nas propriedades do Cuboid e clique nele.Uma


linha vazia aparecerá onde você pode arrastar o arquivo de script (ou encontrar o caminho para ele através do ícone da pasta)


Preencha os campos

Executar Play - agora a máquina começou a se mover. É verdade, simultaneamente com o personagem em nome de quem você está agora olhando o mundo.

Seu controle é o seguinte: W - rola para frente, S - para trás, A e D - vira as rodas dianteiras para a esquerda e para a direita, respectivamente. Um impulso é dado a Q , a máquina, por assim dizer, salta. Em E , pelo contrário, o impulso diminui.

Você pode notar que a máquina cai um pouco lentamente, como na lua. Para melhorar esse momento, existem duas opções. A documentação sugeriu fazer alterações no arquivo AppWorldLogic.cs. Mas não precisamos disso, pois realizei a inicialização no script da máquina de escrever. Exceto algumas linhas que governam a física global.

O fato é que você pode inserir independentemente essas configurações e alterá-las. Para fazer isso, clique na linha superior do editor. Windows> Configurações, na janela que se abre, localize a coluna Física e defina o valor de Velocidade Linear Congelada como 0,1, para Velocidade Angular Congelada também 0,1 e altere o vetor Gravidade mais baixo de (0,0, -9,8) para (0,0, - 19.6)

O mesmo pode ser feito no código adicionando as seguintes linhas ao Init:

Physics.Gravity = new vec3(0.0f, 0.0f, -9.8f * 2.0f);
Physics.FrozenLinearVelocity = 0.1f;
Physics.FrozenAngularVelocity = 0.1f;

Se você iniciar o Play agora, a “máquina” provavelmente se deteriorará novamente e começará a falhar. Para consertar isso, tente girar uma mola linear em cada roda. Levante duas vezes para começar. Ao configurar, você notará que a gravidade durante os saltos é mais forte (embora eu defina o momento do salto como bastante alto por padrão).

Agora que você já se molhou ao configurar este carrinho mal-humorado, é hora de soltar os grilhões do firts_person_controller e observar o que está acontecendo do lado da máquina em si, com uma câmera de terceira pessoa.
Desativado baixado first_person_controller (clique na caixa ao lado do nome dele para que fique vazio).
Crie uma câmera Para fazer isso, clique com o botão direito do mouse na cena e selecione Criar> Câmera> Presecutor. A própria câmera PlayerPresecutor e seu alvo simulado Presecutor_Target serão exibidos.
O manequim pode ser desligado. Clicamos na própria câmera, marque a caixa de seleção Main Player em suas propriedades (para não obter uma tela preta na inicialização). No campo Nó de destino, encontramos nosso cubóide na lista suspensa.

Salve e clique em Reproduzir.

Agora você pode andar totalmente. É verdade que a câmera pode voar muito longe. Para corrigir isso, você precisa ajustar seus limites. Retornamos ao editor e definimos as propriedades da câmera, por exemplo, Distância mínima 10 e Distância máxima 30.

Separadores no mecanismo Unigine


Tendo aprendido a coletar física aproximada das rodas, fiz uma cena de teste com um modelo de biomechos do meu projeto em Nevanger. Aqui está o que parece no momento:



Screenshots







Os principais problemas no momento são alguma instabilidade do design. O que é novamente devido ao fato de que ainda não compreendi completamente todos os aspectos e nuances das configurações. Às vezes, a máquina tropeça em algo e começa a girar ferozmente. Reduzir o amortecimento linear não parece ajudar muito, distorcendo os outros parâmetros também, embora ainda não tenha torcido ou configurado algo, mas não é abrangente.

Outro bug - há situações com o total preso no chão, quando as rodas dianteiras ficam presas e a traseira sob a paisagem. Ou perfurando a própria paisagem em alta velocidade, seguido de um voo por baixo dela. Aparentemente, tudo isso é corrigido pela definição de tolerâncias e iterações, mas até agora não foram encontrados os valores ideais.

Em geral, em uma superfície bastante plana, o movimento já é mais adequado. Não está claro como as juntas de roda se comportam idealmente em uma superfície irregular, como eu entendi nas demos em vídeo do motor para carros que elas usavam desatualizadas (aparentemente), mas juntas de suspensão mais fisicamente "honestas" (a propósito, eu não tentei montar uma máquina nelas, talvez , tudo é um pouco mais fácil lá). As juntas de roda levam em consideração os parâmetros de atrito da paisagem ou apenas interessam se a bandeira da física está ativada.

Impressões gerais do mecanismo


Quanto ao trabalho com o editor, o que aconteceu mais me lembrou o processo de trabalho com o CryEngine. Embora em alguns lugares seja mais conveniente. Mas é como alguém, no mesmo CryEngine foi possível modelar diretamente no editor. Isso não é relevante para mim, porque para isso eu uso o Blender, onde você tem ordens de magnitude com mais controle sobre o modelo, e para alguém isso pode ser importante.

Na figura abaixo, uma lista de materiais é visível à esquerda. As malhas são pintadas através de um grupo de materiais baseados em malha, dos quais é possível clonar suas opções de material. Pintar terrane com uma textura já é mais difícil, mas as máscaras são usadas ao máximo - você pode misturar texturas, mapas de altura e assim por diante, se entender o dispositivo. Para a mesma água, existe seu próprio grupo separado de materiais, que é adicionado literalmente em um clique e parece muito bom.

À direita está a hierarquia dos objetos de cena e a janela de propriedades. É um pouco inconveniente manipular valores numéricos em tempo real - você precisa entrar no ícone com pequenas setas. Alguns controles deslizantes são inicialmente enganosos, porque não mostram todo o intervalo possível do parâmetro, mas, digamos, apenas o intervalo de 0 a 1. A velocidade de vôo da câmera é regulada no campo com um homem correndo por cima, por padrão, de alguma forma, se move lentamente, a julgar pelas sensações . Talvez isso seja mais conveniente quando você trabalha com modelos em escala real.


All Articles