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 justinpatterson · Oct 25, 2014 at 03:57 PM · terrainrotatetarget

Rotating an object toward target AND with terrain?

Hi everyone, I feel like I've just been looking at this too long and haven't come up with the solution but I don't think the question is that bad. I've seen questions about rotating an object toward a target (so be facing the correct direction of where it's walking), and others about rotating an object to the normals of a terrain. I'm trying to make an object slowly look at a target while also having its rotation follow the terrain. Anyone have hints about what I should be doing in the commented line to make this work?

I've tried some basic adding and multiplying of the lookRotation/groundRotation variables but it seems to be super wonky so I know I'm missing something silly.

 //some code figuring out how char controller should move is above here updates a "moveDirection" variable
 
 RaycastHit hit;
 Physics.Raycast(transform.position, -Vector3.up, out hit);
 _direction = (target.position - transform.position).normalized;
 _direction+=new Vector3(hit.normal.x, 0, hit.normal.z);
 _lookRotation = Quaternion.LookRotation(_direction*-1);
 Quaternion groundRotation = Quaternion.FromToRotation (Vector3.up, hit.normal); 
 //do something with _lookRotation and groundRotation
 transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * speed);
 
 //after being rotated, the char controller is then moved by "moveDirection"

If more code is needed for contextual purposes, let me know and I'll provide. Thanks so much for your help!

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

Answer by robertbu · Oct 25, 2014 at 04:49 PM

If I understand your question correctly, the problem can be split into two parts. Aligning with the normal of the surface, and given some alignment with the ground, point in the direction of the target by rotating on the local 'y' axis. In essence you have a tank with a turret where the gun on the turret cannot be raised or lowered. So here is a bit of untested code to solve that problem:


     Quaternion qTo = Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation;
     transform.rotation = Quaternion.Slerp (transform.rotation, qTo, alignmentSpeed * Time.deltaTime);

     Vector3 targetPos = ProjectPointOnPlane(transform.up, transform.position, target.position);
     qTo = Quaternion.LookRotation(targetPos - transform.position, transform.up);
     transform.rotation = Quaternion.Slerp (transform.rotation, qTo, rotationSpeed * Time.deltaTime);


 Vector3 ProjectPointOnPlane(Vector3 planeNormal, Vector3 planePoint, Vector3 point)  {
     planeNormal.Normalize();
     var distance = -Vector3.Dot(planeNormal, (point - planePoint));
     return point + planeNormal * distance;
 }    

The code inside the dashes goes in your Update() or coroutine. 'alignmentSpeed' and 'rotationSpeed' are variables you define. Start with a value of 3.5f for each.

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 justinpatterson · Oct 25, 2014 at 06:37 PM 0
Share

Hi @robertu,

This is exactly what I had in $$anonymous$$d in terms of functionality. I had a few questions and comments.

Comments

I was able to easily export it into my game, everything worked fine. The only change I made to make the objects face frontward to the target ins$$anonymous$$d of backward was:

 qTo = Quaternion.LookRotation((targetPos - transform.position)*-1, transform.up);
 //the " (...)*-1 " is what I added

You've got some rad skills to just freecode that ha ha. Regardless of my comically $$anonymous$$or change, I'm marking this as solved. Thanks again!

Question

Is it possible to condense the code into one influence on rotation? If not, that's fine. I was just curious. I figure it might be better in the long run to influence the transform's rotation just once ins$$anonymous$$d of twice per frame (lines 2 and 5 of your Update() code). I was trying to brainstorm ways to do it. $$anonymous$$y initial idea is to just store another variable, but I was wondering if you had any thoughts on the matter.

avatar image robertbu · Oct 25, 2014 at 07:12 PM 0
Share

It is possible to avoid two assignments to transform.rotation, but I'm not sure it is worth it. The problem is that you need the up vector from the terrain alignment step before you can do the rotation step. The rotation step depends on knowing the axis of rotation as well as the normal for the plane used in ProjectPointOnPlane(). This can be done by independently rotating an transform.up and using the result as the vector and then combining the two rotations when assigning to transform.rotation.

avatar image Smireles · May 25, 2017 at 06:00 AM 0
Share

Great! This really helped me out. Less the Slerp transitions, I needed exactly what your solution gave. Thanks a lot @robertbu

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

28 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

Related Questions

Is there a better way to tilt terrain at runtime? 1 Answer

Quaternions- how to leave out Y rotations... 1 Answer

Camera rotation around player while following. 6 Answers

How do I transfer the image a camera takes in to a box or plane?/create a portal 1 Answer

Rotating a turret body and head 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