84 lines
2.7 KiB
C#
84 lines
2.7 KiB
C#
using UnityEngine;
|
|
using Obi;
|
|
|
|
|
|
[RequireComponent(typeof(ObiRope))]
|
|
public class HosePump : MonoBehaviour {
|
|
|
|
[Header("Bulge controls")]
|
|
public float pumpSpeed = 5;
|
|
public float bulgeFrequency = 3;
|
|
public float baseThickness = 0.04f;
|
|
public float bulgeThickness = 0.06f;
|
|
public Color bulgeColor = Color.cyan;
|
|
|
|
[Header("Flow controls")]
|
|
public ParticleSystem waterEmitter;
|
|
public float flowSpeedMin = 0.5f;
|
|
public float flowSpeedMax = 7;
|
|
public float minEmitRate = 100;
|
|
public float maxEmitRate = 1000;
|
|
|
|
private ObiRope rope;
|
|
public ObiPathSmoother smoother;
|
|
private float time = 0;
|
|
|
|
void OnEnable()
|
|
{
|
|
rope = GetComponent<ObiRope>();
|
|
smoother = GetComponent<ObiPathSmoother>();
|
|
rope.OnSimulationStart += Rope_OnBeginStep;
|
|
}
|
|
void OnDisable()
|
|
{
|
|
rope.OnSimulationStart -= Rope_OnBeginStep;
|
|
}
|
|
|
|
private void Rope_OnBeginStep(ObiActor actor, float stepTime, float substepTime)
|
|
{
|
|
time += stepTime * pumpSpeed;
|
|
|
|
float distance = 0;
|
|
float sine = 0;
|
|
|
|
// iterate over all particles, changing their radius and color based on a sine wave:
|
|
// (note this would not support resizable / cuttable ropes, to add support for that use rope.elements instead)
|
|
for (int i = 0; i < rope.solverIndices.count; ++i)
|
|
{
|
|
int solverIndex = rope.solverIndices[i];
|
|
|
|
if (i > 0)
|
|
{
|
|
int previousIndex = rope.solverIndices[i - 1];
|
|
distance += Vector3.Distance(rope.solver.positions[solverIndex],rope.solver.positions[previousIndex]);
|
|
}
|
|
|
|
sine = Mathf.Max(0, Mathf.Sin(distance * bulgeFrequency - time));
|
|
|
|
rope.solver.principalRadii[solverIndex] = Vector3.one * Mathf.Lerp(baseThickness,bulgeThickness, sine);
|
|
rope.solver.colors[solverIndex] = Color.Lerp(Color.white, bulgeColor, sine);
|
|
}
|
|
|
|
// change particle emission rate/speed based on sine wave at the last particle:
|
|
if (waterEmitter != null)
|
|
{
|
|
var main = waterEmitter.main;
|
|
main.startSpeed = Mathf.Lerp(flowSpeedMin,flowSpeedMax,sine);
|
|
|
|
var emission = waterEmitter.emission;
|
|
emission.rateOverTime = Mathf.Lerp(minEmitRate, maxEmitRate, sine);
|
|
}
|
|
}
|
|
|
|
public void LateUpdate()
|
|
{
|
|
if (smoother != null && waterEmitter != null)
|
|
{
|
|
ObiPathFrame section = smoother.GetSectionAt(1);
|
|
waterEmitter.transform.position = rope.solver.transform.TransformPoint(section.position);
|
|
waterEmitter.transform.rotation = rope.solver.transform.rotation * (Quaternion.LookRotation(section.tangent, section.binormal));
|
|
}
|
|
}
|
|
}
|
|
|