/// ---------------------------------------------
/// Ultimate Character Controller
/// Copyright (c) Opsive. All Rights Reserved.
/// https://www.opsive.com
/// ---------------------------------------------
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
{
using Opsive.Shared.Game;
using Opsive.UltimateCharacterController.Items.Actions;
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
using Opsive.UltimateCharacterController.Networking.Game;
#endif
using Opsive.UltimateCharacterController.Objects;
using UnityEngine;
///
/// The ParticleProjectile extends TrajectoryObject and notifies the MagicItem when the object has collided with another object.
/// TrajectoryObject.CollisionMode should be set to Ignore for the projectile to pass through the object.
///
public class MagicProjectile : TrajectoryObject
{
[Tooltip("Should the projectile be destroyed when there's a collision?")]
[SerializeField] protected bool m_DestroyOnCollision;
[Tooltip("Should the projectile be destroyed after the particle has stopped emitting?")]
[SerializeField] protected bool m_WaitForParticleStop;
public bool DestroyOnCollision { get { return m_DestroyOnCollision; } set { m_DestroyOnCollision = value; } }
public bool WaitForParticleStop { get { return m_WaitForParticleStop; } set { m_WaitForParticleStop = value; } }
protected MagicItem m_MagicItem;
protected uint m_CastID;
///
/// Initializes the object with the specified velocity and torque.
///
/// The starting velocity.
/// The starting torque.
/// The object that instantiated the trajectory object.
/// The MagicItem that created the projectile.
/// The ID of the cast.
public void Initialize(Vector3 velocity, Vector3 torque, GameObject originator, MagicItem magicItem, uint castID)
{
m_MagicItem = magicItem;
m_CastID = castID;
Initialize(velocity, torque, originator);
if (m_Collider != null) {
m_Collider.enabled = false;
}
}
///
/// The object has collided with another object.
///
/// The RaycastHit of the object. Can be null.
protected override void OnCollision(RaycastHit? hit)
{
base.OnCollision(hit);
if (!hit.HasValue) {
return;
}
m_MagicItem.PerformImpact(m_CastID, m_GameObject, hit.Value.transform.gameObject, hit.Value);
// Destroys the projectile when it has collided with an object.
if (m_DestroyOnCollision) {
// The projectile can wait for any particles to stop emitting.
var immediateDestroy = !m_WaitForParticleStop;
if (!immediateDestroy) {
var particleSystem = m_GameObject.GetCachedComponent();
if (particleSystem != null) {
particleSystem.Stop(true, ParticleSystemStopBehavior.StopEmitting);
Scheduler.Schedule(particleSystem.main.duration, ReturnToObjectPool);
immediateDestroy = false;
}
}
if (immediateDestroy) {
ReturnToObjectPool();
} else {
// The projectile is waiting on the particles to be destroyed. Stop moving.
Stop();
}
}
}
///
/// Returns the projectile back to the object pool.
///
private void ReturnToObjectPool()
{
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
if (NetworkObjectPool.IsNetworkActive()) {
// The object may have already been destroyed over the network.
if (!m_GameObject.activeSelf) {
return;
}
NetworkObjectPool.Destroy(m_GameObject);
return;
}
#endif
ObjectPool.Destroy(m_GameObject);
}
}
}