• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Criveratech · Mar 16, 2017 at 07:09 AM · c#2d gamerotate objecttetris

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

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

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.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Criveratech · Mar 17, 2017 at 05:10 PM 0
Share

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?

avatar image NoseKills Criveratech · Mar 18, 2017 at 08:25 AM 1
Share

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 seemingly 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 determine 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.

avatar image Criveratech NoseKills · Mar 18, 2017 at 11:58 AM 1
Share

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

avatar image
0

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)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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

Transform Position X/Y increasing by no reason 2 Answers

How to convert Raycast3D to Raycast2D 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges