Search Unity

Transform.postion local vs parent space confusion.

Discussion in 'Scripting' started by Redz0ne, Feb 17, 2016.

  1. Redz0ne

    Redz0ne

    Joined:
    Oct 19, 2010
    Posts:
    332
    Hello. Long time no see!

    Anyway, on to the meat.

    I'm working on a script that will use the transform.position and am trying to work on moving something relative to it's own self-space matrix... I was at first confused because to me there are three main spaces.

    World-space: This one's pretty easy to understand.

    Parent-space: This is moving something in it's parent space.

    Local/self-space: This works on the axis that's native to the object itself.

    The confusion I'm facing is that depending on the function being used, "local" space is parent space in some and "local" in others... Case in point, using transform.position, there's a local space but it seems to work on the parent-space transformation matrix... And translate works on the self/local space matrix.

    What I need to do is use the transform.position (since I'm working on a system that uses this functionality specifically since translate moves whereas I need to set the position using values that are updated as needed.) But what I need is a way to figure out how to use the data and move it according to it's local/self space and not the parent space which transform.position is set up to use.

    Any tips on where to go so I can learn what I need to get this done?

    For the specifics of what I'm doing, I have a camera object that I'm applying a camera shake to... The camera is nested in a main matrix that moves but the shaking function is handled on the camera itself. And the angle that the camera is at is pointing diagonally downwards. So, when I set the transform.position, it's applying the vertical shake to the parent-space and as a result the vertical movement is up and down according to the parent object and not the camera itself... So the effect is that it is trucking in and out on the vertical rather than shaking it perpendicular to the camera's angle. Does that help explain what I'm looking for? If you need/want more information I'll do what I can but finding a way to address this would be ideal.

    Also of note, I'm not a master at coding... But I can do some code. I'm from an art/rigging background though so I'm not even sure what kind of mathematical functions this even is and my web searching hasn't produced viable results or tips on what I need to learn in order to grasp this.

    P.S. While I'm here... what's with the confusion/conflating of local/self and parent space? Is this something that the Unity team has made or is this more because that's how C# itself works? Because it is pretty confusing to me since I come from a rigging background and confusing/conflating the two could lead to disastrous results in a rig or segment of code for setting up a rigging solution.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,736
    Technically there is only two spaces:

    - world space
    - local space - the position and rotation relative to your parent

    That's it. What you call local space is always identity position, identity rotation, and unity scaling. I am always where I am and I am always facing the way I am facing, and I am always the size I am, except of course if I eat too many cookies, but I digress.

    The shaking effect you want is basically to have an intermediate object that your camera is parented to, let's call that "camera attach point". That might be behind and above your player, for instance.

    Now you put the camera on a separate game object parented to the "camera attach point" and initially oriented with identity local position, identity rotation and unity scaling.

    When you want to shake, you would adjust the transform.localPosition to nonzero values and that would move the camera away from that "camera attach point." When the shaking is over, you would restore the transform.localPosition back to Vector3.zero.
     
  3. Redz0ne

    Redz0ne

    Joined:
    Oct 19, 2010
    Posts:
    332
    Thank you... But that's more of a workaround for the specific example I listed rather than finding a way to solve the underlying issue.

    Do you know what the name is for the mathematical function(s) to convert positional data relative to a rotated origin point?
     
  4. BluHornet

    BluHornet

    Joined:
    Feb 23, 2015
    Posts:
    40
    the two spaces are a 3d architecture thing. C# has nothing to do with it. All 3d anything I have ever used work the same. you have a world position and a local position. I think the fundamental concept here is that position and rotation are actually two different things and have nothing to do with each other. Say I want a third person over the shoulder camera (Gears of War, Ghost Recon, etc) that I want to shake as bullets pass by. The first step is to set the camera's position relative to the player. This can be accomplished by moving the camera to the player's postion (transform.position = player.transform.position). Then I want to set the camera's rotation to match the player's with something like transform.rotation = Quaternion.Euler(player.transform.forward). Then I can move the camera's position with translate by an offset. Since translate works by adding or removing distance to the current position I can just set an offset value like -0.5,2,-7. After this is set every frame I can then adjust the position and rotation with a ping pong or a random range to get the shake on the z axis. As you can see here the position and rotation are handled separately. the way of handling thing like Kurt stated above is a great way to do this and the way I usually do it but in this example you can see the relations better. I use the world position to match the camera, then the global rotation, then I move the camera along in local and set the rotation and position in local. The third "self" space really doesn't exist. space.self is actually local space. see http://docs.unity3d.com/ScriptReference/Space.Self.html. the parent space is not a thing.
     
  5. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    969
    You're probably looking for Transform.(Inverse)TransformDirection/Point/Vector

    http://docs.unity3d.com/ScriptReference/Transform.html

    EDIT: If you're really looking for the actual mathematical functions, this is done with transform matrix multiplication, and you can get the transform matrix of a transform from Transform.localToWorldMatrix/worldToLocalMatrix or create your own with Matrix4x4.TRS
     
  6. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    For your camera movement, maybe you want to used the camera directions (right, up, forward) to do the shaking, these directions are the same as the red, green blue axis displayed on the object when you use the move tool in local space.

    You can access them from the Transform component.
     
    Redz0ne likes this.
  7. Redz0ne

    Redz0ne

    Joined:
    Oct 19, 2010
    Posts:
    332
    @ericbegue: Yes, that's exactly (I think) what I am looking for.

    Thanks. I'll look into this.

    To be fair, I did try the translate function since that does seem to use the "self" positional matrix but that is more of an offset so when I apply the perlin-noise generated float value to it, it adds to it rather than "sets" the position... And using the function to "set" the position (transform.position) since it's using it's "parent" space, that works with the system I set up but moves it in it's "parent" space.

    Why the translate isn't ideal for me is because I need to keep the camera constrained within a certain range (so that it doesn't go off in a direction and I can make a nice smooth-off of the offset-variable) so that when the "shake" is over, it's either at the initial position or close enough that there's no visible snapping if/when I set it back to it's initial starting position. Using translate seems more like an offset.

    I suspect that I may be needing to learn some seriously high-level math... And since I'm coming more from an art background and not a coding background, a lot of this has a pretty steep learning curve. But if there was an actual mathematical term or something for converting this kind of data, that'd give me a very solid point to start from to see if I can hack this.
     
  8. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    You don't need high level math to achieve what you want to achieve. In fact, you have your problem kind of well described, and you are close to hit a solution.

    So, you want the camera to get back to its position after the shaking (as if no shaking occurred at all). Why not store that position in a variable? Let's call that position cameraCenterPosition. Then, the final position would be a composition of that position plus the shaking offset:

    Code (CSharp):
    1. camera.Transform.position = cameraCenterPosition + shakingOffset;
    Though, this way you have to use the cameraCenterPositon as the "real" camera position, that is you have to move the camera though this variable and no more with camera.Transform.position.

    You are right about that some serious maths are required to do computer graphics and it is confusing when you get started. But it just something you have to learn. Don't worry that much about you coming from an art background. Math (and coding) is about learning/understanding definitions and a lot of practice.

    The mathematical tools used in computer graphics are from Linear Algebra. So you need to learn about vectors, matrices and their operations. You don't have to learn advanced stuffs here yet you need to get your fundamentals straight. But that's not enough. More importantly, you'll need to learn how theses tools are applied in computer graphics.
     
    Last edited: Feb 21, 2016