예제 #1
0
        /// <summary>
        /// Does the actual fire.
        /// </summary>
        public void Fire()
        {
            m_LastFireTime = Time.time;

            // Spawn a projectile which will move in the direction that the turret is facing
            var projectile = ObjectPoolBase.Instantiate(m_Projectile, m_FireLocation.position, m_Transform.rotation).GetCachedComponent <Projectile>();

            projectile.Initialize(m_FireLocation.forward * m_VelocityMagnitude, Vector3.zero, null, m_DamageAmount, m_ImpactForce, m_ImpactForceFrames,
                                  m_ImpactLayers, string.Empty, 0, m_SurfaceImpact, m_GameObject);
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null)
            {
                NetworkObjectPool.NetworkSpawn(m_Projectile, projectile.gameObject, true);
            }
#endif

            // Spawn a muzzle flash.
            if (m_MuzzleFlash)
            {
                var muzzleFlash = ObjectPoolBase.Instantiate(m_MuzzleFlash, m_MuzzleFlashLocation.position, m_MuzzleFlashLocation.rotation, m_Transform).GetCachedComponent <MuzzleFlash>();
                muzzleFlash.Show(null, 0, true, null);
            }

            // Play a firing sound.
            if (m_FireAudioClip != null)
            {
                m_AudioSource.clip = m_FireAudioClip;
                m_AudioSource.Play();
            }
        }
예제 #2
0
 void Start()
 {
     m_PrefabPool = GetComponent <NetworkObjectPool>();
     MonobitEngine.MonobitNetwork.ObjectPool = m_PrefabPool;
     NetworkManager.Instance.AddNetworkEventObserver(this);
     PlayerManager.Instance.AddObserver(this);
 }
예제 #3
0
 public void RPCMakeSurePoolExists(string key, string referenceName, int minSize, int maxSize, bool dontDestroyOnLoad)
 {
     if (!m_OnlinePools.ContainsKey(key))
     {
         NetworkObjectPool pool = new NetworkObjectPool(key, minSize, maxSize, referenceName, dontDestroyOnLoad, false);
         m_OnlinePools.Add(key, pool);
     }
 }
예제 #4
0
 public void CreateNetworkPoolWithName(string name, string referenceName, int minSize, int maxSize, bool dontDestroyOnLoad)
 {
     if (!m_OnlinePools.ContainsKey(name))
     {
         NetworkObjectPool pool = new NetworkObjectPool(name, minSize, maxSize, referenceName, dontDestroyOnLoad);
         m_OnlinePools.Add(name, pool);
     }
 }
예제 #5
0
 public void CreateNetworkPoolWithName(string name, string referenceName, bool dontDestroyOnLoad)
 {
     //create the object pool
     if (!m_OnlinePools.ContainsKey(name))
     {
         NetworkObjectPool pool = new NetworkObjectPool(name, DefaultMinimumSize, DefaultMaximumSize, referenceName, dontDestroyOnLoad);
         m_OnlinePools.Add(name, pool);
     }
 }
예제 #6
0
        /// <summary>
        /// A player has entered the room. Ensure the joining player is in sync with the current game state.
        /// </summary>
        /// <param name="player">The Photon Player that entered the room.</param>
        /// <param name="character">The character that the player controls.</param>
        private void OnPlayerEnteredRoom(Player player, GameObject character)
        {
            if (!m_SynchronizeActiveState || m_PhotonView.ViewID == 0 || NetworkObjectPool.SpawnedWithPool(m_GameObject))
            {
                return;
            }

            m_PhotonView.RPC("SetActiveRPC", player, m_GameObject.activeSelf);
        }
예제 #7
0
        /// <summary>
        /// Performs the cast.
        /// </summary>
        /// <param name="origin">The location that the cast should spawn from.</param>
        /// <param name="direction">The direction of the cast.</param>
        /// <param name="targetPosition">The target position of the cast.</param>
        public override void Cast(Transform origin, Vector3 direction, Vector3 targetPosition)
        {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            // The server will spawn the projectile.
            if (m_MagicItem.NetworkInfo != null)
            {
                if (m_MagicItem.NetworkInfo.IsLocalPlayer())
                {
                    m_MagicItem.NetworkCharacter.MagicCast(m_MagicItem, m_Index, m_CastID, direction, targetPosition);
                }
                if (!m_MagicItem.NetworkInfo.IsServer())
                {
                    return;
                }
            }
#endif

            if (m_ProjectilePrefab == null)
            {
                Debug.LogError("Error: A Projectile Prefab must be specified", m_MagicItem);
                return;
            }

            var position = origin.TransformPoint(m_PositionOffset);
            if (targetPosition != position)
            {
                direction = (targetPosition - position).normalized;
            }
            var obj = ObjectPool.Instantiate(m_ProjectilePrefab, position,
                                             Quaternion.LookRotation(direction, m_CharacterLocomotion.Up) * Quaternion.Euler(m_RotationOffset), m_ParentToOrigin ? origin : null);
            var projectile = obj.GetComponent <MagicProjectile>();
            if (projectile != null)
            {
                projectile.Initialize(direction * m_Speed, Vector3.zero, m_GameObject, m_MagicItem, m_CastID);
            }
            else
            {
                Debug.LogWarning($"Warning: The projectile {m_ProjectilePrefab.name} does not have the MagicProjectile component attached.");
            }
            var magicParticle = obj.GetComponent <MagicParticle>();
            if (magicParticle != null)
            {
                magicParticle.Initialize(m_MagicItem, m_CastID);
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_MagicItem.NetworkInfo != null)
            {
                NetworkObjectPool.NetworkSpawn(m_ProjectilePrefab, obj, true);
            }
#endif
        }
    public void Config(ShipControl owner, int damage, bool bounce, float lifetime, NetworkObjectPool poolToReturn)
    {
        m_Owner        = owner;
        m_Damage       = damage;
        m_Bounce       = bounce;
        m_PoolToReturn = poolToReturn;

        if (IsServer)
        {
            // This is bad code don't use invoke.
            Invoke(nameof(DestroyBullet), lifetime);
        }
    }
예제 #9
0
        /// <summary>
        /// Destroys the object.
        /// </summary>
        /// <param name="hitPosition">The position of the destruction.</param>
        /// <param name="hitNormal">The normal direction of the destruction.</param>
        public void Destruct(Vector3 hitPosition, Vector3 hitNormal)
        {
            for (int i = 0; i < m_SpawnedObjectsOnDestruction.Length; ++i)
            {
                if (m_SpawnedObjectsOnDestruction[i] == null)
                {
                    continue;
                }

                var spawnedObject = m_SpawnedObjectsOnDestruction[i].Instantiate(hitPosition, hitNormal, m_NormalizedGravity);
                if (spawnedObject == null)
                {
                    continue;
                }
                var explosion = spawnedObject.GetCachedComponent <Explosion>();
                if (explosion != null)
                {
                    explosion.Explode(m_DamageAmount, m_ImpactForce, m_ImpactForceFrames, m_Originator);
                }
            }

            // The component and collider no longer need to be enabled after the object has been destroyed.
            if (m_Collider != null)
            {
                m_Collider.enabled = false;
            }
            if (m_ParticleSystem != null)
            {
                m_ParticleSystem.Stop();
            }
            m_Destroyed    = true;
            m_DestroyEvent = null;
            enabled        = false;

            // The destructible should be destroyed.
#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
            ObjectPoolBase.Destroy(m_GameObject);
        }
예제 #10
0
    private void SetUpPool()
    {
        if (ObjectPoolManager.Instance != null)
        {
            ObjectPoolManager.Instance.CreateNetworkPoolWithName(m_SfxPool, "Effects/SfxSource", initialPoolSize, maxPoolSize, true);
            m_SfxSources = ObjectPoolManager.Instance.GetNetworkPoolFromManager(m_SfxPool);

            //add our bgm sound source
            m_BGMSource             = gameObject.AddComponent <AudioSource>();
            m_BGMSource.loop        = true;
            m_BGMSource.playOnAwake = false;
            m_BGMSource.volume      = GetBGMVolume();
            GameManager.Instance.DontDestroyNetworkObject(gameObject);
        }
    }
예제 #11
0
        /// <summary>
        /// The object has been enabled.
        /// </summary>
        private void OnEnable()
        {
            m_InitialSync = true;

            // If the object is pooled then the network object pool will manage the active state.
            if (m_SynchronizeActiveState && NetworkObjectPool.SpawnedWithPool(m_GameObject))
            {
                m_SynchronizeActiveState = false;
            }

            if (m_SynchronizeActiveState && m_PhotonView.ViewID != 0 && m_PhotonView.IsMine)
            {
                m_PhotonView.RPC("SetActiveRPC", RpcTarget.Others, true);
            }
        }
예제 #12
0
        /// <summary>
        /// Returns the projectile back to the object pool.
        /// </summary>
        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);
        }
예제 #13
0
        /// <summary>
        /// Performs the cast.
        /// </summary>
        /// <param name="origin">The location that the cast should spawn from.</param>
        /// <param name="direction">The direction of the cast.</param>
        /// <param name="targetPosition">The target position of the cast.</param>
        public override void Cast(Transform origin, Vector3 direction, Vector3 targetPosition)
        {
            if (m_Object == null)
            {
                Debug.LogError("Error: An Object must be specified.", m_MagicItem);
                return;
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            // The local player will spawn the object if the object is a networked magic object.
            if (m_MagicItem.NetworkInfo != null && !m_MagicItem.NetworkInfo.IsLocalPlayer())
            {
                if (m_Object.GetComponent <INetworkMagicObject>() != null)
                {
                    return;
                }
            }
#endif

            var position = MathUtility.TransformPoint(origin.position, m_Transform.rotation, m_PositionOffset);
            if (targetPosition != position)
            {
                direction = (targetPosition - position).normalized;
            }
            m_SpawnedObject = ObjectPool.Instantiate(m_Object, position,
                                                     Quaternion.LookRotation(direction, m_CharacterLocomotion.Up) * Quaternion.Euler(m_RotationOffset), m_ParentToOrigin ? origin : null);

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_MagicItem.NetworkInfo != null && m_MagicItem.NetworkInfo.IsLocalPlayer())
            {
                var networkMagicObject = m_SpawnedObject.GetComponent <INetworkMagicObject>();
                if (networkMagicObject != null)
                {
                    networkMagicObject.Instantiate(m_GameObject, m_MagicItem, m_Index, m_CastID);
                }

                NetworkObjectPool.NetworkSpawn(m_Object, m_SpawnedObject, false);
            }
#endif
        }
예제 #14
0
        /// <summary>
        /// The object has been picked up.
        /// </summary>
        /// <param name="pickedUpBy">A reference to the object that picked up the object.</param>
        protected virtual void ObjectPickedUp(GameObject pickedUpBy)
        {
            // The object may not have been instantiated within the scene.
            if (m_GameObject == null)
            {
                return;
            }

            m_IsDepleted = true;

            // Send an event notifying of the pickup.
            EventHandler.ExecuteEvent(pickedUpBy, "OnObjectPickedUp", this);

            // Optionally play a pickup sound if the object picking up the item is attached to a camera.
            // A null GameObject indicates that the clip will play from the AudioManager.
            var camera = Utility.UnityEngineUtility.FindCamera(pickedUpBy);

            if (camera != null)
            {
                m_PickupAudioClipSet.PlayAudioClip(null);
            }

            if (ObjectPool.InstantiatedWithPool(m_GameObject))
            {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
                if (NetworkObjectPool.IsNetworkActive())
                {
                    NetworkObjectPool.Destroy(m_GameObject);
                    return;
                }
#endif
                ObjectPool.Destroy(m_GameObject);
            }
            else
            {
                // Deactivate the pickup for now. It can appear again if a Respawner component is attached to the GameObject.
                m_GameObject.SetActive(false);
            }
        }
예제 #15
0
        /// <summary>
        /// Returns the GameObject back to the ObjectPool.
        /// </summary>
        private void PoolGameObject()
        {
            // The particle may be looping so it shouldn't be stopped yet.
            if (m_ParticleSystem.IsAlive(true))
            {
                m_PoolEvent = Scheduler.Schedule(m_ParticleSystem.main.duration, PoolGameObject);
                return;
            }
#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);
        }
예제 #16
0
        /// <summary>
        /// Stops the cast.
        /// </summary>
        public override void Stop()
        {
            if (m_SpawnedObject != null)
            {
#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_SpawnedObject);
                    return;
                }
#endif
                ObjectPool.Destroy(m_SpawnedObject);
                m_SpawnedObject = null;
            }

            base.Stop();
        }
예제 #17
0
        /// <summary>
        /// Performs the cast.
        /// </summary>
        /// <param name="origin">The location that the cast should spawn from.</param>
        /// <param name="direction">The direction of the cast.</param>
        /// <param name="targetPosition">The target position of the cast.</param>
        public override void Cast(Transform origin, Vector3 direction, Vector3 targetPosition)
        {
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_MagicItem.NetworkInfo != null && m_MagicItem.NetworkInfo.IsLocalPlayer())
            {
                m_MagicItem.NetworkCharacter.MagicCast(m_MagicItem, m_Index, m_CastID, direction, targetPosition);
            }
#endif

            var position = MathUtility.TransformPoint(origin.position, m_Transform.rotation, m_PositionOffset);
            if (targetPosition != position)
            {
                direction = (targetPosition - position).normalized;
            }
            if (m_ProjectDirectionOnPlane)
            {
                direction = Vector3.ProjectOnPlane(direction, m_CharacterLocomotion.Up);
            }
            // The direction can't be 0.
            if (direction.sqrMagnitude == 0)
            {
                direction = m_CharacterLocomotion.transform.forward;
            }
            var rotation = Quaternion.LookRotation(direction, m_CharacterLocomotion.Up) * Quaternion.Euler(m_RotationOffset);

            // If the cast is currently active then the particle should be reused.
            if (m_Active)
            {
                if (m_SetRendererLengthScale)
                {
                    SetRendererLength(origin.position, targetPosition);
                }
                if (!m_ParentToOrigin)
                {
                    m_ParticleTransform.position = position;
                }
                m_ParticleTransform.rotation = rotation;
                return;
            }

            if (m_ParticlePrefab == null)
            {
                Debug.LogError("Error: A Particle Prefab must be specified.", m_MagicItem);
                return;
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            // The local player will spawn the particle if the object is a networked magic object.
            if (m_MagicItem.NetworkInfo != null && !m_MagicItem.NetworkInfo.IsLocalPlayer())
            {
                if (m_ParticlePrefab.GetComponent <INetworkMagicObject>() != null)
                {
                    return;
                }
            }
#endif

            if (m_FadeEvent != null)
            {
                SchedulerBase.Cancel(m_FadeEvent);
                m_FadeEvent = null;
                SetRendererAlpha(0);
            }
            var obj = ObjectPoolBase.Instantiate(m_ParticlePrefab, position, rotation, m_ParentToOrigin ? origin : null);
            m_ParticleTransform = obj.transform;
            m_ParticleTransform.SetLayerRecursively(m_ParticleLayer);
            m_ParticleSystem = obj.GetCachedComponent <ParticleSystem>();

            if (m_ParticleSystem == null)
            {
                Debug.LogError($"Error: A Particle System must be specified on the particle {m_ParticlePrefab}.", m_MagicItem);
                return;
            }

            m_ParticleSystem.Clear(true);
            m_Renderers = null;
            if (m_SetRendererLengthScale)
            {
                SetRendererLength(origin.position, targetPosition);
            }
            StartMaterialFade(obj);

            // The MagicParticle can determine the impacts.
            var magicParticle = obj.GetComponent <MagicParticle>();
            if (magicParticle != null)
            {
                magicParticle.Initialize(m_MagicItem, m_CastID);
            }
            m_Active = true;

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_MagicItem.NetworkInfo != null && m_MagicItem.NetworkInfo.IsLocalPlayer())
            {
                var networkMagicObject = obj.GetComponent <INetworkMagicObject>();
                if (networkMagicObject != null)
                {
                    networkMagicObject.Instantiate(m_GameObject, m_MagicItem, m_Index, m_CastID);
                }

                NetworkObjectPool.NetworkSpawn(m_ParticlePrefab, obj, false);
            }
#endif
        }
예제 #18
0
        /// <summary>
        /// Throws the throwable object.
        /// </summary>
        public void ThrowItem()
        {
            if (m_Thrown)
            {
                return;
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            // The object has been thrown. If the ItemAction is on the server then that object should be spawned on the network.
            // Non-server actions should disable the mesh renderers so the object can take its place. The mesh renderers will be enabled again in a separate call.
            if (m_NetworkInfo != null)
            {
                EnableObjectMeshRenderers(false);
                if (!m_NetworkInfo.IsServer())
                {
                    ObjectPool.Destroy(m_InstantiatedThrownObject);
                    m_InstantiatedThrownObject = null;
                    return;
                }
            }
#endif

            m_InstantiatedThrownObject.transform.parent = null;
            // The collider was previously disabled. Enable it again when it is thrown.
            var collider = m_InstantiatedThrownObject.GetCachedComponent <Collider>();
            collider.enabled = true;

            // When the item is used the trajectory object should start moving on its own.
            // The throwable item may be on the other side of an object (especially in the case of separate arms for the first person perspective). Perform a linecast
            // to ensure the throwable item doesn't move through any objects.
            var collisionEnabled = m_CharacterLocomotion.CollisionLayerEnabled;
            m_CharacterLocomotion.EnableColliderCollisionLayer(false);
            if (!m_CharacterLocomotion.ActiveMovementType.UseIndependentLook(false) &&
                Physics.Linecast(m_CharacterLocomotion.LookSource.LookPosition(), m_InstantiatedTrajectoryObject.transform.position, out m_RaycastHit,
                                 m_ImpactLayers, QueryTriggerInteraction.Ignore))
            {
                m_InstantiatedTrajectoryObject.transform.position = m_RaycastHit.point;
            }
            m_CharacterLocomotion.EnableColliderCollisionLayer(collisionEnabled);

            var trajectoryTransform = m_ThrowableItemPerpectiveProperties.TrajectoryLocation != null ? m_ThrowableItemPerpectiveProperties.TrajectoryLocation : m_CharacterTransform;
            var lookDirection       = m_LookSource.LookDirection(trajectoryTransform.TransformPoint(m_TrajectoryOffset), false, m_ImpactLayers, true, true);
#if ULTIMATE_CHARACTER_CONTROLLER_VR
            if (m_VRThrowableItem != null && m_CharacterLocomotion.FirstPersonPerspective)
            {
                m_Velocity = m_VRThrowableItem.GetVelocity();
            }
#endif
            var velocity = MathUtility.TransformDirection(m_Velocity, Quaternion.LookRotation(lookDirection, m_CharacterLocomotion.Up));
            // Prevent the item from being thrown behind the character. This can happen if the character is looking straight up and there is a positive
            // y velocity. Gravity will cause the thrown object to go in the opposite direction.
            if (Vector3.Dot(velocity.normalized, m_CharacterTransform.forward) < 0 && m_CharacterTransform.InverseTransformDirection(velocity.normalized).y > 0)
            {
                velocity = m_CharacterTransform.up * velocity.magnitude;
            }
            m_InstantiatedTrajectoryObject.Initialize(m_CharacterLocomotion.Alive ? (velocity + (m_CharacterTransform.forward * m_CharacterLocomotion.LocalVelocity.z)) : Vector3.zero, Vector3.zero, m_Character, false);

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null)
            {
                NetworkObjectPool.NetworkSpawn(m_ThrownObject, m_InstantiatedThrownObject, true);
            }
#endif
            // Optionally change the layer after the object has been thrown. This allows the object to change from the first person Overlay layer
            // to the Default layer after it has cleared the character's hands.
            if (m_StartLayer != m_ThrownLayer)
            {
                Scheduler.ScheduleFixed(m_LayerChangeDelay, ChangeThrownLayer, m_InstantiatedThrownObject);
            }
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null && !m_NetworkInfo.IsLocalPlayer())
            {
                m_Thrown = true;
            }
#endif
        }
 void Awake()
 {
     m_Rigidbody2D = GetComponent <Rigidbody2D>();
     m_ObjectPool  = GameObject.FindWithTag(s_ObjectPoolTag).GetComponent <NetworkObjectPool>();
     Assert.IsNotNull(m_ObjectPool, $"{nameof(NetworkObjectPool)} not found in scene. Did you apply the {s_ObjectPoolTag} to the GameObject?");
 }
예제 #20
0
	void GetInstance()
	{
		instance = this;
	}
예제 #21
0
        /// <summary>
        /// Throws the throwable object.
        /// </summary>
        public void ThrowItem()
        {
            // m_InstantiatedThrownObject will be null for remote players on the network.
            if (m_InstantiatedThrownObject != null)
            {
                m_InstantiatedThrownObject.transform.parent = null;
                // The collider was previously disabled. Enable it again when it is thrown.
                var collider = m_InstantiatedThrownObject.GetCachedComponent <Collider>();
                collider.enabled = true;

                // When the item is used the trajectory object should start moving on its own.
                if (m_InstantiatedTrajectoryObject != null)
                {
                    // The throwable item may be on the other side of an object (especially in the case of separate arms for the first person perspective). Perform a linecast
                    // to ensure the throwable item doesn' move through any objects.
                    if (!m_CharacterLocomotion.ActiveMovementType.UseIndependentLook(false) &&
                        Physics.Linecast(m_CharacterLocomotion.LookSource.LookPosition(), m_InstantiatedTrajectoryObject.transform.position, out m_RaycastHit,
                                         m_ImpactLayers, QueryTriggerInteraction.Ignore))
                    {
                        m_InstantiatedTrajectoryObject.transform.position = m_RaycastHit.point;
                    }

                    var trajectoryTransform = m_ThrowableItemPerpectiveProperties.TrajectoryLocation != null ? m_ThrowableItemPerpectiveProperties.TrajectoryLocation : m_CharacterTransform;
                    var lookDirection       = m_LookSource.LookDirection(trajectoryTransform.TransformPoint(m_TrajectoryOffset), false, m_ImpactLayers, true);
#if ULTIMATE_CHARACTER_CONTROLLER_VR
                    if (m_VRThrowableItem != null && m_CharacterLocomotion.FirstPersonPerspective)
                    {
                        m_Velocity = m_VRThrowableItem.GetVelocity();
                    }
#endif
                    var velocity = MathUtility.TransformDirection(m_Velocity, Quaternion.LookRotation(lookDirection, m_CharacterLocomotion.Up));
                    // Prevent the item from being thrown behind the character. This can happen if the character is looking straight up and there is a positive
                    // y velocity. Gravity will cause the thrown object to go in the opposite direction.
                    if (Vector3.Dot(velocity.normalized, m_CharacterTransform.forward) < 0)
                    {
                        velocity = m_CharacterTransform.up * velocity.magnitude;
                    }
                    m_InstantiatedTrajectoryObject.Initialize(velocity + (m_CharacterTransform.forward * m_CharacterLocomotion.LocalVelocity.z), Vector3.zero, m_Character, false);
                }
            }

#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
            if (m_NetworkInfo != null)
            {
                // The object has been thrown. If the ItemAction is local then that object should be spawned on the network.
                // Non-local actions should disable the mesh renderers so the object can take its place. The mesh renderers will be enabled again in a separate call.
                if (m_NetworkInfo.IsLocalPlayer())
                {
                    NetworkObjectPool.NetworkSpawn(m_ThrownObject, m_InstantiatedThrownObject);
                }
                else
                {
                    EnableObjectMeshRenderers(false);
                }
            }
#endif

            if (m_Inventory != null)
            {
                m_Inventory.UseItem(m_ConsumableItemType, 1);
            }
        }