Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Set player rotation based on tile movement

Discussion in 'Scripting' started by Corva-Nocta, Aug 7, 2023.

  1. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Hey all, I'm working with the TileMap system, Unity's built in grids. Making a simple movement system where the player moves along the grid to navigate around. When the player moves from one tile to another, they snap to the center of each tile. Fairly simple so far. The part I am having trouble trying to figure out is how to make the player rotate to face the direction of a tile before snapping to that tile.

    Code (csharp):
    1. private void MoveToDestination()
    2. {
    3.    Vector3 targetPosition = walkableMap.CellToWorld(path[0]) + new Vector3(0.5f, 0, 0.5f);
    4.    current Tile = path[0];
    5.    transform.position = targetPosition;
    6. }
    So far working just fine. Just need to figure out how to get the rotation to snap to face the next tile direction. Any ideas?
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    You just need to get a direction from the player's current position to the next tile, and use something like Quaternion.LookRotation to generate a rotation facing that direction.

    If you're not sure how to get a direction, the docs have relevant lessons in that: https://docs.unity3d.com/Manual/VectorCookbook.html
     
  3. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Makes sense. LookRotation is pretty easy to use, so I just have to get the angle.

    Thanks for the link! Not sure which one is the exact method to use, but I'll see if I can figure it out
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    You don't need an angle, you need a direction.

    It should be straight forward to work out which of the techniques in the documentation give you a direction.
     
  5. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Oh interesting. So just a direction then. I think I can get that, should be easy to find.

    Trying out a few of the examples to see if I can get them to work
     
  6. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I can throw you one of my functions. You'll more than likely need to play around with it, to do more of what you're wanting:
    Code (CSharp):
    1. void TurnAndMoveTo(Vector3 moveTo)
    2. {
    3.     Vector3 direction = moveTo - transform.position;
    4.     Quaternion targetRotation = Quaternion.LookRotation(direction, Vector3.up);
    5.     transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed);
    6.  
    7.     transform.Translate(0, 0, moveSpeed);
    8. }
     
  7. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Hm, seem to be having trouble finding the proper code to work.
    Looks promising! I'll see if I can modify it a little. Thanks!
     
  8. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    I seem to have some trouble here. Can't quite get any of the codes to work properly. I can get some rotation with some of them, but never seems to get quite right.

    So one way I can easily test it is that since I am snapping from grid coordinate to grid coordinate, the rotations should all be in increments of 45⁰. I can't seem to get any consistency with rotation, or numbers that are indicating 45⁰ snapping.
     
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Again, angles aren't important here, it's about directions. It should only be a few lines of code.

    Code (CSharp):
    1. Vector3 direction = nextCell.transform.position - transform.position // or however you get the direction to the
    2. direction.Normalize();
    3. Quaternion lookRotation = Quaternion.LookRotation(direction, Vector3.forward); // or whatever direction is towards the screen
    4. transform.rotation = lookRotation;
    Needless to say you do this before you move to the next position.
     
    Last edited: Aug 7, 2023
  10. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Hm, I don't know why this is giving me trouble. It seems super straight forward, with each of the different methods. I must be missing something somewhere that isn't in the math that gets the direction
     
  11. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Well, what results are you getting, and what is the code of your current attempt(s) so far?
     
  12. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    OK I think I found part of the problem. Nothing major, but it has to do with the way tilemaps work. Since they are 2D planes, and I'm dealing with Vector3, the numbers have to be converted slightly. If you look at the Vector3 of a tile on a tilemap, X and y are it's position and z is the height, but if you use a normal Vector3 X and z are the position and y is the height. So I think I need to convert slightly, then it should start working properly
     
  13. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Code (csharp):
    1. Vector3 pathPos = new Vector3(path[0].x, 0, path[0].y) + new Vector3(0.5f, 0, 0.5f);
    2.                 Vector3 direction = (pathPos - transform.position).normalized;
    3.                 Quaternion lookRotation = Quaternion.LookRotation(direction, Vector3.forward);
    4.                 transform.rotation = Quaternion.Euler(transform.rotation.x, lookRotation.y, transform.rotation.z);
    This is what I am working with right now. The first line is converting the coordinates from the tilemap position to normal Vector3 position.

    Right now getting results on the Y rotation between -1 and 1
     
  14. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    This line:
    Code (CSharp):
    1. transform.rotation = Quaternion.Euler(transform.rotation.x, lookRotation.y, transform.rotation.z);
    It is 100% not doing what you think it's doing. Quaternion w, x, y and z components don't work the way you think they do; you need a math degree for that.

    You shouldn't need to do any rotation conversion stuff anyway. You only want to make sure your direction is pointing in the right direction. Then you just need to make the look rotation and assign it directly.
     
  15. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Ah that may be my problem.

    if I try to just set it as:
    Code (csharp):
    1. transform.rotation = lookRotation;
    the player does rotate, but into all kinds of weird angles. Its not just rotating on the Y axis its rotating on the X and Z as well.
     
  16. Corva-Nocta

    Corva-Nocta

    Joined:
    Feb 7, 2013
    Posts:
    801
    Code (csharp):
    1. Vector3 pathPos = new Vector3(path[0].x, 0, path[0].y) + new Vector3(0.5f, 0, 0.5f);
    2.                 Vector3 direction = (pathPos - transform.position).normalized;
    3.                 Quaternion lookRotation = Quaternion.LookRotation(direction, Vector3.up);
    4.                 transform.rotation = lookRotation;
    Got it working :D Thanks for the help!
     
  17. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    Code (CSharp):
    1. transform.LookAt(pathPos,Vector3.up);
     
  18. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    If I remember correctly, which isn't saying much, the "Vector3.up" part is what axis it either rotates on, or what it calculates off of. Because I remember having an issue with the Y, and in my particular case I just needed it to always be 0.

    So I had to modify it, something like:
    Code (CSharp):
    1. Vector3 direction = (pathPos - transform.position).normalized;
    2. direction.y = 0;
    3. Quaternion lookRotation = Quaternion.LookRotation(direction, Vector3.up);
    That's why I mentioned play around with it. :D

    But as far as a good learning staple, I remember that method helping me a lot with learning ways to modify directions/quaternions/eulers..

    Awesome! one problem down, a million to go.. I love playing with code, you're always learning something new.
     
    Corva-Nocta likes this.