ObiParticleAttachment is a component used to attach Obi particles to a target object in the scene. It works with all Obi actors (cloth, ropes, etc). There's two different ways an attachment can work:
You can add attachments at runtime too. This is how you create an attachment:
var attachment = actor.AddComponent<ObiParticleAttachment>(); attachment.target = targetTransform; attachment.particleGroup = particleGroup;
You can also change the particle group and/or target at runtime. As soon as you change either the particle group or the target, the attachment will rebind itself: all particles in the particle group will be attached at their current positions relative to the target transform. If you wish to attach the particles at some position other than their current position, use the particles API to set their positions before creating/modifying the attachment.
Particle groups are small scriptable objects that contain a list of particle indices. They can either be created at runtime:
var group = ScriptableObject.CreateInstance<ObiParticleGroup>(); group.particleIndices.Add(particleIndex); // index of the particle in the actor attachment.particleGroup = group;
or retrieved from the actor's blueprint:
attachment.particleGroup = actor.blueprint.groups[0];
The blueprint's groups array will contain as many particle groups you have created in the blueprint editor, or in the case of ropes/rods, as many control points the blueprint has.
You can enable/disable attachments at runtime just like you do with any other component in unity:
attachment.enabled = true; //enable the attachment attachment.enabled = false; // disable the attachment
Here's some sample code that will make an attached particle "snap" to the center of the target transform. To do this, these are the steps it follows:
using UnityEngine; using Obi; public class SnapAttachment : MonoBehaviour { public ObiParticleAttachment attachment; private ObiActor actor; void Start() { actor = GetComponent<ObiActor>(); actor.OnBlueprintLoaded += (ObiActor a, ObiActorBlueprint blueprint) => { Snap(); }; // in case the actor is already loaded: Snap(); } private void Snap() { if (attachment == null || !actor.isLoaded) return; // disable attachment: var trfm = attachment.target; attachment.enabled = false; attachment.target = null; // snap particle position to the transform: int index = actor.solverIndices[attachment.particleGroup.particleIndices[0]]; actor.solver.positions[index] = actor.solver.transform.InverseTransformPoint(trfm.position); // re-enable the attachment: attachment.target = trfm; attachment.enabled = true; } }