Skip to content

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.

csharp
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.

csharp
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

MethodType
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
csharp
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.

csharp
float current = m_Water.GetFloat("waveSpeed");

HasParameter(string name)

Whether the shader actually declares a parameter by that name.

csharp
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

csharp
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