Moving object from point A to point B using rigid body forces [SOLVED]

Ok, I have a sword script, and have been able to extrapolate to two extremes of the swing. Though I will later implement more points to guide the sword along an arc, all I need to know is how to make the sword swing (fastest in the middle, slowing down at the end) from two vector coordinates. I would not be rotating the object, since the object this script will be manipulating will be simply a empty that the model will always face with its up vector.

This was a bit bigger of a problem than I initially thought. How would I go about doing this in javascript?

Code for Swing Pathing

//Define the location of both sides of the swing. r = Relative/Screenspace Coordinates.
static var x1r = 0;
static var x2r = 0;
static var y1r = 0;
static var y2r = 0;
static var z1 = 1;
static var z2 = 1;

function Update () {
   if(Input.GetButtonDown("Fire1")){
      checkMouseCoords1();
      Debug.Log("X: "+x1r+"   Y: "+y1r);
   }
   if(Input.GetButtonUp("Fire1"))
   {
      checkMouseCoords2();
      Debug.Log("X: "+x2r+"   Y: "+y2r);
   }
   swing(sword,Camera.main.ScreenToWorldPoint(new Vector3(x1r,y1r,z1)),Camera.main.ScreenToWorldPoint(new Vector3(x2r,y2r,z2)),swingForce);
}

function isClose(v1:Vector3,v2:Vector3,range:int)
{
    if((v1.x < v2.x + range)&&(v1.x > v2.x - range)&&(v1.y < v2.y + range)&&(v1.y > v2.y - range)&&(v1.z < v2.z + range)&&(v1.z > v2.z - range))
    {
        return true;
    }
    return false;
}

function swing (r1:Rigidbody, v1:Vector3, v2:Vector3, force:float)
{
   var t1 = r1.transform;
   if(isClose(t1.position,v1,0.1))
   {
       t1.LookAt(v2);
   }else{t1.LookAt(v1);}
   if(!isClose(t1.position,v2,0.1))
   {
       t1.Translate(t1.forward * Time.deltaTime * force);
   }
}

You’ll want to switch out transform.Translate() with Vector3.Lerp(), and modify the time parameter of the linear interpolation in such a way that the animation eases in and out. You can either program this manually, or use one of the existing “tweening” libraries. I personally always use Mathfx in combination with Vector3.Lerp() and a coroutine.

private IEnumerator RunSwing()
{
    float erpPos = 0;
    while (erpPos < 1)
    {
        t1.position = Vector3.Lerp(v1, v2, Mathfx.Hermite(0,1, erpPos));  //Hermite will ease in and out.
        erpPos += Time.deltaTime/SWING_DURATION;
        yield return null;
    }

    t1.position = v2;
}
1 Like

I did what you suggested. Maybe I converted from C# wrong, but this causes my object to complete the swing instantaneously. (Like I said, I probably just converted from C# wrong) What did I do wrong here?

function RunSwing(t1:Transform, v1:Vector3, v2:Vector3,SwingTime:float)
{
    var erpPos : float = 0;
    while (erpPos < 1)
    {
        t1.position = Vector3.Lerp(v1, v2, Hermite(0,1, erpPos));  //Hermite will ease in and out.
        erpPos += Time.deltaTime/SwingTime;
    }
    t1.position = v2;
}

static function Hermite(start : float, end : float, value : float) : float
{
    return Mathf.Lerp(start, end, value * value * (3.0 - 2.0 * value));
}

You have to call RunSwing as a coroutine, i.e. StartCoroutine(RunSwing()). Don’t start the coroutine every frame either, meaning that if it’s in Update(), you only start the coroutine if there isn’t one running already. You could use a field variable boolean “_canSwing” for instance, that gets set to false at the start of RunSwing, and to true at the end of it.

1 Like

Thank you.

1 Like