Material
Loading a material and driving its shader parameters at runtime. For authoring materials and shaders, see the Materials and shaders guide.
Material.LoadShared(string jmaterialPath)
Loads a .jmaterial asset. Every caller loading the same path gets the same material — changing a parameter on it changes it for every entity using that file.
Material glow = Material.LoadShared("Materials/Glow.jmaterial");Throws if the material can't be loaded, so a typo in the path fails loudly rather than leaving you with a null you carry around.
InstantiateMaterial()
Creates a private clone that only you use. You own its lifetime — dispose it in OnDestroy.
public class Enemy : GameEntity
{
private Material? m_Flash;
protected override void OnCreate()
{
m_Flash = Material.LoadShared("Materials/HitFlash.jmaterial")
.InstantiateMaterial();
}
public void OnHit() => m_Flash?.SetFloat("flashAmount", 1.0f);
protected override void OnDestroy() => m_Flash?.Dispose();
}Shared or instantiated — get this right first
LoadShared gives you the shared material. Setting a parameter on it tints every enemy in the level, not the one that got hit. InstantiateMaterial() gives you a private copy.
Cloning is deliberately a verb here rather than something that happens implicitly, because leaked clones are among the easiest performance problems to create and the hardest to find. The cost of that choice is that you have to call Dispose().
Setting parameters
| Method | Type |
|---|---|
SetFloat(string name, float value) | A single number |
SetVector2(string name, Vector2 value) | |
SetVector3(string name, Vector3 value) | |
SetVector4(string name, Vector4 value) | |
SetColor(string name, Vector4 value) | A colour as r, g, b, a |
SetBool(string name, bool value) | |
SetTexture(string name, string textureAssetPath) | A texture, by asset path |
m_Water.SetFloat("waveSpeed", 2.5f);
m_Water.SetVector2("scrollDirection", new Vector2(1, 0.2f));
m_Outline.SetColor("outlineColor", new Vector4(1, 0.8f, 0, 1));
m_Sign.SetTexture("albedo", "Textures/SignSpanish.png");Reading parameters back
GetFloat, GetVector2, GetVector3, GetVector4, GetColor, GetBool — each takes the parameter name and returns its current value.
float current = m_Water.GetFloat("waveSpeed");HasParameter(string name)
Whether the shader actually declares a parameter by that name.
if (m_Effect.HasParameter("dissolveAmount"))
m_Effect.SetFloat("dissolveAmount", t);A misspelled parameter fails quietly
Setting a parameter the shader doesn't declare doesn't throw — it logs a warning naming both the parameter and the material, and does nothing else. If a material change appears to have no effect, check the Log panel before assuming the shader is wrong. HasParameter is the programmatic version of that check.
Dispose()
Releases a material you instantiated. Call it in OnDestroy — nothing does it for you.
Example: a dissolve effect
using JoystickEngine;
public class Dissolver : GameEntity
{
private Material? m_Mat;
protected override void OnCreate()
{
m_Mat = Material.LoadShared("Materials/Dissolve.jmaterial")
.InstantiateMaterial();
}
public void Vanish() => RunCoroutine(Dissolve(1.2f));
private System.Collections.IEnumerator Dissolve(float duration)
{
float t = 0;
while (t < duration)
{
t += Time.DeltaTime;
m_Mat!.SetFloat("dissolveAmount", t / duration);
yield return null;
}
}
protected override void OnDestroy() => m_Mat?.Dispose();
}What isn't scriptable
Assigning a material to a renderer is done in the Properties panel — there's no SpriteRendererComponent.Material property in 0.1.0. A material loaded from script affects rendering through its own parameter values, not by being attached from code.
For a plain colour tint you don't need a material at all — see SpriteRendererComponent.Color.
See also
- Materials and shaders guide —
.matvs.jmaterial, the Shader Editor - SpriteRendererComponent — tinting and texture swaps without a material
- Rendering — what a distinct material costs in batching