Forum rules - please read before posting.

Reset First Person Camera?

In my game the player is able to switch to first person (from third) view (and back again) via button press - this switches to the first person camera and changes movement method from direct to first person. The first switch in a scene is fine, but:
if you switch to first person and look up or down then switch to third, then back to first person again, the first person camera is still pointed in the direction it was in before reverting to third person. How can I ensure the camera reverts back to it's initial "forwards" direction when re-entering first person?

Comments

  • edited February 8

    You can do this with the camera's SetPitch function, setting the pitch angle to zero.

    Here's a script that calls it whenever you switch to the first-person camera:

    using UnityEngine;
    using AC;
    
    public class ResetFPCamera : MonoBehaviour
    {
    
        void OnEnable () { EventManager.OnSwitchCamera += OnSwitchCamera; }
        void OnDisable () { EventManager.OnSwitchCamera -= OnSwitchCamera; }
    
        void OnSwitchCamera (_Camera fromCamera, _Camera toCamera, float transitionTime)
        {
            if (toCamera is FirstPersonCamera)
            {
                (toCamera as FirstPersonCamera).SetPitch (0f);
            }
        }
    
    }
    
  • I can't get this to work I'm afraid. Note that I am on AC 1.77.4. Is the code different?

  • In what way exactly does it not work? Where did you place it, and do you get an error?

  • edited February 9

    I'm sot seeing any effect on the camera's pitch - and in the inspector I can see the x axis of the fp camera is the same as it was before switching back to it.

    I placed the script in the scene on an empty game object.

    I tried it with my usual actionlist asset for switching between third and first person, but also tested with just an action list in the scene that just switches to first person, waits a second, switches to third, waits a second then switches back to first - but still the camera was the same pitch it was before switching.

    For testing, how can I edit the script so that I can place it the scene and just use Object: Call Event and call the SetPitch function? See if it works that way.

  • This variant will reset the pitch when its ResetPitch function is called with the Object: Call event Action:

    using UnityEngine;
    using AC;
    
    public class ResetFPCamera : MonoBehaviour
    {
    
        public void ResetPitch ()
        {
            if (KickStarter.mainCamera.attachedCamera is FirstPersonCamera)
            {
                FirstPersonCamera fpCamera = (FirstPersonCamera) KickStarter.mainCamera.attachedCamera;
                fpCamera.SetPitch (0f);
                Debug.Log ("Reset pitch of " + fpCamera);
            }
        }
    
    }
    
  • Hmm still not happening. Is this working for you by any chance? I've even tried animating the camera directly and setting the x axis to 0, but still nope.

    The only way I can get the pitch to be set to 0 is when both fields of the "Constrain Pitch Rotation" are set to zero. However it is unavailable for editing to both the animator and Object: Call Event action.

    Perhaps there is a way to edit the first person camera script to expose these fields, so the values can be set through Object: Call Event. I would set them both to 0 when not in first person, then set them to the desired amounts (-40 and 60 in this case) when enabling first person mode.

  • Is this working for you by any chance?

    It is. I take it the Debug.Log statement is appearing?

    The only way I can get the pitch to be set to 0 is when both fields of the "Constrain Pitch Rotation" are set to zero.

    You can update this with custom code - it could be inserted into the above script(s):

    fpCamera.minY = fpCamera.maxY = 0f;
    
  • No debug statement is showing - absolutely no mention of the script at all in the console. Does my camera need to have a certain name, an exact spelling for it to register? It's odd that it's working fine for you but for me there's no sign of the script doing anything at all.

  • If the log isn't showing with the variant on Feb 10, make sure the first-person camera is active at the time. Alternatively, comment out "if" line to have it reset at any time.

  • Okay, I commented out that line, it still does not work but I get this exception when I try and use the script:

    InvalidCastException: Specified cast is not valid.
    ResetFPCamera.ResetPitch () (at Assets/MyGame/ResetFPCamera.cs:11)
    UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
    UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)
    AC.ActionEvent.Run () (at Assets/AdventureCreator/Scripts/Actions/ActionEvent.cs:39)
    AC.ActionList+<RunAction>d__38.MoveNext () (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:467)
    UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
    UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
    AC.ActionList:BeginActionList(Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:378)
    AC.ActionList:Interact(Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:279)
    AC.ActionList:Interact() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:242)
    AC.AC_Trigger:Interact(GameObject) (at Assets/AdventureCreator/Scripts/Logic/AC_Trigger.cs:331)
    AC.PositionDetectObject:Process(AC_Trigger) (at Assets/AdventureCreator/Scripts/Logic/AC_Trigger.cs:646)
    AC.AC_Trigger:_Update() (at Assets/AdventureCreator/Scripts/Logic/AC_Trigger.cs:96)
    AC.StateHandler:Update() (at Assets/AdventureCreator/Scripts/Game engine/StateHandler.cs:237)
    
  • edited February 13

    Ah, it was because the Camera script was on it (the AC one not the actual Unity camera component) as well as the first person camera. It's working now, thank you.

    IMAGE

  • edited February 13

    Oh wait, it seems if you reset pitch without the first person camera being active, you get this:

        InvalidCastException: Specified cast is not valid.
        ResetFPCamera.ResetPitch () (at Assets/MyGame/ResetFPCamera.cs:11)
        UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166)
        UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:58)
        AC.ActionEvent.Run () (at Assets/AdventureCreator/Scripts/Actions/ActionEvent.cs:39)
        AC.ActionList+<RunAction>d__38.MoveNext () (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:467)
        UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
        UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
        AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
        AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:616)
        AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:575)
        AC.<RunAction>d__38:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:539)
        UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
        AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
        AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:616)
        AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:575)
        AC.<RunAction>d__38:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:539)
        UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
        AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
        AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:616)
        AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:575)
        AC.<RunAction>d__38:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:539)
        UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
        AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
        AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:616)
        AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:575)
        AC.<RunAction>d__38:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:539)
        UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
        AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
        AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:616)
        AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:575)
        AC.<RunAction>d__38:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:539)
        UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
        AC.ActionList:ProcessAction(Int32) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:408)
        AC.ActionList:ProcessActionEnd(ActionEnd, Int32, Boolean) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:616)
        AC.ActionList:EndAction(Action) (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:575)
        AC.<RunAction>d__38:MoveNext() (at Assets/AdventureCreator/Scripts/ActionList/ActionList.cs:539)
        UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
    

    The thing is, I'd rather it be reset when it is not active, otherwise you get this nasty snap back into it's default position.

  • edited February 14

    Use this:

    using UnityEngine;
    using AC;
    
    public class ResetFPCamera : MonoBehaviour
    {
    
        public void ResetPitch ()
        {
            FirstPersonCamera fpCamera = Object.FindObjectOfType<FirstPersonCamera> ();
            fpCamera.SetPitch (0f);
            Debug.Log ("Reset pitch of " + fpCamera);
        }
    
    }
    
  • Yes this appears to be working perfectly, thank you.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.