Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
5
Question by blernsball · Feb 26, 2014 at 01:43 PM · 2drotationquaternionaxislookrotation

Rotating a 2D sprite to face a target on a single axis.

Yes, yet another one of THESE questions. I know this has been asked numerous times before, but after scouring the board for days I can't find a solution.

My game is a top-down space shooter, I'm working in the 2D mode in unity (on the XY plane).

Basically when the player comes within a certain range of an enemy I'd like the enemy to turn and face the player. I'm using a circle collider w/trigger to do the detection and capture the target transform (the player's transform). That part works.

The issue (as always) is that the enemy will not turn around the Z-axis only when it turns. It rotates on all axis and usually ends up with the underside of the enemy sprite "facing" the player. When looking at it in 2D mode you end up looking at the edge of the sprite and it disappears.

Here is the code i'm using:

targetTransform = the player's transform

transform = the enemy's transform

Vector3 vectorToTarget = targetTransform.position - transform.position;

transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(vectorToTarget,Vector3.forward), 1 * Time.deltaTime);

Here is the log output in a typical run.

TARGETPOS:(1.1, 1.4, 0.0) SELFPOS:(5.0, 5.0, 0.0) VECTOR:(-3.9, -3.6, 0.0)

All those look correct to me. I have a feeling the issue lies in how the rotation is being done.

Some solutions I have seen involve modifying the x or y components of the Quaternion that returns from Quaternion.LookRotation. While that does sort of work, I've also read numerous things that say to never modify the components on a Quaternion in that way.

example: http://forum.unity3d.com/threads/36377-transform-LookAt-or-Quaternion-LookRotation-on-1-axis-only

I am sort of lost here. Should I not be using Quaternions to do rotation in 2D? I'm also wondering if this could be caused by the game object being rotated. I'm thinking that possibly LookRotation is not sure what the front of the ship is. In the documentation for LookRotation there is this section:

Returns the computed quaternion. If used to orient a Transform, the Z axis will be aligned with forward and the Y axis with upwards if these vectors are orthogonal.

I'm not quite sure what they are saying here. Does this mean that LookRotation always assumes that Z is forward? How would that ever work in 2D mode?

Any suggestions/help would be appreciated.

http://i.imgur.com/cr3nBuH.png

http://i.imgur.com/b8lIz6u.png

EDIT: I can use :

transform.LookAt(transform.position + new Vector3(0,0,1), vectorToTarget);

to get it to work, but the rotation is immediate instead of a nice fluid turn over time that Slerp will provide.

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

3 Replies

· Add your reply
  • Sort: 
avatar image
57
Best Answer

Answer by robertbu · Feb 27, 2014 at 02:16 PM

Try this:

 Vector3 vectorToTarget = targetTransform.position - transform.position;
 float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
 Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
 transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed);

You will have to define a 'speed' variable or replace it with a constant. If you don't want the rotation eased, replace 'Slerp' with RotateTowards, and adjust 'speed'.

Comment
Add comment · Show 16 · 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 blernsball · Feb 28, 2014 at 02:29 AM 0
Share

Thanks for the response, but that doesn't quite work. Although it does rotate around the z-axis, it doesn't end up pointing in the correct direction. It's not consistent in the direction it points either.

avatar image robertbu · Feb 28, 2014 at 02:34 AM 1
Share

This code depends on the 'forward' of your sprite being the right side of your sprite. If you are using the top of your sprite, then you can rotate your texture in Photoshop, or you need to adjust the 'angle' before passing it to AngleAxis(). AS for not consistent, you will have to explain. Sometimes this happens because the pivot point you want to rotation around is not the same a the pivot point of the object. With sprites, you can usually fix this by selecting the texture and changing the Anchor in the Inspector.

avatar image blernsball · Feb 28, 2014 at 03:05 AM 4
Share

Cool, I got it working by subtracting 90 from the angle like so:

float angle = ($$anonymous$$athf.Atan2(vectorToTarget.y, vectorToTarget.x) * $$anonymous$$athf.Rad2Deg) - 90;

Better then modifying all my textures. Thanks for the help!

As a follow-up, I guess that Quaternion.LookRotation doesn't work unless the object and axis are in very specific orientations?

avatar image Hsni blernsball · Sep 18, 2018 at 11:53 AM 1
Share

Did the job for me too. Thanks @blernsball and @robertbu.

avatar image Xain blernsball · May 19, 2019 at 07:39 PM 1
Share

thank u so much man

avatar image IronHead43 blernsball · Feb 05, 2021 at 06:19 PM 0
Share

thanks this really saved me!

avatar image robertbu · Feb 28, 2014 at 03:15 AM 0
Share

Correct. For LookAt() or LookRotation() to work without extra steps, the 'forward' of the object has to be facing positive 'z' when the rotation is (0,0,0).

avatar image samuelstelzer · Jun 24, 2015 at 09:47 PM 0
Share

Oh my god, thank you so much, I've been trying this for hours today! THAN$$anonymous$$ YOU!

Show more comments
avatar image
0

Answer by servival · Jun 27, 2015 at 01:33 PM

This is a tank turret code that I've created and i hope it helps:

 using UnityEngine;
 using System.Collections;
 
 public class AISmoothLookAT : MonoBehaviour {
     
     public Transform target;
     public Transform looker;
     
     public Transform Xsmoothlooker;
     public Transform Ysmoothlooker;
     
     public float Xspeed = 2f;
     public float Yspeed = 2f;
     
     
     
     // Use this for initialization
     void Start () {
         
     }
     
     // Update is called once per frame
     void Update () {
         
         looker.LookAt (target);
         
         
         float YRotation = looker.eulerAngles.y;
         float XRotation = looker.eulerAngles.x;
         
 
         
         Xsmoothlooker.rotation = Quaternion.Slerp(Xsmoothlooker.rotation , Quaternion.Euler(0 , YRotation, 0), Time.deltaTime * Xspeed);
         Ysmoothlooker.rotation = Quaternion.Slerp(Ysmoothlooker.rotation , Quaternion.Euler(XRotation , YRotation, 0), Time.deltaTime * Yspeed);
     }
 }
 

One more thing: Don't make the X rotating turret a child of Y rotating turret.

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
avatar image
0

Answer by Frizack400 · Jul 04, 2017 at 10:06 AM

Hey I have had the same problem and think I have found a way to do this quite simply. I would love your imput as its both a question and an answer. http://answers.unity3d.com/questions/1373642/using-quaternions-in-2d-to-follow-a-rotation-both.html

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

35 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

Related Questions

Transform Z axis rotation from center of screen toward mouse cursor with Quaternion.LookRotation for a top down game. 2 Answers

Unity 2D: my LookRotation keeps rotating on the wrong axis 1 Answer

Quaternion.LookRotation only on Y axis 0 Answers

Rotate multiple objects around a object, maintaining their own trajectory(not rotating their local forward vector) 1 Answer

Smooth rotation about global axis instead of local axis. 1 Answer


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