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
1
Question by CrowbarSka · Oct 09, 2018 at 01:01 PM · rotationrotate objectquaternions2d rotationlook at

How can I make a character look in a direction that's halfway between its direction of 2D movement and facing the camera?

This is a bit of a specific one so bear with me.

I have a game with Rigidbody2D-based characters. It's side view, and characters can float/swim around X/Y axes freely.

My NPCs are 3D meshes, so they can be rotated to look in the direction of their movement. I have the mesh as a child of an empty gameobject which I can use for this purpose.

The problem is that I want their rotation to be limited to a narrower cone, so they're not facing absolutely in that direction, but kind of half-facing the camera so you can see their faces.

alt text

See this image above. The character can move along X and Y, but they should not have free rotation. It should be clamped to a circle kind of like the green cone (same angle in all directions).

The result should be that they always look kind of like one of the blue faces in the image on the right, always half-facing the camera and half-facing their direction of movement.

I'm struggling to figure out the maths required to get this effect. I've got something approximately working but it's not smooth and it's not accurate.

 void LookTowardsTarget(Vector3 target)
 {
 Vector3 direction = (lastLightPosition - transform.position).normalized;

 float clampedX = direction.x * maxPivotAngle;
 float clampedY = direction.y * maxPivotAngle;

 if (direction.x < 0 && clampedY < 0)
     clampedY = -clampedY;
 else if (direction.x > 0 && clampedY < 0)
     clampedX = -clampedX;
 else if (direction.x > 0 && clampedY > 0)
     clampedY = -clampedY;
 else if (direction.x < 0 && clampedY > 0)
     clampedX = -clampedX;

 lookPivot.rotation = Quaternion.Euler(clampedX, clampedY, 0f);
 }

The 4 "if" statements are there to correct and negate certain axes being negative or positive in the code that precedes it. I'm happy to throw all this away though.

Uhh... help?! Rotational mathematics are really not my strong point!

rotatingcharacter.png (128.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

1 Reply

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

Answer by LCStark · Oct 09, 2018 at 01:42 PM

Vector3.Slerp or Quaternion.Slerp should help you with this one. You can interpolate spherically between two vectors (or two rotations), so setting the t parameter to 0.5f will give you a half-way vector (or rotation).

Comment
Add comment · Show 5 · 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 CrowbarSka · Oct 09, 2018 at 09:26 PM 0
Share

Awesome, that works much better! Thank you! Here's my resulting code:

 // Pivots a transform to look part-way between a) a position in world space and b) towards the camera .
     void LookTowardsTarget(Vector3 target)
     {
         // Get the direction as a non-normalized vector.
         Vector3 directionToTarget = transform.position - target;
 
         // Calculate the rotation as a Quaternion.
         // We do this by finding a lerp value between Quaternion.identity (straight forwards along Z) and a look rotation from above.
         // We use a fixed lerp value as specified in the Inspector.
         Quaternion rot = Quaternion.Lerp(
             Quaternion.identity,
             Quaternion.LookRotation(directionToTarget, Vector3.up),
             lookPivotAmount);
 
         // Set the transforms rotation.
         lookPivot.rotation = rot;
     }

There is a little snag whereby the 'move up' and 'move down' variants in my example image don't ever show, it's always snapped somewhere between the two adjacent ones (i.e. there is no 12 o'clock or 6 o'clock). Any ideas?

avatar image LCStark CrowbarSka · Oct 10, 2018 at 09:51 AM 0
Share

I can't be sure this is the source of the problem, since I haven't used LookRotation a lot, but I think it is the cause here. If your target is above you, you're trying to find a rotation which looks in the up direction, but also has its own relative up direction as close to the global up as possible. When the directionToTarget is close to Vector3.up, the resulting rotation will snap between up being on the left and right.

I think it would be better if you first calculated your target vector and then used LookRotation to get the rotation you need.

Vector3 directionToTarget = targetPosition - currentPosition;
Vector3 directionToCamera = cameraPosition - currentPosition;

Vector3 lookDirection = Vector3.Slerp(directionToTarget, directionToCamera, 0.5f); Quaternion rot = Quaternion.LookRotation(lookDirection, up);


You can always use Debug.DrawRay to check whether the vectors you've generated are correct. ( Debug.DrawRay documentation).
avatar image CrowbarSka LCStark · Oct 12, 2018 at 01:04 PM 0
Share

That works perfectly! Thank you so much!

I ended up turning this into a static method so I can call it from any object. I just pass in the object's position, the 'look target' position, and a float that controls how strongly it pivots.

 public static Quaternion LookTowardsTarget(Vector3 target, Vector3 origin, float lookPivotAmount)
 {
     Vector3 directionToTarget = origin - target;
     Vector3 directionToCamera = origin - CameraController.mainCameraTransform.position;
 
     Vector3 lookDirection = Vector3.Slerp(directionToTarget, directionToCamera, lookPivotAmount);
 
     Quaternion rot = Quaternion.LookRotation(lookDirection, Vector3.up);
 
     return rot;
 }

I also found that your initial direction calculations were the wrong way round. :p

Show more comments

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

124 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

Related Questions

Rotating 2D sprite to match surface. 0 Answers

Quaternion reset rotations didnt smooth 0 Answers

Rotating an object in relation to its endpoints 1 Answer

(2D) rotate object to face movement direction 1 Answer

Strange rotation pattern. 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