update() too fast?

Hi there

I’m a beginner with Unity programming and currently trying to create a funvtional Tetris clone. So far, everything I wanted works. I’m working right now on the script that should delete the full lines and move the ones above downwards. So here are the scripts I have for that. The function checkLines() is called out of the update() function:

 //check, if there is a full Line
function checkLines(){
	var line : int;
	for (var a=19;a>=0;a--){
		for(var b=0;b<10;b++){
			if(board[b,a]==1) line++;
			}
		if (line>=10){
			deleteLines(a);
			moveLines(a);
			}
		line=0;
		}
	}

//delete the full line
function deleteLines(a:int){
	for(var X=0;X<10;X++){
		if(blocksLevel[X,a]){
			Destroy(blocksLevel[X,a].gameObject);
			board[X,a]=0;
			}
		}
	}

    //move lines above the deleted
    function moveLines(a:int){
    	for(var Y=a+1;Y<20;Y++){
    		for(var X=0;X<10;X++){
    			if(blocksLevel[X,Y]){
    				blocksLevel[X,Y].transform.position.y -=2.2;
    				blocksLevel[X,Y].name = "block"+X+a;
    				board[X,Y]=0;
    				board[X,a]=1;
    				}
    			}
    		}
    	}

This script works exactly as I want it to work as long there is just one single line to delete. As soon as there are 2 to 4 lines, the results are kinda random meaning that sometimes not all blocks get deleted or not all blocks are moved down one unit.

To me it looks like that unity is “jumping” over some lines of code because the update function is called to soon. Is that possible? Is there a problem with my code? What is causing my problem?

I’m be really thankful if you could help me

Thanks
mitti2000

Edit: I changed the script to a version without GameObject.Find calls as suggested by Yokimato

2 Answers

2

You have a lot of GameObject.Find calls. These are slow when compared to what you could be doing.

I would suggest storing references to the block GameObjects in memory so that you do not have to call Find so much. I think not only with this solve your issue, but the game itself will probably run alot smoother (and it’s a good practice to get into).

Thanks for your input. I know I shouldn't have that many GameObject.Find calls. I just don't know how I should manage the script I posted without them. The thing is, that when the blocks get instantiated, they are children of an empty simly named "block(clone)". Every empty contains 4 of those blocks. As soon as they are set, I rename each of them accoring to their xy-position on the board. That way, I can "find" them again later when I have to delete them. Would it theoretically work if I would store the blocks in a 2D array? Or is there another way I could do that?

I think storing the gameobjects in a 2d array sounds like a great, simple way to keep your code easy to understand while keeping the performance where it needs to be.

I'll try that. I'll let you know if that solved my problem tomorrow. Thanks again.

Hi Yokimato I removed the GameObject.Find calls. The script definitly works better but still shows strange behaviour. Specially in the moveLines function. The blocks get destroyed but then not all blocks get moved... Is there a way to "pause" the update function until the subroutines are done? (if that would be a possible solution)

Does anybody else have an idea how to solve my problem? Thanks

Ok, in the meantime I found the solution myself. Here is my script now:

//check, if there is a full Line
function checkLines(){
	var line : int;
	for (var a=19;a>=0;a--){
		for(var b=0;b<10;b++){
			if(blocksLevel[b,a]) line++;
			}
		if (line>=10){
			deleteLines(a);
			moveLines(a);
			}
		line=0;
		}
	}

//delete the full line
function deleteLines(a:int){
	for(var X=0;X<10;X++){
		if(blocksLevel[X,a]){
			Destroy(blocksLevel[X,a].gameObject);
			}
		}
	}

//move lines above the deleted
function moveLines(a:int){
	var b= a+1;
	for(var Y=b;Y<20;Y++){
		for(var X=0;X<10;X++){
			if(blocksLevel[X,Y]){
				blocksLevel[X,Y-1]=blocksLevel[X,Y];
				blocksLevel[X,Y-1].transform.position.y -=2.2;
				blocksLevel[X,Y-1].name = "blockcopy"+X+(Y-1);
				blocksLevel[X,Y]=null;
				}
			}
		}
	}

I did 2 main things to my prior scripts. As mentioned before, I removed all GameObject.Find calls. Then, instead of using the board array to store either 1 or 0 if there’s a block at that position or not, I have another array blocksLevel. There I store the Transform of the block itself. When the block is deleted, I set the accoring position in the array to Null.

I hope that might help some other beginner like me
mitti2000