1
\$\begingroup\$

I'm creating Third Person game with multiple switching cameras. I'm using the default Third Person Control asset provided with Unity, and it comes with a script that aligns the movement to the camera.

The problem is, this script only seems to align with the "Main Camera" tagged camera. My game has multiple cameras with their own tag (Camera), and I need to switch the controls based on the current active camera's direction. I briefly modified the script to substitute "main" with "current", so the movement could be based around the current active camera instead, but it doesn't seem to work.

Could someone explain what am I missing here? Thanks!

using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

 namespace UnityStandardAssets.Characters.ThirdPerson
{
  [RequireComponent(typeof (ThirdPersonCharacter))]
  public class ThirdPersonUserControlCamera : MonoBehaviour
  {
      private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object
      private Transform m_Cam;                  // A reference to the main camera in the scenes transform
      private Vector3 m_CamForward;             // The current forward direction of the camera
      private Vector3 m_Move;
      private bool m_Jump;                      // the world-relative desired move direction, calculated from the camForward and user input.


      private void Start()
      {
          // get the transform of the main camera
          if (Camera.current != null) // changed from Camera.main to Camera.current
          {
              m_Cam = Camera.current.transform; // changed from Camera.main to Camera.current
          }
          else
          {
              Debug.LogWarning(
                  "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
              // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
          }

          // get the third person character ( this should never be null due to require component )
          m_Character = GetComponent<ThirdPersonCharacter>();
      }


      private void Update()
      {
          if (!m_Jump)
          {
              m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
          }
      }


      // Fixed update is called in sync with physics
      private void FixedUpdate()
      {
          // read inputs
          float h = CrossPlatformInputManager.GetAxis("Horizontal");
          float v = CrossPlatformInputManager.GetAxis("Vertical");
          bool crouch = Input.GetKey(KeyCode.C);

          // calculate move direction to pass to character
          if (m_Cam != null)
          {
              // calculate camera relative direction to move:
              m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
              m_Move = v*m_CamForward + h*m_Cam.right;
          }
          else
          {
              // we use world-relative directions in the case of no main camera
              m_Move = v*Vector3.forward + h*Vector3.right;
          }
 #if !MOBILE_INPUT
          // walk speed multiplier
          if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
 #endif

          // pass all parameters to the character control script
          m_Character.Move(m_Move, crouch, m_Jump);
          m_Jump = false;
      }
  }
 }

EDIT: This script manages the camera:

  using UnityEngine;
  using System.Collections;

  public class CameraManager : MonoBehaviour
 {
  public GameObject[] cameras;
  public GameObject startCamera;

// Use this for initialization
void Start()
{
    cameras = GameObject.FindGameObjectsWithTag("Camera");

    for (int i = 0; i < cameras.Length; i++)
    {
        cameras[i].SetActive(false);
    }

    startCamera.SetActive(true);
}

public void DeactivateAllCameras()
{
    cameras = GameObject.FindGameObjectsWithTag("Camera");

    for (int i = 0; i < cameras.Length; i++)
    {
        cameras[i].SetActive(false);
    }
  }
}

This script triggers other cameras:

    using UnityEngine;
    using System.Collections;

    public class CameraTrigger : MonoBehaviour
    {
public GameObject myCamera;
private CameraManager myCameraManager;

// Use this for initialization
void Start ()
{
    myCameraManager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<CameraManager>();
}

void OnTriggerEnter(Collider other)
{
    if(other.CompareTag("Player"))
    {
        myCameraManager.DeactivateAllCameras();
        myCamera.SetActive(true);
    }
  }
}
\$\endgroup\$
  • \$\begingroup\$ The docs are a little ambiguous (as they so often are), but it looks like Camera.current might only be correctly populated in certain camera events like OnPreRender. (Which makes sense - other events like FixedUpdate aren't specific to a particular "current" camera) How are you switching cameras at the moment? Are you enabling/disabling the Camera scripts or the camera GameObjects themselves using SetActive? We could probably add a little script that keeps track of which camera is active for gameplay purposes. \$\endgroup\$ – DMGregory Nov 20 '16 at 15:53
  • \$\begingroup\$ I'm enabling and disabling the GameObjects themselves via another script that manages which camera is active... and that's the camera I'd like to call on the Third Person Controller instead of the Main Camera. \$\endgroup\$ – Platoon Nov 20 '16 at 18:09
  • \$\begingroup\$ jhocking's answer would work with that. If you edit your question to include your camera switching script, we can show you how to integrate the needed changes. \$\endgroup\$ – DMGregory Nov 20 '16 at 18:16
  • \$\begingroup\$ Alright, I just edited the question with my 2 scripts managing the cameras. I'd like to thank you for your great assistance DMGregory! \$\endgroup\$ – Platoon Nov 20 '16 at 18:59
0
\$\begingroup\$

Add a public SetCamera(camera) method to your third-person controller, and have that method put the camera transform into m_cam. Then whatever code changes the camera view also calls controller.SetCamera(newCamera)

\$\endgroup\$
  • \$\begingroup\$ Hi jhocking, I don't think I get it correctly, could you show me an example with the camera scripts I edited into the question? Thanks. \$\endgroup\$ – Platoon Nov 21 '16 at 6:14
  • \$\begingroup\$ Okay, I just figured it out using the SetCamera method on fixed update and it's now working correctly. Thanks! \$\endgroup\$ – Platoon Nov 27 '16 at 3:43
0
\$\begingroup\$

based from http://answers.unity3d.com/questions/15801/finding-cameras.html

Use Something Like This

 Camera cam = GameObject.Find("YourCameraName").GetComponent<Camera>();

if( cam == GameObject.Find("CameraOne").GetComponent<Camera>() ) {

}      
     
if ( cam == GameObject.Find("CameraTwo").GetComponent<Camera>() ) {

}

This will be alot of hardwork so , goodluck :)

   ANSWER EDITED     
\$\endgroup\$
  • \$\begingroup\$ ...this code doesn't look like it solves the question. The first line selects a single hard-coded camera. The subsequent lines check if that hardcoded camera is equal to some other hardcoded camera (both comparisons are always false unless the object gets renamed, so that code on its own doesn't accomplish anything). It does not show how to get a reference to the camera that is currently serving as the player's viewpoint. \$\endgroup\$ – DMGregory Nov 20 '16 at 16:05
  • \$\begingroup\$ Thanks! Unfortunately, like DMGregory said, I need a function to call the current active camera (all others are disabled) and use it in place of the previous MainCamera, and that doesn't do it. \$\endgroup\$ – Platoon Nov 20 '16 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.