/// <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 foundCamera = Shared.Camera.CameraUtility.FindCamera(pickedUpBy); if (foundCamera != null) { m_PickupAudioClipSet.PlayAtPosition(m_Transform.position); } if (ObjectPoolBase.InstantiatedWithPool(m_GameObject)) { #if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER if (NetworkObjectPool.IsNetworkActive()) { NetworkObjectPool.Destroy(m_GameObject); return; } #endif ObjectPoolBase.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); } }
/// <summary> /// Removes any slices which have existed for more than the visible time. /// </summary> private void RemoveOldSlices() { if (m_TrailSlicesCount == 0) { if (!m_GenerateSlices) { if (ObjectPoolBase.InstantiatedWithPool(m_GameObject)) { ObjectPoolBase.Destroy(m_GameObject); } else { m_GameObject.SetActive(false); } } return; } var startIndex = m_TrailSlicesIndex - m_TrailSlicesCount + 1; if (startIndex < 0) { startIndex = m_TrailSlices.Length + startIndex; } var count = m_TrailSlicesCount; for (int i = 0; i < count; ++i) { var trailSlice = m_TrailSlices[(startIndex + i) % m_TrailSlices.Length]; if (trailSlice.Time + m_VisibilityTime > Time.time) { break; } // The slice has existed for more than the visiblity time - remove it by decreasing the count. m_TrailSlicesCount--; } if (m_SmoothedTrailSlicesCount == 0) { return; } startIndex = m_SmoothedTrailSlicesIndex - m_SmoothedTrailSlicesCount + 1; if (startIndex < 0) { startIndex = m_SmoothedTrailSlices.Length + startIndex; } count = m_SmoothedTrailSlicesCount; for (int i = 0; i < count; ++i) { var trailSlice = m_SmoothedTrailSlices[(startIndex + i) % m_SmoothedTrailSlices.Length]; if (trailSlice.Time + m_VisibilityTime > Time.time) { break; } // The slice has existed for more than the visiblity time - remove it by decreasing the count. m_SmoothedTrailSlicesCount--; m_SmoothedTrailSlicesPrevCount--; } if (m_TrailSlicesCount == 0 && m_SmoothedTrailSlicesCount == 0) { m_GenerateSlices = false; } }
/// <summary> /// The object is no longer alive. /// </summary> /// <param name="position">The position of the damage.</param> /// <param name="force">The amount of force applied to the object while taking the damage.</param> /// <param name="attacker">The GameObject that killed the character.</param> public virtual void Die(Vector3 position, Vector3 force, GameObject attacker) { #if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER if (m_NetworkInfo != null && m_NetworkInfo.IsLocalPlayer()) { m_NetworkHealthMonitor.Die(position, force, attacker); } #endif // Spawn any objects on death, such as an explosion if the object is an explosive barrel. if (m_SpawnedObjectsOnDeath != null) { for (int i = 0; i < m_SpawnedObjectsOnDeath.Length; ++i) { var spawnedObject = ObjectPoolBase.Instantiate(m_SpawnedObjectsOnDeath[i], m_Transform.position, m_Transform.rotation); Explosion explosion; if ((explosion = spawnedObject.GetCachedComponent <Explosion>()) != null) { explosion.Explode(gameObject); } var rigidbodies = spawnedObject.GetComponentsInChildren <Rigidbody>(); for (int j = 0; j < rigidbodies.Length; ++j) { rigidbodies[j].AddForceAtPosition(force, position); } } } // Destroy any objects on death. The objects will be placed back in the object pool if they were created within it otherwise the object will be destroyed. if (m_DestroyedObjectsOnDeath != null) { for (int i = 0; i < m_DestroyedObjectsOnDeath.Length; ++i) { if (ObjectPoolBase.InstantiatedWithPool(m_DestroyedObjectsOnDeath[i])) { ObjectPoolBase.Destroy(m_DestroyedObjectsOnDeath[i]); } else { Object.Destroy(m_DestroyedObjectsOnDeath[i]); } } } // Change the layer to a death layer. if (m_DeathLayer.value != 0) { m_AliveLayer = m_GameObject.layer; m_GameObject.layer = m_DeathLayer; } // Play any take death audio. Use PlayAtPosition because the audio won't play if the GameObject is inactive. m_DeathAudioClipSet.PlayAtPosition(m_Transform.position); // Deactivate the object if requested. if (m_DeactivateOnDeath) { SchedulerBase.Schedule(m_DeactivateOnDeathDelay, Deactivate); } // The attributes shouldn't regenerate. if (m_ShieldAttribute != null) { m_ShieldAttribute.CancelAutoUpdate(); } if (m_HealthAttribute != null) { m_HealthAttribute.CancelAutoUpdate(); } // Notify those interested. EventHandler.ExecuteEvent <Vector3, Vector3, GameObject>(m_GameObject, "OnDeath", position, force, attacker); if (m_OnDeathEvent != null) { m_OnDeathEvent.Invoke(position, force, attacker); } }