- Home /
NullReferenceException in build not in editor,NullReferenceException in builds not in editor
Hey, thanks for taking the time to read this.
Getting a NullReferenceException on my Windows Standalone x86_64 build. Using Development Build and Script Debugging I have found the following error:
NullReferenceException
at (wrapper managed-to-native) UnityEngine.GameObject.get_transform(UnityEngine.GameObject)
at Paddles.AutomatePaddles (System.Single deltaSpeed) [0x00001] in E:\Unity\Quad Pong Xtreme\Assets\Script\Paddles.cs:79
at Paddles.Update () [0x00033] in E:\Unity\Quad Pong Xtreme\Assets\Script\Paddles.cs:32
(Filename: E:/Unity/Quad Pong Xtreme/Assets/Script/Paddles.cs Line: 79)
What confuses me is that this refers to a very straightforward line of code:
Vector3 ballPositionV3 = ball.transform.position;
In case it's useful, here's the whole script. The variable ball is set in the inspector;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Paddles : MonoBehaviour
{
[SerializeField] List <GameObject> balls = new List<GameObject>();
[SerializeField] bool isAutomated;
[SerializeField] float paddleSpeed = 15f;
[SerializeField] float paddleLimit = 3.2f;
[SerializeField] float aiSenseRange = 3.7f;
[SerializeField] GameObject ball;
float moveX;
float moveY;
ParticleSystem ps;
GameplayManager gm;
float aiDetectionPoint;
private void Start()
{
gm = FindObjectOfType<GameplayManager>();
aiDetectionPoint = paddleLimit - aiSenseRange;
ps = transform.GetChild(0).GetChild(0).gameObject.GetComponent<ParticleSystem>();
}
private void LateUpdate()
{
float deltaSpeed = paddleSpeed * Time.deltaTime;
if(gm.GetCurrentSceneName() == "Preload" || isAutomated) {
transform.Translate(AutomatePaddles(deltaSpeed));
} else {
PlayerInput(deltaSpeed);
PaddleMove();
}
ApplyPaddleLimit();
}
void PlayerInput(float deltaSpeed) {
moveX = Input.GetAxis("Horizontal") * deltaSpeed;
moveY = Input.GetAxis("Vertical") * deltaSpeed;
}
void PaddleMove() {
switch(tag) {
case "Bounce Horizontal":
transform.Translate(moveX, 0, 0);
break;
case "Bounce Vertical":
transform.Translate(0, moveY, 0);
break;
}
}
void ApplyPaddleLimit() {
Vector3 position = transform.position;
switch(tag) {
case "Bounce Vertical":
if(transform.position.y > paddleLimit) {
position.y = paddleLimit;
} else if(transform.position.y < -paddleLimit) {
position.y = -paddleLimit;
}
break;
case "Bounce Horizontal":
if(transform.position.x > paddleLimit) {
position.x = paddleLimit;
} else if(transform.position.x < -paddleLimit) {
position.x = -paddleLimit;
}
break;
}
transform.position = position;
}
Vector2 AutomatePaddles(float deltaSpeed) {
Vector3 ballPositionV3 = ball.transform.position; // <-- Line 79
Vector2 ballPosition = new Vector2(ballPositionV3.x, ballPositionV3.y);
Vector2 ballVelocity = ball.GetComponent<Rigidbody2D>().velocity;
Vector2 translate = new Vector2(0, 0);
switch(tag) {
case "Bounce Vertical":
if((ballVelocity.x < 0 && ballPosition.x < -aiDetectionPoint) || (ballVelocity.x > 0 && ballPosition.x > aiDetectionPoint)) {
translate.y = ballPosition.y - transform.position.y;
if(Mathf.Abs(translate.y) > deltaSpeed) {
if(translate.y < 0) {
translate.y = -deltaSpeed;
} else {
translate.y = deltaSpeed;
}
}
}
break;
case "Bounce Horizontal":
if((ballVelocity.y > 0 && ballPosition.y > aiDetectionPoint) || (ballVelocity.y < 0 && ballPosition.y < -aiDetectionPoint)) {
translate.x = ballPosition.x - transform.position.x;
if(Mathf.Abs(translate.x) > deltaSpeed) {
if(translate.x < 0) {
translate.x = -deltaSpeed;
} else {
translate.x = deltaSpeed;
}
}
}
break;
}
return translate;
}
public void PrepareToDestroyPaddle() {
GetComponent<SpriteRenderer>().color = new Color(1, 1, 1, 0);
ps.Play();
Invoke("Kill", 2);
}
void Kill() {
Destroy(gameObject);
}
}
,Hey, thanks for taking the time to read this.
I actually want this as a WebGL build, but even in dev mode, the WebGL wasn't giving me a usable set of errors, so I did a Windows build with dev and script debugging on. The below is the error that is caught, followed by the very simple code it references
NullReferenceException
at (wrapper managed-to-native) UnityEngine.GameObject.get_transform(UnityEngine.GameObject)
at Paddles.AutomatePaddles (System.Single deltaSpeed) [0x00001] in E:\Unity\Quad Pong Xtreme\Assets\Script\Paddles.cs:79
at Paddles.Update () [0x00033] in E:\Unity\Quad Pong Xtreme\Assets\Script\Paddles.cs:32
(Filename: E:/Unity/Quad Pong Xtreme/Assets/Script/Paddles.cs Line: 79)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Paddles : MonoBehaviour
{
[SerializeField] List <GameObject> balls = new List<GameObject>();
[SerializeField] bool isAutomated;
[SerializeField] float paddleSpeed = 15f;
[SerializeField] float paddleLimit = 3.2f;
[SerializeField] float aiSenseRange = 3.7f;
[SerializeField] GameObject ball;
float moveX;
float moveY;
ParticleSystem ps;
GameplayManager gm;
float aiDetectionPoint;
private void Start()
{
gm = FindObjectOfType<GameplayManager>();
aiDetectionPoint = paddleLimit - aiSenseRange;
ps = transform.GetChild(0).GetChild(0).gameObject.GetComponent<ParticleSystem>();
}
private void LateUpdate()
{
float deltaSpeed = paddleSpeed * Time.deltaTime;
if(gm.GetCurrentSceneName() == "Preload" || isAutomated) {
transform.Translate(AutomatePaddles(deltaSpeed));
} else {
PlayerInput(deltaSpeed);
PaddleMove();
}
ApplyPaddleLimit();
}
void PlayerInput(float deltaSpeed) {
moveX = Input.GetAxis("Horizontal") * deltaSpeed;
moveY = Input.GetAxis("Vertical") * deltaSpeed;
}
void PaddleMove() {
switch(tag) {
case "Bounce Horizontal":
transform.Translate(moveX, 0, 0);
break;
case "Bounce Vertical":
transform.Translate(0, moveY, 0);
break;
}
}
void ApplyPaddleLimit() {
Vector3 position = transform.position;
switch(tag) {
case "Bounce Vertical":
if(transform.position.y > paddleLimit) {
position.y = paddleLimit;
} else if(transform.position.y < -paddleLimit) {
position.y = -paddleLimit;
}
break;
case "Bounce Horizontal":
if(transform.position.x > paddleLimit) {
position.x = paddleLimit;
} else if(transform.position.x < -paddleLimit) {
position.x = -paddleLimit;
}
break;
}
transform.position = position;
}
Vector2 AutomatePaddles(float deltaSpeed) {
Vector2 ballPosition = ball.transform.position; <---- Line 79
Vector2 ballVelocity = ball.GetComponent<Rigidbody2D>().velocity;
Vector2 translate = new Vector2(0, 0);
switch(tag) {
case "Bounce Vertical":
if((ballVelocity.x < 0 && ballPosition.x < -aiDetectionPoint) || (ballVelocity.x > 0 && ballPosition.x > aiDetectionPoint)) {
translate.y = ballPosition.y - transform.position.y;
if(Mathf.Abs(translate.y) > deltaSpeed) {
if(translate.y < 0) {
translate.y = -deltaSpeed;
} else {
translate.y = deltaSpeed;
}
}
}
break;
case "Bounce Horizontal":
if((ballVelocity.y > 0 && ballPosition.y > aiDetectionPoint) || (ballVelocity.y < 0 && ballPosition.y < -aiDetectionPoint)) {
translate.x = ballPosition.x - transform.position.x;
if(Mathf.Abs(translate.x) > deltaSpeed) {
if(translate.x < 0) {
translate.x = -deltaSpeed;
} else {
translate.x = deltaSpeed;
}
}
}
break;
}
return translate;
}
public void PrepareToDestroyPaddle() {
GetComponent<SpriteRenderer>().color = new Color(1, 1, 1, 0);
ps.Play();
Invoke("Kill", 2);
}
void Kill() {
Destroy(gameObject);
}
}
ball cannot be found? ok easiest way i found to fix this across both build and non build is do a simple check in Awake or start:
void Awake()
{
if(ball == null)
{
ball = GameObject.FindObjectOfType<Ball>(); // if it has a script on it, otherwise
//ball = GameObject.FindGameObjectWithTag("Ball");// then add this tag to the ball.
}
}
oh looks like after looking at code a bit your getting the ball from a list of possible balls, so when you Instantiate the ball from the list set:
ball = balls[selection];
If thats the only error you are getting try that make a new build and see if it solves the issue or if a new one arises.
I personally don't like setting things in the inspector that much and i make my code do as much of the work as possible so when i hit play the code populates with the available scene objects or in not found will load a prefab and instantiate when called like a window panel for example. It's just one way of doing things. Yes, it's a lot more code but i enjoy writing code so that's not a problem to $$anonymous$$$$anonymous$$ It's not for everyone but if you always make your code do the work, you have less of a chance of a null reff error upon build :)
Answer by vurtual · Jan 13, 2021 at 07:03 PM
Thanks for the advice. I have done various builds - WebGL, WebGL with dev mode, Windows Standalone, Windows Standalone with dev mode, Windows Standalone with dev mode and script debugging, all so far without success.
I hope I've understood your suggestion properly, I now have:
// variable declarations
[SerializeField] GameObject ballPrefab;
// in the Start() method
if(ballPrefab == null) {
ballPrefab = Resources.Load("Prefabs/Ball") as GameObject;
}
// in the Update method
if(gm.balls.Count <=0) { //gm being the gameplay manager
Instantiate(ballPrefab, Vector3.zero, Quaternion.identity);
}
It still works in the editor, and fails in the Windows build, with this error:
ArgumentException: The Object you want to instantiate is null.
at UnityEngine.Object.CheckNullArgument (System.Object arg, System.String message) [0x00009] in <cbc2a4dc69734303bc7c8542260e1c75>:0
at UnityEngine.Object.Instantiate (UnityEngine.Object original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) [0x00001] in <cbc2a4dc69734303bc7c8542260e1c75>:0
at UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) [0x00001] in <cbc2a4dc69734303bc7c8542260e1c75>:0
at PreloadManager.Update () [0x00033] in E:\Unity\Quad Pong Xtreme\Assets\Script\PreloadManager.cs:49
so what do I attempt next?
I've solved this. Simply put, the syntax for Resources.Load has changed from what I had found, and the prefab has to be in a folder named Resources in the Assets folder. It can be in a further subfolder though. I put my ball prefab in Assets/Resources/Prefabs and used the following code:
ball = Resources.Load<GameObject>("Prefabs/Ball");
I do have to work out how to do the same for Audio now, but that's a new question/
Thank you to @zareda-games for getting me on the right track
Answer by NathoSteveo · Jan 14, 2021 at 10:50 AM
it's good to keep mind if using models through script to enable read/write
Your answer
Follow this Question
Related Questions
Touch in WebGL on Windows, STILL broken? 2 Answers
Debugging WebGL/Windows Standalone 0 Answers
Why is Debug.Log so much slower on Windows than Mac? 3 Answers
WebGL build size is much smaller compared to PC build size 0 Answers
Using unity as a library for creating windows, mac and web application 0 Answers