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

What's the opposite of LookAt?

Discussion in 'Scripting' started by Treasureman, Mar 19, 2016.

  1. Treasureman

    Treasureman

    Joined:
    Jul 5, 2014
    Posts:
    563
    I'm writing a script that makes an enemy look at the player, but I want to write it so hat when a certain variable is true, the enemy will look away. What would be the opposite of the LookAt function in Javascript so that I can get the enemy to look away from me (yes, I tried LookAway)?
     
  2. iamthwee

    iamthwee

    Joined:
    Nov 27, 2015
    Posts:
    2,149
    transform.rotation = Quaternion.LookRotation(transform.position - target.position);
     
  3. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Did you try DoNotLookAt?

    More seriously:
    LookAt( position - ( target - position))
     
  4. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    target.LookAt(position); // towards you
    position.LookAt(target); // towards enemy (inverse)
     
    Last edited: Mar 20, 2016
  5. Treasureman

    Treasureman

    Joined:
    Jul 5, 2014
    Posts:
    563
    No, I mean make the enemy look away from the player
     
  6. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    It's the same thing, we are just talking about which way "anything" is looking. Rotation is only that, rotation. Position is separate and unrelated thing. If player is looking at enemy, if you apply that direction to enemy it means it's looking away from player.
     
  7. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Just to clarify a bit:
    Let's say the enemy location is the point E and the player location is the point P.
    If you want the enemy to look at the player, the enemy has to look in the direction of the player. That direction is given by the vector P - E.
    Now you want the enemy to look into the opposite direction, which is simply the negative of P - E, which is E - P.
     
  8. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    475
    For anyone googling here, all of the answers are nonsensical other than this one,

    transform.rotation = Quaternion.LookRotation(transform.position - target.position);

    which is correct.
     
  9. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,524
    Well, not quite. This works as well:

    because
    position - (target - position)
    is an absolute position "behind" position. Just looking at "position" wouldn't make any sense since you can not look at yourself. "target - position" is the relative vector from you to the target. If you don't add this relative vector to your position but subtracting it you end up 180° behind you.

    Though I agree that using LookRotation is simpler and easier to understand since the first thing LookAt will do internally is subtracting it's own position to get a relative direction again.
     
  10. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    More generally, if you already know some particular rotation, and you want to look in the opposite direction, you could always apply an additional rotation of 180 degrees:

    Code (CSharp):
    1. // Note:  Order of multiplication is important
    2. // This rotates 180 degrees around the local "up" of the original rotation:
    3. Quaternion oppositeRotation = originalRotation * Quaternion.AngleAxis(180, Vector3.up);
    4.  
    5. // ...whereas this rotates 180 degrees around the GLOBAL "up" direction of your world
    6. // e.g. if the original rotation was looking down at the floor, this will continue looking at the floor
    7. // (rather than at the sky), but the floor on the opposite side of the viewer
    8. Quaternion oppositeRotation = Quaternion.AngleAxis(180, Vector3.up) * originalRotation;
    You can substitute different directions for "up" depending on context (e.g. 2D games sometimes use Z instead of Y for "up").

    Note that LookRotation also depends on your choice of "up", it just uses Vector3.up as a default if you don't provide the second argument.
     
    Bunny83 likes this.
  11. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    475
    cheers @Bunny83 ! I feel that 2xposition-target is just too tricky. I just know there's somewhere it fails numerically but I can't figure it out! :)
     
  12. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    Couldn't you just do a LookAt()* -1 ? Or am I missing something here?
     
  13. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    475
    @exiguous - you're thinking of LookRotation .. and indeed that is exactly the correct answer

    Code (CSharp):
    1. For anyone googling here, all of the answers are nonsensical other than this one,
    2.  
    3. transform.rotation = Quaternion.LookRotation(transform.position - target.position);
    4.  
    5. which is correct.

    ("transform.position - target.position" is what you're thinking of .. "-1 times the direction to the enemy")
     
  14. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    8,988
    JDeyby likes this.
  15. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    One of the solutions already suggested is to replace
    LookRotation(x)
    with
    LookRotation(x * -1)
    (or something mathematically equivalent).

    Note this is NOT the same thing as
    LookRotation(x) * -1
    . That's not legal Unity code, and it's not entirely clear what operation it would informally refer to.

    You can take the inverse of a Quaternion, and there's a sense in which that is analogous to multiplying by -1, but it would not (usually) result in looking in the opposite direction, but rather in a "mirror image"--for example, instead of turning 30 degrees left, you'd turn 30 degrees right (which is a net difference of 60 degrees--not 180 degrees).

    There's also a mathematical sense in which Quaternions are a special kind of 4-dimensional vector, and so a Quaternion could be multiplied by a scalar in the same way that a vector could, but Unity doesn't allow this because that operation doesn't make sense conceptually when you are using that Quaternion to represent a rotation (rather than as a generalization of complex numbers into more dimensions). I'm not sure exactly what you'd get if you ignored that restriction, multiplied by -1 anyway, and then tried to interpret the result as a rotation again.


    And the function LookAt (as opposed to LookRotation) doesn't have any output at all; it sets the rotation of a Transform and then returns void. You definitely can't multiply void by -1.
     
  16. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,524
    Well, technically Unity does not implement a
    * operator
    for the Quaternion struct that allows the multiplication by a scaler since, as you said, we are only dealin with rotations and therefore unit quaternions all the way.

    Though whenever you manually construct a quaternion that is not normalized, Unity will automatically normalize it whenever you assign it as rotation to a transform. So scaling the quaternion by any number has no effect at all since it would be re-normalized anyways. The conjugate / inverse of a quaternion is not the same as multiplying it by -1. Multiplying by -1 would represent the exact same quaternion since the vector part of the quaternion would be flipped / inverted as well as the scaler / angle part. So a 30° rotation about an axis "A" is the same as a -30° rotation around the axis "-A". The inverse would only invert one of the two parts. The conjugate generally is about inverting the complex / vector part.
     
  17. Fattie

    Fattie

    Joined:
    Jul 5, 2012
    Posts:
    475
    @exiguous - if you're confused by all that :) -

    As I said, when you wrote: something like looking times minus one, what you are thinking of is exactly ...

    "target.position - transform.position" is the direction to the enemy,

    "transform.position - target.position" is the direction from enemy to you.