uNet FPS Camera Error [C#] [Unity 5]
I am working on getting uNet setup for my game and I am running into an error when disabling the Main Camera and switching to the Player Camera. I am using the default FPSController. I have a script that should disable the Main Camera upon start the Local Server. This does work. And you can have 2 clients see each other at once, but you are unable to rotate the camera as the player. The mouse does not even disappear while playing. Something is wrong and I have no clue what it is.
Thanks for any help in advance!
I am following this tutorial: https://www.youtube.com/watch?v=NLnzlwCRjgc
I am getting these errors:
1. NullReferenceException: Object reference not set to an instance of an object UnityStandardAssets.Characters.FirstPerson.FirstPersonController.Start () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:50)
2. NullReferenceException: Object reference not set to an instance of an object UnityStandardAssets.Characters.FirstPerson.FirstPersonController.UpdateCameraPosition (Single speed) (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:197) UnityStandardAssets.Characters.FirstPerson.FirstPersonController.FixedUpdate () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:131)
3. NullReferenceException: Object reference not set to an instance of an object UnityStandardAssets.Characters.FirstPerson.FirstPersonController.RotateView () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:239) UnityStandardAssets.Characters.FirstPerson.FirstPersonController.Update () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:64)
4. NullReferenceException: Object reference not set to an instance of an object UnityStandardAssets.Characters.FirstPerson.FirstPersonController.UpdateCameraPosition (Single speed) (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:189) UnityStandardAssets.Characters.FirstPerson.FirstPersonController.FixedUpdate () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:131)
5. NullReferenceException: Object reference not set to an instance of an object UnityStandardAssets.Characters.FirstPerson.FirstPersonController.PlayFootStepAudio () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:172) UnityStandardAssets.Characters.FirstPerson.FirstPersonController.ProgressStepCycle (Single speed) (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:159) UnityStandardAssets.Characters.FirstPerson.FirstPersonController.FixedUpdate () (at Assets/Standard Assets/Characters/FirstPersonCharacter/Scripts/FirstPersonController.cs:130)
Here is my script:
PlayerNetworkSetup.cs
using UnityEngine;
using UnityEngine.Networking;
public class PlayerNetworkSetup : NetworkBehaviour {
[SerializeField]Camera cam;
[SerializeField]AudioListener audioListener;
void Start()
{
if (isLocalPlayer)
{
GameObject.Find("Scene Camera").SetActive(false);
GetComponent<CharacterController>().enabled = true;
GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().enabled = true;
cam.enabled = true;
audioListener.enabled = true;
}
}
}
I did modify the FirstPersonController slightly, but nothing that had to to with mouse movements...
FirstPersonController.cs
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;
namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
[RequireComponent(typeof (AudioSource))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private bool m_IsWalking;
[SerializeField] private float m_WalkSpeed;
[SerializeField] public float m_RunSpeed;
[SerializeField] [Range(0f, 1f)] private float m_RunstepLenghten;
[SerializeField] private float m_JumpSpeed;
[SerializeField] private float m_StickToGroundForce;
[SerializeField] private float m_GravityMultiplier;
[SerializeField] private MouseLook m_MouseLook;
[SerializeField] private bool m_UseFovKick;
[SerializeField] private FOVKick m_FovKick = new FOVKick();
[SerializeField] private bool m_UseHeadBob;
[SerializeField] private CurveControlledBob m_HeadBob = new CurveControlledBob();
[SerializeField] private LerpControlledBob m_JumpBob = new LerpControlledBob();
[SerializeField] private float m_StepInterval;
[SerializeField] private AudioClip[] m_FootstepSounds; // an array of footstep sounds that will be randomly selected from.
[SerializeField] private AudioClip m_JumpSound; // the sound played when character leaves the ground.
[SerializeField] private AudioClip m_LandSound; // the sound played when character touches back on ground.
private Camera m_Camera;
private bool m_Jump;
private float m_YRotation;
private Vector2 m_Input;
public Vector3 m_MoveDir = Vector3.zero;
private CharacterController m_CharacterController;
private CollisionFlags m_CollisionFlags;
private bool m_PreviouslyGrounded;
private Vector3 m_OriginalCameraPosition;
private float m_StepCycle;
private float m_NextStep;
public bool m_Jumping;
private AudioSource m_AudioSource;
// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Camera = Camera.main;
m_OriginalCameraPosition = m_Camera.transform.localPosition;
m_FovKick.Setup(m_Camera);
m_HeadBob.Setup(m_Camera, m_StepInterval);
m_StepCycle = 0f;
m_NextStep = m_StepCycle/2f;
m_Jumping = false;
m_AudioSource = GetComponent<AudioSource>();
m_MouseLook.Init(transform , m_Camera.transform);
}
// Update is called once per frame
private void Update()
{
RotateView();
// the jump state needs to read here to make sure it is not missed
if (!m_Jump)
{
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
}
if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)
{
StartCoroutine(m_JumpBob.DoBobCycle());
PlayLandingSound();
m_MoveDir.y = 0f;
m_Jumping = false;
}
if (!m_CharacterController.isGrounded && !m_Jumping && m_PreviouslyGrounded)
{
m_MoveDir.y = 0f;
}
m_PreviouslyGrounded = m_CharacterController.isGrounded;
}
private void PlayLandingSound()
{
m_AudioSource.clip = m_LandSound;
m_AudioSource.Play();
m_NextStep = m_StepCycle + .5f;
}
private void FixedUpdate()
{
float speed;
GetInput(out speed);
// always move along the camera forward as it is the direction that it being aimed at
Vector3 desiredMove = transform.forward*m_Input.y + transform.right*m_Input.x;
// get a normal for the surface that is being touched to move along it
RaycastHit hitInfo;
Physics.SphereCast(transform.position, m_CharacterController.radius, Vector3.down, out hitInfo,
m_CharacterController.height/2f, ~0, QueryTriggerInteraction.Ignore);
desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).normalized;
m_MoveDir.x = desiredMove.x*speed;
m_MoveDir.z = desiredMove.z*speed;
if (m_CharacterController.isGrounded)
{
m_MoveDir.y = -m_StickToGroundForce;
if (m_Jump)
{
m_MoveDir.y = m_JumpSpeed;
PlayJumpSound();
m_Jump = false;
m_Jumping = true;
}
}
else
{
m_MoveDir += Physics.gravity*m_GravityMultiplier*Time.fixedDeltaTime;
}
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime);
ProgressStepCycle(speed);
UpdateCameraPosition(speed);
m_MouseLook.UpdateCursorLock();
}
private void PlayJumpSound()
{
m_AudioSource.clip = m_JumpSound;
m_AudioSource.Play();
}
private void ProgressStepCycle(float speed)
{
if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0))
{
m_StepCycle += (m_CharacterController.velocity.magnitude + (speed*(m_IsWalking ? 1f : m_RunstepLenghten)))*
Time.fixedDeltaTime;
}
if (!(m_StepCycle > m_NextStep))
{
return;
}
m_NextStep = m_StepCycle + m_StepInterval;
PlayFootStepAudio();
}
private void PlayFootStepAudio()
{
if (!m_CharacterController.isGrounded)
{
return;
}
// pick & play a random footstep sound from the array,
// excluding sound at index 0
int n = Random.Range(1, m_FootstepSounds.Length);
m_AudioSource.clip = m_FootstepSounds[n];
m_AudioSource.PlayOneShot(m_AudioSource.clip);
// move picked sound to index 0 so it's not picked next time
m_FootstepSounds[n] = m_FootstepSounds[0];
m_FootstepSounds[0] = m_AudioSource.clip;
}
private void UpdateCameraPosition(float speed)
{
Vector3 newCameraPosition;
if (!m_UseHeadBob)
{
return;
}
if (m_CharacterController.velocity.magnitude > 0 && m_CharacterController.isGrounded)
{
m_Camera.transform.localPosition =
m_HeadBob.DoHeadBob(m_CharacterController.velocity.magnitude +
(speed*(m_IsWalking ? 1f : m_RunstepLenghten)));
newCameraPosition = m_Camera.transform.localPosition;
newCameraPosition.y = m_Camera.transform.localPosition.y - m_JumpBob.Offset();
}
else
{
newCameraPosition = m_Camera.transform.localPosition;
newCameraPosition.y = m_OriginalCameraPosition.y - m_JumpBob.Offset();
}
m_Camera.transform.localPosition = newCameraPosition;
}
private void GetInput(out float speed)
{
// Read input
float horizontal = CrossPlatformInputManager.GetAxis("Horizontal");
float vertical = CrossPlatformInputManager.GetAxis("Vertical");
bool waswalking = m_IsWalking;
#if !MOBILE_INPUT
// On standalone builds, walk/run speed is modified by a key press.
// keep track of whether or not the character is walking or running
m_IsWalking = !Input.GetKey(KeyCode.LeftShift);
#endif
// set the desired speed to be walking or running
speed = m_IsWalking ? m_WalkSpeed : m_RunSpeed;
m_Input = new Vector2(horizontal, vertical);
// normalize input if it exceeds 1 in combined length:
if (m_Input.sqrMagnitude > 1)
{
m_Input.Normalize();
}
// handle speed change to give an fov kick
// only if the player is going to a run, is running and the fovkick is to be used
if (m_IsWalking != waswalking && m_UseFovKick && m_CharacterController.velocity.sqrMagnitude > 0)
{
StopAllCoroutines();
StartCoroutine(!m_IsWalking ? m_FovKick.FOVKickUp() : m_FovKick.FOVKickDown());
}
}
private void RotateView()
{
m_MouseLook.LookRotation (transform, m_Camera.transform);
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
//dont move the rigidbody if the character is on top of it
if (m_CollisionFlags == CollisionFlags.Below)
{
return;
}
if (body == null || body.isKinematic)
{
return;
}
body.AddForceAtPosition(m_CharacterController.velocity*0.1f, hit.point, ForceMode.Impulse);
}
}
}
@Zakkary19, i too am having these exact errors, been looking for an answear for 5 - 6 hours for my spacegame, im using the photon service ins$$anonymous$$d but, the errors are the same, i think it has to do with the main camera being disabled when the fps controller script tries to acess it causing it to return null. please anyone tell me if you got an answear because i cant find a way to make it start the script later so that the camera is on or whatever the problem is... and i need to give a copy to someone thats on vacation here, he leaves friday, goddamn unity, not writing good and descriptive error messages.
Answer by Cynikal · Nov 03, 2016 at 02:27 PM
NullReference = The Camera is NOT being assigned.
Have it be because your isLocalPlayer is not coming as true, or the camera name it's looking for is wrong.
Answer by corbinivon · Nov 03, 2016 at 02:14 PM
Hello @Zakkary19 . I Just had this issue myself and stumbled across the answer for myself. Here is what I think that you should do: 1) In your --PlayerNetworkSetup.cs--, under --void Start()--, get rid of all the code that disables the camera entirely. 2) In your --FirstPersonController.cs--, Right after line 63, add the following code. It worked for me.
if (!isLocalPlayer)
{
m_Camera.enabled = false;
return;
}
m_Camera.enabled = true;
This will fix the error, but do note that there will be more problems.