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