Example #1
0
        /// <summary>
        /// Initialize the camera to follow the character.
        /// </summary>
        /// <param name="character">The character to initialize. Can be null.</param>
        private void InitializeCharacter(GameObject character)
        {
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                return;
            }
#endif

            if (character == m_Character)
            {
                return;
            }

            // If the character is not null then the previous character should be notified that there is no longer a camera attached.
            if (m_Character != null)
            {
                EventHandler.ExecuteEvent <CameraController>(m_Character, "OnCharacterAttachCamera", null);
                EventHandler.ExecuteEvent <ILookSource>(m_Character, "OnCharacterAttachLookSource", null);
                EventHandler.UnregisterEvent <Vector3>(m_Character, "OnCameraPositionalForce", AddPositionalForce);
                EventHandler.UnregisterEvent <Vector3>(m_Character, "OnCameraRotationalForce", AddRotationalForce);
                EventHandler.UnregisterEvent <Vector3, Vector3, float>(m_Character, "OnAddSecondaryCameraForce", OnAddSecondaryForce);
                EventHandler.UnregisterEvent <bool>(m_Character, "OnCharacterImmediateTransformChange", OnImmediateTransformChange);
                EventHandler.UnregisterEvent(m_Character, "OnAnimatorSnapped", PositionImmediately);
                EventHandler.UnregisterEvent <Ability, bool>(m_Character, "OnCharacterAbilityActive", OnAbilityActive);
                EventHandler.UnregisterEvent <ItemAbility, bool>(m_Character, "OnCharacterItemAbilityActive", OnItemAbilityActive);
                EventHandler.UnregisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives);
                StateManager.LinkGameObjects(m_Character, m_GameObject, false);
            }

            // The character should no longer be using the zoom state if the camera is no longer attached.
            if (m_Zoom && m_Character != null)
            {
                SetZoom(false);
            }

            // Set the character values.
            if (enabled = (character != null))
            {
                m_Character           = character;
                m_CharacterTransform  = m_Character.transform;
                m_CharacterLocomotion = character.GetCachedComponent <UltimateCharacterLocomotion>();
                m_CharacterInventory  = character.GetCachedComponent <InventoryBase>();

                InitializeAnchor();
            }
            else
            {
                m_Character           = null;
                m_CharacterTransform  = null;
                m_CharacterLocomotion = null;
                m_CharacterInventory  = null;
            }

            // Notify the view types of the character that is being attached.
            for (int i = 0; i < m_ViewTypes.Length; ++i)
            {
                m_ViewTypes[i].AttachCharacter(m_Character);
            }

            if (m_Character != null)
            {
                m_ViewType.ChangeViewType(true, 0, 0, m_CharacterTransform.rotation);
                if (m_ViewType.RotatePriority)
                {
                    KinematicObjectManager.SetCameraRotation(m_KinematicObjectIndex, m_ViewType.Rotate(0, 0, true));
                    KinematicObjectManager.SetCameraPosition(m_KinematicObjectIndex, m_ViewType.Move(true));
                }
                else
                {
                    KinematicObjectManager.SetCameraPosition(m_KinematicObjectIndex, m_ViewType.Move(true));
                    KinematicObjectManager.SetCameraRotation(m_KinematicObjectIndex, m_ViewType.Rotate(0, 0, true));
                }
                m_ViewType.UpdateFieldOfView(true);

                // Registered for any interested events.
                EventHandler.RegisterEvent <Vector3>(m_Character, "OnCameraPositionalForce", AddPositionalForce);
                EventHandler.RegisterEvent <Vector3>(m_Character, "OnCameraRotationalForce", AddRotationalForce);
                EventHandler.RegisterEvent <Vector3, Vector3, float>(m_Character, "OnAddSecondaryCameraForce", OnAddSecondaryForce);
                EventHandler.RegisterEvent <bool>(m_Character, "OnCharacterImmediateTransformChange", OnImmediateTransformChange);
                EventHandler.RegisterEvent(m_Character, "OnAnimatorSnapped", PositionImmediately);
                EventHandler.RegisterEvent <Ability, bool>(m_Character, "OnCharacterAbilityActive", OnAbilityActive);
                EventHandler.RegisterEvent <ItemAbility, bool>(m_Character, "OnCharacterItemAbilityActive", OnItemAbilityActive);
                EventHandler.RegisterEvent <bool>(m_Character, "OnCameraChangePerspectives", OnChangePerspectives);

                // Notify the camera components of the attached character.
                EventHandler.ExecuteEvent <GameObject>(m_GameObject, "OnCameraAttachCharacter", character);

                // Notify the character of the attached camera.
                EventHandler.ExecuteEvent <CameraController>(m_Character, "OnCharacterAttachCamera", this);
                EventHandler.ExecuteEvent <ILookSource>(m_Character, "OnCharacterAttachLookSource", this);
                EventHandler.ExecuteEvent <bool>(m_Character, "OnCameraWillChangePerspectives", m_ViewType.FirstPersonPerspective);
                EventHandler.ExecuteEvent <bool>(m_Character, "OnCameraChangePerspectives", m_ViewType.FirstPersonPerspective);

                StateManager.LinkGameObjects(m_Character, m_GameObject, true);

#if UNITY_EDITOR
                // Show a warning if the movement type isn't what is recommended for the current view type. Only show this when the character is initially attached
                // because a mismatch is most likely when initially setting up the character.
                var recommendedMovementTypes = m_ViewType.GetType().GetCustomAttributes(typeof(RecommendedMovementType), true);
                if (recommendedMovementTypes != null && recommendedMovementTypes.Length > 0)
                {
                    var movementType = m_CharacterLocomotion.ActiveMovementType;
                    var isRecommendedMovementType = false;
                    for (int i = 0; i < recommendedMovementTypes.Length; ++i)
                    {
                        var recommendedMovementType = recommendedMovementTypes[0] as RecommendedMovementType;
                        if (recommendedMovementType.Type.IsInstanceOfType(movementType))
                        {
                            isRecommendedMovementType = true;
                            break;
                        }
                    }
                    if (!isRecommendedMovementType)
                    {
                        Debug.LogWarning($"Warning: The {UnityEngineUtility.GetFriendlyName(movementType.GetType())} MovementType is active while the ViewType " +
                                         $"recommends using {UnityEngineUtility.GetFriendlyName((recommendedMovementTypes[0] as RecommendedMovementType).Type)}.");
                    }
                }
#endif
            }
            else
            {
                // Notify the camera components of the attached character.
                EventHandler.ExecuteEvent <GameObject>(m_GameObject, "OnCameraAttachCharacter", character);
            }
        }