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 Ulftek · Jan 08, 2019 at 05:55 AM · transform.lookat

FlyCam and LookAt problem

This is my first question here, so please bear with me :). I also did some searches and seemed to find some issues similar to my problem, but they unfortunately weren't close enough to help me. Or perhaps I didn't know the correct terminology to look up.

I found a pretty good FlyCam script (found here: http://wiki.unity3d.com/index.php/FlyCam_Extended) that I use to control my camera, and it works great. I more or less pulled a "script kiddie with this, but I was able to tweak it a bit for my needs, but here is the code for it:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerController : MonoBehaviour
 {
     /*
     EXTENDED FLYCAM
         Desi Quintans (CowfaceGames.com), 17 August 2012.
         Based on FlyThrough.js by Slin (http://wiki.unity3d.com/index.php/FlyThrough), 17 May 2011.
  
     LICENSE
         Free as in speech, and free as in beer.
  
     FEATURES
         WASD/Arrows:    Movement
                   Q:    Climb
                   E:    Drop
                       Shift:    Move faster
                     Control:    Move slower
                         End:    Toggle cursor locking to screen (you can also press Ctrl+P to toggle play mode on and off).
     */
 
     public static PlayerController instance;
     public float clickToSpeed = 0.5f;
     public bool clickToLocation;
     public Transform target;
 
     public float cameraSensitivity = 200;
     public float climbSpeed = 20;
     public float normalMoveSpeed = 100;
     public float slowMoveFactor = 0.25f;
     public float fastMoveFactor = 3;
 
     private float rotationX = 0.0f;
     private float rotationY = 0.0f;
 
     void Awake()
     {
         if (instance == null)
         {
             instance = this;
             //DontDestroyOnLoad(gameObject);
         }
         else if (instance != this)
         {
             Destroy(gameObject);
         }
     }
 
     void Start()
     {
         //Screen.lockCursor = true;
     }
 
     void Update()
     {
         if (Input.GetMouseButton(1))
         {
             rotationX += Input.GetAxis("Mouse X") * cameraSensitivity * Time.deltaTime;
             rotationY += Input.GetAxis("Mouse Y") * cameraSensitivity * Time.deltaTime;
             rotationY = Mathf.Clamp(rotationY, -90, 90);
 
             transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
             transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);
         }
         
 
         if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
         {
             transform.position += transform.forward * (normalMoveSpeed * fastMoveFactor) * Input.GetAxis("Vertical") * Time.deltaTime;
             transform.position += transform.right * (normalMoveSpeed * fastMoveFactor) * Input.GetAxis("Horizontal") * Time.deltaTime;
         }
         else if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))
         {
             transform.position += transform.forward * (normalMoveSpeed * slowMoveFactor) * Input.GetAxis("Vertical") * Time.deltaTime;
             transform.position += transform.right * (normalMoveSpeed * slowMoveFactor) * Input.GetAxis("Horizontal") * Time.deltaTime;
         }
         else
         {
             transform.position += transform.forward * normalMoveSpeed * Input.GetAxis("Vertical") * Time.deltaTime;
             transform.position += transform.right * normalMoveSpeed * Input.GetAxis("Horizontal") * Time.deltaTime;
         }
 
 
         if (Input.GetKey(KeyCode.Q)) { transform.position += transform.up * climbSpeed * Time.deltaTime; }
         if (Input.GetKey(KeyCode.E)) { transform.position -= transform.up * climbSpeed * Time.deltaTime; }
 
         if (Input.GetKeyDown(KeyCode.End))
         {
             //Screen.lockCursor = (Screen.lockCursor == false) ? true : false;
         }
 
         GoToTarget();
     }
 
     private void GoToTarget()
     {
         if (clickToLocation)
         {
             transform.LookAt(target);
             transform.position = Vector3.Lerp(transform.position, target.position, clickToSpeed);
         }
 
         // Check to see if the player has gotten to the location.  If so, make clickToLocation false.
         if (transform.position == target.position)
         {
             clickToLocation = false;
         }
     }
 }

My issue comes in when I use transform.LookAt(target). I have an option for the user to click on an item from a panel and when they do, the camera looks towards the target, as it should, then Lerp is used to move them to it. All of that works great. The problem is that when I go to hold down the right-mouse button after this, the new direction I'm facing via LookAt isn't "known" by the variables connected to the mouse, so the camera quickly points back to the old direction that it "knows". So what I'd like to do is be able to update that information from what LookAt does. As I mentioned, I went very much "script kiddie" on this so I'm not entirely sure what is going on, but near as I can tell, I would think that if I can somehow get the info from LookAt into transform.localRotation, I'll be good to go:

 transform.localRotation = Quaternion.AngleAxis(rotationX, Vector3.up);
 transform.localRotation *= Quaternion.AngleAxis(rotationY, Vector3.left);

Am I in the ballpark on this? This feels right, but I just don't know how to get the information from the way the camera is facing from LookAt into transform.localRotation.

Thanks in advance!

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 Ady_M · Jan 08, 2019 at 03:52 PM

Does this fix your problem?:

 if (clickToLocation)
 {
     transform.LookAt(target);
     transform.position = Vector3.Lerp(transform.position, target.position, clickToSpeed);

     // Calculating rotationX and rotationY after using LookAt
     Vector3 vectorForwardAlongGround = transform.forward;
     vectorForwardAlongGround.y = 0;
     rotationX = Vector3.SignedAngle (vectorForwardAlongGround, transform.forward,  transform.right);
     rotationY = Vector3.SignedAngle (Vector3.forward, vectorForwardAlongGround,  Vector3.up);
 }


Updated on 10/1-2019:

 

It turns out you've been using rotationX to yaw and rotationY to pitch when it's the other way around in Unity. Rotating an object on its local X-axis should make it pitch up/down.

 

Use the following code for the input part.

Note that Mouse X now affects rotationY

and Mouse Y affects rotationX (also don't forget the minus sign here: rotationX -=).

 

This may feel unintuitive in the beginning, but you'll get used to it. It's important to respect the game engine's coordinate system otherwise it may confuse those who try to help and cause problems with the built-in functions.

 if (Input.GetMouseButton(1))
 {
     rotationY += Input.GetAxis("Mouse X") * cameraSensitivity * Time.deltaTime;
     rotationX -= Input.GetAxis("Mouse Y") * cameraSensitivity * Time.deltaTime;
     rotationX = Mathf.Clamp(rotationX, -90, 90);
     
     // A compact way of yawing (using rotationY) and then pitching (using rotationX)
     transform.localRotation = Quaternion.Euler(rotationX, rotationY, 0);
 }

 

In the GoToTarget method use the code from my first answer.

 rotationX = Vector3.SignedAngle (vectorForwardAlongGround, transform.forward,  transform.right);
 rotationY = Vector3.SignedAngle (Vector3.forward, vectorForwardAlongGround,  Vector3.up);

 

I've tested it and it works.

Comment
Add comment · Show 6 · 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 Ady_M · Jan 08, 2019 at 04:32 PM 0
Share

There are potentially two problems with your script besides the one you mentioned.

 

Problem 1: Vector3.Lerp

 

Are you intentionally using Lerp like that? It can make it difficult to control the speed. What it is actually doing is cutting the distance in half every frame because clickToSpeed is 0.5. If clickToSpeed were 0.1 then it would cut the distance by 10% very frame. But because the distance gets shorter after each frame (after each Lerp), 10% is not the same in units (cm, meters, feet, etc) as it was the frame before. In other words, your object slows down as it gets closer to the destination. If you did that on purpose then don't worry about it. But if it wasn't your intention then try using Vector3.$$anonymous$$oveTowards() ins$$anonymous$$d. Be aware, though, that it would make the movement linear.

 

Problem 2: Checking if the destination has been reached

 

Avoid doing if (float1 == float2) as it may yield unpredictable results (Vector3 consists of 3 floats: x, y and z). Ins$$anonymous$$d, you should check if the float value is less than. The float value to check in this case would be the distance between the object and the target.

 // Check to see if the player has gotten to the location.  If so, make clickToLocation false.
 if (Vector3.Distance (transform.position, target.position) < 0.01f)
 {
     transform.position = target.position; // Unnecessary if you use Vector3.$$anonymous$$oveTowards above
     clickToLocation = false;
 }
avatar image Ulftek Ady_M · Jan 08, 2019 at 08:56 PM 0
Share

Ok, now you've given me a conundrum LOL. Now I have to decide between slowing down when getting close (Lerp) or just going full speed using $$anonymous$$oveTowards (which I didn't know about so I learned something :) ).

As far as your advice to avoid if (float1 == float2), I see what you mean, but I wasn't sure of any other way to get my object to keep heading that way. When I did to turn it off was put the sphere colliders on them which are bigger than their float coordinates so the Lerp stops well before reaching them anyway and also makes clickToLocation = false; To be honest, I think your $$anonymous$$oveTowards() would allow me to avoid all of that hassle with colliders and triggers, messing with clickToLocation, etc.

And I wasn't sure if I could go with something like less than with those floats. I wasn't sure if something would act goofy with it depending on which direction you are co$$anonymous$$g from, you may end up with your own location already being negative in relation to where you're wanting to go. Does that make sense? Or is that something I wouldn't have had to worry about?

avatar image Ulftek · Jan 08, 2019 at 08:43 PM 0
Share

Unfortunately no. Once I right-click, it faces me in an entirely different direction than I was facing before I moved to the target. On the plus side, it managed to actually change where to face on the right-click (something I haven't been able to manage myself), so I think this is heading somewhere. It just didn't change it correctly to the way I was facing after the move.

avatar image Ulftek · Jan 10, 2019 at 06:07 PM 0
Share

I've been tinkering around with the code you gave. I "think" I have half of the problem solved. I seem to have rotationX figured out, but so far I haven't been able to get rotationY figured out. Here is my code so far (based on yours with rotationY commented out since it isn't working). Any advice on rotationY? I'm slowly grasping what is going on here, but it is VERY new to me so for now I am blindly making changes here and there hoping that they work. That is pretty much happened with my "fix" for rotationX.

 Vector3 direction = target.position - transform.position;
                 direction.y = 0;
 
                 float angleX = Vector3.SignedAngle(direction, transform.forward, Vector3.up);
                 //float angleY = Vector3.SignedAngle(direction, transform.right, Vector3.left);
 
                 transform.rotation = Quaternion.LookRotation(direction);
 
                 rotationX -= angleX;
                 //rotationY -= angleY;
                 //rotationY = Vector3.SignedAngle(Vector3.forward, direction, Vector3.up);
avatar image Ady_M Ulftek · Jan 10, 2019 at 07:51 PM 0
Share

I found the problem and updated my answer.

avatar image Ulftek · Jan 10, 2019 at 10:27 PM 0
Share

Works now! Thank you!! The rotationX to yaw and rotationY to pitch came from the script I was using. Guess that's what happens when I "script kiddie" something like this...when something doesn't work, I don't know enough to effectively troubleshoot. Tell me, I was having a terrible time getting things to line up on x and y. Could this be due to the way the original script was written? For example, my tinkering after adding my latest comment gave me better results, but nowhere near as perfect as what you just gave me. The y was still janky, but just not as bad. But while I was poking around, I noticed that I was working with x in the inspector for rotationY and y in the inspector for rotationX. It was pretty confusing.

This is my first foray into 3D program$$anonymous$$g. Up until now I've been doing relatively simple 2D stuff in Unity. But one thing is clear...even though I learned a lot fumbling through this, I definitely need to find a good place to learn more about this. Any recommendations? I've been reading up on the documentation, but it isn't the same as a good tutorial.

Again, thank you VERY much!

avatar image
0

Answer by badadam · Jan 10, 2019 at 08:05 PM

You can use Animation tab. You can add animation to your camera by pressing record button after you select your final time and change the rotation and position values of the camera without writing code in a few minutes.

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 Ady_M · Jan 10, 2019 at 08:39 PM 0
Share

I'm pretty sure he's looking for a more dynamic solution.

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

98 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

Related Questions

How do I make an object in game face the direction it's traveling while viewing from above? 1 Answer

NavMesh Lookat causes jittery glitch in character 0 Answers

Transform.LookAt() when transform.forward is offset 1 Answer

Firing a projectile from orbit 1 Answer

Problems with using gravity and also MoveTowards/LookAt functions 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