- Home /
Rocket Projectiles in Flight Simulator error
Hello all,
In an attempt to make a flight simulator, I designed a target that would be shot at by the player with rockets as well. I am also limiting the rockets to 10, as you will see in my code, so I decided not to use object pooling. I keep getting this error, which I understand what is causing it but don't have a clue how to fix it...
NullReferenceException: Object reference not set to an instance of an object
RocketMovement.Update () (at Assets/Scripts/RocketMovement.cs:23)
...which would be caused by the fact that the script wouldn't be able to reference the necessary components because it was Instantiated.
Here's the 2 scripts...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RocketMovement : MonoBehaviour
{
public GameObject rocket;
public int shotRockets = 0;
public RocketMoveAfterSpawn otherScript;
void Update()
{
if (Input.GetKeyDown("space"))
{
if (shotRockets < 11)
{
Instantiate(rocket);
rocket.name = "rocket_" + (shotRockets + 1);
rocket.transform.position = transform.position;
rocket.transform.rotation = (transform.rotation * Quaternion.Euler(0, 90, 0));
rocket.SetActive(true);
shotRockets++;
otherScript.moveRocket(rocket);
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RocketMoveAfterSpawn : MonoBehaviour
{
public bool collisionVar = false;
public float speed = 60;
public GameObject plane;
void Update()
{
speed += plane.transform.right.y * Time.deltaTime;
if (speed < 40f)
{
speed = 40f;
}
}
public void moveRocket(GameObject rocket)
{
if (transform.position.y == Terrain.activeTerrain.SampleHeight(transform.position))
{
collisionVar = true;
}
while (collisionVar == false)
{
transform.position = transform.forward * speed * 2.0f * Time.deltaTime;
}
Destroy(rocket);
}
void OnCollisionEnter(Collision collision)
{
collisionVar = true;
}
}
So in all, I have two questions...
What can I do to fix this error?
Is there a more efficient way to do this or track them?
Any recommended tutorials would help with anything anyone suggests, Thanks!
Answer by unity_ek98vnTRplGj8Q · Jul 14, 2020 at 10:26 PM
You are close here, but you don't need to have your rocket spawner script ALSO tell the rockets to move (it won't work how you have it set up anyway). Instead, just remove the call to otherScript.moveRocket(rocket) entirely. Now make sure that your RocketMoveAfterSpawn script is attached to the rocket prefab that you are spawning (I assume it already is), then just call moveRocket inside the update function of that script. There are a couple other small things you need to fix, so here are the completed scripts
public class RocketMovement : MonoBehaviour
{
public GameObject rocket;
public int shotRockets = 0;
public RocketMoveAfterSpawn otherScript;
void Update()
{
if (Input.GetKeyDown("space"))
{
if (shotRockets < 11)
{
Instantiate(rocket);
rocket.name = "rocket_" + (shotRockets + 1);
rocket.transform.position = transform.position;
rocket.transform.rotation = (transform.rotation * Quaternion.Euler(0, 90, 0));
rocket.SetActive(true); //You probably dont need this either
shotRockets++;
}
}
}
Dont use the while loop in the moveRocket function, it will crash unity!
public class RocketMoveAfterSpawn : MonoBehaviour
{
public bool collisionVar = false;
public float speed = 60;
public GameObject plane;
void Update()
{
//This is a weird calculation but I assume you are doing this on purpose
speed += plane.transform.right.y * Time.deltaTime;
if (speed < 40f)
{
speed = 40f;
}
moveRocket();
}
private void moveRocket()
{
if (transform.position.y == Terrain.activeTerrain.SampleHeight(transform.position))
{
collisionVar = true;
}
if (collisionVar == false)
{
//This looks like it should be "+=" instead of "="
transform.position = transform.forward * speed * 2.0f * Time.deltaTime;
}
else Destroy(gameObject);
}
void OnCollisionEnter(Collision collision)
{
collisionVar = true;
}
}
Just to clarify, the error you are getting is because you are using the variable "otherScript" without setting it equal to something first. Assu$$anonymous$$g the other script is on your rocket object, you could have used rocket.GetComponent() to get a reference to the otherScript to use it, but that is going in a bad direction for what you want to do
@unity_ek98vnTRplGj8Q This worked perfect! Thank you so much. I needed to do some adjustments to the original script to get the movement correct, but its perfect now! The calculation is weird for the plane movement because the model was rotated 90 degrees.
Anyways, I am encountering another issue. The OnCollisionEnter() function isn't picking up on my collisions. I know the settings get really picky, so would you $$anonymous$$d helping with that too? I'm not sure I understand that fully yet...
$$anonymous$$y Rockets and Targets both have mesh colliders and are both convex triggers. Rigidbodys both have unchecked Uses Gravity and checked IsKinematic?
And now this one too...
$$anonymous$$issingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Object.Instantiate[T] (T original) (at <e98ed0368295432e8c11e52d6243ee11>:0)
Rocket$$anonymous$$ovement.Update () (at Assets/Scripts/Rocket$$anonymous$$ovement.cs:16)
Any ideas on either?
If your colliders are triggers then you want to use OnTriggerEnter rather than OnCollisionEnter. If that still doesn't work then I would first check you collision matrix (Edit->Project Settings-> Physics) to make sure that the layers your objects are on are allowed to collide. If that still doesn't work, or they are only colliding sometimes then I can help you transition your code to use raycasting ins$$anonymous$$d of collisions for your rockets as collisions are not reliable if the object is moving too fast.
As far as the missing reference exception, it looks like the "Rocket" object you are using for instantiation has been destroyed. Is this object a prefab (that you dragged in from you project folder) or is it an object that you dragged in from the scene? If it is a prefab then you likely destroyed it accidentally. $$anonymous$$ake sure you are calling Destroy() directly on the gameobject attached to the scripts and not on another game object
Raycasting would probably be better to use now that I am thinking about it. I found out the reason it was causing that error, because it was deleting the original prefab from the hierarchy. I'm fixing that right now but I wouldn't be opposed to hearing your input on it.
Here's the updated code too...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rocket$$anonymous$$ovement : $$anonymous$$onoBehaviour
{
public GameObject rocket;
public int shotRockets = 0;
void Update()
{
if (Input.GetKeyDown("space"))
{
if (shotRockets < 11)
{
Instantiate(rocket);
rocket.name = "rocket_" + (shotRockets + 1);
rocket.transform.position = transform.position;
rocket.transform.rotation = (transform.rotation * Quaternion.Euler(0, 90, 0));
rocket.SetActive(true);
shotRockets++;
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rocket$$anonymous$$oveAfterSpawn : $$anonymous$$onoBehaviour
{
public bool collisionVar = false;
public float speed = 60;
public GameObject plane;
public GameObject explode;
void Update()
{
moveRocket();
if (transform.position.x > 1000.0f || transform.position.y > 800.0f || transform.position.z > 1000.0f || transform.position.x < 0.0f || transform.position.y < 0.0f || transform.position.z < 0.0f)
{
Destroy(gameObject);
}
}
private void moveRocket()
{
if (gameObject != null)
{
float terrainHeightAtRocketPosition = Terrain.activeTerrain.SampleHeight(transform.position);
if (terrainHeightAtRocketPosition >= transform.position.y)
{
explode.transform.position = transform.position;
explode.SetActive(true);
collisionVar = true;
Destroy(explode, 5);
}
if (collisionVar == false)
{
//This looks like it should be "+=" ins$$anonymous$$d of "="
transform.position += -transform.forward * 250.0f * Time.deltaTime;
}
if (collisionVar == true)
{
Destroy(gameObject);
}
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Target")
{
explode.transform.position = transform.position;
explode.SetActive(true);
collisionVar = true;
Destroy(explode, 5);
Destroy(collision.gameObject, 5);
}
}
}
Your answer
Follow this Question
Related Questions
"Only assignment, call, increment, decrement and new object expressions can be used as statements" 1 Answer
weird problem with scripting 1 Answer
3rd Person Camera to Rotate With the Player 0 Answers
Need help fixing my script 1 Answer
AudioSource.PlayClipAtPoint creating unlimited AudioOneShot 1 Answer