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
3
Question by EDarkness · Apr 07, 2013 at 03:16 AM · movingdirections

How do I face my character in the direction the player is moving?

This seems like it should be something simple, but how do I simply set the character the character is using in the direction the player is moving in? I've been playing with this topic all day and haven't found anything that even remotely works. If anyone has played any Diablo style action adventure games, then you can imagine the way this functions. The rotation should happen on the y axis as the character on the screen adjusts to whatever direction the player is moving in.

All of the options I've looked at does some crazy rotation stuff with the transform, and that just seems overly complicated for what should be:

Moving left? Character faces left.

Instantly looking right? Character faces right.

Not sure what's going on with this, but my theory says take whatever direction the movement vector is going, then look in that direction.

Anyone have any ideas?

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
5

Answer by janzdott · Apr 07, 2013 at 04:59 AM

You can set the rotation of the character using Quaternion.LookRotation. For example..

 GameObject character;
 
 character.transform.rotation = Quaternion.LookRotation(Vector3.forward, Vector3.up);

That will make the character face forward. You can change the first Vector3 to any direction you want, and the character will face that direction

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 Fattie · Apr 07, 2013 at 07:44 AM 0
Share

Jarz, beginners should really just use "LookAt" rather than touching quaternions for any reason

avatar image EDarkness · Apr 07, 2013 at 02:39 PM 0
Share

Thanks for the assist. I tried both ways and neither worked. Whebert's suggestion caused the graphic to turn strange directions and then it stopped moving in the direction the controller was pointing in.

I tried janzdott's idea by changing the forward Vector3, but the movement got all strange and I started getting errors that the rotation viewing vector is 0. The rotation does seem fine, though. However, now the movement is all messed up.

I'm pretty new to Unity, but this seems like such a simple thing. Something that should have been done many many times. Why is this so hard? Ugh.

Sorry guys, just a little frustrated. Been messing around with this for days now.

Anyway I have... (all in Update())

 CharacterController Character$$anonymous$$ove = GetComponent<CharacterController>();
 float cordX = Input.GetAxis("Horizontal");
 float cordZ = Input.GetAxis("Vertical");
 private Vector3 direction = Vector3.zero;
 
 public float moveSpeed = 10.0f;
 float cordX = Input.GetAxis("Horizontal");
 float cordZ = Input.GetAxis("Vertical");
 
 if (Character$$anonymous$$ove.isGrounded) {
 
 direction = new Vector3(cordX, 0, cordZ);
 direction = transform.TransformDirection(direction);
 direction *= moveSpeed;
 
 }
 
 direction.y -= gravity * Time.deltaTime;
 
     rotationDirection = new Vector3(cordX, 0, cordZ);
     
     transform.rotation = Quaternion.LookRotation(rotationDirection, Vector3.up);
     
     Character$$anonymous$$ove.$$anonymous$$ove(direction * Time.deltaTime);
 

I figured that something in there is causing the movement to be all messed up once the rotation is in. Perhaps you guys can see something I'm missing.

avatar image BadSeedProductions · Jan 22, 2016 at 03:20 AM 0
Share

That's great if you want the character to look in one direction :P

avatar image Wicaodian · May 24, 2016 at 07:00 AM 0
Share

Thank You So $$anonymous$$uch You Saved $$anonymous$$y Life :')

avatar image
2

Answer by whebert · Apr 07, 2013 at 05:03 AM

Apply this to your game object to look in the direction of your movementVector:

 transform.LookAt(transform.position + movementVector);


EDIT: (I first responded in a comment then realized I should've edited my answer)

Your sample code helps us understand what you want to accomplish a bit better. I think there are a couple of reasons you're not seeing what you want to see with your current code.

One issue I see is that you're moving your CharacterController in a relative direction (using the direction = transform.TransformDirection(direction)), but rotating with the world absolute of Vector3(cordX, 0, cordZ), so the two won't match.

And also, since your relative direction changes every single frame based on your new forward direction, your movement direction will probably just be spinning around your current location since, say, moving to the right relative to where you are will make you go in a tiny circle.

The error you see about the look rotation viewing vector being 0 is that you're not checking for your direction vector to be (0,0,0), which will cause that error.

If you want the relative movement, you might want to use a damping so that you won't spin in place every frame. I took your code and made a few modifications. Not sure if this is what you want, and I don't know what else you have attached to this game object besides your CharacterController, but the following might do something like you want?

 using UnityEngine;
 using System.Collections;
 
 public class CCTest : MonoBehaviour {
     
     public float rotateDegreesPerSecond = 180.0f;
     private Vector3 direction = Vector3.zero;
     public float moveSpeed = 10.0f;    
     public float gravity = 10.0f;
     
     // Use this for initialization
     void Start () {
         
     }
     
     // Update is called once per frame
     void Update () {
     
         CharacterController CharacterMove = GetComponent<CharacterController>();
         float cordX = Input.GetAxis("Horizontal");
         float cordZ = Input.GetAxis("Vertical");
          
         if (CharacterMove.isGrounded) {
  
             direction = new Vector3(cordX, 0, cordZ);
             direction = transform.TransformDirection(direction);
          
         }
         
         // If direction is not zero, rotate towards direction (via rotateDegreesPerSecond) and move CharacterController in current forward vector
         if(direction != Vector3.zero)
         {
             // Take care of direction being directly behind our current forward vector since the 
             // Quaternion.RotateTowards will continuously alternate between right and left rotations to get there,
             // resulting in never getting there, just wiggling around the current transform.rotation.
             if(Vector3.Angle(transform.forward, direction) > 179)
             {
                 // This will cause us to always turn to the right to go the opposite direction
                 direction = transform.TransformDirection(new Vector3(.01f, 0, -1));
             }
             transform.rotation = Quaternion.RotateTowards( transform.rotation, Quaternion.LookRotation(direction), rotateDegreesPerSecond * Time.deltaTime);
 
             Vector3 moveDirection = transform.forward;
             moveDirection.y -= gravity * Time.deltaTime;
             CharacterMove.Move(moveDirection * moveSpeed * Time.deltaTime);
         }
     }
 }
Comment
Add comment · Show 14 · 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 Loius · Apr 07, 2013 at 06:21 AM 0
Share

Be careful with this one - movementVector.y must be zero or your dude will tilt. Hilarious, but probably not the intended effect. :)

avatar image Fattie · Apr 07, 2013 at 07:43 AM 0
Share

dude you meant non-zero, right ?

avatar image Loius · Apr 07, 2013 at 07:57 AM 0
Share

Actually I meant dot-zee. $$anonymous$$oving between Blender and Unity sucks. edit- wait, no, that's blender dangit

yeah, you have to look at a point on your movement plane. If your dude moves on the X/Z plane like most flat games, the Y of movement has to be zero so the transform looks along its current X/Z plane ins$$anonymous$$d of looking up or down

I mean I guess to be technically most correct, if you want to avoid tilt, you should be sure that the movement vector lies on the plane of expected facing directions of the character. And if tilt is a thing you want - like with a spaceship - then never$$anonymous$$d, tilt away.

avatar image whebert · Apr 07, 2013 at 01:55 PM 0
Share

Yeah, I didn't know what type of game OP needed this for, but sounded like it was using fairly simple movementVectors, like (1,0,0) or (-1,0,0), at least in his example. But like you said, if the game is only moving in XY plane, just make sure Y component is 0, and in any case, make sure your movement vector is not Vector.zero.

avatar image EDarkness · Apr 08, 2013 at 12:02 AM 0
Share

Thanks for the information, Whebert. Unfortunately, now the character won't move at all. I have to get some work done around the house, but once I finish I'll look more closely at what was done.

Show more comments
avatar image
1

Answer by Dracorat · Apr 08, 2013 at 05:26 PM

I'm writing a game with Diablo-style movement.

I have placed the "ground plane" at height 0 and turned off its material renderer (so it's invisible) There is no 3rd dimension (hills) in my game, but you could easily account for height in yours by adding a fixed value along the Y axis with your ground-based collider. (I have 0 hard coded at the appropriate spot.)

At any rate, here is the actual code that makes the character look at the mouse (and even better, I don't do it right away, I do it over time so there's a rotation speed.)

 using UnityEngine;
 using System.Collections;
 
 public class MainMovement : MonoBehaviour {
     private float lookSpeed = 200;
     
     void Start () {
     }
     
     void FaceInput() {
         GameObject shipModel = GameObject.Find("ShipModel"); // Necessary because I have a few objects all packaged together in to one prefab and not all of it needs to rotate.
         Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hitLocation;
         if(Physics.Raycast(mouseRay, out hitLocation)){
             Vector3 deltaLook = new Vector3(hitLocation.point.X, 0, hitLocation.Z) - this.transform.position; // Here, 0 is a hard-locked Y value. This is where you'd account for terrain height if you wanted. Most likely by using the model's Y value - not the raycast Y value so that the model doesn't "tilt" up or down.
             Quaternion targetRotation = Quaternion.LookRotation(deltaLook);
             shipModel.transform.rotation = Quaternion.RotateTowards(shipModel.transform.rotation, targetRotation, Time.deltaTime * lookSpeed); // LookAt is immediate, RotateTowards will go over time
         }
     }
     
     void Update () {
         FaceInput();
     }
 }
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

18 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

Related Questions

rotating/moving colliders with or without rigidbodies? 2 Answers

Help moving an object towards one it is looking at. 1 Answer

Dragging Objects with the mouse 1 Answer

Moving Platforms + Third Person Controller 0 Answers

Player Don't stops walking when I stop pressing a key 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