Jump to content
  • Advertisement
ethancodes

C# Ball appears to pass through brick intermittently

Recommended Posts

I've got a bug with my brick breaker style game. The bricks move down one line at a time ever 1.5 seconds. What appears to be happening is occasionally the ball will be just about to hit the brick when the brick moves down a line, and now the ball is behind it. I'm not sure how to fix this. I have two ideas but I'm not sure of implementation. 1 solution would be to check where they were and where they are going to be before rendering the frame. Then if they crossed paths, then register the brick as hit. Solution 2 would be change how the bricks move. I could maybe slide them down line by line, instead of a jump down. I'm not sure of this will fix the issue or not. Any ideas?

Share this post


Link to post
Share on other sites
Advertisement
Posted (edited)

Don't allow the bricks to move down during the time the ball is that close and moving up.

ED: Missed the Unity tag.

Edited by fleabay

Share this post


Link to post
Share on other sites
16 hours ago, Scouting Ninja said:

You can try the Unity LateUpdate here. You could also use OnCollisionStay2D instead of OnCollisionEnter2D.

So for LateUpdate, I would do the bricks, right? So that way we wold first check if they hit, and if they did destroy any appropriate bricks, and then the remainder would move?

Also, a friend had recommending using Lerp to just kind of slide them down so that they are not moving one whole line all at once. Moving them 1 unit over time would allow the ball to hit correctly, right? Would this be a viable solution?

Share this post


Link to post
Share on other sites
2 minutes ago, ethancodes said:

Also, a friend had recommending using Lerp to just kind of slide them down so that they are not moving one whole line all at once. Moving them 1 unit over time would allow the ball to hit correctly, right? Would this be a viable solution?

Yes very acceptable. Give this a try.

 

4 minutes ago, ethancodes said:

So for LateUpdate, I would do the bricks, right?

Yes. The way this works is it updates after everything else, so before the new cycle of physics updates start. There is more physics updates per second than frames rendered, late update often fixes collision problems in unity between none dynamic and dynamic objects.

Share this post


Link to post
Share on other sites

This appears to be working now. I do have a random error that has been happening (even before I fixed this). Occasionally I get an error AFTER ending the game, that says "Can't destroy Transform component of 'InsertAnyBrickTypeHere'. If you want to destroy the game object, please call 'Destroy' on the game object instead. Destroying the transform component is not allowed." This error shows up with no apparent pattern that I could find. It'll show up with or without explosive bricks present, whether I destroyed 1 brick or more than one, whether I hit 1 or more explosive brick, whether I end the game by losing or by hitting the stop button. It may not show up for 5-10 test plays, and then all the sudden it pops up. I have never seen it if we do not destroy any bricks. I can't figure out why it is giving this error. I checked through my Brick and ExplosiveBrick code and can't find anywhere that I'm trying to destroy a Transform. Any ideas?

Share this post


Link to post
Share on other sites
27 minutes ago, ethancodes said:

can't find anywhere that I'm trying to destroy a Transform. Any ideas?

This happens some times when you link a scene object using a public transform instead of public GameObject.

A other thing could be if you are checking for child objects, Unity often returns transforms when you ask for a child. You fix this by adding .gameObject after it.

The Unity find by name function can also return a transform.

 

With out viewing your code it is hard to tel where you are using a transform instead of a child.

Share this post


Link to post
Share on other sites

Alright this gives me an idea. I had changed the way the bricks move by putting them inside of a parent object and then moving that object. Because of this there are several places that are set up with some of the possible causes you mentioned. I'll check them all out and see if I can fix it.

Share this post


Link to post
Share on other sites
Posted (edited)

Alright I've been hunting for this error and can't figure it out to save my life. I've tried commenting out sections of code that could possibly have to do with it, but haven't had any luck stopping the error. I'll post the code and maybe you can spot what i'm missing. 

public class Brick : MonoBehaviour {

	public AudioClip crack;
	public Sprite[] hitSprites;
	public static int breakableCount = 0;
	public GameObject smoke;

	protected LevelManager levelManager;
	public int maxHits;
	public int timesHit;
	private bool isBreakable;

	// Use this for initialization
	void Start () {
		isBreakable = (this.tag == "Breakable");

		//keep track of breakable bricks
		if (isBreakable){
			breakableCount++;
		}
		timesHit = 0;
		levelManager = GameObject.FindObjectOfType<LevelManager>();
	}

	void OnCollisionEnter2D (Collision2D collision)
	{	//if brick is at end of screen, game over
		if (collision.gameObject.tag == "EndScreen") {
			levelManager = GameObject.FindObjectOfType<LevelManager>();

			levelManager.LoadLevel("Lose");
		}
		//play audio clip when ball hits brick
		AudioSource.PlayClipAtPoint (crack,transform.position);
		if (isBreakable) {
			HandleHits ();
		}
	}
	//track number of times brick is hit, destroy brick when maxHits is reached
	void HandleHits ()
	{
		timesHit++;
		maxHits = hitSprites.Length + 1;

		DestroyBrick();	
	}

	public virtual void DestroyBrick ()
	{
		if (timesHit >= maxHits) {
			breakableCount--;
			//levelManager.BrickDestroyed ();
			PuffSmoke ();
			Destroy (this.gameObject);
		} else {
			LoadSprites ();
		}
	}

	protected void LoadSprites ()
	{
		int spriteIndex = timesHit - 1;
		if (hitSprites [spriteIndex] != null) { //if statement keeps it from loading nothing if level designer forgets to assign a sprite
			this.GetComponent<SpriteRenderer> ().sprite = hitSprites [spriteIndex];
		} else {
			Debug.LogError("Brick sprite missing");
		}
	}

	protected void PuffSmoke ()
	{
		var smokePuff = Instantiate(smoke, transform.position, Quaternion.identity);
			var effect = smokePuff.GetComponent<ParticleSystem>().main;

			effect.startColor = GetComponent<SpriteRenderer>().color; 
	}
}
public class BoardManager : MonoBehaviour {


		private int columns = 20;                //Number of columns in our game board.
		private int rows = 22;  				//Number of rows in our game board. Only 16 - 22 are available for brick spawning

		public int brickCount;               //Number of bricks to spawn.
		public GameObject brickHolder;
		public GameObject target;			//location of object that bricks are moving towards
		public float speed;

		protected float delay = 5.0f;                //Delay till bricks move down 1 row.

		//Define brick types to assign sprites to in editor
		public GameObject oneHitBrick;                                
		public GameObject twoHitBrick;                                  
		public GameObject threeHitBrick;                                 
		public GameObject explodingBarrel;  //temporarily represented by the unbreakable brick

		public List<GameObject> bricks = new List<GameObject>();

		private GridSquare randomPosition;		//Position at the randomIndex
		private GridSquare[,] gridPositions = new GridSquare[20,23];   //list of positions on game board
		private List<GridSquare> gridOptions = new List<GridSquare>(); //list of options to place next brick
		private GridSquare tempPosition;


		// Use this for initialization
		void Awake ()
		{
			brickHolder = Instantiate(brickHolder, Vector3.zero,Quaternion.identity) as GameObject;
		}
		void Update ()
		{
			transform.position = Vector3.MoveTowards(transform.position, target.transform.position , speed * Time.deltaTime);
		}

		//Clears our array gridPositions and prepares it to generate a new board.
		void InitialiseList ()
		{
			//Clear our array gridPositions.
			Array.Clear(gridPositions, 0, gridPositions.Length);

			//Loop through x axis (columns).
			for(int x = 0; x < columns; x++)
			{
				//Within each column, loop through y axis (rows).
				//start at 16 to spawn our bricks offscreen
				for(int y = 0; y <= rows; y++)
				{
					bool visible = true;
					//At each index add a new Vector3 to our array with the x and y coordinates of that position.
					gridPositions[x,y] = new GridSquare(new Vector3(x,y,0), visible);
				}
			}
		}
	
		//RandomPosition returns a random position from our gridPositions array.
		GridSquare RandomPosition ()
		{
			if (AllSquaresVisible()) //check if all gridPositions are unoccupied
			{
				//set randomPosition to a random element in gridPositions array
				randomPosition = gridPositions[Random.Range(0,gridPositions.GetLength(0)),Random.Range(16,gridPositions.GetLength(1))];

				//ensures the GridSquare will not be re-used 
				randomPosition.IsVisible = false;

				//Return the randomly selected GridSquare
				return randomPosition;
			} 
				//call CheckBorders to populate list gridOptions
				CheckBorders(randomPosition); 

				//set randomPosition value to a random number between 0 and the count of items in our List gridOptions.
				randomPosition = gridOptions[Random.Range(0, gridOptions.Count)];

				//make sure the chosen GridSquare can't be re-used
				randomPosition.IsVisible = false;

				//Return the randomly selected Vector3 position.
				return randomPosition;	
			

		}
		//Check to see if all squares are visible
		private bool AllSquaresVisible ()
		{
			for (int i = 0; i < gridPositions.GetLength (0); i++)
			{
				for (int j = 16; j < gridPositions.GetLength (1); j++) 
				{
					if (!gridPositions [i, j].IsVisible) 
					{
						return false;
					}
				}
			}
			return true;
		}
		//check borders is used to check above, below, left, and right of the current GridSquare to see if those options are available for next brick, and then each
		//available option is added to list gridOptions
		public void CheckBorders (GridSquare currentPosition)
		{
			gridOptions.Clear (); //empty gridOptions list

			if (currentPosition.GridPosition.x != 0) { //check to make sure we are not on column 1, if not, check 1 column to the left. If available, set to gridOptions list
				tempPosition = gridPositions[(int)currentPosition.GridPosition.x - 1, (int)currentPosition.GridPosition.y];

				if (tempPosition.IsVisible == true) {
					gridOptions.Add (tempPosition);
				}
			}

			if (currentPosition.GridPosition.x != 19) { //check to make sure we are not on column 19, if not, check 1 column to the right. If available, set to gridOptions list
				tempPosition = gridPositions[(int)currentPosition.GridPosition.x + 1, (int)currentPosition.GridPosition.y];

				if (tempPosition.IsVisible == true) {
					gridOptions.Add (tempPosition);
				}
			}

			if (currentPosition.GridPosition.y != 16) { //check to make sure we are not on row 18, if not, check 1 row under. If available, set to gridOptions list
				tempPosition = gridPositions[(int)currentPosition.GridPosition.x, (int)currentPosition.GridPosition.y - 1];

				if (tempPosition.IsVisible == true) {
					gridOptions.Add (tempPosition);
				}
			}

			if (currentPosition.GridPosition.y != 22) { //check to make sure we are not on row 30, if not, check 1 row up. If available, set to gridOptions list
				tempPosition = gridPositions[(int)currentPosition.GridPosition.x, (int)currentPosition.GridPosition.y + 1];

				if (tempPosition.IsVisible == true) {
					gridOptions.Add (tempPosition);
				}
			}
		}

		//LayoutObjectAtRandom accepts an array of game objects to choose from along with a minimum and maximum range for the number of objects to create.
		void LayoutObjectAtRandom (int brickCount)
		{
			bricks.Add(oneHitBrick);
			bricks.Add(twoHitBrick);
			bricks.Add(threeHitBrick);
			bricks.Add(explodingBarrel);

			//Instantiate objects until the randomly chosen limit objectCount is reached
			for(int i = 0; i < brickCount; i++)
			{
				//Choose a position for randomPosition by getting a random position from our list of available Vector3s stored in gridPosition
				GridSquare selectedPosition = RandomPosition();

				GameObject brick = bricks[Random.Range(0,bricks.Count)];

				//Instantiate tileChoice at the position returned by RandomPosition with no change in rotation
				selectedPosition.AssociatedBrick = Instantiate(brick, selectedPosition.GridPosition, Quaternion.identity, brickHolder.transform);

			}
		}


		//SetupScene initializes our level and calls the previous functions to lay out the game board
		public void SetupScene (int level)
		{
			//Reset our list of gridpositions.
			InitialiseList ();

			brickCount = (int)Mathf.Log(level, 2f); //set the number of bricks based on the current level

			//Instatiate random bricks based on level
			LayoutObjectAtRandom (brickCount);
		}
}

These are the only two scripts that I can think would be causing this error. I have 2 other scripts that I've recently worked with, but neither of them have their game objects instantiated when I'm getting these errors, so I don't think that has anything to do with it.

Edited by ethancodes

Share this post


Link to post
Share on other sites
On 5/22/2018 at 5:08 AM, ethancodes said:

It may not show up for 5-10 test plays, and then all the sudden it pops up.

This tells me it could be a brick; like one of your existing bricks has a typo somewhere.

52 minutes ago, ethancodes said:

I'll post the code and maybe you can spot what i'm missing. 

That code looks fine to me.

The only part that could maybe be responsible is this:

		//Clears our array gridPositions and prepares it to generate a new board.
		void InitialiseList ()
		{
			//Clear our array gridPositions.
			Array.Clear(gridPositions, 0, gridPositions.Length);

			//Loop through x axis (columns).
			for(int x = 0; x < columns; x++)
			{
				//Within each column, loop through y axis (rows).
				//start at 16 to spawn our bricks offscreen
				for(int y = 0; y <= rows; y++)
				{
					bool visible = true;
					//At each index add a new Vector3 to our array with the x and y coordinates of that position.
					gridPositions[x,y] = new GridSquare(new Vector3(x,y,0), visible);
				}
			}
		}

You call array clear, but it is unknown if you destroy the old objects in the array. Sometimes if an array holds gameObjects you must first destroy all the game objects before clearing the list.

If you don't there could be some left over objects in the scene.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Similar Content

    • By ethancodes
      I'm working on a system for my game that will allow the player to stack pick ups in a queue. As one pick up expires, the next automatically activates. I'm having an issue though where if I pick up the first one, it activates fine, but if i pick up a second directly after it, it overrides the first one, activates the second one, and then once it has run it's course, everything goes back to normal gameplay, no first pick up. I'm not sure why this is happening. Hopefully someone can spot what I'm doing wrong in my code.
      Here is the code for the pick up manager:
      // Update is called once per frame void Update () { if (pickUpQueue.Count != 0 && !pickUpActive) { pickUpActive = true; pickUpQueue[0].ActivatePickUp(); } DeactivatePickUp(); } void DeactivatePickUp () { if (pickUpQueue.Count != 0 && pickUpActive) { Destroy (pickUpQueue [0]); pickUpQueue.RemoveAt (0); pickUpActive = false; } } And here is the PickUp:
      public override void ActivatePickUp () { ball.GetComponent<Ball>().Speed = 2.0f; //increase ball speed... ball.GetComponent<Ball>().StartCoroutine(timer); //...set time that power up is active }  
      There is also a Base Pick Up:
      public void OnCollisionEnter2D (Collision2D collision) { Vector2 tweak = new Vector2 (Random.Range(0f, 0.2f),Random.Range(0f, 0.2f)); this.gameObject.GetComponent<Rigidbody2D>().velocity += tweak; //if the pickup makes contact with the paddle or ball.... if (collision.gameObject.tag == "Paddle" || collision.gameObject.tag == "Ball") { GameObject.FindObjectOfType<GameManager>().GetComponent<PickUpManager>().pickUpQueue.Add(this); Destroy(gameObject); //...and finally destroy power up object } } As a side note, I am trying to find a solution to this that will work for all of my pickups. Some pickups are ammo based, some are timed. 
    • By Hellados
      Hello guys, my name is Giorgi and i'm newbie game developer i'm learning Pixel art and after pixel art  i want learn C# and don't know how and where start i'm bad with programming language and know only HTML/CSS
    • By D34DPOOL
      Edit Your Profile D34DPOOL 0 Threads 0 Updates 0 Messages Network Mod DB GameFront Sign Out Add jobEdit jobDeleteC# Programmer for a Unity FPS at Anywhere   Programmers located Anywhere.
      Posted by D34DPOOL on May 20th, 2018
      Hello, my name is Mason, and I've been working on a Quake style arena shooter about destroying boxes on and off for about a year now. I have a proof of concept with all of the basic features, but as an artist with little programming skill I've reached the end of my abilities as a programmer haha. I need someone to help fix bugs, optomize code, and to implent new features into the game. As a programmer you will have creative freedom to suggest new features and modes to add into the game if you choose to, I'm usually very open to suggestions :).
      What is required:
      Skill using C#
      Experience with Unity
      Experience using UNET (since it is a multiplayer game), or the effort and ability to learn it
      Compensation:
      Since the game currently has no funding, we can split whatever revenue the game makes in the future. However if you would perfer I can create 2D and/or 3D assets for whatever you need in return for your time and work.
      It's a very open and chill enviornment, where you'll have relative creative freedom. I hope you are interested in joining the team, and have a good day!
       
      To apply email me at mangemason@yahoo.com
    • By Andrew Parkes
      I am a talented 2D/3D artist with 3 years animation working experience and a Degree in Illustration and Animation. I have won a world-wide art competition hosted by SFX magazine and am looking to develop a survival game. I have some knowledge of C sharp and have notes for a survival based game with flexible storyline and PVP. Looking for developers to team up with. I can create models, animations and artwork and I have beginner knowledge of C sharp with Unity. The idea is Inventory menu based gameplay and is inspired by games like DAYZ.
      Here is some early sci-fi concept art to give you an idea of the work level. Hope to work with like minded people and create something special. email me andrewparkesanim@gmail.com.
      Developers who share the same passion please contact me, or if you have a similar project and want me to join your team email me. 
      Many thanks, Andrew.

    • By davejones
      Is there a way to automatically change the start position of an animation? I have a bunch of animations set up on 3D models in unity. The issue is that I need to move the 3D models, however when I do so the animation start positions are not updated and I have to do it manually.

      Changing the transform of key frames is time consuming with the amount of animations I have, so I was wondering if there was a way to do it automatically?
    • By mike44
      The reference assemblies for framework ".NETFramework,Version=v3.5" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend.

      Hi
      what to do with the above error in ms code/Unity3d Project on Ubuntu 18.04? I've installed it like:
      https://www.microsoft.com/net/learn/...ux/ubuntu18-04
      Many thanks
    • By Dave Haylett
      Hi.
      I have pulled in five NuGet packages for my Visual Studio 2017 project, however when I build the project, VS spits out 10 .DLL and .XML files in the root of the binary folder, to do with the packages. Can't I shove them into a \packages folder so the user doesn't see these ugly resources next to the .exe file?
      I've Googled moving the packages but the only responses seem to be around moving the installation folder of the NuGet packages on the local machine, as opposed to where VS builds them to.
    • By MoreLion
      hey all! We are looking for members for our Unity horror game! 
      Here’s the story:
      After a deadly virus plunges the world into chaos killing 85% of the human population there are now what they call “zones” these zones are watched very closely by the surviving government, people are checked every day for the virus, even if you touch the spit or any human waste or fluids of the victim who is infected, you will die. But one day, people in the west zone start to go missing, 1 woman goes outside the walls to uncover the mystery, is there more to the virus than meets the eye?, That is where your story starts.
      This game is not a long development game, I have loads other game ideas,
      I will also allow you to have a bit of creative freedom if you wish to add or share a idea!
      And no, it’s not a zombie game lol I feel like zombie games are too generic, in this game you will encounter terrifying beasts!
      There is some concept art one of our concept artists have made
      If interested email liondude12@gmail.com
  • Advertisement
  • Popular Now

  • Forum Statistics

    • Total Topics
      631362
    • Total Posts
      2999571
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!