/// <summary> /// Initializes the object. /// </summary> /// <param name="characterLocomotion">The character that is being managed by the KinematicObjectManager.</param> public void Initialize(UltimateCharacterLocomotion characterLocomotion) { m_CharacterLocomotion = characterLocomotion; OnAttachLookSource(m_CharacterLocomotion.LookSource); EventHandler.RegisterEvent <ILookSource>(m_CharacterLocomotion.gameObject, "OnCharacterAttachLookSource", OnAttachLookSource); EventHandler.RegisterEvent <bool>(m_CharacterLocomotion.gameObject, "OnCharacterChangeUpdateLocation", OnChangeUpdateLocation); // The class is pooled so reset any variables. m_HorizontalMovement = m_ForwardMovement = m_DeltaYawRotation = 0; Initialize(characterLocomotion.transform); m_CharacterHandler = m_CharacterLocomotion.GetComponent <UltimateCharacterLocomotionHandler>(); m_CharacterIK = m_CharacterLocomotion.GetComponent <CharacterIKBase>(); // Wait a moment before finishing with the initialization. This allows the character to be created at runtime. m_CompleteInitEvent = Scheduler.ScheduleFixed(Time.fixedDeltaTime / 2, () => { if (m_CharacterHandler == null) { m_CharacterHandler = m_CharacterLocomotion.GetComponent <UltimateCharacterLocomotionHandler>(); } if (m_CharacterIK == null) { m_CharacterIK = m_CharacterLocomotion.GetComponent <CharacterIKBase>(); } var smoothedBones = m_CharacterLocomotion.SmoothedBones; if (smoothedBones != null && smoothedBones.Length > 0) { var validBones = 0; for (int i = 0; i < smoothedBones.Length; ++i) { if (smoothedBones[i] != null) { validBones++; } } if (validBones > 0) { m_SmoothedBones = new SmoothFixedLocation[validBones]; var index = 0; for (int i = 0; i < smoothedBones.Length; ++i) { if (smoothedBones[i] == null) { continue; } m_SmoothedBones[index] = GenericObjectPool.Get <SmoothFixedLocation>(); m_SmoothedBones[index].Initialize(smoothedBones[i]); index++; } } } m_CompleteInitEvent = null; }); }
/// <summary> /// Cancels an event. /// </summary> /// <param name="scheduledEvent">The event to cancel.</param> public static void Cancel(ScheduledEventBase scheduledEvent) { // Objects may be wanting to be cancelled as the game is stopping but the Scheduler has already been destroyed. Ensure the Scheduler is still valid. if (s_Instance == null) { return; } Instance.CancelEventInternal(scheduledEvent); }
/// <summary> /// Invokes the scheduled event with the specified index. /// </summary> /// <param name="scheduledEvent">The event that should be invoked.</param> /// <param name="index">The index of the event to invoke.</param> private void Invoke(ScheduledEventBase scheduledEvent, int index) { // An end time of -1 indicates that the event reoccurs forever and must manually be cancelled. if (scheduledEvent.EndTime != -1) { // Remove the event from the list before the invoke to prevent the invoked method from adding a new event and changing the order. RemoveActiveEvent(index, scheduledEvent.Location); } scheduledEvent.Invoke(); if (scheduledEvent.EndTime != -1) { ObjectPool.Return(scheduledEvent); } }
/// <summary> /// Stops managing the character. /// </summary> public void UnregisterCharacter() { if (m_CompleteInitEvent != null) { Scheduler.Cancel(m_CompleteInitEvent); m_CompleteInitEvent = null; } if (m_SmoothedBones != null) { for (int i = 0; i < m_SmoothedBones.Length; ++i) { ObjectPool.Return(m_SmoothedBones[i]); } m_SmoothedBones = null; } EventHandler.UnregisterEvent <ILookSource>(m_CharacterLocomotion.gameObject, "OnCharacterAttachLookSource", OnAttachLookSource); }
/// <summary> /// Internal method to cancel an event. /// </summary> /// <param name="scheduledEvent">The event to cancel.</param> private void CancelEventInternal(ScheduledEventBase scheduledEvent) { if (scheduledEvent == null) { return; } if (scheduledEvent != null && scheduledEvent.Active) { var removeIndex = -1; if (scheduledEvent.Location == ScheduledEventBase.InvokeLocation.Update) { for (int i = m_ActiveUpdateEventCount - 1; i >= 0; --i) { if (m_ActiveUpdateEvents[i] == scheduledEvent) { removeIndex = i; break; } } } else { for (int i = m_ActiveFixedUpdateEventCount - 1; i >= 0; --i) { if (m_ActiveFixedUpdateEvents[i] == scheduledEvent) { removeIndex = i; break; } } } if (removeIndex != -1) { RemoveActiveEvent(removeIndex, scheduledEvent.Location); ObjectPool.Return(scheduledEvent); scheduledEvent = null; } } }
/// <summary> /// Adds the scheduled event to the ActiveUpdateEvents or ActiveFixedUpdate events array. /// </summary> /// <param name="scheduledEvent">The scheduled event to add.</param> private void AddScheduledEvent(ScheduledEventBase scheduledEvent) { if (scheduledEvent.Location == ScheduledEventBase.InvokeLocation.Update) { if (m_ActiveUpdateEventCount >= m_MaxEventCount) { Debug.LogError("Error: The ActiveEvents array is full so the new event cannot be added. The Scheduler.MaxEventCount value should be increased."); return; } m_ActiveUpdateEvents[m_ActiveUpdateEventCount] = scheduledEvent; m_ActiveUpdateEventCount++; } else // FixedUpdate. { if (m_ActiveFixedUpdateEventCount >= m_MaxEventCount) { Debug.LogError("Error: The ActiveEvents array is full so the new event cannot be added. The Scheduler.MaxEventCount value should be increased."); return; } m_ActiveFixedUpdateEvents[m_ActiveFixedUpdateEventCount] = scheduledEvent; m_ActiveFixedUpdateEventCount++; } scheduledEvent.Active = true; }