Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Hamesh81 · Oct 29, 2013 at 05:35 AM · rotationaxislookatlookrotationmatch

How can I rotate towards/look at a specific axis of a collided object?

I am creating some control functionality for a "tightrope" (grey box below). When the character is on the rope (colliding via raycast, the yellow line in the diagram) I would like the character's transform.forward (blue) to smoothly rotate on the Y axis towards the rope's transform.right (red), so that the character's forward direction is aligned with the direction in which the rope is going. This allows a player to navigate across the rope using only the "forward" key without needing to use the "left" and "right" keys to adjust their position so they don't fall off the rope. Since the slope of the rope is irrelevant, the rotation needs to be only on the Y axis.

alt text

I have tried using the following 2 ways:

 transform.rotation = Quaternion.RotateTowards(transform.rotation, hit.transform.rotation, 1.0f);
 transform.LookAt(hit.transform.right, Vector3.up);

The first way does not seem to do anything. The second, transform.LookAt does rotate the player, but affects all three axes not only the Y and its speed cannot be controlled, it simply snaps to the rotation. I'm not sure if LookAt is the best way to do this or if there is a better alternative. Any suggestions?

explanation.jpg (25.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
1
Best Answer

Answer by Tomer-Barkan · Oct 29, 2013 at 05:54 AM

First, you'd need to store the target direction since you want this done over more than one frame.

Then, you can use Vector3.RotateTowards() to slowly rotate the transform.forward towards your target. If you don't care about height, you can set y to be the same as the character's.

 private Vector3 targetRotation;
 private bool rotating = false;

 public void Update() {
     if (rotating) {
         Vector3 newForward = Vector3.RotateTowards(transform.forward, targetRotation, 1.0f * Time.deltaTime, 0);
         transform.forward = newForward;
         if (newForward.normalized == targetRotation.normalized) {
             rotating = false;
         }
     }
 }

 public void OnCollisionEnter(Collision collision) {
     if (collision.collider.tag == "Rope") { // check if collided with rope
         rotating = true;
         targetRotation = collision.collider.transform.right;
         targetRotation.y = transform.position.y; // set target Y rotation to current Y
     }
 }
Comment
Add comment · Show 18 · 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 Tomer-Barkan · Oct 29, 2013 at 06:17 AM 1
Share

fixed transform.y to transform.position.y. Sorry

avatar image Hamesh81 · Oct 29, 2013 at 06:24 AM 0
Share

Thanks a lot, I changed the OnCollision part to work with the raycast I'm using but there is still one error:

error CS1061: Type UnityEngine.Transform' does not contain a definition for y' and no extension method y' of type UnityEngine.Transform' could be found (are you missing a using directive or an assembly reference?)

Here is the code I am using:

 private Vector3 targetRotation;
     private bool rotating = false;
 
 void Update () {
         
         if (rotating) {
         Vector3 newForward = Vector3.RotateTowards(transform.forward, targetRotation, 1.0f * Time.deltaTime, 0);
         transform.forward = newForward;
         if (newForward.normalized == targetRotation.normalized) {
             rotating = false;
             }
         }
 if (hit.transform) // Hit collider
                     {
                         
                         rotating = true;
                         targetRotation = hit.transform.right;
                         targetRotation.y = transform.y; // set target Y rotation to current Y
                     }
 
 }

Apologies about the formatting, I had to copy and paste the code snippets together.

avatar image Tomer-Barkan · Oct 29, 2013 at 06:29 AM 0
Share

I changed transform.y to transform.position.y... line 18 in your code.

avatar image Hamesh81 · Oct 29, 2013 at 06:34 AM 0
Share

Ok, there's no errors now thanks a lot. The rotation works but for some reason the rotation is not affecting only the Y axis. The character has a large rotation offset around (what looks like) the X axis when the rotation is finished. Any ideas why this is happening?

avatar image Tomer-Barkan · Oct 29, 2013 at 06:48 AM 0
Share

The X rotation should be 0 after the rotation finishes. If it started with a non-0 rotation, then indeed the rotation will change to 0.

So you should be looking directly forward, not up or down at all... Is this not the case or is this not what you want?

Show more comments
avatar image
2

Answer by robertbu · Oct 29, 2013 at 05:42 AM

The typical way to solve this problem is to manipulate the point the character looks at so that the point has the same 'Y' value as the character:

 var q = Quaternion.LookRotation(hit.transform.right);
 // and this get executed each frame in Update()
 transform.rotation = Quaternion.RotateTowards(transform.rotation, q, speed * Time.deltaTime);
Comment
Add comment · Show 4 · 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 Hamesh81 · Oct 29, 2013 at 06:03 AM 0
Share

Thanks for that, I had to edit your code to fix a few things but there are still a few errors:

error CS1061: Type UnityEngine.Transform' does not contain a definition for y' and no extension method y' of type UnityEngine.Transform' could be found (are you missing a using directive or an assembly reference?)

error CS0117: UnityEngine.Quaternion' does not contain a definition for LookAt'

error CS1502: The best overloaded method match for UnityEngine.Quaternion.RotateTowards(UnityEngine.Quaternion, UnityEngine.Quaternion, float)' has some invalid arguments error CS1503: Argument #2' cannot convert object' expression to type UnityEngine.Quaternion'

And here is what the code looks like now:

 var v3 = hit.transform.right;
 v3.y = transform.y;
 var q = Quaternion.LookAt(v3);
 transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 1.2f * Time.deltaTime);
avatar image robertbu · Oct 29, 2013 at 06:10 AM 0
Share

Sorry, I tired and mixed up things a bit. Code above fixed. Since you are using a Vector for a look direction, you don't need to bring the 'Y' down. You need to bring the 'y' down when you are looking at a point. @tbkn brings up a good point. Given what you are doing, you don't need to calculate q each frame unless your system is dynamic.

avatar image Hamesh81 · Oct 29, 2013 at 06:38 AM 0
Share

No problems at all. I tried using your new code, but it doesn't seem to do anything. I put everything inside Update into the "if" statement that checks for the raycast hit but the rotation stays the same whether the raycast hits or not. Any ideas?

avatar image robertbu · Oct 29, 2013 at 01:53 PM 0
Share

'speed' is degrees per second, so it should be a larger number...try 90. Put a Debug.Log() statement inside your if to verify the hit. As a test you can just assign the rotation.

 transform.rotation = q;

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

17 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

Related Questions

Rotate with joystick - LookAt axis flipping 1 Answer

Local child rotation and transform.LookAt 2 Answers

Bullet not moving towards player 3 Answers

Look Rotation flipping object rotation after 180 degrees 1 Answer

Match rotation of gameobejcts in one (Y) axis 2 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