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\$
4
  • \$\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, 2016 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, 2016 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, 2016 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, 2016 at 18:59

2 Answers 2

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\$
2
  • \$\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, 2016 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, 2016 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\$
2
  • \$\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, 2016 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, 2016 at 17:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .