Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by elmidiachi · Sep 07, 2016 at 08:01 PM · c#scripting problemnullreferenceexception

NullReference in script? Prefab is linked in inspector

Hey all! I’m a starting developer, been having fun with Unity, C# and the tutorials from Brackeys for a few weeks now. Enjoying the hell out of the Making a Multiplayer FPS tutorials from Brackeys! With help from the 14th episode, I tried to implement an UI bar to show the players stamina, instead of the fuel from the tutorial. Turns out I get a “NullReferenceException: Object reference not set to an instance of an object PlayerUI.Update () (at Assets/Scripts/PlayerUI.cs:19)”. It’s driving me crazy since the code doesn’t give any errors while building, plus, yeah I made sure the right prefabs are connected in the inspector. Still, the stamina for the sprinting works, but the bar doesn’t. Been trying a few days now, but I don’t have much hair left. So I would like some help from any of you super smart people. Anyway, this is my PlayerController:

 using UnityEngine;
 using UnityEngine.Networking;
 using System.Collections;
 [RequireComponent(typeof(PlayerMotor))]
 
 public class PlayerController : MonoBehaviour {
     [SerializeField]
     private float speed = 5f;
     [SerializeField]
     private float defaultSpeed = 5f;
     [SerializeField]
     private float runspeed = 10f;
     [SerializeField]
     private float staminaStopSpeed = 1f;
     [SerializeField]
     private float lookSensitivity = 3f;
     private bool cantSprint = false;
     private PlayerMotor motor;
     private Animator animator;
     [SerializeField]
     private float staminaAmount = 1f;
     private float staminaBurn = 0.3f;
     private float staminaRegen = 0.1f;
     private float staminaStopSec = 3f;
     //getter stamina
     public float GetStaminaAmount () {
         Debug.Log (staminaAmount);
         return staminaAmount;    
     }
     void Start () {
         motor = GetComponent<PlayerMotor>();
         animator = GetComponentInChildren<Animator>();
     }
     void Update () {
         //movement 3d vector
         float xMov = Input.GetAxis("Horizontal");
         float zMov = Input.GetAxis("Vertical");
         Vector3 movHorizontal = transform.right * xMov;
         Vector3 movVertical = transform.forward * zMov;
 
         //final movement vector
         Vector3 velocity = (movHorizontal + movVertical) * speed;
 
         //animate movement 
         animator.SetFloat("ForwardVelocity", zMov);
 
         //apply movement in player motor script
         motor.Move (velocity);
         float yRot = Input.GetAxisRaw("Mouse X");
         Vector3 rotation = new Vector3 (0f, yRot, 0f) * lookSensitivity;
 
         //apply rotation
         motor.Rotate(rotation);
 
         // CAMERA rotate
         float xRot = Input.GetAxisRaw("Mouse Y");
         float cameraRotationX = xRot * lookSensitivity;
 
         //apply camerarotation
         motor.RotateCamera(cameraRotationX);
         
         //apply run
         if (Input.GetButton ("Sprint") && cantSprint == false && staminaAmount > 0.05f) {
             //stamina burn
             staminaAmount -= staminaBurn * Time.deltaTime;
             speed = runspeed;
             animator.speed = 2f;
         } else {
             //stamina regen
             staminaAmount += staminaRegen * Time.deltaTime;
             speed = defaultSpeed;
             animator.speed = 1f;
         }
         //clamp stamina
         staminaAmount = Mathf.Clamp (staminaAmount, 0f, 1f);
         if (staminaAmount <= 0.05f) {
             cantSprint = true;
             Invoke("StaminaStop", staminaStopSec);
             animator.speed = 0.2f;
             cantSprint = false;
         }
         if (staminaAmount >= 1f) {
             speed = defaultSpeed;
             animator.speed = 1f;
         }
         //just to test if the stamina calculations are working
         GetStaminaAmount();
     }
     //stamina invoke method
     void StaminaStop() {
         speed = staminaStopSpeed;
         }
 }


Then the playerSetup script:

 using UnityEngine;
 using UnityEngine.Networking;
 [RequireComponent(typeof(PlayerManager))]
 [RequireComponent(typeof(PlayerController))]
 
 public class PlayerSetup : NetworkBehaviour {
     [SerializeField]
     Behaviour[] componentsToDisable;
     [SerializeField]
     string remoteLayerName = "RemotePlayer";
     [SerializeField]
     string dontDrawLayerName = "DontDraw";
     [SerializeField]
     GameObject playerGraphics;
     [SerializeField]
     GameObject playerUIPrefab;
     private GameObject playerUIInstance;
     Camera sceneCamera;
     
 void Start() {
         if (!isLocalPlayer) {
             DisableComponents();
             AssignRemoteLayer();
         } else {
             sceneCamera = Camera.main;
             if (sceneCamera != null) {
                 sceneCamera.gameObject.SetActive(false);
             }
             //disable player graphics for local player
             SetLayerRecursively (playerGraphics, LayerMask.NameToLayer(dontDrawLayerName));
 
             //create player UI
             playerUIInstance = Instantiate (playerUIPrefab);
             playerUIInstance.name = playerUIPrefab.name;
 
             //configure player UI
             PlayerUI ui = playerUIInstance.GetComponent<PlayerUI>();
             if (ui == null)
                 Debug.LogError ("No player UI component on player prefab");
             ui.SetController (GetComponent<PlayerController>());
         }
         GetComponent<PlayerManager>().Setup();
     }
     void SetLayerRecursively (GameObject obj, int newLayer) {
         obj.layer = newLayer;
         foreach (Transform child in obj.transform){
             SetLayerRecursively (child.gameObject, newLayer);
         }
     }
     public override void OnStartClient() {
         base.OnStartClient();
         string netID = GetComponent<NetworkIdentity>().netId.ToString();
         PlayerManager player = GetComponent<PlayerManager>();
         GameManager.RegisterPlayer(netID, player);
     }
     void AssignRemoteLayer() {
         gameObject.layer = LayerMask.NameToLayer(remoteLayerName);
     }
     void DisableComponents () {
         for (int i = 0; i < componentsToDisable.Length; i++) {
             componentsToDisable[i].enabled = false;
             }
     }
     //when destroyed
     void OnDisable () {
         Destroy (playerUIInstance);
         if (sceneCamera != null) {
             sceneCamera.gameObject.SetActive(true);
         }
         GameManager.UnRegisterPlayer(transform.name);
     }
 }

And last but not least, the playerUI script:

 using UnityEngine;
 public class PlayerUI : MonoBehaviour {
     [SerializeField]
     RectTransform StaminaFill;
     private PlayerController controller;
     public void SetController (PlayerController _controller) {
         controller = _controller;
     }
     void Start () {
         controller = GetComponent<PlayerController>();
     }
     void Update () {
         SetStaminaAmount(controller.GetStaminaAmount());
     }
     void SetStaminaAmount (float _amount) {
         StaminaFill.localScale = new Vector3 (1f, _amount, 1f);
     }
 }

So once again, the stamina calculates correct. It works. The prefabs are linked in the inspector correctly (the colored bar rect transform in the playerUI). Still, the bar doesn’t empty/ refill and I get this nullreference at the “SetStaminaAmount() in the PlayerUI Update()”, so I guess the script can’t find the right controller? Or it can’t receive the float amount from the public float in the controller OR the configure playerUI in the setup script doenst work… pff. I don’t get it! It should work right? I hope someone has the answer! Thanks in advance!

Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image doublemax · Sep 07, 2016 at 08:22 PM 0
Share

The first thing to do is to add a check for null after you get the PlayerController component. If it's null there, you know where to start looking.

The SetController() method is also suspicious. Is it possible that it gets called from somewhere and overwrites controller with a null value? Add another Debug.Log() there.

avatar image Bonfire-Boy · Sep 07, 2016 at 08:32 PM 0
Share

Does the GameObject this is running on have a PlayerController component? You could add logging after line 10 to check that it's found the controller.

avatar image Bonfire-Boy · Sep 07, 2016 at 08:36 PM 1
Share

Ah, the problem may be to do with the sequence. PlayerUI.Start won't run until PlayerSetUp.Start has finished, so it will overwrite the value you've set controller to. If you want it to keep the value set in PlayerSetUp.Start, you could remove the PlayerUI.Start function (or change its name to Awake so that it runs as soon as you instantiate it).

avatar image Lewwwer · Sep 07, 2016 at 08:43 PM 0
Share

As I can see you assign the controller 3 times. 1) In the inspector 2) PlayerSetup script 40th line 3) Start at the PlayerUI

The 3) option is what happens before the Update, so maybe it is the source of the problem. $$anonymous$$aybe the PlayerController component and the PlayerUI component are in different object. Or the other possibility is that some other code calls SetController() as doublemax mentioned.

avatar image Bonfire-Boy Lewwwer · Sep 07, 2016 at 10:14 PM 0
Share

Not in the inspector (it's private). From the code we've seen. the setting of the controller in PlayerSetup is redundant because it happens before it's set in PlayerUI.Start. $$anonymous$$y suspicion is that there's a controller component on the PlayerSetup object not the PlayerUI object.

avatar image elmidiachi · Sep 08, 2016 at 12:59 AM 0
Share

Wow :) thanks for all the answers peeps! That's really awesome! Yeah I already thought it was the PlayerController which couldnt be found, but I really didnt understand why. Now I guess it has to do with the start() functions, which one in which script comes first right? Darn. I didnt think about that. The setup and the controller are both on the same gameObject and the playerUI is instantiated with every new player joining the game. So. First thing to try tomorrow is changing the Start() from the playerUI script to Awake(). I have a feeling thats it :) can't wait to try, keep You posted!

avatar image Bonfire-Boy elmidiachi · Sep 08, 2016 at 01:07 AM 1
Share

If the PlayerUI GameObject is never going to have its own PlayerController component, then you're better off just removing its Start() function as it will confuse things.

If you want the PlayerUI to use its own PlayerController component by default (if there is one), and then have other objects be able to override that default (as you're doing when you call its SetController() from PlayerSetup.Start()), then you should change the PlayerUI.Start() to Awake()..

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Blue-Cut · Sep 07, 2016 at 08:33 PM

 SetStaminaAmount(controller.GetStaminaAmount());

At this line, the only object that could be null is clearly the 'controller'.

There are 2 ways in your code to set the variable 'controller'. The first one is in PlayerUI, method Start() :

 controller = GetComponent<PlayerController>();

And the second one in PlayerSetup, method Start() :

 ui.SetController (GetComponent<PlayerController>());

This doesn't sound good. I think that one of these two ways is doing a GetComponent<PlayerController> on a gameObject that actually doesn't have the PlayerController attached.

If the PlayerSetup is on the gameObject with the PlayerController, so delete the PlayerUI's Start().

If the PlayerUI is on the gameObject with the PlayerController, remove the line that does SetController in the PlayerSetup's Start

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image elmidiachi · Sep 08, 2016 at 07:38 PM 0
Share

Again, thanks a lot for all the replies! You really helped me out here! I changed the start method into an awake and it works! I completely understand why now, cuz with every player joining the game, a prefab UI gameObject (not a child of the player object) is instantiated. The UI script had to get the 'right' player to show the sta$$anonymous$$abar for by 'getting' the 'setter' method I wrote on one of the player scripts. However, I forgot it was being overwritten (eh, english?) by the other scripts so it had to be called first to get the right UI for a newly added player in the game! I know I didn't write that long scripts yet, but still, the length can confuse me I guess so I couldn't see what I did wrong. Learned a lot again, thank you so much!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Unable to use global Dictionary in function. "NullReferenceException" 1 Answer

Scripting Help with My Projectile System 1 Answer

HELP!!! This NullReferenceException won't go away! :( 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges