Search Unity

LookRotation - Combine transform.forward / transform.up

Discussion in 'Scripting' started by ldouglas, Aug 27, 2018.

  1. ldouglas

    ldouglas

    Joined:
    May 6, 2016
    Posts:
    16
    Hi everyone,

    First off: apologies for the 'basic nature' of my question(s), I really tried to find a solution for hours but I can't seem to find one - hence this post.

    While not being a professional / developer, I'm still totally into learning / creating Unity-driven VR-projects for my own fun's sake.

    So... I'll dive right into it:
    I've written my own FPS-controller-script which I'm trying to improve / extend constantly.

    Currently I'm trying to 'create' footprints (auto-generated cubes ATM).
    I'm using a raycast in order to determine the slope-value of the object the player is currently walking on.

    Now, as these footprints shall face 1.) the forward-direction of the player-capsule / 2.) 'rest' on the actual surface / it's slope-'value' I'm trying to combine forward / up-values in order to generate the right angle.

    I tried to achieve this using 'LookRotation':
    upload_2018-8-27_20-45-3.png

    upload_2018-8-27_20-46-29.png

    Which seemed to work at first glance - until I realised that this would only take the CharacterCapsule's forward-direction into consideration:

    upload_2018-8-27_20-45-34.png

    In order to see whether raycastHit2.transform.up would actually return a valid transform-value, I then tried the following:
    upload_2018-8-27_20-48-32.png

    The 'slope-angel' would then be applied as desired - but without facing the player's forward-direction, of course...

    upload_2018-8-27_20-51-28.png

    Basically my question would be:
    Is there a way to 'calculate' / combine up / forward-values of different objects?

    Am I completely wrong by trying to use 'LookRotation' for this task?

    I'd like to thank everyone in advance for having spent time reading this post.

    Best,
    Lex
     
  2. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Have you tried setting the
    transform.up
    of the 'footprint' cube to be the normal of the raycast hit point. Does that work?
     
    ldouglas likes this.
  3. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    instead of:
    Code (CSharp):
    1. footprint.transform.rotation = Quaternion.LookRotation(CharacterCapsule.transform.forward,raycastHit2.transform.up);
    you need to use:
    Code (CSharp):
    1. footprint.transform.rotation = Quaternion.LookRotation(CharacterCapsule.transform.forward,raycastHit2.normal);
    from "raycastHit2.transform.up" to "raycastHit2.normal".
     
    ldouglas likes this.
  4. ldouglas

    ldouglas

    Joined:
    May 6, 2016
    Posts:
    16
    Hi @Doug_B ,
    Thank you for your input - unfortunately, this doesn't work either - result is the same as image #2 / #3.
     
  5. ldouglas

    ldouglas

    Joined:
    May 6, 2016
    Posts:
    16
    Hi @JoshuaMcKenzie ,
    Thank you providing these snippets - unfortunately, this doesn't work either - result is the same as image #2 / #3.
     
  6. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    Are you still also setting footprint.transform.up?
    Ah, right... I forgot that the forward parameter in LookRotation has the priority, we want the opposite.

    you'll need to get the capsule's rotation and rotate it by the difference in rotation the normal is from the capsule's up.

    Code (CSharp):
    1. footprint.transform.rotation = CharacterCapsule.transform.rotation * Quaternion.FromToRotation(CharacterCapsule.transform.up,raycastHit2.normal);
    basically what this does is it finds the angle (and direction) from the capsule's "up" to the normal of the surface its on. then it grabs the capsule's current rotation and rotates it by that same angle. It then takes this result and applies it to the footprint (the capsule's rotation will remain unaffected by this).
     
    flashframe and ldouglas like this.
  7. ldouglas

    ldouglas

    Joined:
    May 6, 2016
    Posts:
    16
    @JoshuaMcKenzie Thank you very much for your efforts.
    While this does change the directions of the auto-generated footprints, there's still something off, unfortunately...

    Again, thank you very much for the response!

    upload_2018-8-28_13-11-28.png
     
  8. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Swap the operands of the multiplication, as quaternion multiplication is noncommutative, i.e. Q1 * Q2 is not guaranteed to be the same as if you calculated Q2 * Q1.
     
    Last edited: Aug 29, 2018
    ldouglas likes this.
  9. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    Thats odd... that definitely should have worked, @ldouglas, Whats the current code?

    The order I have it multiplying by should be the correct order. We are starting at the orientation of the capsule and then rotating it by the offset rotation we found. Plus we are modifying the rotation in worldspace, which makes that result he is seeing even more confusing...

    Fortunately there is more than one way to get the desired rotation, we can try using Cross products:
    Code (CSharp):
    1. void create_footprint()
    2.     {
    3.         if(Vector3.Dot(raycastHit2.normal,CharacterCapsule.transform.up) < 0.1f)
    4.             return; // slope too steep or facing away, wouldn't make sense to spawn a footprint now
    5.  
    6.         //Create footpriint
    7.         //*************
    8.         GameObject footprint = GameObject.CreatePrimitive(PrimitiveType.Cube);
    9.         footprint.transform.localScale = new Vector3(0.1f,0.1f,0.25f);
    10.         footprint.transform.position = raycastHit2.point;
    11.  
    12.         // find the direction that is perpendicular to both the hit normal and the character's right,
    13.         // and that is the desired forward direction
    14.         Vector3 forward = Vector3.Cross(raycastHit2.normal,CharacterCapsule.transform.right);
    15.  
    16.         // now set the foot prints rotation so that it has that desired direction as forward and the normal as up.
    17.         footprint.transform.rotation.SetLookRotation(forward,raycastHit2.normal);
    18.     }
     
    ldouglas likes this.
  10. ldouglas

    ldouglas

    Joined:
    May 6, 2016
    Posts:
    16
    Thanks @Suddoha - this seems to work!
     
  11. ldouglas

    ldouglas

    Joined:
    May 6, 2016
    Posts:
    16
    Thank you, @JoshuaMcKenzie - really appreciate the elaborate response.
    Will give this a try for sure!
     
  12. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Well, quaternion multiplication does not rotate an object as if you used the world coordinate system for each of the rotations, i.e. if you expressed it as two seperate rotations, it would definitly not rotate around the world space y-axis and then around the world space z-axis.