836 lines
29 KiB
C#
836 lines
29 KiB
C#
|
using System;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace RayFire
|
|||
|
{
|
|||
|
[DisallowMultipleComponent]
|
|||
|
[AddComponentMenu ("RayFire/Rayfire Man")]
|
|||
|
[HelpURL ("https://rayfirestudios.com/unity-online-help/components/unity-man-component/")]
|
|||
|
public class RayfireMan : MonoBehaviour
|
|||
|
{
|
|||
|
// UI
|
|||
|
public bool setGravity;
|
|||
|
public float multiplier = 1f;
|
|||
|
public RigidbodyInterpolation interpolation = RigidbodyInterpolation.None;
|
|||
|
public float colliderSize = 0.05f;
|
|||
|
public int coplanarVerts = 30;
|
|||
|
public MeshColliderCookingOptions cookingOptions = (MeshColliderCookingOptions)30;
|
|||
|
public CollisionDetectionMode meshCollision = CollisionDetectionMode.ContinuousDynamic;
|
|||
|
public CollisionDetectionMode clusterCollision = CollisionDetectionMode.Discrete;
|
|||
|
public float minimumMass = 0.1f;
|
|||
|
public float maximumMass = 400f;
|
|||
|
public RFMaterialPresets materialPresets = new RFMaterialPresets();
|
|||
|
public GameObject parent;
|
|||
|
public float globalSolidity = 1f;
|
|||
|
public float timeQuota = 0.03f;
|
|||
|
public QuotaType quotaAction = QuotaType.Skip;
|
|||
|
public RFManDemolition advancedDemolitionProperties = new RFManDemolition();
|
|||
|
public RFPoolingFragment fragments = new RFPoolingFragment();
|
|||
|
public RFPoolingParticles particles = new RFPoolingParticles();
|
|||
|
public bool debugState = true;
|
|||
|
public bool debugBuild;
|
|||
|
public bool debugEditor;
|
|||
|
|
|||
|
// Coroutines
|
|||
|
public List<RFPhysic> physicList = new List<RFPhysic>();
|
|||
|
public List<RayfireRigid> dmlList = new List<RayfireRigid>();
|
|||
|
public List<RayfireRigid> fadeOffList = new List<RayfireRigid>();
|
|||
|
public List<RayfireRigid> offActList = new List<RayfireRigid>();
|
|||
|
public List<RayfireRigid> velActList = new List<RayfireRigid>();
|
|||
|
|
|||
|
// Non Serialized
|
|||
|
[NonSerialized] public Transform transForm;
|
|||
|
[NonSerialized] public RFStorage storage;
|
|||
|
[NonSerialized] bool physicsDataCorState;
|
|||
|
[NonSerialized] bool dmlCorState;
|
|||
|
[NonSerialized] float dmlThisFrame;
|
|||
|
[NonSerialized] bool fadeOffCorState;
|
|||
|
[NonSerialized] bool offActCorState;
|
|||
|
[NonSerialized] bool velActCorState;
|
|||
|
|
|||
|
// Static
|
|||
|
public static RayfireMan inst;
|
|||
|
public const int buildMajor = 1;
|
|||
|
public static int buildMinor = 75;
|
|||
|
public static int coplanarVertLimit = 30;
|
|||
|
static readonly float fadeOffsetRate = 2f;
|
|||
|
|
|||
|
public static float colliderSizeStatic = 0.05f;
|
|||
|
public static MeshColliderCookingOptions cookingOptionsStatic = (MeshColliderCookingOptions)30;
|
|||
|
public static bool debugStateStatic = true;
|
|||
|
public static bool debugBuildStatic;
|
|||
|
public static bool debugEditorStatic;
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Common
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Awake
|
|||
|
void Awake()
|
|||
|
{
|
|||
|
// Set static instance
|
|||
|
SetInstance();
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Instance
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Set instance
|
|||
|
void SetInstance()
|
|||
|
{
|
|||
|
// Inst not define, set to this
|
|||
|
if (inst == null)
|
|||
|
{
|
|||
|
inst = this;
|
|||
|
}
|
|||
|
|
|||
|
// Inst defined
|
|||
|
if (inst != null)
|
|||
|
{
|
|||
|
// Instance is this mono - > Init
|
|||
|
if (inst == this)
|
|||
|
{
|
|||
|
// Set vars
|
|||
|
SetVariables();
|
|||
|
|
|||
|
// Runtime ops
|
|||
|
if (Application.isPlaying == true)
|
|||
|
Init();
|
|||
|
}
|
|||
|
|
|||
|
// Inst is not this mono. Destroy.
|
|||
|
if (inst != this)
|
|||
|
{
|
|||
|
if (Application.isPlaying == true)
|
|||
|
Destroy (gameObject);
|
|||
|
else if (Application.isEditor == true)
|
|||
|
DestroyImmediate (gameObject);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// init ops
|
|||
|
void Init()
|
|||
|
{
|
|||
|
// Start pooling objects for fragments
|
|||
|
SetPooling();
|
|||
|
|
|||
|
// Create storage and stat root check coroutine
|
|||
|
SetStorage();
|
|||
|
|
|||
|
// Rigid. Velocity cache
|
|||
|
StartCoroutine (PhysicsManCor ());
|
|||
|
|
|||
|
// Rigid. Demolition
|
|||
|
StartCoroutine (DemolitionManCor());
|
|||
|
|
|||
|
// Rigid. Offset fading
|
|||
|
StartCoroutine (FadeOffsetCor());
|
|||
|
|
|||
|
// Rigid. Offset activation
|
|||
|
StartCoroutine (OffsetActivationCor());
|
|||
|
|
|||
|
// Rigid. Velocity activation
|
|||
|
StartCoroutine (VelocityActivationCor());
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Enable/Disable
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Disable
|
|||
|
void OnDisable()
|
|||
|
{
|
|||
|
fragments.inProgress = false;
|
|||
|
particles.poolProgress = false;
|
|||
|
physicsDataCorState = false;
|
|||
|
dmlCorState = false;
|
|||
|
fadeOffCorState = false;
|
|||
|
offActCorState = false;
|
|||
|
velActCorState = false;
|
|||
|
if (storage != null)
|
|||
|
storage.inProgress = false;
|
|||
|
}
|
|||
|
|
|||
|
// Activation
|
|||
|
void OnEnable()
|
|||
|
{
|
|||
|
if (Application.isPlaying == true && gameObject.activeSelf == true)
|
|||
|
Init();
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Methods
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Set vars
|
|||
|
void SetVariables()
|
|||
|
{
|
|||
|
// Get components
|
|||
|
transForm = GetComponent<Transform>();
|
|||
|
|
|||
|
// Reset amount
|
|||
|
advancedDemolitionProperties.ResetCurrentAmount();
|
|||
|
|
|||
|
// Set gravity
|
|||
|
SetGravity();
|
|||
|
|
|||
|
// Set Physic Materials if needed
|
|||
|
materialPresets.SetMaterials();
|
|||
|
|
|||
|
// Set static properties
|
|||
|
colliderSizeStatic = colliderSize;
|
|||
|
cookingOptionsStatic = cookingOptions;
|
|||
|
debugStateStatic = debugState;
|
|||
|
debugBuildStatic = debugBuild;
|
|||
|
debugEditorStatic = debugEditor;
|
|||
|
coplanarVertLimit = coplanarVerts;
|
|||
|
}
|
|||
|
|
|||
|
// Set gravity
|
|||
|
void SetGravity()
|
|||
|
{
|
|||
|
if (setGravity == true)
|
|||
|
Physics.gravity = -9.81f * multiplier * Vector3.up;
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Physics data cor
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Collect Rigid.Physics for Velocity cache
|
|||
|
public void AddToPhysicCor (RayfireRigid rigid)
|
|||
|
{
|
|||
|
// TODO collect only if demolition, cluster, velocity act
|
|||
|
|
|||
|
// Already in physicList
|
|||
|
if (rigid.physics.velCache == true)
|
|||
|
return;
|
|||
|
|
|||
|
// Has no rigidbody to cache
|
|||
|
if (rigid.physics.rb == null)
|
|||
|
return;
|
|||
|
|
|||
|
rigid.physics.velCache = true;
|
|||
|
physicList.Add (rigid.physics);
|
|||
|
}
|
|||
|
|
|||
|
// Rigid.Physics.Velocity cache
|
|||
|
IEnumerator PhysicsManCor ()
|
|||
|
{
|
|||
|
// Stop if running
|
|||
|
if (physicsDataCorState == true)
|
|||
|
yield break;
|
|||
|
|
|||
|
// Set running state
|
|||
|
physicsDataCorState = true;
|
|||
|
|
|||
|
// Check list, remove null, cache velocity
|
|||
|
VelocityCache();
|
|||
|
|
|||
|
while (physicsDataCorState == true)
|
|||
|
{
|
|||
|
// Check list, remove null, cache velocity
|
|||
|
VelocityCache();
|
|||
|
|
|||
|
// TODO check for active state and velCache state every 5-10 seconds
|
|||
|
// TODO set velCache = false at demolition
|
|||
|
|
|||
|
yield return null;
|
|||
|
}
|
|||
|
|
|||
|
// Set state
|
|||
|
physicsDataCorState = false;
|
|||
|
}
|
|||
|
|
|||
|
// Check list, remove null, cache velocity
|
|||
|
void VelocityCache()
|
|||
|
{
|
|||
|
if (physicList.Count == 0)
|
|||
|
return;
|
|||
|
|
|||
|
for (int i = physicList.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
if (physicList[i].rb == null)
|
|||
|
{
|
|||
|
physicList[i].velCache = false;
|
|||
|
physicList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Cache velocity
|
|||
|
physicList[i].velocity = physicList[i].rb.velocity;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Demolition cor
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Demolition
|
|||
|
IEnumerator DemolitionManCor ()
|
|||
|
{
|
|||
|
// Stop if running
|
|||
|
if (dmlCorState == true)
|
|||
|
yield break;
|
|||
|
|
|||
|
// Set running state
|
|||
|
dmlCorState = true;
|
|||
|
|
|||
|
while (dmlCorState == true)
|
|||
|
{
|
|||
|
// Remove nulls
|
|||
|
RemoveNull (dmlList);
|
|||
|
|
|||
|
// Reset current frame total demolition time
|
|||
|
dmlThisFrame = 0;
|
|||
|
|
|||
|
if (dmlList.Count > 0)
|
|||
|
{
|
|||
|
for (int i = dmlList.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
// Demolition Time quota check
|
|||
|
if (timeQuota > 0 && dmlThisFrame > timeQuota)
|
|||
|
{
|
|||
|
// Continue at next frame
|
|||
|
if (quotaAction == QuotaType.Postpone)
|
|||
|
break;
|
|||
|
|
|||
|
// Skip object demolition completely
|
|||
|
if (quotaAction == QuotaType.Skip)
|
|||
|
{
|
|||
|
dmlList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Timestamp
|
|||
|
float t1 = Time.realtimeSinceStartup;
|
|||
|
|
|||
|
// Init demolition
|
|||
|
if (dmlList[i].limitations.demolitionShould == true)
|
|||
|
dmlList[i].Demolish();
|
|||
|
|
|||
|
// Check for slicing planes and init slicing
|
|||
|
else if (dmlList[i].limitations.bld == true && dmlList[i].limitations.slicePlanes != null && dmlList[i].limitations.slicePlanes.Count > 1)
|
|||
|
dmlList[i].Slice();
|
|||
|
|
|||
|
// Remove
|
|||
|
dmlList.RemoveAt (i);
|
|||
|
|
|||
|
// Sum total demolition time
|
|||
|
dmlThisFrame += Time.realtimeSinceStartup - t1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Wait for next frame
|
|||
|
yield return null;
|
|||
|
}
|
|||
|
|
|||
|
// Set state
|
|||
|
dmlCorState = false;
|
|||
|
}
|
|||
|
|
|||
|
// Add Rigid object to demolition list
|
|||
|
public void AddToDemolitionCor(RayfireRigid rigid)
|
|||
|
{
|
|||
|
// Already in list
|
|||
|
if (dmlList.Contains (rigid) == true)
|
|||
|
return;
|
|||
|
|
|||
|
// Max depth reached
|
|||
|
if (rigid.limitations.depth > 0 && rigid.limitations.currentDepth >= rigid.limitations.depth)
|
|||
|
rigid.dmlTp = DemolitionType.None;
|
|||
|
|
|||
|
// None demolition type
|
|||
|
if (rigid.dmlTp == DemolitionType.None)
|
|||
|
return;
|
|||
|
|
|||
|
// Add at 0 index
|
|||
|
dmlList.Insert (0, rigid);
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Rigid Offset Activation coroutine
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Velocity Activation
|
|||
|
IEnumerator OffsetActivationCor ()
|
|||
|
{
|
|||
|
// Stop if running
|
|||
|
if (offActCorState == true)
|
|||
|
yield break;
|
|||
|
|
|||
|
// Set running state
|
|||
|
offActCorState = true;
|
|||
|
|
|||
|
RayfireRigid rigid;
|
|||
|
while (offActCorState == true)
|
|||
|
{
|
|||
|
if (offActList.Count > 0)
|
|||
|
{
|
|||
|
int count = offActList.Count;
|
|||
|
for (int i = count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
// Set rigid to avoid calling list
|
|||
|
rigid = offActList[i];
|
|||
|
|
|||
|
// Null
|
|||
|
if (rigid == null)
|
|||
|
{
|
|||
|
offActList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Not inactive anymore
|
|||
|
if (rigid.activation.activated == true)
|
|||
|
{
|
|||
|
rigid.activation.offsetCorState = false;
|
|||
|
offActList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Activate
|
|||
|
if (rigid.activation.loc == true)
|
|||
|
{
|
|||
|
if (Vector3.Distance (rigid.tsf.localPosition, rigid.physics.localPosition) > rigid.activation.off)
|
|||
|
rigid.Activate();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Vector3.Distance (rigid.tsf.position, rigid.physics.initPosition) > rigid.activation.off)
|
|||
|
rigid.Activate();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Wait for next frame
|
|||
|
yield return null;
|
|||
|
}
|
|||
|
|
|||
|
// Set state
|
|||
|
offActCorState = false;
|
|||
|
}
|
|||
|
|
|||
|
// Add Rigid object to inactive
|
|||
|
public void AddToOffsetActivationCor(RayfireRigid rigid)
|
|||
|
{
|
|||
|
// Already in list
|
|||
|
if (rigid.activation.offsetCorState == true)
|
|||
|
return;
|
|||
|
|
|||
|
// Add at 0 index
|
|||
|
rigid.activation.offsetCorState = true;
|
|||
|
offActList.Insert (0, rigid);
|
|||
|
}
|
|||
|
|
|||
|
public void RemoveOffsetActivationCor(RayfireRigid rigid)
|
|||
|
{
|
|||
|
if (offActList.Contains (rigid) == true)
|
|||
|
{
|
|||
|
offActList.RemoveAt (offActList.IndexOf (rigid));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Rigid Velocity Activation coroutine
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Velocity Activation
|
|||
|
IEnumerator VelocityActivationCor ()
|
|||
|
{
|
|||
|
// Stop if running
|
|||
|
if (velActCorState == true)
|
|||
|
yield break;
|
|||
|
|
|||
|
// Set running state
|
|||
|
velActCorState = true;
|
|||
|
|
|||
|
RayfireRigid rigid;
|
|||
|
while (velActCorState == true)
|
|||
|
{
|
|||
|
if (velActList.Count > 0)
|
|||
|
{
|
|||
|
int count = velActList.Count;
|
|||
|
for (int i = count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
// Set rigid to avoid calling list
|
|||
|
rigid = velActList[i];
|
|||
|
|
|||
|
// Null
|
|||
|
if (rigid == null)
|
|||
|
{
|
|||
|
velActList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Not inactive anymore
|
|||
|
if (rigid.activation.activated == true)
|
|||
|
{
|
|||
|
rigid.activation.velocityCorState = false;
|
|||
|
velActList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Activate
|
|||
|
if (rigid.physics.velocity.magnitude > rigid.activation.vel)
|
|||
|
rigid.Activate();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Wait for next frame
|
|||
|
yield return null;
|
|||
|
}
|
|||
|
|
|||
|
// Set state
|
|||
|
velActCorState = false;
|
|||
|
}
|
|||
|
|
|||
|
// Add Rigid object to inactive
|
|||
|
public void AddToVelocityActivationCor(RayfireRigid rigid)
|
|||
|
{
|
|||
|
// Already in list
|
|||
|
if (rigid.activation.velocityCorState == true)
|
|||
|
return;
|
|||
|
|
|||
|
// Add at 0 index
|
|||
|
rigid.activation.velocityCorState = true;
|
|||
|
velActList.Insert (0, rigid);
|
|||
|
}
|
|||
|
|
|||
|
public void RemoveVelocityActivationCor(RayfireRigid rigid)
|
|||
|
{
|
|||
|
if (velActList.Contains (rigid) == true)
|
|||
|
{
|
|||
|
velActList.RemoveAt (velActList.IndexOf (rigid));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Fade offset cor
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Check offset for fade
|
|||
|
IEnumerator FadeOffsetCor ()
|
|||
|
{
|
|||
|
// Stop if running
|
|||
|
if (fadeOffCorState == true)
|
|||
|
yield break;
|
|||
|
|
|||
|
// Repeat check time
|
|||
|
WaitForSeconds delay = new WaitForSeconds (fadeOffsetRate);
|
|||
|
|
|||
|
// Set running state
|
|||
|
fadeOffCorState = true;
|
|||
|
|
|||
|
while (fadeOffCorState == true)
|
|||
|
{
|
|||
|
// Remove nulls
|
|||
|
RemoveNull (fadeOffList);
|
|||
|
|
|||
|
// Check distance for all rigids in list
|
|||
|
for (int i = fadeOffList.Count - 1; i >= 0; i--)
|
|||
|
{
|
|||
|
// Already fading. Remove and check other.
|
|||
|
if (fadeOffList[i].fading.state > 0)
|
|||
|
{
|
|||
|
fadeOffList.RemoveAt (i);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// Check
|
|||
|
if (Vector3.Distance (fadeOffList[i].tsf.position, fadeOffList[i].physics.initPosition) > fadeOffList[i].fading.byOffset)
|
|||
|
{
|
|||
|
fadeOffList[i].Fade();
|
|||
|
fadeOffList.RemoveAt (i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
yield return delay;
|
|||
|
}
|
|||
|
|
|||
|
// Set state
|
|||
|
fadeOffCorState = false;
|
|||
|
}
|
|||
|
|
|||
|
// Add Rigid object to offset fading
|
|||
|
public void AddToOffsetFadeCor(RayfireRigid rigid)
|
|||
|
{
|
|||
|
// TODO check if already in list
|
|||
|
|
|||
|
// Already fading
|
|||
|
if (rigid.fading.state > 0)
|
|||
|
return;
|
|||
|
|
|||
|
// Add at 0 index
|
|||
|
fadeOffList.Insert (0, rigid);
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Other
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Create RayFire manager if not created
|
|||
|
public static void RayFireManInit()
|
|||
|
{
|
|||
|
if (inst == null)
|
|||
|
{
|
|||
|
GameObject rfMan = new GameObject ("RayFireMan");
|
|||
|
inst = rfMan.AddComponent<RayfireMan>();
|
|||
|
}
|
|||
|
|
|||
|
if (Application.isPlaying == false)
|
|||
|
{
|
|||
|
inst.SetInstance();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Max fragments amount check
|
|||
|
public static bool MaxAmountCheck
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (inst.advancedDemolitionProperties.currentAmount < inst.advancedDemolitionProperties.maximumAmount)
|
|||
|
return true;
|
|||
|
|
|||
|
inst.advancedDemolitionProperties.AmountWarning();
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Remove nulls
|
|||
|
static void RemoveNull(List<RayfireRigid> list)
|
|||
|
{
|
|||
|
if (list.Count > 0)
|
|||
|
for (int i = list.Count - 1; i >= 0; i--)
|
|||
|
if (list[i] == null)
|
|||
|
list.RemoveAt (i);
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Pooling
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Enable objects pooling for fragments
|
|||
|
void SetPooling()
|
|||
|
{
|
|||
|
// Setup emitter pooling
|
|||
|
particles.SetupEmitters(transform);
|
|||
|
|
|||
|
// Pooling. Mot in editor
|
|||
|
if (Application.isPlaying == true && particles.Enable == true && particles.poolProgress == false)
|
|||
|
StartCoroutine (particles.StartPoolingCor ());
|
|||
|
|
|||
|
// Create pool root
|
|||
|
fragments.CreatePoolRoot (transform);
|
|||
|
|
|||
|
// Create pool instance
|
|||
|
fragments.CreateInstance (transform);
|
|||
|
|
|||
|
// Pooling. Mot in editor
|
|||
|
if (Application.isPlaying == true && fragments.enable == true && fragments.inProgress == false)
|
|||
|
StartCoroutine (fragments.StartPoolingCor (transForm));
|
|||
|
}
|
|||
|
|
|||
|
// Emitter Pooling
|
|||
|
public void StartEmitterPooling()
|
|||
|
{
|
|||
|
// Already running
|
|||
|
if (particles.emitProgress == true)
|
|||
|
return;
|
|||
|
|
|||
|
// Only at play mode
|
|||
|
if (Application.isPlaying == false)
|
|||
|
return;
|
|||
|
|
|||
|
// Global particle pooling disabled
|
|||
|
if (particles.Enable == false)
|
|||
|
return;
|
|||
|
|
|||
|
// All emitters are full
|
|||
|
if (particles.NeedState() == false)
|
|||
|
return;
|
|||
|
|
|||
|
// Start pooling
|
|||
|
StartCoroutine (particles.StartEmitterPoolingCor ());
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Storage
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Create storage root
|
|||
|
void SetStorage()
|
|||
|
{
|
|||
|
// Create
|
|||
|
if (storage == null)
|
|||
|
storage = new RFStorage();
|
|||
|
|
|||
|
// Create storage if has no
|
|||
|
storage.CreateStorageRoot (transform);
|
|||
|
|
|||
|
// Start empty root removing coroutine if not running
|
|||
|
if (Application.isPlaying == true && storage.inProgress == false)
|
|||
|
StartCoroutine (storage.StorageCor ());
|
|||
|
}
|
|||
|
|
|||
|
// Destroy all storage objects
|
|||
|
public void DestroyStorage()
|
|||
|
{
|
|||
|
storage.DestroyAll();
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Parent
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Set root to manager or to the same parent
|
|||
|
public static void SetParentByManager (Transform tm, Transform original, bool noRegister = false)
|
|||
|
{
|
|||
|
if (inst == null)
|
|||
|
return;
|
|||
|
|
|||
|
// Storage
|
|||
|
if (inst.advancedDemolitionProperties.parent == FragmentParentType.Manager)
|
|||
|
tm.parent = inst.storage.storageRoot;
|
|||
|
|
|||
|
// Global parent
|
|||
|
else if (inst.advancedDemolitionProperties.parent == FragmentParentType.GlobalParent
|
|||
|
&& inst.advancedDemolitionProperties.globalParent != null)
|
|||
|
tm.parent = inst.advancedDemolitionProperties.globalParent;
|
|||
|
|
|||
|
// Storage if no local parent
|
|||
|
else if (original == null || original.parent == null)
|
|||
|
tm.parent = inst.storage.storageRoot;
|
|||
|
|
|||
|
// Local parent
|
|||
|
else
|
|||
|
tm.parent = original.parent;
|
|||
|
|
|||
|
// Register in storage
|
|||
|
if (noRegister == false)
|
|||
|
inst.storage.RegisterRoot (tm);
|
|||
|
}
|
|||
|
|
|||
|
// Set root to manager or to the same parent
|
|||
|
public static void SetParentByManager (Transform tm)
|
|||
|
{
|
|||
|
if (inst == null)
|
|||
|
return;
|
|||
|
|
|||
|
if (inst.advancedDemolitionProperties.parent == FragmentParentType.Manager)
|
|||
|
tm.parent = inst.storage.storageRoot;
|
|||
|
|
|||
|
// Global parent
|
|||
|
else if (inst.advancedDemolitionProperties.parent == FragmentParentType.GlobalParent
|
|||
|
&& inst.advancedDemolitionProperties.globalParent != null)
|
|||
|
tm.parent = inst.advancedDemolitionProperties.globalParent;
|
|||
|
|
|||
|
// Register in storage
|
|||
|
inst.storage.RegisterRoot (tm);
|
|||
|
}
|
|||
|
|
|||
|
// Get parent for connected cluster detached shards
|
|||
|
public static Transform GetParentByManager(RayfireRigid scr)
|
|||
|
{
|
|||
|
// Manager parent
|
|||
|
if (inst != null && inst.advancedDemolitionProperties.parent == FragmentParentType.Manager)
|
|||
|
return inst.storage.storageRoot;
|
|||
|
|
|||
|
// Parent of main cluster
|
|||
|
if (scr.clsDemol.cluster.mainCluster != null && scr.clsDemol.cluster.mainCluster.tm != null)
|
|||
|
return scr.clsDemol.cluster.mainCluster.tm.parent;
|
|||
|
|
|||
|
// Parent of Rigid
|
|||
|
return scr.transform.parent;
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Destroy/Deactivate Fragment/Shard
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Check if fragment is the last child in root and delete root as well
|
|||
|
public static void DestroyFragment (RayfireRigid scr, Transform tm, float time = 0f)
|
|||
|
{
|
|||
|
// Decrement total amount.
|
|||
|
if (Application.isPlaying == true)
|
|||
|
inst.advancedDemolitionProperties.currentAmount--;
|
|||
|
|
|||
|
// Deactivate
|
|||
|
scr.gameObject.SetActive (false);
|
|||
|
|
|||
|
// Destroy
|
|||
|
if (scr.reset.action == RFReset.PostDemolitionType.DestroyWithDelay)
|
|||
|
DestroyOp (scr, tm, time);
|
|||
|
}
|
|||
|
|
|||
|
// Destroy rigidroot shard
|
|||
|
public static void DestroyShard (RayfireRigidRoot scr, RFShard shard)
|
|||
|
{
|
|||
|
// Deactivate
|
|||
|
shard.tm.gameObject.SetActive (false);
|
|||
|
|
|||
|
// Destroy
|
|||
|
if (scr.reset.action == RFReset.PostDemolitionType.DestroyWithDelay)
|
|||
|
DestroyGo (shard.tm.gameObject);
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Destroy
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Check if fragment is the last child in root and delete root as well
|
|||
|
public static void DestroyGo (GameObject go)
|
|||
|
{
|
|||
|
Destroy (go);
|
|||
|
}
|
|||
|
|
|||
|
// Check if fragment is the last child in root and delete root as well
|
|||
|
static void DestroyOp (RayfireRigid scr, Transform tm, float time = 0f)
|
|||
|
{
|
|||
|
// Set delay
|
|||
|
if (time == 0)
|
|||
|
time = scr.reset.destroyDelay;
|
|||
|
|
|||
|
// Object is going to be destroyed. Timer is on
|
|||
|
scr.reset.toBeDestroyed = true;
|
|||
|
|
|||
|
// Destroy object
|
|||
|
inst.fragments.DestroyOrReset (scr, time);
|
|||
|
|
|||
|
// Destroy root
|
|||
|
if (tm != null && tm.childCount == 0)
|
|||
|
{
|
|||
|
// TODO collect root in special roots list, check every 10 seconds and destroy if they are empty
|
|||
|
Destroy (tm.gameObject, time);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
/// Debug
|
|||
|
/// /////////////////////////////////////////////////////////
|
|||
|
|
|||
|
// Debug message
|
|||
|
public static void Log (string str, UnityEngine.Object go = null)
|
|||
|
{
|
|||
|
// Disabled
|
|||
|
if (debugStateStatic == false)
|
|||
|
return;
|
|||
|
|
|||
|
// Only in Editor
|
|||
|
if (debugEditorStatic == true && Application.isEditor == false)
|
|||
|
return;
|
|||
|
|
|||
|
// Only in Debug build
|
|||
|
if (debugBuildStatic == true && Debug.isDebugBuild == false)
|
|||
|
return;
|
|||
|
|
|||
|
Debug.Log (str, go);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|