Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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 NWHCoding · Aug 02, 2018 at 06:11 PM · rotationquaternionrotate

Snap and align two cubes

Hello, the problem is probably simple but I have spent way too much time on it so far:

I have cube 1 that is slowly rotating in place along x, y, z axis. I have cube 2 that I can snap to cube 1. Snapping the position works great but the thing I cannot make work is snapping rotation. Essentially I would need to rotate cube 2 the least amount possible so that one of it's faces is flush with cube 1.

Any help would be great.

EDIT: Some more info Here is the code I have at the moment (very naive tho):

 Vector3 rotationDiff = otherAnchor.transform.localRotation.eulerAngles - transform.localRotation.eulerAngles;
     for(int i = 0; i < 3; i++)
     {
         rotationDiff[i] = rotationDiff[i] % 90f;
         if (rotationDiff[i] > 45f) rotationDiff[i] -= 90f;
         else if (rotationDiff[i] < -45f) rotationDiff[i] += 90f;
     }
     transform.localRotation = Quaternion.Euler(rotationDiff) * transform.localRotation;

And the video of it in action. Notice that the small subcube is always in roughly the same position as it tries to keep the user set rotation as much as possible. Also, everything works perfectly fine as long as rotation is only along one axis.

Video: https://youtu.be/GfzIbWuV54o

EDIT 2: This is the solution I went for in the end. Works great but needs some optimization:

 // Position this objects initially so that, once rotated, this object is still in the correct position
                 transform.position = otherAnchor.GlobalPosition + (transform.position - GlobalPosition);
 
                 // Make this object face the other object along the face normals
                 if (Mathf.Abs(Vector3.Dot(otherAnchor.GlobalFaceNormal(), GlobalFaceNormal())) < 1f)
                 {
                     rotationAxis = Vector3.Cross(-otherAnchor.GlobalFaceNormal(), GlobalFaceNormal()).normalized;
                     float angle = Vector3.SignedAngle(-otherAnchor.GlobalFaceNormal(), GlobalFaceNormal(), rotationAxis);
                     transform.localRotation = Quaternion.AngleAxis(-angle, rotationAxis) * transform.localRotation;
                 }
 
                 // Find one alignment axis from this object that is not the same as the rotation axis
                 Vector3 thisAlignmentAxis = Vector3.zero;
                 float normalForwardDot = Mathf.Abs(Vector3.Dot(GlobalFaceNormal(), transform.forward));
                 float normalRightDot = Mathf.Abs(Vector3.Dot(GlobalFaceNormal(), transform.right));
                 thisAlignmentAxis = normalForwardDot < normalRightDot ? transform.forward : transform.right;
 
                 // Calculate all possible dots between this alignment axis and all directions of the other object
                 float xDot = Vector3.Dot(thisAlignmentAxis, otherAnchor.transform.right);
                 float yDot = Vector3.Dot(thisAlignmentAxis, otherAnchor.transform.up);
                 float zDot = Vector3.Dot(thisAlignmentAxis, otherAnchor.transform.forward);
                 float dot45 = 0.7f;
 
                 // Find nearest axis to this alignment axis on the other object so that least rotation is needed to align them
                 Vector3 otherAlignmentAxis = Vector3.zero;
                 if (Mathf.Abs(xDot) > dot45 && Mathf.Abs(xDot) < 1f) otherAlignmentAxis = xDot > 0 ? otherAnchor.transform.right : -otherAnchor.transform.right;
                 else if (Mathf.Abs(zDot) > dot45 && Mathf.Abs(zDot) < 1f) otherAlignmentAxis = zDot > 0 ? otherAnchor.transform.forward : -otherAnchor.transform.forward;
                 else if (Mathf.Abs(yDot) > dot45 && Mathf.Abs(yDot) < 1f) otherAlignmentAxis = yDot > 0 ? otherAnchor.transform.up : -otherAnchor.transform.up;
                 else Debug.Log("Could not find alignment axis.");
 
                 // Apply rotation around rotation axis so that two alignment axis are pointing at the same direction
                 transform.localRotation = Quaternion.FromToRotation(thisAlignmentAxis, otherAlignmentAxis) * transform.localRotation;
 
                 // Fix position once more to make sure that both anchors are at the exactly same position
                 transform.position += otherAnchor.GlobalPosition - GlobalPosition;

Comment
Add comment · Show 2
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 bennett_apps · Aug 02, 2018 at 07:17 PM 0
Share

During runtime or in the scene?

avatar image NWHCoding bennett_apps · Aug 02, 2018 at 09:48 PM 0
Share

During runtime. This is somewhat of a building block game but blocks can be rotated. I have this joint system that snaps the nearest face to the other block and the problem would be solved if I just copied the rotation of the other object to the object I am trying to place but I do not want my object to rotate more than 90 degrees in any direction. Let's say you are snapping a (rectangular) wing to a (rectangular) fuselage, you want your wing to snap with the face that is nearest to the fuselage.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by JVene · Aug 02, 2018 at 08:49 PM

This sounds like you actually want the "snapped" cube to become a child, so it assumes the rotation of the parent.


More to the point, however, is that you probably want an empty GameObject that owns the first cube, and this empty game object is the one that should rotate as you've described. That way, any an all objects made children of the empty, parent gameobject will rotate and move with the parent in the way it appears you want.


You can experiment in the editor before coding by creating this arrangement in the scene to see how this parental arrangement works.

Comment
Add comment · Show 1 · 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 NWHCoding · Aug 02, 2018 at 10:02 PM 0
Share

Put some more info above. Beco$$anonymous$$g child is not really possible due to the system of triggers I have and the fact that the child still needs rotate locally to keep the user set rotation as much as possible.

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.

Follow this Question

Answers Answers and Comments

125 People are following this question.

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

Related Questions

Rotating wrong 0 Answers

How to instantiate on custom rotation? 1 Answer

Use Lerp to rotate object 2 Answers

Rotate object in the direction where it is going 1 Answer

Transform.Rotate producing unexpected results when being used after setting localEulerAngles 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges