Source file unity-csharp/systemic-design/ElementSource.cs from the GDnD code examples. Download raw file
// GDnD wiki example (3 of 3: ChemistryRules.cs, ChemistryBody.cs, ElementSource.cs)
// Demonstrates: the "element" side of a Breath of the Wild-style chemistry engine. A trigger
// volume that applies its element to every ChemistryBody inside it: a campfire (Fire), a pond
// (Water), an ice patch (Ice), a charged plate (Electricity) or a gust (Wind). Expose() applies
// rule 2, so sources can change each other: water puts a campfire out, fire melts ice to water.
// Related pages: [[breath-of-the-wild]], [[emergent-design]], [[unity-collider2d-and-triggers]],
// [[source-botw-breaking-conventions-gdc-2017]]
// Unity 6 (6000.x), 2D physics.
//
// Setup: add to a GameObject with a Collider2D set to Is Trigger. Trigger callbacks need a
// Rigidbody2D on at least one of the two objects (the moving ChemistryBody usually has one;
// otherwise give the source a Kinematic Rigidbody2D). Call Expose from anything that throws an
// element at the source, e.g. a water-bucket projectile calling source.Expose(Element.Water).
using UnityEngine;
namespace GDnD.Systemic.Chemistry
{
[RequireComponent(typeof(Collider2D))]
public class ElementSource : MonoBehaviour
{
[SerializeField] private Element element = Element.Fire;
[SerializeField] private Vector2 windDirection = Vector2.right;
public Element Current => element;
public void Expose(Element incoming) => element = ChemistryRules.Combine(element, incoming);
private void OnTriggerStay2D(Collider2D other)
{
if (element != Element.None && other.TryGetComponent(out ChemistryBody target))
target.ReceiveElement(element, windDirection);
}
}
}