/// --------------------------------------------- /// Ultimate Character Controller /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.UltimateCharacterController.Objects.ItemAssist { using Opsive.Shared.Events; using Opsive.Shared.Game; using Opsive.UltimateCharacterController.Character; using Opsive.UltimateCharacterController.Game; using Opsive.UltimateCharacterController.Items; using Opsive.UltimateCharacterController.Items.Actions.PerspectiveProperties; using UnityEngine; /// /// The Smoke component is attached to a GameObject with the a ParticleSystem attached representing smoke. /// public class Smoke : MonoBehaviour { private GameObject m_GameObject; private Transform m_Transform; private Item m_Item; private int m_ItemActionID; private ParticleSystem[] m_Particles; private ParticleSystemSimulationSpace[] m_SimulationSpace; private GameObject m_Character; private int m_StartLayer; /// /// Initialize the default values. /// private void Awake() { m_GameObject = gameObject; m_Transform = transform; m_Particles = GetComponentsInChildren(); m_SimulationSpace = new ParticleSystemSimulationSpace[m_Particles.Length]; m_StartLayer = m_GameObject.layer; } /// /// A weapon has been fired and the smoke needs to show. /// /// The item that the muzzle flash is attached to. /// The ID which corresponds to the ItemAction that spawned the smoke. /// The character that the smoke is attached to. public void Show(Item item, int itemActionID, UltimateCharacterLocomotion characterLocomotion) { m_Character = characterLocomotion.gameObject; EventHandler.RegisterEvent(m_Character, "OnCharacterChangePerspectives", OnChangePerspectives); m_Item = item; m_ItemActionID = itemActionID; m_GameObject.layer = characterLocomotion.FirstPersonPerspective ? LayerManager.Overlay : m_StartLayer; // Disable the object after the particles are done playing. float maxLifeTime = 0; for (int i = 0; i < m_Particles.Length; ++i) { m_Particles[i].Play(); var lifeTime = 0f; if ((lifeTime = m_Particles[i].main.startLifetime.Evaluate(0)) > maxLifeTime) { maxLifeTime = lifeTime; } } Scheduler.Schedule(maxLifeTime, DestroySelf); } /// /// Place itself back in the ObjectPool. /// public void DestroySelf() { ObjectPool.Destroy(m_GameObject); } /// /// The character perspective between first and third person has changed. /// /// Is the character in a first person perspective? private void OnChangePerspectives(bool firstPersonPerspective) { // All of the particles should be set to local space so they'll change correctly when switching perspective. for (int i = 0; i < m_Particles.Length; ++i) { m_SimulationSpace[i] = m_Particles[i].main.simulationSpace; var mainParticle = m_Particles[i].main; mainParticle.simulationSpace = ParticleSystemSimulationSpace.Local; } // When switching locations the local position and rotation should remain the same. var localPosition = m_Transform.localPosition; var localRotation = m_Transform.rotation; var itemAction = m_Item.ItemActions[m_ItemActionID]; var perspectiveProperties = (firstPersonPerspective ? itemAction.FirstPersonPerspectiveProperties : itemAction.ThirdPersonPerspectiveProperties); var smokeLocation = (perspectiveProperties as IShootableWeaponPerspectiveProperties).SmokeLocation; m_Transform.parent = smokeLocation; m_Transform.localPosition = localPosition; m_Transform.rotation = localRotation; // Switch the particle simulation space back to the previous value. for (int i = 0; i < m_Particles.Length; ++i) { var mainParticle = m_Particles[i].main; mainParticle.simulationSpace = m_SimulationSpace[i]; } m_GameObject.layer = firstPersonPerspective ? LayerManager.Overlay : m_StartLayer; } /// /// The object has been disabled. /// private void OnDisable() { if (m_Character != null) { EventHandler.UnregisterEvent(m_Character, "OnCharacterChangePerspectives", OnChangePerspectives); } m_Character = null; } } }