A couple of issues with pinsetter code

hi
I am having 2 issues with the Pinsetter code at this point.

  1. when playtesting game I get this : " NullReferenceException: Object reference not set to an instance of an object
    PinSetter.Update () (at Assets/Scripts/PinSetter.cs:28)"

yet I have same as Ben yet he doesn’t get this Null Refrence

  1. I have animations working great for tidy and reset while using buttons. But I cannot get script to actvate animations for tidy or reset.

the spelling is exactly the same for both so I know that is not the issue.

  1. View does not always reset to beginning view of lane.

Michael


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PinSetter : MonoBehaviour {

    public int lastStandingCount = -1;
	public Text standingDisplay;
	public float distanceToRaise = 1f;
	public float distanceToLower = -1f;
	public GameObject pinSet;

	private Ball ball;
    private float lastChangeTime;
    private int lastSettledCount = 10;
    private bool ballEnteredBox = false;
    private ActionMaster actionMaster = new ActionMaster();
    private Animator animator;

	// Use this for initialization
	void Start () {
	   ball = GameObject.FindObjectOfType<Ball> ();
	   animator = GetComponent<Animator> ();
		}

	void Update () {
	  standingDisplay.text = CountStanding ().ToString ();

	  if (ballEnteredBox) {
	   UpdateStandingCountAndSettle();
	  }
	}

	public void RaisePins () {
		foreach (Pin pin in GameObject.FindObjectsOfType<Pin>()){
		pin.RaiseIfStanding();
	   }
	}

	public void LowerPins () {
		foreach (Pin pin in GameObject.FindObjectsOfType<Pin>()){
		pin.Lower();
	   }
	}

	public void ResetPins () {
		Instantiate (pinSet, new Vector3 (-5f, 20f, 1843f), Quaternion.identity);
	}


	void UpdateStandingCountAndSettle () {
	 // Update the standing count
	 // Call PinsHaveSettled() when they have 
	 int currentStanding = CountStanding ();

	 if (currentStanding != lastStandingCount) {
	       lastChangeTime = Time.time;
	       lastStandingCount = currentStanding;
	       return;
	   }

	   float settleTime = 3f; //How ;long to settle time for pins settled
	   if ((Time.time - lastChangeTime) > settleTime) {
	      PinsHaveSettled();
	   }
	}

	void PinsHaveSettled () {
	  int standing = CountStanding ();
	  int pinFall = lastSettledCount - standing ();
	  lastSettledCount = standing;

	  ActionMaster.Action action = actionMaster.Bowl (pinFall);

	  if (action == ActionMaster.Action.Tidy) {
	    animator.SetTrigger ("tidyTrigger");
	  } else if (action  == ActionMaster.Action.EndTurn) {
			animator.SetTrigger ("resetTrigger");
		} else if (action  == ActionMaster.Action.Reset) {
			animator.SetTrigger ("resetTrigger");
		} else if (action  == ActionMaster.Action.EndGame) {
			throw new UnityException ("Don't know how to handle this");
	  }

	  ball.Reset ();
	  lastStandingCount = -1;
	  ballEnteredBox = false;
	  standingDisplay.color = Color.blue;
	}


	int CountStanding () {
	 int standing = 0;

	 foreach (Pin pin in GameObject.FindObjectsOfType<Pin>()){
	     if (pin.IsStanding()) {
	      standing++;
	     }
	  }

	  return standing;
	} 

	void OnTriggerEnter (Collider collider) {
	 GameObject thingHit = collider.gameObject;

	 //Ball enters play box//
	 if (thingHit.GetComponent<Ball> ()) {
	     ballEnteredBox = true;
	     standingDisplay.color = Color.red;
	    }

 }
}

Hi Michael,

For item 1, if you are getting a NullReferenceException here, most likely you haven’t dragged the UI Text GameObject into the Standing Display field, exposed by your code;

public Text standingDisplay;

For item 2, if you are confident (and have checked) that the names of the triggers are spelled correctly (and are the same from a case-sensitive perspective), I’d add some Debug.Log statements within if statement inside the PinsHaveSettled method, one for the if and one for each of the else if conditions and see what, if anything, gets output.

Regarding item 3, under which circumstances does it not, are they always the same?

Hi Rob
thanks for replying.

  1. the standing count is added to standing display and does update with pins count etc.

  2. I cannot use debug because of the first issue filling my console when game is playing.

  3. now it is not resetting the ball at all.

Let’s comment out the code that is getting repeatedly called in item 1 then…

void Update () 
{
    // standingDisplay.text = CountStanding ().ToString ();    // comment out this line

    if (ballEnteredBox) 
    {
        UpdateStandingCountAndSettle();
    }
}

In the above, we are commenting out line 28 which is where you NullReferenceException error was identified.

So, this should a) stop the error from appearing for now (this is not a fix obviously) and b) enable you to add the Debug.Log statements for item 2.

Note, if you collapse the items displayed in the console, you will not really need to comment out the line above, as the repeated issues will just increase a count to the side of the unique item, e.g.

hi

I totally forgot about Collapse.

So I collapsed and saw a couple of issues after commenting out the offending line, and ironically after uncommenting them the error disappeared.

now I noticed that an error appears that I do not have an animator attached but I do.
But I have it attached to the swiper bar and not the pinsetter as that would move as per the animation instead of swiper bar. (previous lesson)

The only way to get it to work is separating the 2 items.
So now I need to figure a way to attach the swiper bar to the script instead of pinsetter collider.

I think I need to attach it to the actionMaster script.


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActionMaster {

    public enum Action { Tidy, Reset, EndTurn, EndGame };

    private int[] bowls = new int[21];
    private int bowl = 1;

    public Action Bowl (int pins) {
		if (pins < 0 || pins > 10) {
		throw new UnityException ("Invalid Pins");
		}

		  bowls [bowl - 1] = pins;

		  if (bowl == 21) {
		    return Action.EndGame;
		  }
		  //Handle last-frame special cases

		  if (bowl >= 19 && pins == 10 ) {
		      bowl++;
		      return Action.Reset;
		  }  else if  (bowl == 20 ) {
		      bowl++;
			  if (bowls[19-1]==10 && bowls[20-1]==0) {
		      return Action.Tidy;
			  } else if (bowls[19-1] + bowls[20-1] == 10) {
		      return Action.Reset;
		      } else if ( Bowl21Awarded() ) {
		       return Action.Tidy;
		      } else {
		         return Action.EndGame;
		      }
		  } 



        //if first ball of frame
        // return action tidy

        if (bowl % 2 != 0) {//midFrame (or last frame)
            if (pins == 10){
				bowl += 2;
				return Action.EndTurn;
            } else {
				bowl += 1;
				return Action.Tidy;
            }

         } else if (bowl % 2 == 0) {
         bowl += 1;
         return Action.EndTurn;
         }

        throw new UnityException("Not sure what action tyo return!");
    }


    private bool Bowl21Awarded () {
    // Remember that arrays start at 0 //
				return (bowls [19-1] + bowls [20-1] >= 10);
    }
}

Michael

1 Like

Hey,

I totally forgot about Collapse.

Bet you won’t again though :slight_smile:

So I collapsed and saw a couple of issues after commenting out the offending line, and ironically after uncommenting them the error disappeared.

So, that’s the NullReferenceException error resolved then? Item 1?

now I noticed that an error appears that I do not have an animator attached but I do.
But I have it attached to the swiper bar and not the pinsetter as that would move as per the animation instead of swiper bar. (previous lesson)

Ok, you do, but you have to remember that the error will be being generated by a specific GameObject effectively, so, from the GameObject’s perspective - you don’t.

So, this would explain why the if / else if statements weren’t triggering your animation then - item 2.

The only way to get it to work is separating the 2 items.
So now I need to figure a way to attach the swiper bar to the script instead of pinsetter collider.

I think I need to attach it to the actionMaster script.

Which lecture are you currently on Michael? Not wishing to spoil the learning process in anyway, but the end result of this section has the Swiper as a child object of the Pin Setter GameObject.

Incidentally, if you apply a little code formatting when pasting your code in to your replies, the forum will handle all of those using statements and the closing brackets etc.


See also;

Hi
I found out I had an issue on lesson 218 after Ben could have the code run the tidy and reset functions etc. without the buttons. where as mine would not work but the buttons would tidy and reset.
I could not have the swiper as a child because it would cause the pinsetter collider to move. thus destroying the pins.

I Debug.Log for the tidy, reset and end of turn functions in the script and when I added the animator to the pinsetter collider they showed up in the log.
Unfortunately the pinsetter is clearing the pins and the swiper does not work unless I press a button. If the swiper is a child of pinsetter it is not visible at all.
Michael

It sounds like it might be worth back-tracking a few lectures then, if you want to align what you have to the course.

I’m not sure if you are aware of it, but you can access GitHub to download / view the code at each stage of changes from the course - this can be quite useful for comparison purposes if you aren’t able to spot the exact lecture where the difference(s) have started from.

It’s obviously quite a long section and I would be hesitant about suggesting fixes to issues which may take you any further off course so to speak.

Here’s the link to the GitHub organisation link (may be useful for upcoming sections etc);

and here is the link to the specific repository for Bowl Master;

Specific commits can be found here, and I think you want to look around May 12, 2015;

Hope this is of some help.

HI
I have accessed all these scripts and I also have the cpompleted game downloaded but do not wish to get ahead of myself.

I think under the circumstance I need to re watch the change in animation to see what I missed as the challenge was to prevent the pinsetter from moving and destroying the pins. (which I thought I did until today)
michael

I think under the circumstance I need to re watch the change in animation to see what I missed as the challenge was to prevent the pinsetter from moving and destroying the pins. (which I thought I did until today)

Consider then which components a GameObject would require in order to effect another 3D object in the game world. :slight_smile:

I don’t know, everything I try when the swiper is a child of the pinsetter the pinsetter always moves. I even had the animation turn off pinsetter when it starts the sweep.
I re watched lesson 208 when Ben had to redo the animation and I did the exact same thing
it doesn’t work

Hi
Ok so I have spent the day trying to figure out why pins are not resetting (renewing). I have the swiper as a child of Pinsetter and it is working fine for all animations etc. Unfortunately pins are not resetting and have rebuilt the swiper a dozen times today trying to figure out what I have done.

The only thing I can come up is if swiper actually clears pins, they will not renew. The game hierarchy says they have been cloned, but they are not visible. If I turn off swiper to clear for testing (set as trigger) and swiper goes through the pins and a new set appears on top of old set (these are visible).

Michael

Privacy & Terms