Move object in an arc

Hi.

I’m getting very close to being able to move object in an arc, but I just can’t figure out the final piece. Here’s the code I have.

I manage to get the object to move to 50 units from the center and then place newPos’s around an arc, but then using Vector3.Lerp to move the object to these points makes it go in straight lines rather than following the same arc I’m using to draw them…

BTW in this I’m simply trying to get my object to rotate along an arc on the Z axis based on the Y axis of the camera.

I really all works how it should other than the object doesn’t actually travel in arcs.

using UnityEngine;

public class rotateRelative : MonoBehaviour
{
    [SerializeField]
    Transform m_cameraTrans = null;
    [SerializeField]
    float m_speed = 10f;

    const float RADIUS = 50f;

    void Update()
    {
        float yRot = m_cameraTrans.eulerAngles.y * Mathf.Deg2Rad;
        Vector3 newPos = new Vector3(Mathf.Cos(yRot), Mathf.Sin(yRot), 0f) * RADIUS;
        transform.position = Vector3.Lerp(transform.position, newPos, Time.deltaTime * m_speed);
    }
}

I am going to explain two methods:

Method 1: Perfect Arc

So this method assumes that it will always be a perfect half circle arc towards the target location. Meaning if the Target is really far the arc will be huge.

/* Variables */
float counter;
bool endReached;
float speed = 1f;
Vector3 startPos;

void Start () {
   counter = 0;
   endReached = false;
  startPos = transform.position;
}

void Update () {
  if (endReached)
      return;

// Still firing
Vector3 pos = new Vector3 ( 
        startPos.x, 
        startPos.y + Mathf.Sin( Mathf.PI * 2 * counter / 360),
        startPos.z + Mathf.Sin( Mathf.PI * 2 * counter / 360)
 );

// Move the transform
transform.position = Vector3.lerp ( transform.position, pos, 1f);

// Update Counter
counter += speed;

// Break the loop
if (counter >= 180)
endReached = true;
}

Now if you are using collision there is no need to use the endReached variable.

Method 2: Missile Firing

Imagine I am firing missiles up in the air, they then lock-on to a target and head to wards that target. They might miss if the target moves but it all depends on the turning rate of the missile and if I set the target to be lock-on or not.

The only thing is you have to turn your transform in a direction at the start otherwise it will just move in straight line. The bad part is that this can actually miss the target or enter a straight line before the target is reached.

/* Variables */
Transform target;
Vector3 targetPos;
float smooth; // Kind like turn speed
float speed; // Movement speed
void Start () {
    targetPos = target.position;
}

void Update () {
   // If Lock:
 if (isLockon)
      targetPos = target.position;

// Rotate in arc
SmoothLookAt (targetPost);



// Move
  transform.Translate (transform.forward * speed);
    }

void SmoothLookAt(Vector3 target)
 {
     Vector3 dir = target - transform.position;
     Quaternion targetRotation = Quaternion.LookRotation(dir);
     transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * smooth);
 }

Hope this helped.

So using Lerp to translate is always going to move in a straight line between the two input vectors. I believe using it in this manner would require lots of vectors to approximate an arc that would appear smooth to the player.

Let me suggest a different method.

When an object has a child and that child is located at some offset, then that offset is like a radius of rotation. You rotate the parent and the child moves in a circle around the parent.

So what you can do is have your object that is meant to travel in an arc be a child of another GameObject. Rotate the parent and the child moves in the arc. Each frame, after rotating the parent, you can set the child’s rotation to be whatever you want and it won’t affect the parent or the translation. So if you don’t want the moving object to appear to rotate at all you can, for instance, store it’s rotation before the movement occurs. And each frame, after updating the rotation of the parent, set the rotation of the child to be its original rotation again.

Does that make sense / suit your needs? Do you know how to do this if it does?

so, how did this end up?

what i am trying to achievie is making Vector3.Slerp to work clockwise and counter-clockwise when i choose to