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 /
  • Help Room /
avatar image
0
Question by JavaMcGee · Nov 18, 2016 at 05:00 AM · rotationsnappingalignalign two objects

How do i rotate a cube least amount to align faces with another?

Hi,

My first post... I'm trying to make a basic interaction where the player can pick up blocks on the ground and attach them to others. It's not like a m*craft grid thing, the blocks can be in any orientation. When player picks up a block A they can rotate it. When the block is placed near a face of another block B, A will snap into place to align with the face of B (see pics). The orientation matters because there will be symbols on the block faces (not shown), so block A need A to rotate only the smallest/nearest amount to align with B. I'm stuck with getting the rotation right.

okay alignment: alt text

bad alignment: alt text

Here's my Snap function where my understanding of rotation geometry is failing short and could use advice on how to get the desired effect. Variables mentioned here are holdingPart - the block the player is holding (transparent in the pic); nearPointingAtPart - the block on the ground; and pointerHit - the raycast hitting the block face that the player is pointing at.

 void SnapHeldPart()
 {
     // rotate the held object a little bit to align with the pointed-at part
     var vec = holdingPart.transform.eulerAngles - nearPointingAtPart.transform.eulerAngles;
     vec.Set(Mathf.Round(vec.x / 90f) * 90f, Mathf.Round(vec.y / 90f) * 90f, Mathf.Round(vec.z / 90f) * 90f);
     holdingPart.transform.eulerAngles = vec + nearPointingAtPart.transform.eulerAngles;
     // position the held part by the selected surface normal on another cube.
     Vector3 placePoint = (nearPointingAtPart.transform.position + pointerHit.normal * 0.51f);
     holdingPart.transform.position = placePoint;
 }
 

Thanks

good.png (43.6 kB)
bad.png (44.7 kB)
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

Answer by ElijahShadbolt · Nov 18, 2016 at 07:36 AM

I figured out a solution which works for all rotations of the block and/or camera. It requires the desired forward and upward vectors of your holdingPart block, i.e. pointerRay.direction (forwards, like say, the direction of your raycast) and Camera.main.transform.up (upwards).

 using UnityEngine;
 
 public class BlockRotation : MonoBehaviour
 {
     public GameObject holdingPart;
     private GameObject nearPointingAtPart;
     private RaycastHit pointerHit;
     private Ray pointerRay;
 
     public float blockDistance = 0.51f;
 
     void Update()
     {
         pointerRay = Camera.main.ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(pointerRay, out pointerHit))
         {
             nearPointingAtPart = pointerHit.transform.gameObject;
             SnapHeldPart();
         }
     }
 
     void SnapHeldPart()
     {
         // other-block directions
         Vector3 f = nearPointingAtPart.transform.forward,
             r = nearPointingAtPart.transform.right,
             u = nearPointingAtPart.transform.up;
 
         // placing-block directions
         Vector3 forw = GetDirectionVector(f, r, u, pointerRay.direction);
         Vector3 up = GetDirectionVector(f, r, u, Camera.main.transform.up);
 
         // set rotation
         holdingPart.transform.rotation = Quaternion.LookRotation(forw, up);
 
         // set position
         holdingPart.transform.position = nearPointingAtPart.transform.position + pointerHit.normal * blockDistance;
     }

     // returns the face normal of a cube (defined by normals f,r,u) which is the closest angle to dir.
     private Vector3 GetDirectionVector(Vector3 f, Vector3 r, Vector3 u, Vector3 dir)
     {
         float af = Vector3.Angle(dir, f);
         float ar = Vector3.Angle(dir, r);
         float au = Vector3.Angle(dir, u);
         if (af <= 45f)
             return f;
         else if (af >= 135f)
             return -f;
         else if (ar <= 45f)
             return r;
         else if (ar >= 135f)
             return -r;
         else if (au <= 45f)
             return u;
         else// if (au >= 135f)
             return -u;
     }
 }
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 JavaMcGee · Nov 19, 2016 at 01:17 AM 1
Share

Thank you very much - I'll give that a try asap

avatar image
0

Answer by JavaMcGee · Dec 18, 2016 at 12:28 AM

Appreciate the suggestion but I couldn't get that working quite the way I wanted. It resets the rotation of the held cube after it is snapped, but what I wanted was to keep the rotation as close to the current as possible, however it was previously rotated by the player, rounding it to the closest that aligns with the fixed cube. I also had problems fixing a behavior where it flipped rotation by 45deg depending on which side of cube's face (across a diagonal I guess) that the ray was pointing at.

I found that my originally posted code was closer than I thought if I just don't subtract rotations. Change to the following - although this doesn't behave the way I wanted if the base cube is rotated too much.

 preSnapPartRotation = holdingPart.transform.rotation;
             holdingPart.transform.rotation = ModRotation(nearPointingAtPart.transform.rotation, 90f) * RoundRotation(preSnapPartRotation, 90f);

Anyway, the point of this was to see if handling and snapping blocks together like this would be useful (and fun) for a game I had in mind, but unfortunately it feels like an awkward way to make the player manipulate objects. Going to try to think up something different.

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.

Follow this Question

Answers Answers and Comments

91 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

Related Questions

Rotate around local Y axis using Joystick Vector3 0 Answers

Smooth snapping rotation 1 Answer

align object with collision normal then look at an object on one axis 0 Answers

How to make rotating objects with snapping to grid while the object contains children 0 Answers

3D rotation with snap 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