- Home /
Tetris transform.rotate messes up childrens position?
(All done in 2d)
So Im currently trying to do a Tetris game, the only thing not working so far afaik is that the I blocks children get messed up when I rotate it, but only if I rotate it once to the left or 3 times to the right,(<---).
private void rotateRight()
{
if (this.tag != "3")
{
this.transform.Rotate(0, 0, -90,Space.World);
if (!GameObject.Find("Array").GetComponent<CoolTestArray>().checkIfValidPosition(this.gameObject) || !inBorder())
{
this.transform.Rotate(0, 0, 90,Space.World);
}
}
checkMoveability();
}
private void rotateLeft()
{
if (this.tag != "3")
{
this.transform.Rotate(0, 0, +90,Space.World);
if (!GameObject.Find("Array").GetComponent<CoolTestArray>().checkIfValidPosition(this.gameObject) || !inBorder())
{
this.transform.Rotate(0, 0, -90,Space.World);
}
}
checkMoveability();
}
this as I said, works fine, as long as I dont turn it towards the left side, because if I do, the childrens coordinates instead of becoming x=1,2,3,4 become x=0,1,3,4 however the block is still shown as if all the children are next to each other. The block consists of an empty gameObject with 4 children that are put to be the I. Any help would be appreciated.
Edit:
Im to stupid to upload images from a Url so take these links instead:
https://puu.sh/uN37X/042880a7e6.png - Hierarchy
https://puu.sh/uN307/4ad9fa5c7b.jpg - The I Block rotated to the left
https://puu.sh/uN32z/89d50affb5.png - childPositions before/after rotating(also tried to round the positions)
https://puu.sh/uN3eC/ad35b8ef70.jpg - what happens because of my problem
Answer by NoseKills · Mar 17, 2017 at 04:31 PM
I'd say the log output in the screenshots already reveals one underlying issue here. The x position of one of your blocks prints out as 0.9999999...(which can be expected due to rotations and floating point precision)
You are making a grid based game but you are using the float position of gameObjects to determine where a block is in the grid (I'm guessing since we can't see that part of the code). If the x-coordinate is determined by just casting to int a la var x = (int)transform.position.x
, anything less tah 1 will produce 0
.
You might be able to fix this just by making sure you round up when necessary : var x = (int)(transform.position.x + 0.5f)
.
The real solution would be to implement the game logic to use an actual grid (or integer vectors) and describe block positions as positions in the grid. Then just make your block graphics update their own position based on the grid.
When you select your data types so they can only represent values that make sense in your game, you eliminate a huge amount of bugs from the get go.
this is correct, in the method that saves the child.transforms in an array it does indeed cast to int, however im rounding the child transforms every rotate, and everytime the block is moved, as well as before it is saved in the array with $$anonymous$$athf.Round wich should return the float to the nearest Integer.
public void roundPosition(GameObject l)
{
for (int i = 0; i < this.gameObject.transform.childCount; i++)
{
l.transform.GetChild(i).position = new Vector3($$anonymous$$athf.Round(l.transform.GetChild(i).position.x), $$anonymous$$athf.Round(l.transform.GetChild(i).position.y), $$anonymous$$athf.Round(l.transform.GetChild(i).position.z));
}
}
am i doing something wrong here?
In theory that is correct. You could use Debug.Log to print out the positions at every step of the way in the logic to find out where the rounding error still happens... BUT the main issue still is that the position is stored in transform.position, which uses floats to store the coordinates and also you can't be sure you are the only one modifying it. Any modification to the transform's rotation etc. or its parent transform might cause the position to change as well even when it see$$anonymous$$gly shouldn't. In fact, I don't think you can be sure at all what happens when you set transform.position, because it's a property, it might do some math that causes rounding errors already right there and then.
So ins$$anonymous$$d of wasting time debugging the current system I'd try to move to a system where the position is stored as integers as much of the time as possible.
A sort of a compromise between the current system and redoing all of the logic to use a grid etc. could be just adding some sort of a BlockPosition component on all of the small blocks. A component that has methods for converting the transform.position to 3 integers ($$anonymous$$athf.RoundToInt() ) and vice versa, then using those 3 integers ins$$anonymous$$d of transform.position every time you need to compare or deter$$anonymous$$e the coordinates of the block in the game logic.
The least this would do is narrow down the spot where the bug can happen to these 2 methods, ins$$anonymous$$d of any place where transform.position is used.
Thank you very much,i chose your approach of implementing a component that gives me the coordinates as int and now it works perfectly fine
Answer by Spidlee · Mar 16, 2017 at 09:08 PM
Here's what I usually do when it comes to animating gameobjects be it with or without animators.
Parent Object (root level): used as a pivot for transformations that involve the whole group. Could be an empty gameobject if you want.
Children Object (under the parent): i only apply local transformations for children when i want them to move individually within the group.
What you would want to do, in the instance of Tetris style, would be to create a Root Object for transformations, and have your blocks organised under it using local transforms. And all you'd be doing for rotations would be rotating the Root Object.
(if you're already doing that and still experiencing strange behaviours, could you take a screenshot of your object hierarchy so we can have more information, thanks)
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
The object doesn't line up.When it changes the object that is rotating around. 1 Answer
How can I flip only my 'Player' gameobject, and l leave it's child object alone? 2 Answers
2D rigidbody top down movement problem 3 Answers