Multiplayer Player Prefab or Camera Script: NullReferenceException

Hi!

I have a problem! I want to test multiplayer a little bit so i set up a scene with network manager and the network identity on the player prefab! i dragged the player prefab in the slot in the network manager! the camera control is seperatly and not connected with the player prefab! offline everything works ok, but when i start the multiplayer test i get the following NullReferenceException:

NullReferenceException: Object reference not set to an instance of an object CameraOrbit.Start () (at Assets/Scripts/Camera Scripts/CameraOrbit.cs:29)

NullReferenceException: Object reference not set to an instance of an object CameraOrbit.HandleCamera () (at Assets/Scripts/Camera Scripts/CameraOrbit.cs:64) CameraOrbit.Update () (at Assets/Scripts/Camera Scripts/CameraOrbit.cs:45)

Player Movement is working correctly but the camera wont. ive tried several things now but i cant find the right solution. the error occurs in the camera script. CameraOrbit.cs und CameraZoom.cs are attached to the MainCamera. MainCamera is NOT attached to the player!

     using System.Collections;
     using System.Collections.Generic;
     using UnityEngine;
   
     public class CameraOrbit : Orbit {
   
         public Vector3 targetOffset = new Vector3 (0, 2, 0);
         public Vector3 cameraPositionZoom = new Vector3 (-0.5f, 0, 0);
         public float cameraLenght = -10f;
         public float cameraLenghtZoom = -5f;
         public Vector2 orbitSpeed = new Vector2 (0.01f, 0.01f);
         public Vector2 orbitOffset = new Vector2 (0, -0.8f);
         public Vector2 angleOffset = new Vector2 (0, -0.25f);
   
         private float _zoomValue;
         private Vector3 _cameraPositionTemp;
         private Vector3 _cameraPosition;
   
         private Transform _playerTarget;
         private Camera _mainCamera;
   
         void Awake ()
         {
           
         }
   
         // Use this for initialization
         void Start () {
                 _playerTarget = GameObject.FindGameObjectWithTag ("Player").transform;
   
                 sphericalVectorData.Lenght = cameraLenght;
                 sphericalVectorData.Azimuth = angleOffset.x;
                 sphericalVectorData.Zenith = angleOffset.y;
   
                 _mainCamera = Camera.main;
   
                 _cameraPositionTemp = _mainCamera.transform.localPosition;
                 _cameraPosition = _cameraPositionTemp;
   
         }
       
         // Update is called once per frame
         void Update () {
   
             HandleCamera ();
         }
   
         void HandleCamera ()
         {
             if ( Input.GetMouseButton (1) )
             {
                 sphericalVectorData.Azimuth += Input.GetAxis ("Mouse X") * orbitSpeed.x;
                 sphericalVectorData.Zenith += Input.GetAxis ("Mouse Y") * orbitSpeed.y;
   
                 sphericalVectorData.Zenith = Mathf.Clamp (sphericalVectorData.Zenith + orbitOffset.x, orbitOffset.y, 0f);
             }
   
                 float distanceToObject = _zoomValue;
                 float deltaDistance = Mathf.Clamp (_zoomValue, distanceToObject, -distanceToObject);
                 sphericalVectorData.Lenght += (deltaDistance - sphericalVectorData.Lenght);
   
                 Vector3 lookAt = targetOffset;
   
                 lookAt += _playerTarget.position;
   
                 base.Update ();
   
                 transform.position += lookAt;
                 transform.LookAt (lookAt);
   
                 if ( _zoomValue == cameraLenghtZoom )
                 {
                     Quaternion targetRotation = transform.rotation;
                     targetRotation.x = 0f;
                     targetRotation.z = 0f;
                     _playerTarget.rotation = targetRotation;
                 }
   
                 _cameraPosition = _cameraPositionTemp;
                 _zoomValue = cameraLenght;
         }
     }

ive tried to set the _playerTarget variable public and i saw that this variable stays empty after start. i think thats the problem. can anyone help? Thank you

if i write in the update function

if ( _playerTarget == null )
{
_playerTarget = GameObject.FindGameObjectWithTag (“Player”).transform;
}

it will work, but at the start i get still the eorror message until the player spawns. is there any other solution for this? what do i wrong? :slight_smile:

Do it in OnStartClient instead of Start, but you’ll have to make your orbit script inherit from NetworkBehaviour.

Thank you for that advice :slight_smile: The error is gone, but the _playerTarget variable is still empty and the camera dont work when the player prefab spawned :frowning:

You can try something like this.

GameObject player = FindObjectOfType<NetworkManager>().client.connection.playerControllers[0].gameObject;

Thank you! Now the variable will be filled with the correct data! Everything works fine instead the camera :frowning:

The problem is, the camera is not attached to the playerprefab and if i connect with 2 local players, i can only handle the “host” camera with every single client. ive tried several things now, but nothing worked correctly.

These are my scripts … nothing works for seperate camera control for local players

CharacterMovement.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class CharacterMovement : NetworkBehaviour {

    private MovementMotor motor;

    public float moveMagnitude = 0.05f;
    public float speed = 0.7f;
    public float speedMoveWhileAttack = 0.1f;
    public float speedAttack = 1.5f;
    public float turnSpeed = 10f;
    public float speedJump = 20f;

    private float speedMoveMultiplier = 1f;

    private Vector3 direction;

    private Animator anim;
    public Camera mainCamera;

    private string PARAMETER_STATE = "State";


    void Awake ()
    {
        motor = GetComponent<MovementMotor> ();
        anim = GetComponent<Animator> ();
        anim.SetInteger (PARAMETER_STATE, 0);
        //mainCamera.enabled = false;
    }

    // Use this for initialization
    void Start () {
        anim.applyRootMotion = false;
        Instantiate (mainCamera, this.transform);
        if ( isLocalPlayer )
        {

            mainCamera = Camera.main;
            GameObject.Find ("Main Camera").gameObject.transform.IsChildOf(this.transform);
            mainCamera.enabled = false;
        }

    }

    public override void OnStartLocalPlayer ()
    {
        mainCamera.enabled = true;
    }

    // Update is called once per frame
    void FixedUpdate ()
    {
        if ( isLocalPlayer)
        {
            MovementAndJumping ();
        }
    }

    private Vector3 MoveDirection
    {
        get { return direction; }
        set { direction = value * speedMoveMultiplier;

            if ( direction.magnitude > 0.1f )
            {
                var newRotation = Quaternion.LookRotation (direction);
                transform.rotation = Quaternion.Lerp (transform.rotation, newRotation, Time.deltaTime * turnSpeed);
            }

            direction *= speed * (Vector3.Dot (transform.forward, direction) + 1f) * 5f;
            motor.Move (direction);

            AnimationMove (motor.charController.velocity.magnitude * 0.1f);
        }
    }

    void Moving (Vector3 dir, float mult)
    {
        speedMoveMultiplier = 1 * mult;
        MoveDirection = dir;
    }

    void Jump ()
    {
        anim.SetInteger (PARAMETER_STATE, 2);
        motor.Jump (speedJump);
    }

    void AnimationMove (float magnitude)
    {
        if ( magnitude > moveMagnitude )
        {
            float speedAnimation = magnitude * 2f;

            if ( speedAnimation < 1f )
            {
                speedAnimation = 1f;
            }

            if ( anim.GetInteger (PARAMETER_STATE) != 3 )
            {
                anim.SetInteger (PARAMETER_STATE, 1);
                anim.speed = speedAnimation;
            }
        }
        else
        {
            if ( anim.GetInteger (PARAMETER_STATE) != 3 )
            {
                anim.SetInteger (PARAMETER_STATE, 0);
                anim.Play ("Idle");
            }
           
        }
    }


        void MovementAndJumping ()
        {
            Vector3 moveInput = Vector3.zero;
            Vector3 forward = Quaternion.AngleAxis (-90, Vector3.up) * mainCamera.transform.right;

            moveInput += forward * Input.GetAxis ("Vertical");
            moveInput += mainCamera.transform.right * Input.GetAxis ("Horizontal");

            moveInput.Normalize ();
            Moving (moveInput.normalized, 1f);

        if ( Input.GetKeyDown (KeyCode.Space))
        {
            Jump ();
        }


        }
    }

MovementMotor.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MovementMotor : MonoBehaviour {

    public float gravityMultiplier = 1f;
    public float lerpTime = 10f;

    private Vector3 moveDirection = Vector3.zero;
    private Vector3 targetDirection = Vector3.zero;
    private float fallVelocity = 0f;

    [HideInInspector]
    public CharacterController charController;

    public float distanceToGround = 0.1f;

    private bool isGrounded;

    private Collider myCollider;

    void Awake ()
    {
        charController = GetComponent<CharacterController> ();
        myCollider = GetComponent<Collider> ();
    }

    // Use this for initialization
    void Start () {
        distanceToGround = myCollider.bounds.extents.y;
    }
   
    // Update is called once per frame
    void Update () {
        isGrounded = OnGroundCheck ();

        moveDirection = Vector3.Lerp (moveDirection, targetDirection, Time.deltaTime * lerpTime);
        moveDirection.y = fallVelocity;

        charController.Move (moveDirection * Time.deltaTime);

        if ( !isGrounded )
        {
            fallVelocity -= 90f * gravityMultiplier * Time.deltaTime;
        }
    }

    public bool OnGroundCheck ()
    {
        RaycastHit hit;

        if ( charController.isGrounded )
        {
            return true;
        }

        if(Physics.Raycast(myCollider.bounds.center, -Vector3.up, out hit, distanceToGround + 0.1f) )
        {
            return true;
        }

        return false;
    }

    public void Move(Vector3 dir)
    {
        targetDirection = dir;
    }

    public void Stop ()
    {
        moveDirection = Vector3.zero;
        targetDirection = Vector3.zero;
    }

    public void Jump(float jumpSpeed)
    {
        if ( isGrounded )
        {
            fallVelocity = jumpSpeed;
        }
    }
}

CameraOrbit.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class CameraOrbit : Orbit{

    public Vector3 targetOffset = new Vector3 (0, 2, 0);
    public Vector3 cameraPositionZoom = new Vector3 (-0.5f, 0, 0);
    public float cameraLenght = -10f;
    public float cameraLenghtZoom = -5f;
    public Vector2 orbitSpeed = new Vector2 (0.01f, 0.01f);
    public Vector2 orbitOffset = new Vector2 (0, -0.8f);
    public Vector2 angleOffset = new Vector2 (0, -0.25f);

    private float _zoomValue;
    private Vector3 _cameraPositionTemp;
    private Vector3 _cameraPosition;

    public Transform _playerTarget;
    private Camera _mainCamera;

    void Awake ()
    {
   
    }

    // Use this for initialization
    void Start () {

        _playerTarget = GameObject.FindGameObjectWithTag ("Player").transform;
   
        sphericalVectorData.Lenght = cameraLenght;
        sphericalVectorData.Azimuth = angleOffset.x;
        sphericalVectorData.Zenith = angleOffset.y;

        _mainCamera = Camera.main;

        _cameraPositionTemp = _mainCamera.transform.localPosition;
        _cameraPosition = _cameraPositionTemp;
    }
   
    // Update is called once per frame
    void Update () {

        if ( _playerTarget == null )
        {
            _playerTarget = GameObject.FindGameObjectWithTag ("Player").transform;
        }

        if (_playerTarget != null)
        {
                HandleCamera ();
        }

    }

    void HandleCamera ()
    {
        if ( Input.GetMouseButton (1))
        {
                sphericalVectorData.Azimuth += Input.GetAxis ("Mouse X") * orbitSpeed.x;
                sphericalVectorData.Zenith += Input.GetAxis ("Mouse Y") * orbitSpeed.y;

                sphericalVectorData.Zenith = Mathf.Clamp (sphericalVectorData.Zenith + orbitOffset.x, orbitOffset.y, 0f);

        }

            float distanceToObject = _zoomValue;
            float deltaDistance = Mathf.Clamp (_zoomValue, distanceToObject, -distanceToObject);
            sphericalVectorData.Lenght += (deltaDistance - sphericalVectorData.Lenght);

            Vector3 lookAt = targetOffset;

            lookAt += _playerTarget.position;

            base.Update ();

            transform.position += lookAt;
            transform.LookAt (lookAt);

            if ( _zoomValue == cameraLenghtZoom )
            {
                Quaternion targetRotation = transform.rotation;
                targetRotation.x = 0f;
                targetRotation.z = 0f;
                _playerTarget.rotation = targetRotation;
            }

            _cameraPosition = _cameraPositionTemp;
            _zoomValue = cameraLenght;
    }
}

Orbit.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class Orbit : MonoBehaviour {

    public SphericalVector sphericalVectorData = new SphericalVector (0, 0, 1);

    protected virtual void Update ()
    {
        transform.position = sphericalVectorData.Position;
    }

}