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 gzxmx94 · Oct 15, 2017 at 10:11 PM · transformobjectrelative rotationrelative position

Place object rotated relative to another object?

Hello, I am trying to make a procedural world generator but making the connections seems a bit difficult.

When connecting everything in a straight line everything works because that's easy, I use this:

         to.transform.position = from.transform.position + from_offsets.position_offsets[taken_idx] - to_offsets.position_offsets[0];
         to.transform.eulerAngles = from.transform.eulerAngles + from_offsets.rotation_offsets[taken_idx] - to_offsets.rotation_offsets[0];
 

But this doesn't account for the rotation, so something like this is impossible:

https://imgur.com/a/eANxp

How can I place Object B relative to Object A when I have two offsets which both consist of a position + rotation offset like this:

     public Vector3[] position_offsets;
     public Vector3[] rotation_offsets;

You can see this in the screenshots.

So to sum up:

I have Object A with it's transform (Position, Rotation), connection point(Offset and Rotation), and Object B with it's connection point (Offset and Rotation) and I need to place B relative to A like in the screenshots. How to do that programatically (C#)?

My current code produces this (inclusive what I want):

alt text

And this is the full code if needed (probably not):

 public class ConnectionOffsets : MonoBehaviour
 {
     // 0 shall be entry point (exit in case of 180 degree turn), 1 shall be forward / exit point (entry in case of 180 degree turn), 2 left, 3 right
     public Vector3[] position_offsets;
     public Vector3[] rotation_offsets;
 }
 
     bool ConnectFromFirstAvailable(GameObject from, GameObject to, int first_available = 0)
     {
         if(from == null || to == null)
         {
             return false;
         }
 
         ConnectionOffsets from_offsets = from.GetComponent<ConnectionOffsets>();
 
         if(from_offsets == null)
         {
             return false;
         }
 
         int taken_idx = first_available;
         for (int i = first_available; i < from_offsets.taken.Length; ++i)
         {
             if(!from_offsets.taken[i])
             {
                 taken_idx = i;
                 break;
             }
         }
 
         if (taken_idx < from_offsets.taken.Length && from_offsets.taken[taken_idx])
         {
             return false;
         }
 
         ConnectionOffsets to_offsets = to.GetComponent<ConnectionOffsets>();
 
         if(to_offsets == null || to_offsets.taken[0] != null)
         {
             return false;
         }
 
         to_offsets.taken[0] = from;
         from_offsets.taken[taken_idx] = to;
 
         Vector3 total_relative_pos = from_offsets.position_offsets[taken_idx] - to_offsets.position_offsets[0];
         Vector3 total_relative_rot = from_offsets.rotation_offsets[taken_idx] - to_offsets.rotation_offsets[0];
 
         to.transform.position = from.transform.position + total_relative_pos;
         to.transform.eulerAngles = from.transform.eulerAngles + total_relative_rot;
 
         /*to.transform.Translate(total_relative_pos, from.transform);*/
         
         return true;
     }

Edit: I have made progress that allows me to place the objects I need under a certain rotation:

     private Vector2 RotatePointAroundPoint(float center_x, float center_y, float point_x, float point_y, float angle)
     {
         return RotatePointAroundPoint(new Vector2(center_x, center_y), new Vector2(point_x, point_y), angle);
     }
 
     private Vector2 RotatePointAroundPoint(Vector2 center, Vector2 point, float angle)
     {
         float x1 = point.x - center.x;
         float y1 = point.y - center.y;
 
         angle *= Mathf.Deg2Rad;
 
         float x2 = x1 * Mathf.Cos(angle) - y1 * Mathf.Sin(angle);
         float y2 = x1 * Mathf.Sin(angle) + y1 * Mathf.Cos(angle);
 
         point.x = x2 + center.x;
         point.y = y2 + center.y;
 
         return point;
     }
 
     private Vector2 RotatePointAroundPoint(float point_x, float point_y, float angle)
     {
         return RotatePointAroundPoint(new Vector2(point_x, point_y), angle);
     }
 
     private Vector2 RotatePointAroundPoint(Vector2 point, float angle)
     {
         float x1 = point.x;
         float y1 = point.y;
 
         angle *= Mathf.Deg2Rad;
 
         float x2 = x1 * Mathf.Cos(angle) - y1 * Mathf.Sin(angle);
         float y2 = x1 * Mathf.Sin(angle) + y1 * Mathf.Cos(angle);
 
         point.x = x2;
         point.y = y2;
 
         return point;
     }
 
     bool ConnectFromFirstAvailable(GameObject from, GameObject to, int first_available = 0)
     {
         if(from == null || to == null)
         {
             return false;
         }
 
         ConnectionOffsets from_offsets = from.GetComponent<ConnectionOffsets>();
 
         if(from_offsets == null)
         {
             return false;
         }
 
         int taken_idx = first_available;
         for (int i = first_available; i < from_offsets.taken.Length; ++i)
         {
             if(!from_offsets.taken[i])
             {
                 taken_idx = i;
                 break;
             }
         }
 
         if (taken_idx < from_offsets.taken.Length && from_offsets.taken[taken_idx])
         {
             return false;
         }
 
         ConnectionOffsets to_offsets = to.GetComponent<ConnectionOffsets>();
 
         if(to_offsets == null || to_offsets.taken[0] != null)
         {
             return false;
         }
 
         to_offsets.taken[0] = from;
         from_offsets.taken[taken_idx] = to;
 
         Vector3 to_position_offsets = to_offsets.position_offsets[0];
         Vector3 to_rotation_offsets = to_offsets.rotation_offsets[0];
         Vector3 from_position_offsets = from_offsets.position_offsets[taken_idx];
         Vector3 from_rotation_offsets = from_offsets.rotation_offsets[taken_idx];
 
         Vector2 correction;
 
         // correct position
         correction = RotatePointAroundPoint(to_position_offsets.z, to_position_offsets.y, from_rotation_offsets.x);
         to_position_offsets.z = correction.x;
         to_position_offsets.y = correction.y;
 
         correction = RotatePointAroundPoint(to_position_offsets.z, to_position_offsets.x, from_rotation_offsets.y);
         to_position_offsets.z = correction.x;
         to_position_offsets.x = correction.y;
 
         correction = RotatePointAroundPoint(to_position_offsets.x, to_position_offsets.y, from_rotation_offsets.z);
         to_position_offsets.x = correction.x;
         to_position_offsets.y = correction.y;
 
         // correct angles
 
         correction = RotatePointAroundPoint(from.transform.eulerAngles.z, from.transform.eulerAngles.y, to_rotation_offsets.x);
         to_rotation_offsets.z = correction.x;
         to_rotation_offsets.y = correction.y;
 
         correction = RotatePointAroundPoint(from.transform.eulerAngles.z, from.transform.eulerAngles.x, to_rotation_offsets.y);
         to_rotation_offsets.z = correction.x;
         to_rotation_offsets.x = correction.y;
 
         correction = RotatePointAroundPoint(from.transform.eulerAngles.x, from.transform.eulerAngles.y, to_rotation_offsets.z);
         to_rotation_offsets.x = correction.x;
         to_rotation_offsets.y = correction.y;
 
         // apply transforms
         Vector3 total_relative_pos = from_position_offsets - to_position_offsets;
         Vector3 total_relative_rot = from.transform.eulerAngles; // + from_rotation_offsets - to_rotation_offsets;
 
         to.transform.rotation = Quaternion.Euler(to_rotation_offsets);
         to.transform.Rotate(Vector3.right, from_rotation_offsets.z);
         to.transform.Rotate(Vector3.up, from_rotation_offsets.y);
         to.transform.Rotate(Vector3.forward, from_rotation_offsets.x);
         to.transform.position = from.transform.TransformPoint(total_relative_pos); 
 
         return true;
     }

But this only works for either one nonzero x y or z rotation, if multiple rotations have rotations then it doesn't work

Edit2:

Alright the solution seems to be:

     private Vector2 RotatePointAroundPoint(float point_x, float point_y, float angle)
     {
         return RotatePointAroundPoint(new Vector2(point_x, point_y), angle);
     }
 
     private Vector2 RotatePointAroundPoint(Vector2 point, float angle)
     {
         float x1 = point.x;
         float y1 = point.y;
 
         angle *= Mathf.Deg2Rad;
 
         float x2 = x1 * Mathf.Cos(angle) - y1 * Mathf.Sin(angle);
         float y2 = x1 * Mathf.Sin(angle) + y1 * Mathf.Cos(angle);
 
         point.x = x2;
         point.y = y2;
 
         return point;
     }
 
     bool ConnectFromFirstAvailable(GameObject from, GameObject to, int first_available = 0)
     {
         if(from == null || to == null)
         {
             return false;
         }
 
         ConnectionOffsets from_offsets = from.GetComponent<ConnectionOffsets>();
 
         if(from_offsets == null)
         {
             return false;
         }
 
         int taken_idx = first_available;
         for (int i = first_available; i < from_offsets.taken.Length; ++i)
         {
             if(!from_offsets.taken[i])
             {
                 taken_idx = i;
                 break;
             }
         }
 
         if (taken_idx < from_offsets.taken.Length && from_offsets.taken[taken_idx])
         {
             return false;
         }
 
         ConnectionOffsets to_offsets = to.GetComponent<ConnectionOffsets>();
 
         if(to_offsets == null || to_offsets.taken[0] != null)
         {
             return false;
         }
 
         to_offsets.taken[0] = from;
         from_offsets.taken[taken_idx] = to;
 
         Vector3 to_position_offsets = to_offsets.position_offsets[0];
         Vector3 to_rotation_offsets = to_offsets.rotation_offsets[0];
         Vector3 from_position_offsets = from_offsets.position_offsets[taken_idx];
         Vector3 from_rotation_offsets = from_offsets.rotation_offsets[taken_idx];
 
         Vector2 correction;
 
         // correct position
         correction = RotatePointAroundPoint(to_position_offsets.z, to_position_offsets.y, from_rotation_offsets.x);
         to_position_offsets.z = correction.x;
         to_position_offsets.y = correction.y;
 
         correction = RotatePointAroundPoint(to_position_offsets.z, to_position_offsets.x, from_rotation_offsets.y);
         to_position_offsets.z = correction.x;
         to_position_offsets.x = correction.y;
 
         correction = RotatePointAroundPoint(to_position_offsets.x, to_position_offsets.y, from_rotation_offsets.z);
         to_position_offsets.x = correction.x;
         to_position_offsets.y = correction.y;
 
         // apply transforms (and correct rotation)
         to.transform.rotation = Quaternion.Euler(from.transform.eulerAngles);
         to.transform.Rotate(from_rotation_offsets, Space.Self);
         to.transform.Rotate(to_rotation_offsets, Space.Self);
         to.transform.position = from.transform.TransformPoint(from_position_offsets - to_position_offsets); 
 
         return true;
     }
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

0 Replies

· Add your reply
  • Sort: 

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

137 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 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

Move to object if collision is triggered 0 Answers

Moving instantiated Objects to target locations 1 Answer

How can I use the collision from a moving game object(such as a projectile) and use it to "pick up" another game object? 0 Answers

How to make a cylinder that dynamically connects two objects? 0 Answers

Child Relative path to object is wrong 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