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 CigarBear · Jan 23, 2017 at 12:55 PM · c#rotationquaternionpositioningsnapping

I am having a weird issue with Quaternion.FromToRotation

So I am starting on a new project where I am building a random dungeon out of room prefabs. The first thing that happens is I instantiate a game object called "Start Room". This room has 4 exits as empty child game objects set in the locations that represent exits out of the room. Once the "Start Room"has been placed at 0,0,0 it spawns a new clone of a room prefab for each of its exits.

The new prefab that the "Start Room"has called has a single entrance and can have up to 3 exits as empty child game objects. The new prefab is then positioned at the "Start Room"exit and then Quaternion.FromToRotation is used to rotate the entrance of the newly spawned prefab to face the "Start Room"exit. Each Entrance and Exit child game object face to where their z axis is facing outward from the prefab so the entrance rotates on the y axis so that its z axis faces the z axis of the exit(if that makes sense)

This works fine for the most part but every so often one or two of the newly spawned prefabs are positioned correctly but the rotation is flipped 180 degrees on the z axis and I am not really sure why.

This is the script used to call the "Start Room" as well as position and rotate the newly spawned rooms:

  using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 public class RoomPooler : MonoBehaviour
 {
     public GameObject startRoomPrefab;
     public GameObject roomPrefab;
     public static RoomPooler pooler;
 
     void Awake()
     {
         pooler = this;
     }
 
     void Start()
     {
         SpawnStartRoom();
     }
 
     void SpawnStartRoom()
     {
         GameObject startRoom = Instantiate(startRoomPrefab, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
         startRoom.GetComponent<StartRoomScript>().AssignExits();
     }
 
     public void SpawnAdditionalRooms(GameObject exit)
     {
         GameObject newRoom = Instantiate(roomPrefab);
         newRoom.GetComponent<Room>().AssignEntrance();
         AlignEntranceToExit(newRoom, newRoom.GetComponent<Room>().entrance, exit.transform.parent.gameObject, exit);
     }
 
     void AlignEntranceToExit(GameObject newRoom, GameObject entrance, GameObject exitParent, GameObject exitChild)
     {
         Vector3 v1 = newRoom.transform.position - entrance.transform.position;
         Vector3 v2 = exitChild.transform.position - exitParent.transform.position;
         newRoom.transform.position = exitChild.transform.position + v2.normalized * v1.magnitude;
         newRoom.transform.rotation = Quaternion.FromToRotation(v1, v2) * newRoom.transform.rotation;
     }
 
 

The "Start Room" uses this script to call a new room for each exit:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class StartRoomScript : MonoBehaviour
 {
     public List<GameObject> doors;
 
     public void AssignExits()
     {
         for (int i = 0; i < doors.Count; i++)
         {
             RoomPooler.pooler.SpawnAdditionalRooms(doors[i]);
         }
     }
 }

The Rooms use this script to assign a random entrance from its list of doors. For now it also attaches another script that just draws a line in OnDrawGizmos for each of the exits x,y and z. Also until I can figure out the issue the Room script does not call for an addition room.

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 public class Room : MonoBehaviour
 {
     public List<GameObject> doors;
     public GameObject entrance;
 
 
     public void AssignEntrance()
     {
 
         int pickRandomDoorForEntrance = Random.Range(0, doors.Count);
         entrance = doors[pickRandomDoorForEntrance];
         entrance.name = "Entrance";
         doors.Remove(entrance);
         for (int i = 0; i < doors.Count; i++)
         {
             doors[i].gameObject.AddComponent<Exits>();
             doors[i].name = "Exit # " + i;
         }
 
     }
 
 
 }


I have attached a screen capture of what happens. The first is when everything aligns correctly but the second is where the rooms are misaligned because it has been rotated on the z axis as well as the y axis.

I could understand if it happens all the time but this does not. Sometimes it works correctly without an issue but sometimes it does not. These are also the only scripts in the project so there is no other scripting interfering.

Anyone have any thoughts?

Correct Rotation

Incorrect Rotation

getting-there.png (154.5 kB)
correct-rotation.png (234.5 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
Best Answer

Answer by CigarBear · Jan 24, 2017 at 04:16 PM

So after playing around with this project for a few hours this morning I figured out a solution to correct the issue that I was having by using transform.RotateAround as the fix.

Here is the original script :

  using UnityEngine;
  using System.Collections;
  using System.Collections.Generic;
  public class RoomPooler : MonoBehaviour
  {
      public GameObject startRoomPrefab;
      public GameObject roomPrefab;
      public static RoomPooler pooler;
  
      void Awake()
      {
          pooler = this;
      }
  
      void Start()
      {
          SpawnStartRoom();
      }
  
      void SpawnStartRoom()
      {
          GameObject startRoom = Instantiate(startRoomPrefab, new Vector3(0, 0, 0), Quaternion.identity) as GameObject;
          startRoom.GetComponent<StartRoomScript>().AssignExits();
      }
  
      public void SpawnAdditionalRooms(GameObject exit)
      {
          GameObject newRoom = Instantiate(roomPrefab);
          newRoom.GetComponent<Room>().AssignEntrance();
          AlignEntranceToExit(newRoom, newRoom.GetComponent<Room>().entrance, exit.transform.parent.gameObject, exit);
      }
  
      void AlignEntranceToExit(GameObject newRoom, GameObject entrance, GameObject exitParent, GameObject exitChild)
      {
          Vector3 v1 = newRoom.transform.position - entrance.transform.position;
          Vector3 v2 = exitChild.transform.position - exitParent.transform.position;
          newRoom.transform.position = exitChild.transform.position + v2.normalized * v1.magnitude;
          newRoom.transform.rotation = Quaternion.FromToRotation(v1, v2) * newRoom.transform.rotation;
      }


This is the new script with the changes I made. Note importing System so I could have access to Single:

 using UnityEngine;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 public class RoomPooler : MonoBehaviour
 {
     public GameObject startRoomPrefab;
     public GameObject roomPrefab;
     public static RoomPooler pooler;
 
     void Awake()
     {
         pooler = this;
     }
 
     void Start()
     {
         SpawnStartRoom();
     }
 
     void SpawnStartRoom()
     {
         GameObject startRoom = Instantiate(startRoomPrefab) as GameObject;
         startRoom.GetComponent<StartRoomScript>().AssignExits();
     }
 
     public void SpawnAdditionalRooms(GameObject exit)
     {
         GameObject newRoom = Instantiate(roomPrefab);
         newRoom.GetComponent<Room>().AssignEntrance();
         GameObject entranceGO = newRoom.GetComponent<Room>().entrance;
         Vector3 VectorToMatch = -exit.transform.forward;
         Single correctRotation = MatchRotation(VectorToMatch) - MatchRotation(entranceGO.transform.position);
         newRoom.transform.RotateAround(entranceGO.transform.position, Vector3.up, correctRotation);
         Vector3 correctPosition = exit.transform.position - entranceGO.transform.position;
         newRoom.transform.position += correctPosition;
     }
     
 
     private static float MatchRotation(Vector3 vector)
     {
         return Vector3.Angle(Vector3.forward, vector) * Mathf.Sign(vector.x);
     }
 }
 


@andrewgotow I want to think you for your assistance with this. It was because of your help I was pointed in the right direction.

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 andrewgotow · Jan 25, 2017 at 12:49 AM 0
Share

No problem! I'm glad you were able to find a solution!

avatar image
1

Answer by andrewgotow · Jan 23, 2017 at 03:12 PM

FromToRotation is designed to create a rotation which will transform a vector into another vector, however vectors just represent "directions", not full orientations. As a result, there's some ambiguity about how to do this. If you're facing forward, and someone tells you to turn around, you could turn either left or right, and both would be correct. Your "heading" would be the same either way, but the rotations you apply are totally different. The same is true in 3 dimensions. Your room could flip over the X axis completely, and the FromToRotation is just as valid as if it spun in place on the Y axis.

You could replace the call to FromToRotation with a call to `Quaternion.LookRotation`, which takes an up vector as a parameter, or you could apply a second rotation to correct for the potential 180° rotation...

 newRoom.transform.rotation *= Quaternion.FromToRotation(v1,v2);
 newRoom.transform.rotation *= Quaternion.FromToRotation(newRoom.transform.up, exitChild.transform.up);
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 CigarBear · Jan 23, 2017 at 03:31 PM 0
Share

So I applied the second rotation to correct the rotation issue and while that corrected it another issue has appeared lol.

Now ins$$anonymous$$d of flipping the newRoom 180 in the z it randomly rotates one of the pieces on the y axis. For example the newly attached screen shot shows the entrance and exit on one piece swapped. It should be rotated on the y 180 but ins$$anonymous$$d it is rotated 0 on the y.alt text

flippedy.png (207.8 kB)
avatar image andrewgotow CigarBear · Jan 23, 2017 at 06:27 PM 0
Share

Hmm... I suppose it could be the same problem again, maybe that wasn't such a great suggestion on my part :P

Could you try the Quaternion.LookRotation method? I think that's going to be a better solution in the end.

avatar image CigarBear andrewgotow · Jan 23, 2017 at 07:21 PM 0
Share

I made the following change but none of the entrances and exits are rotated correctly

 newRoom.transform.rotation = Quaternion.LookRotation(newRoom.transform.position - exitParent.transform.position);

Of course I have not used Quaternion.LookRotation before now so I am still researching

Incorrect Rotation

capture1.png (157.0 kB)

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

8 People are following this question.

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

Related Questions

Flip over an object (smooth transition) 3 Answers

Transform rotation and position on key input: rotation only working the first time 2 Answers

How can i rotate a object more than once (90 degrees)? 1 Answer

Trouble with Camera Rotation Math 2 Answers

Weird shake when I try to rotate player according to Virtual Cameras rotation. 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