Skip to content

Working with materials at runtime

Use Unity’s Material API to change colors, floats, vectors and textures during play. Planets has no special runtime planet controller or generator API. Choose the renderer and material slot explicitly; the prefab root is not necessarily the surface renderer.

Control cloud contribution on one instance

Section titled “Control cloud contribution on one instance”

This example creates one material copy for the selected slot, changes Clouds Output, then restores the previous assignment and destroys the copy when the component is removed. Use it with a Terrestrial, Oceanic or Sand surface that exposes _CloudsOutput.

  1. Save the following as PlanetCloudAmount.cs in your own Scripts folder.
  2. Attach it to a scene GameObject.
  3. Assign the planet’s surface Renderer and the correct Material Slot in the Inspector.
  4. Enter Play Mode and change Amount, or call SetAmount from your own runtime code.
using UnityEngine;
public sealed class PlanetCloudAmount : MonoBehaviour
{
[SerializeField] Renderer surface;
[SerializeField, Min(0)] int materialSlot;
[SerializeField, Range(0f, 1f)] float amount = 0.279f;
static readonly int CloudsOutput = Shader.PropertyToID("_CloudsOutput");
Material original;
Material owned;
int ownedSlot;
Renderer owner;
void Awake()
{
if (!surface) return;
Material[] slots = surface.sharedMaterials;
if (materialSlot < 0 || materialSlot >= slots.Length) return;
original = slots[materialSlot];
if (!original || !original.HasProperty(CloudsOutput)) return;
owner = surface;
ownedSlot = materialSlot;
owned = new Material(original);
slots[ownedSlot] = owned;
owner.sharedMaterials = slots;
SetAmount(amount);
}
public void SetAmount(float value)
{
amount = Mathf.Clamp01(value);
if (owned) owned.SetFloat(CloudsOutput, amount);
}
void Update()
{
if (owned) owned.SetFloat(CloudsOutput, Mathf.Clamp01(amount));
}
void OnDestroy()
{
if (!owned) return;
if (owner)
{
Material[] slots = owner.sharedMaterials;
if (ownedSlot < slots.Length && slots[ownedSlot] == owned)
{
slots[ownedSlot] = original;
owner.sharedMaterials = slots;
}
}
Destroy(owned);
}
}

This is a custom integration example, not a component shipped with Planets. Keep the renderer/slot assignment fixed while this component owns its material. Removing visible clouds does not automatically remove Cloud Shadows; change _CloudShadows separately if your effect needs both removed.

Unity methodExampleUse
SetFloat_CloudsOutputNumeric material control
SetColor_CityLightColorColor, including alpha when the shader uses it
SetVector_UVSpeedGas motion vector; nonzero XY components produce motion
SetTexture_CloudsTopCompatible replacement texture

Use HasProperty before applying a setting to a material that may use another shader. The Shader Reference provides exact IDs, including _FrenselMult, _SurfraceMap, _NormlalDistortionFactor, _LigntingMaskPow and Sun’s TriplanarFalloff without a leading underscore.

Editing a shared material affects every renderer using it. Accessing Renderer.material can create an implicit copy; avoid repeatedly creating copies while updating an effect. Clone once, reuse it and destroy it when ownership ends.

MaterialPropertyBlock is another Unity option for per-renderer overrides. Check its interaction with your renderer and batching configuration in your own scene before choosing it for performance. Planets does not supply a custom batching or material-lifecycle layer. See Performance considerations.