- Home /
Object Reference not set to an instance of an object only appears occasionally?
So I fire a raycast, which acts as a gun, and when it hits a bird it is supposed to explode and destroy the bird gameobject. So, here is my problem, while it always spawns the explosion and plays the sound, it doesn't always destroy the bird. And when it doesn't it leaves the all dreaded object reference not set error. This has completely stumped me, any ideas why?
I also fall through the terrain sometimes when I shoot a bird, the explosion and sound still happens, but the terrain just deletes, Im not sure if this is related or if the bird deletes when I do it, (and the terrain has the "dirt" tag)
Thanks, and here is my script and a picture of the bird gameobject inspector settings.
var hit : RaycastHit;
var dirtPrefab : GameObject;
var birdexplode : GameObject;
var muzzlePoint : Transform;
var c1 : Color = Color.grey;
var c2 : Color = Color.white;
var bulletdistance = 200000;
var lineRenderer : LineRenderer;
function Start() {
lineRenderer = gameObject.AddComponent(LineRenderer);
lineRenderer.material = new Material (Shader.Find("Particles/Additive"));
lineRenderer.SetColors(c1, c2);
lineRenderer.SetWidth(0.04,0.01);
lineRenderer.SetVertexCount(2);
}
var timer : float;
var timeToWait : float = 0.1;
function Update(){
timer += Time.deltaTime;
if(timer > timeToWait)
{
var origin = transform.position;
var direction = transform.forward;
var endPoint = origin + direction * bulletdistance;
lineRenderer.SetPosition(0, origin);
if(Input.GetButtonDown("Fire1")){
StartCoroutine("Shoot");
//lineRenderer.SetVertexCount(2);
audio.Play();
}
}
}
function Shoot(){
var fwd = muzzlePoint.TransformDirection (Vector3.forward);
if (Physics.Raycast (muzzlePoint.position, fwd, hit, bulletdistance)){
timer = 0;
endPoint = hit.point;
lineRenderer.SetPosition(1, endPoint);
if(hit.collider.gameObject.tag == "dirt"){
Instantiate(dirtPrefab, hit.point, hit.transform.rotation);
// Invoke("LineRenderClear", 1);
}
if(hit.collider.gameObject.tag == "flyinganimal"){
Invoke("destroyhit", 1.3);
hit.transform.audio.Play();
Debug.Log("YOU HIT DA BIRD");
hit.transform.gameObject.GetComponent("Seagull").enabled = false;
Instantiate(birdexplode, hit.point, hit.transform.rotation);
}
}
}
function LineRenderClear () {
// lineRenderer.SetVertexCount(0);
}
function destroyhit () {
Destroy(hit.transform.gameObject);
}
Thanks Again,
It looks to me like you should consider using the OnCollision functions to handle this.
Also, is there any particular reason why you use
StartCoroutine("Shoot");
Where should I use "oncollision" and what should I replace it with?
And no, I was really tired when I made this script, i replaced it with Invoke, thanks. Doesn't seem to change much though, it does happen less often though, not sure if its a coincidence or not. What does it change?
I dont think i could use oncollision with a raycast, can I?
Answer by meat5000 · Sep 07, 2013 at 11:35 PM
function OnCollisionEnter()
{
}
function OnCollisionStay()
{
}
function OnCollisionExit()
{
}
Basically, you pick one that is best suited for the situation.
I would try something like this, on a bird
function OnCollisionEnter(col : Collision)
{
if(col.collider.gameObject.name == "Bullet")
{
Destroy(gameObject);
}
}
Also it looks like you are mixing code.
C# ?
lineRenderer.material = new Material (Shader.Find("Particles/Additive"));
JS ?
var dirtPrefab : GameObject;
Bad JS ?
var origin = transform.position;
If you are using JS, declare your variables fully.
var origin : Vector3 = transform.position;
Also, I'm not so sure that shoot function needs to be in a coroutine at all.
again, thanks, but it's a raycast, unless there is something I don't know, a ray wont register as a collider.
As for the other things, thanks, it helped. But I still don't know why it occasionaly isn't working and how to fix it, any ideas?
Look again at the second half of the answer :P
Also, birdexplode is not being set to the object.
In the Start() routine your need to fill birdexplode with whatever the actual object is you are trying to instantiate.
You could also consider passing your hit info to the destroyhit() function as an argument.
Another point,
Invoke("destroyhit", 1.3);
A lot can happen in 1.3 seconds. The information in 'hit' may have changed by the time the function is invoked.
Also I just noticed you are not Zeroing your timer, but adding to it.
var timer : float;
timer += Time.deltaTime;
make timer = 0 in start