/// --------------------------------------------- /// 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); } } }