This page has been translated automatically.
Unigine Basics
1. Introduction
2. Managing Virtual Worlds
3. Preparing 3D Models
4. Materials
5. Cameras and Lighting
7. Making Cutscenes and Recording Videos
8. Preparing Your Project for Release
9. Physics
10. Optimization Basics
11. PROJECT2: First-Person Shooter
12. PROJECT3: Third-Person Cross-Country Arcade Racing Game
13. PROJECT4: VR Application With Simple Interaction

Managing Materials

Changing parameters of the material assigned to the object surface via code, and replacing one assigned material with another.

Materials can be operated not only in the Editor — sometimes it is required to assign materials via code (in case of procedural content generation, for example) or configure some of their parameters. To control materials via API, we use the following two classes:

  • Materials class that represents an interface for managing loaded materials (this is a manager class that can help you find a required material, for example).
  • Material class that is used to manage each individual material.

The following example demonstrates how to inherit a new material from the base one, which is called mesh_base.

Source code (C#)
private void Init()
{

	// creating a box (ObjectMeshDynamic node)
	ObjectMeshDynamic my_mesh = Primitives.CreateBox(new vec3(1.5f, 1.5f, 1.5f));

	// getting the base mesh_base material to inherit from
	Material mesh_base = Materials.FindManualMaterial("Unigine::mesh_base");
	
	// inherit a new child material from it
	Material my_mesh_base = mesh_base.Inherit();
	
	// save a child material to "materials/my_mesh_base0.mat" (before being saved
	// this material only exists in RAM and is deleted as soon as the app is closed)
	my_mesh_base.CreateMaterialFile("materials/my_mesh_base0.mat");

	// setting the albedo color for the material to red
	my_mesh_base.SetParameterFloat4("albedo_color", new vec4(255, 0, 0, 255));

	// assigning the "my_mesh_base0.mat" material to surface 0 of the my_mesh object (ObjectMeshDynamiс)
	my_mesh.SetMaterialPath("materials/my_mesh_base0.mat", 0);

	// assigning the "my_mesh_base0.mat" material to all surfaces of the my_mesh object (ObjectMeshDynamiс)
	my_mesh.SetMaterialPath("materials/my_mesh_base0.mat", "*");
}

private void Shutdown()
{
	// deleting the "materials/my_mesh_base0.mat" material
	Materials.RemoveMaterial(Materials.FindMaterialByPath("materials/my_mesh_base0.mat").GUID, true);
}

Practice#

Now let's create an interactive poster in our interior with an ability to change its albedo texture and apply a light filter to the picture (add a tone).

First, we're gonna need a Static Mesh plane.

  1. Go to the archviz/textures folder and find the plane.mesh asset.
  2. Drag it to the scene (a new Static Mesh object will be created) and change its name to "poster".
  3. Set poster's transformation as shown on the image below:

  4. In the Surface Material section create a child material for the surface (click create a child material) to be able to change its parameters and drag the tex01.jpg asset to the Albedo field in the Textures tab.

Let's create the Customizable component (inherited from Interactable) that switches textures from the list (the array parameter) on the object — Action(0), and changes the albedo color multiplier by overrriding the method — Action(1). The code of the component looks like this:

Customizable.cs
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 Customizable : Interactable
{
	public  List<AssetLink> textures = null;
	private int current_texture = 0;
	
	public void Init()
	{
		// setting the tooltip text that will be displayed when hovering over the object
		tooltip = "Right-click on the object switches the listed object materials in a cyclic order."
+" Pressing the 'TAB' button randomly changes the color tone.";
	}

	// overriding the action for the child component
	public override void Action(int num)
	{
		// selecting the action
		switch (num)
		{
			// switching between the listed albedo textures of the object material in a cyclic order
			case 0:
				// if the texture list is not set or empty, we do nothing
				if(textures == null || textures.Count < 0)
					return;

				current_texture++;
				if (current_texture >= textures.Capacity)
					current_texture = 0;

				(node as Unigine.Object).SetMaterialTexture("albedo", textures[current_texture].AbsolutePath,0);
			break;
			// randomly changing the albedo color multiplier for the current material on the object
			case 1:
				(node as Unigine.Object).GetMaterial(0).SetParameterFloat4("albedo_color", MathLib.RandColor());
			break;
		}
	}
}

Then let's assign our component to the poster node and fill the texture array (tex01, tex02, tex03).

Now the image on the poster can be changed in one click.

Last update: 2024-12-13
Build: ()