0
\$\begingroup\$

I run into the problem with moving object regarding to its rotation. The thing is that I'm changing object position by assigning new transform.localPosition value. In specific cases I want to modify assigned value by slightly changing z axis (height) of the object.

I tried to do it with use of transform.up. I expected move along local z axis (like in Unity scene preview), but it doesn't work as expected.

transform.Translate(Vector3.up, Space.Self) works exactly as I want, but as I said I want to combine it with transform.localPosition i already use. How should I modify passed Vector3 so it works correctly?

Update:

Class below is used to simulate move of an object around sphere. For example plane flying around Earth. I adjust plane rotation so it's chassis is facing Earth. Object is moving on the Earth surface though. I want to move it slightly up so it flies. That's why I want to move it along local z axis as it is distance from the core of the Earth.

Full class snippet (I'm using LeanTouch package)

public Transform lookAtTarget;
RaycastHit hit;
RaycastHit lastHit;

public float rotationSmoothTime = 0.3F;
public float moveSmoothTime = 0.3F;
private Vector3 rotationVelocity = Vector3.zero;
private Vector3 moveVelocity = Vector3.zero;
private Vector3 lastNewRightDir;

protected virtual void Awake ()
{
    Use.UpdateRequiredSelectable (gameObject);
    lastNewRightDir = transform.right;
}

void Update ()
{
    var fingers = Use.GetFingers ();
    if (fingers.Count < 1)
    {
        Move (lastFingerScreenPosition, Vector2.zero);
        return;
    }
    LeanFinger finger = fingers[0];
    Move (finger.ScreenPosition, finger.ScreenDelta);
    lastFingerScreenPosition = finger.ScreenPosition;
}

public void Move (Vector2 fingerScreenPosition, Vector2 scaledDelta)
{
    var ray = Camera.main.ScreenPointToRay (fingerScreenPosition);
    LayerMask mask = LayerMask.GetMask ("Interactable");

    bool newHit = Physics.Raycast (ray, out hit, float.PositiveInfinity, mask);

    Vector3 rightDir = transform.right;
    Vector3 newRightDir = lastNewRightDir;

    Vector3 targetPosition = lastHit.point;

    if (newHit)
    {
        targetPosition = hit.point;
        lastHit = hit;
    }
    else if (lastHit.distance == 0)
    {
        return;
    }

    Vector3 forwardDir = (targetPosition - lookAtTarget.position).normalized;

    if (targetPosition != transform.position && scaledDelta != Vector2.zero)
    {
        newRightDir = (targetPosition - transform.position).normalized;
        lastNewRightDir = newRightDir;
    }

    rightDir = Vector3.SmoothDamp (rightDir, newRightDir, ref rotationVelocity, rotationSmoothTime);
    Vector3 upwardDir = Vector3.Cross (forwardDir, rightDir);
    transform.rotation = Quaternion.LookRotation (forwardDir, upwardDir);


    transform.localPosition = Vector3.SmoothDamp (transform.localPosition, targetPosition, ref moveVelocity, moveSmoothTime);
}}

Before transform.localPosition = Vector3.SmoothDamp (transform.localPosition, targetPosition, ref moveVelocity, moveSmoothTime); the targetPosition value should be adjusted so object moves 1 unit alongside local z axis.

\$\endgroup\$
4
  • \$\begingroup\$ @Zibelas I'm setting it this way. The targetPosition variable is based on raycast hit. transform.localPosition = Vector3.SmoothDamp (transform.localPosition, targetPosition, ref moveVelocity, moveSmoothTime); The thing is that y axis is height of the object. During move object should be lets say 1 unit above ground. So i want to add this value to targetPosition. Vector3.up won't work correctly as I want to apply this 1 unit based on transform rotation, not global rotation. I though transform.up would work this way, but clearly I'm wrong. \$\endgroup\$ – Ardoos Oct 28 '20 at 11:35
  • \$\begingroup\$ @Zibelas I updated my question with class snippet. I hope it helps with understanding my issue. \$\endgroup\$ – Ardoos Oct 28 '20 at 11:57
  • \$\begingroup\$ why are you using transform.rotation and not transform.localRotation? \$\endgroup\$ – Zibelas Oct 28 '20 at 12:18
  • \$\begingroup\$ To be honest I didn't think setting height would be such a problem and it was easier for me to calculate it that way. I don't think it's a problem though. Plane is rotated correctly and setting it using transform.localRotation would give the same result. \$\endgroup\$ – Ardoos Oct 28 '20 at 13:23
1
\$\begingroup\$

transform.up is a vector in world space, but transform.position moves an object in its parent's space. If the parent (or grandparent, etc) is rotated, then these two spaces can differ.

To get the object's up vector relative to its parent coordinate system, just multiply:

Vector3 localUpInParentSpace = transform.localRotation * Vector3.up;

Then you can add it to your localPosition:

upwardShift = 1.0f; // Substitute whatever distance you want to move here.
Vector3 shiftedLocalPosition = transform.localPosition + localUpInParentSpace * upwardShift;

This moves along the object's local y+ axis. If you want to move along the object's local z+ axis, use Vector3.forward instead of Vector3.up.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks, that is exactly what I was trying to do! \$\endgroup\$ – Ardoos Oct 29 '20 at 8:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.