138 lines
4.1 KiB
C#
138 lines
4.1 KiB
C#
using UnityEngine;
|
|
|
|
namespace Obi
|
|
{
|
|
[ExecuteInEditMode]
|
|
[RequireComponent(typeof(ObiCollider))]
|
|
public class ObiForceZone : MonoBehaviour
|
|
{
|
|
[SerializeProperty("sourceCollider")]
|
|
[SerializeField] private ObiCollider m_SourceCollider;
|
|
|
|
protected ObiForceZoneHandle forcezoneHandle;
|
|
|
|
/// <summary>
|
|
/// The ObiCollider this ObiForceZone should affect.
|
|
/// </summary>
|
|
/// This is automatically set when you first create the ObiForceZone component, but you can override it afterwards.
|
|
public ObiCollider SourceCollider
|
|
{
|
|
set
|
|
{
|
|
if (value != null && value.gameObject != this.gameObject)
|
|
{
|
|
Debug.LogError("The ObiCollider component must reside in the same GameObject as ObiForceZone.");
|
|
return;
|
|
}
|
|
|
|
RemoveCollider();
|
|
m_SourceCollider = value;
|
|
AddCollider();
|
|
|
|
}
|
|
get { return m_SourceCollider; }
|
|
}
|
|
|
|
public ObiForceZoneHandle Handle
|
|
{
|
|
get
|
|
{
|
|
// don't check forcezoneHandle.isValid:
|
|
// CreateForceZone may defer creation, so we get a non-null, but invalid handle.
|
|
// If calling handle again right away before it becomes valid, it will call CreateForceZone again and create a second handle to the same zone.
|
|
if (forcezoneHandle == null)
|
|
{
|
|
var world = ObiColliderWorld.GetInstance();
|
|
|
|
// create the material:
|
|
forcezoneHandle = world.CreateForceZone();
|
|
forcezoneHandle.owner = this;
|
|
}
|
|
return forcezoneHandle;
|
|
}
|
|
}
|
|
|
|
public ForceZone.ZoneType type;
|
|
public ForceZone.ForceMode mode;
|
|
public float intensity;
|
|
|
|
[Header("Damping")]
|
|
public ForceZone.DampingDirection dampingDir;
|
|
public float damping = 0;
|
|
|
|
[Header("Falloff")]
|
|
public float minDistance;
|
|
public float maxDistance;
|
|
[Min(0)]
|
|
public float falloffPower = 1;
|
|
|
|
[Header("Tint")]
|
|
public Color color = Color.clear;
|
|
|
|
[Header("Pulse")]
|
|
public float pulseIntensity;
|
|
public float pulseFrequency;
|
|
public float pulseSeed;
|
|
|
|
protected float intensityVariation;
|
|
|
|
public void OnEnable()
|
|
{
|
|
forcezoneHandle = ObiColliderWorld.GetInstance().CreateForceZone();
|
|
forcezoneHandle.owner = this;
|
|
FindSourceCollider();
|
|
}
|
|
|
|
public void OnDisable()
|
|
{
|
|
RemoveCollider();
|
|
ObiColliderWorld.GetInstance().DestroyForceZone(forcezoneHandle);
|
|
}
|
|
|
|
private void FindSourceCollider()
|
|
{
|
|
if (SourceCollider == null)
|
|
SourceCollider = GetComponent<ObiCollider>();
|
|
else
|
|
AddCollider();
|
|
}
|
|
|
|
private void AddCollider()
|
|
{
|
|
if (m_SourceCollider != null)
|
|
m_SourceCollider.ForceZone = this;
|
|
}
|
|
|
|
private void RemoveCollider()
|
|
{
|
|
if (m_SourceCollider != null)
|
|
m_SourceCollider.ForceZone = null;
|
|
}
|
|
|
|
public virtual void UpdateIfNeeded()
|
|
{
|
|
if (!Handle.isValid)
|
|
return;
|
|
|
|
var fc = ObiColliderWorld.GetInstance().forceZones[Handle.index];
|
|
fc.type = type;
|
|
fc.mode = mode;
|
|
fc.intensity = intensity + intensityVariation;
|
|
fc.minDistance = minDistance;
|
|
fc.maxDistance = maxDistance;
|
|
fc.falloffPower = falloffPower;
|
|
fc.damping = damping;
|
|
fc.dampingDir = dampingDir;
|
|
fc.color = color;
|
|
ObiColliderWorld.GetInstance().forceZones[Handle.index] = fc;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (Application.isPlaying)
|
|
intensityVariation = Mathf.PerlinNoise(Time.time * pulseFrequency, pulseSeed) * pulseIntensity;
|
|
}
|
|
}
|
|
}
|
|
|