I'm trying to adjust the mouse sensitivity of the First Person Controller using a slider in game.

Hello, I’m trying to adjust the mouse sensitivity of the First Person Controller using a slider in game. Here’s the code I’m using:

GUI.Label(Rect(550,260,100,40), "Mouse Sensitivity");
GetComponent(MouseLook).sensitivityX = GetComponent(MouseLook).sensitivityY = GUI.HorizontalSlider(new Rect(0,0,200,50), GetComponent(MouseLook).sensitivityX, 1, 20);

Here’s the error I’m getting:

NullReferenceException: Object reference not set to an instance of an object
NetworkManagerScript.OnGUI () (at Assets/scripts/NetworkManagerScript.js:216)

NetworkManager I named early on, it’s more like the overall game manager as it currently keeps track of most of the functions currently in the game outside of the player. I should note that it’s not attached to the First Person Controller where MouseLook is.

Anybody?

Nobody?

Anybody at all?

You can only reference GUI from within the void OnGUI() function. Is that it?

Kurt

You’ve got an error in NetworkManagerScript:216 so put 216 line code here, even if it’s not attached no where compiler will throw an error if there is. Your project is compiled as whole unit, not just those parts which are on scene.

It’s in the OnGUI() function.

I did post line 216.

GetComponent(MouseLook).sensitivityX = GetComponent(MouseLook).sensitivityY = GUI.HorizontalSlider(new Rect(0,0,200,50), GetComponent(MouseLook).sensitivityX, 1, 20);

What I’m trying to do is access the MouseLook script file which contains all the functions and variables for the mouse. This is in the MouseLook script:

enum Axes {MouseXandY, MouseX, MouseY}
  var Axis : Axes = Axes.MouseXandY;
  public var sensitivityX = 15.0;
  public var sensitivityY = 15.0;
  var minimumX = -360.0;
  var maximumX = 360.0;
  var minimumY = -60.0;
  var maximumY = 60.0;
  var rotationX = 0.0;
  var rotationY = 0.0;
  var lookSpeed = 2.0;
   
  var toggle:boolean = true;
  function Update ()
  {

  if (Input.GetKeyDown ("escape"))
  {
       if (toggle)
       {
         Screen.lockCursor = false;
         Screen.showCursor = true;
         
         toggle = false;

       }
       else
       {
         Screen.lockCursor = true;
         Screen.showCursor = false;
         
         toggle = true;
       }
     }

     if (toggle)
     {
       if (Axis == Axes.MouseXandY)
    {
    // Read the mouse input axis
    rotationX += Input.GetAxis("Mouse X") * sensitivityX;
    rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
   
    // Call our Adjust to 360 degrees and clamp function
    Adjust360andClamp();
   
    // Most likely you wouldn't do this here unless you're controlling an object's rotation.
    // Call our look left and right function.
    //KeyLookAround();
   
    // Call our look up and down function.
    //KeyLookUp();
   
    // If the user isn't pressing a key to look up, transform our X angle to the mouse.
    //if (!Input.GetAxis("LookAround"))
    //{
    // If you don't want to allow a key to affect X, keep this line but take it out of the if
    transform.localRotation = Quaternion.AngleAxis (rotationX, Vector3.up);
    //}
   
    // If the user isn't pressing a key to look up, transform our Y angle to the mouse.
    //if (!Input.GetAxis("LookUp"))
    //{
    // Multiply the Quaterion so we don't loose our X we just transformed
    // If you don't want to allow a key to affect Y, keep this line but take it out of the if
    transform.localRotation *= Quaternion.AngleAxis (rotationY, Vector3.left);
    //}
    }
    else if (Axis == Axes.MouseX)
    {
    // Read the mouse input axis
    rotationX += Input.GetAxis("Mouse X") * sensitivityX;
   
    // Call our Adjust to 360 degrees and clamp function
    Adjust360andClamp();
   
    // if you're doing a standard X on object Y on camera control, you'll probably want to
    // delete the key control in MouseX. Also, take the transform out of the if statement.
    // Call our look left and right function.
    //KeyLookAround();
   
    // Call our look up and down function.
    //KeyLookUp();
   
    // If the user isn't pressing a key to look up, transform our X angle to the mouse.
    //if (!Input.GetAxis("LookAround"))
    //{
    //If you don't want to allow a key to affect X, keep this line but take it out of the if
    transform.localRotation = Quaternion.AngleAxis (rotationX, Vector3.up);
    //}
   
    }
    else
    {
    // Read the mouse input axis
    rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
   
    // Call our Adjust to 360 degrees and clamp function
    Adjust360andClamp();
   
    // Call our look left and right function.
    //KeyLookAround();
   
    // Call our look up and down function.
    //KeyLookUp();
   
    // If the user isn't pressing a key to look up, transform our Y angle to the mouse
    //if (!Input.GetAxis("LookUp"))
    //{
    // If you don't want to allow a key to affect Y, keep this line but take it out of the if
    transform.localRotation = Quaternion.AngleAxis (rotationY, Vector3.left);
    //}
   
    }
       
       if (Input.GetKeyDown ("escape")) {
         Screen.lockCursor = false;
       }
       
       if (!Screen.lockCursor && Input.GetKeyDown ("escape")) {
         Screen.lockCursor = true;
       }


     }
  }
  function KeyLookAround ()
  {
//  If you're not using it, you can delete this whole function.
//  Just be sure to delete where it's called in Update.
  // Read the mouse input axis
  rotationX += Input.GetAxis("LookAround") * lookSpeed;
  // Call our Adjust to 360 degrees and clamp function
  Adjust360andClamp();
  // Transform our X angle
  transform.localRotation = Quaternion.AngleAxis (rotationX, Vector3.up);
  }
  function KeyLookUp ()
  {
//  If you're not using it, you can delete this whole function.
//  Just be sure to delete where it's called in Update.
  // Read the mouse input axis
  rotationY += Input.GetAxis("LookUp") * lookSpeed;
  // Adjust for 360 degrees and clamp
  Adjust360andClamp();
  // Transform our Y angle, multiply so we don't loose our X transform
  transform.localRotation *= Quaternion.AngleAxis (rotationY, Vector3.left);
  }
  function Adjust360andClamp ()
  {
//  This prevents your rotation angle from going beyond 360 degrees and also
//  clamps the angle to the min and max values set in the Inspector.
  // During in-editor play, the Inspector won't show your angle properly due to
  // dealing with floating points. Uncomment this Debug line to see the angle in the console.
  // Debug.Log (rotationX);
  // Don't let our X go beyond 360 degrees + or -
  if (rotationX < -360)
  {
  rotationX += 360;
  }
  else if (rotationX > 360)
  {
  rotationX -= 360;
  }   
  // Don't let our Y go beyond 360 degrees + or -
  if (rotationY < -360)
  {
  rotationY += 360;
  }
  else if (rotationY > 360)
  {
  rotationY -= 360;
  }
  // Clamp our angles to the min and max set in the Inspector
  rotationX = Mathf.Clamp (rotationX, minimumX, maximumX);
  rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
  }
  function Start ()
  {
     Screen.lockCursor = true;
  // Make the rigid body not change rotation
  if (rigidbody)
  {
  rigidbody.freezeRotation = true;
  }
  }

Break the problem down so you can single-step the problematic line.

First do:
MouseLook ML = GetComponent();

If you breakpoint it and ML is null, that is your problem.

And then use the ML as you do above (ML.sensitivityx… etc.)

Kurt

So I created this:

var playerPrefab:GameObject;

//Mouse controls
var ML:MouseLook;

function Awake()
{
   var ML = playerPrefab.GetComponent(MouseLook);
}

and changed line 216 to this:

ML.sensitivityX = ML.sensitivityY = GUI.HorizontalSlider(new Rect(100,100,200,50), ML.sensitivityX, 1, 20);

playerPrefab has the First Person Controller in it which has the MouseLook script.

The project runs however no slider appears. These are the errors:

NullReferenceException: Object reference not set to an instance of an object
GameManager.OnGUI () (at Assets/scripts/GameManager.js:221)

Apologies for answering in C# before. Now I’m writing in Javascript.

Please see the following script, and how I made a tiny project from the Unity standard assets and got the following script working.

#pragma strict

// 2:51 PM 9/15/2014 - answering Unity3D forum:
// http://forum.unity3d.com/threads/im-trying-to-adjust-the-mouse-sensitivity-of-the-first-person-controller-using-a-slider-in-game.267462
//
// To Use This Script:
//    Import Character Controller Standard Unity Assets
//    Make a new scene
//    Delete the Main Camera
//    Drag the First Person Controller from the standard package into your scene
//    Attach this script to the root of that controller
//    Place a plane under the character to keep him from falling and give you a reference
//    Run. Notice no errors.
//    Cbeck the debug log and see what the value of MouseLook is at Awake() time

var ML:MouseLook;

function Awake ()
{
    ML = gameObject.GetComponent( MouseLook);
    // Is this perhaps what you want? If the MouseLook is not in the
    // root of the object where you put this script, this will instead find
    // it if it is in child objects.
// ML = gameObject.GetComponentInChildren(MouseLook);
  
    Debug.Log( "MouseLook: " + ML);
}

function OnGUI()
{
    ML.sensitivityX = ML.sensitivityY = GUI.HorizontalSlider(new Rect(100,100,200,50), ML.sensitivityX, 1, 20);
}

This seems to modify the sensitivity the way you would expect it should in my scene.

Kurt

I used the Debug.Log and got this:

MouseLook: FPC (MouseLook)
UnityEngine.Debug:Log(Object)
GameManager:Awake() (at Assets/scripts/GameManager.js:38)

So it is being called correctly and is accessing the right script. However the slider isn’t coming up. This is my entire GUI script:

//GUI
function OnGUI()
{
   if (!optionsMenu)
   {
     if(!Network.isClient && !Network.isServer)
     {
       playerName = GUI.TextField (Rect (btnX, btnY - 25, 200, 20), playerName, 25);
       if(GUI.Button(Rect(btnX, btnY, btnW, btnH), "Start Server"))
       {
         Debug.Log("Starting server...");
         startServer();
         optionsMenu = false;
         toggleMenu = false;
       }
 
       if(GUI.Button(Rect(btnX, btnY * 1.2 + btnH, btnW, btnH), "Refresh Hosts"))
       {
         Debug.Log("Refreshing...");
         refreshHostList();
       }
 
       if(GUI.Button(Rect(btnX, btnY * 3.4 + btnH, btnW, btnH), "Options"))
       {
         Debug.Log("Loading options...");
         optionsMenu = true;
       }
 
       if(GUI.Button(Rect(btnX, btnY * 5.6 + btnH, btnW, btnH), "Exit"))
       {
         Debug.Log("Closing game...");
         exitGame();
       }
 
       if (hostData)
       {
         for(var i:int = 0; i<hostData.length; i++)
         {
           if(GUI.Button(Rect(btnX * 2 + btnW, btnY * 1.2 + (btnH * i), btnW * 3, btnH * .5), hostData[i].gameName))
           {
             Network.Connect(hostData[i]);
             optionsMenu = false;
             toggleMenu = false;
           }
         }
       }
     }
   }

   /*else if (Input.GetKeyDown(KeyCode.Return))
   {
       chatting = true;
   }*/

   /*if (Input.GetKeyDown(KeyCode.Return) && chatting)
   {
       chatting = false;
   }*/

   if (chatting)
   {
     GUILayout.Label (log);
     myMessage = GUILayout.TextField (myMessage);
     if(GUILayout.Button ("Send Message"))
     {
       networkView.RPC("Chat", RPCMode.All, (playerName + ": " + myMessage));
     }
   }

   if (toggleMenu)
   {
     if(GUI.Button(Rect(btnX, btnY * 3.4 + btnH, btnW, btnH), "Options"))
     {
       Debug.Log("Loading options...");
       optionsMenu = true;
       toggleMenu = false;
     }

     if(GUI.Button(Rect(btnX, btnY * 5.6 + btnH, btnW, btnH), "Exit"))
     {
       Debug.Log("Closing game...");
       exitGame();
     }
   }

   if (optionsMenu)
   {
     GUI.Label(Rect(btnX, btnY - 10,150,40), "Mouse Sensitivity");
     ML.sensitivityX = ML.sensitivityY = GUI.HorizontalSlider(new Rect(btnX, btnY,200,50), ML.sensitivityX, 1, 20);
 
     if(GUI.Button(Rect(btnX, btnY * 5.6 + btnH, btnW, btnH), "Return"))
     {
       Debug.Log("Returning to main menu...");
       optionsMenu = false;
       toggleMenu = true;
     }
   }

}

The GUI.Label “Mouse Sensitivity” shows up, but not the slider. This is the error that happens when it tries to create it:

NullReferenceException: Object reference not set to an instance of an object
GameManager.OnGUI () (at Assets/scripts/GameManager.js:225)

Edit: When I create a new project and follow the instructions in the script you gave me it works fine.

Edit 2: Ah, I dragged the player prefab into the ML box in the Unity editor and it’s working now. I wonder why I needed to do that. Although it changes the sensitivity, it doesn’t update it until I close the game and go back in. It’s only changing the prefab rather than the instance.

I modified the code in an attempt to have it modify the instance rather than the prefab:

function spawnPlayer()
{
   var playerInstance = Network.Instantiate(playerPrefab, spawnObject.position, Quaternion.identity, 0);
   var ML = playerInstance.gameObject.GetComponent(MouseLook);
   Debug.Log( "Player Instance: " + playerInstance);
}
ML.sensitivityX = ML.sensitivityY = GUI.HorizontalSlider(new Rect(btnX, btnY + 20,200,50), ML.sensitivityX, 1, 10);

Didn’t work, still just modifies the prefab. According to the log it is actually accessing the instance:

MouseLook: FPC(Clone) (MouseLook)
UnityEngine.Debug:Log(Object)
NetworkManager:spawnPlayer() (at Assets/scripts/NetworkManager.js:74)
NetworkManager:OnServerInitialized() (at Assets/scripts/NetworkManager.js:82)
UnityEngine.Network:InitializeServer(Int32, Int32, Boolean)
NetworkManager:startServer() (at Assets/scripts/NetworkManager.js:57)
NetworkManager:OnGUI() (at Assets/scripts/NetworkManager.js:157)

Not sure what else to suggest. You might have to just resort to divide-and-conquer: start with the known-working script above, or start with your script, and either add or remove lines to bring one “towards” the other until things stop working, then see what you added that caused the problem.

Edit: also: if you cannot drop that known good into your project and have it work, then the problem may lie elsewhere in your project’s code.

Kurt