Possible bug with FirstPersonController.TransformLook

adampliska

New member
I might have found a bug in the TransformLook ViewType. I use this viewtype to "zoom into" objects in my game world. So I flip between a 3rd person viewtype and this first person transform look view type. If I enable the transformlook viewtype, and set the proper move and rotation targets, then unzoom (going back to the 3rd person view type) (also I set the move/rotation targets to null) and then close the application - I get an error.

In this case the error is started in the CameraController.OnDestroy method. The system calls InitializeCharacter(null) to clear out the character. This leads to each view type's AttachCharacter method being called. When the TransformLook view type's AttachCharacter method is called, null is passed for the character. In the AttachCharacter method there is a small bit of code that checks to see if the move target OR the rotation target is null, and in that case, use the character transform. Finally, the code will attempt to get the animator for the character, which is null. This leads into an extension method. thre is no null check in that extention method and so the code tires to access a value from a dictionary with a null key - error.

I recommend either updating the FirstPersonController.TransformLook script to check for null characters and avoid trying to access the animator OR
update the GetCachedComponent extension method to check for a null game object and returning null if detected.

-- Adam
 
What is the stack trace of the error that you are receiving? What is the value of m_Character? When AttachCharacter(null) is called m_Character gets set to null so TransformLook.AttachCharacter should return early here:

Code:
            if (m_MoveTarget == null || m_RotationTarget == null) {
                if (m_Character == null) {
                    return;
                }
 
Ahh I must have an old version! Here is what the method looks like for me:

C#:
/// <summary>
        /// Attaches the view type to the specified character.
        /// </summary>
        /// <param name="character">The character to attach the camera to.</param>
        public override void AttachCharacter(GameObject character)
        {
            base.AttachCharacter(character);

            if (m_MoveTarget == null || m_RotationTarget == null) {
                Transform moveTarget = m_CharacterTransform, rotationTarget = m_CharacterTransform;
                var characterAnimator = m_Character.GetCachedComponent<Animator>();
                if (characterAnimator != null) {
                    moveTarget = characterAnimator.GetBoneTransform(HumanBodyBones.Head);
                    rotationTarget = characterAnimator.GetBoneTransform(HumanBodyBones.Hips);
                }

                m_MoveTarget = moveTarget;
                m_RotationTarget = rotationTarget;
            }
        }

And here is the stack:
Code:
ArgumentNullException: Value cannot be null.
Parameter name: key
System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) (at <fb001e01371b4adca20013e0ac763896>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].TryGetValue (TKey key, TValue& value) (at <fb001e01371b4adca20013e0ac763896>:0)
Opsive.UltimateCharacterController.Utility.GameObjectExtensions.GetCachedComponent[T] (UnityEngine.GameObject gameObject) (at Assets/Opsive/UltimateCharacterController/Scripts/Utility/GameObjectExtensions.cs:34)
Opsive.UltimateCharacterController.FirstPersonController.Camera.ViewTypes.TransformLook.AttachCharacter (UnityEngine.GameObject character) (at Assets/Opsive/UltimateCharacterController/Scripts/FirstPersonController/Camera/TransformLook.cs:69)
Opsive.UltimateCharacterController.Camera.CameraController.InitializeCharacter (UnityEngine.GameObject character) (at Assets/Opsive/UltimateCharacterController/Scripts/Camera/CameraController.cs:444)
Opsive.UltimateCharacterController.Camera.CameraController.OnDestroy () (at Assets/Opsive/UltimateCharacterController/Scripts/Camera/CameraController.cs:922)
 
Top