/// <summary> /// The object has been spawned. Initialize the item pickup. /// </summary> public void ObjectSpawned() { var photonView = gameObject.GetCachedComponent <PhotonView>(); if (photonView == null || photonView.InstantiationData == null) { return; } // Return the old. for (int i = 0; i < m_ItemTypeCounts.Length; ++i) { ObjectPool.Return(m_ItemTypeCounts[i]); } // Setup the item counts. var itemTypeCountLength = (photonView.InstantiationData.Length - (m_TrajectoryObject != null ? 3 : 0)) / 2; if (m_ItemTypeCounts.Length != itemTypeCountLength) { m_ItemTypeCounts = new ItemTypeCount[itemTypeCountLength]; } for (int i = 0; i < itemTypeCountLength; ++i) { var itemTypeCount = ObjectPool.Get <ItemTypeCount>(); itemTypeCount.Initialize(ItemTypeTracker.GetItemType((int)photonView.InstantiationData[i * 2]), (float)photonView.InstantiationData[i * 2 + 1]); m_ItemTypeCounts[i] = itemTypeCount; } Initialize(true); // Setup the trajectory object. if (m_TrajectoryObject != null) { var velocity = (Vector3)photonView.InstantiationData[photonView.InstantiationData.Length - 3]; var torque = (Vector3)photonView.InstantiationData[photonView.InstantiationData.Length - 2]; var originatorID = (int)photonView.InstantiationData[photonView.InstantiationData.Length - 1]; GameObject originator = null; if (originatorID != -1) { var originatorView = PhotonNetwork.GetPhotonView(originatorID); if (originatorView != null) { originator = originatorView.gameObject; } } m_TrajectoryObject.Initialize(velocity, torque, originator); } }
/// <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); } }