Example #1
0
    Vector3 SlowDogCurve()
    {
        min.Clear();
        var line = GetComponent <LineRenderer>();
        //find desired velocity vector
        var   Vt  = target.GetComponent <Rigidbody>().velocity;
        var   Vm0 = rb.velocity;
        var   Pt0 = target.transform.position;
        var   Pm0 = transform.position;
        float Sm  = 20; //speed of missile, fixed constant

        //loop over all time t = [0, 100)
        line.SetWidth(.1f, 1f);
        line.SetPosition(0, new Vector3(40, 0, 0));
        line.SetPosition(1, Vector3.zero);
        line.SetPosition(2, new Vector3(0, 40, 0));
        int i = 0;

        for (float t = 0.1f; t < 97; t += 0.1f)
        {
            //assuming constant acceleration
            var Pt = t * Vt + Pt0;
            //assuming constant velocity
            Vector3 Vm, Pm;
            if (false) //constant velocity
            {
                Vm = (Pt - Pm0).normalized * Sm;
                Pm = t * Vm + Pm0;
            }
            else
            {
                //a = 2 * (Vt * t + Pt0 - Pm0 - Vm0 * t) / (t*t);
                var Pm1 = Vm0 * t;
                Vm = Pt - Pm0 - Pm1;
                var a = Vm.normalized * MaxAcceleration;
                Pm = Pm0 + Pm1 + a * t * t / 2;
            }
            var dist = (Pt - Pm).magnitude;
            min.Update(dist, t, Vm);
            line.SetPosition(i + 3, new Vector3((float)i / 10, dist / 10, 0));
            i++;
        }
        Logdump.Log("t=" + min.time + " minDist: " + min.index + " minV: " + min.result.magnitude);
        //InterceptionMarker.transform.position = min.time * Vt + Pt0;
        //if too slow, use target velocity vector
        //var desiredVm = (min.index > 1 ) ? min.result : Vt;
        var desiredVm = min.result;

        transform.LookAt(desiredVm.normalized + transform.position);
        //InterceptionMarker.transform.position = desiredVm.normalized * 5 + transform.position;
        var changeReq = MaxAcceleration * desiredVm.normalized;// desiredVm - rb.velocity;

        //changeReq = changeReq.normalized * MaxAcceleration;// Mathf.Min(changeReq.magnitude, MaxAcceleration); //cap change speed, but still in direction of desired vel, not necessarily orthogonal to current Vm though...
        //rb.velocity = minVm;
        return(changeReq);
    }
Example #2
0
    void Update()
    {
        var x = SpaceScale * 60 * Mathf.Sin(Time.time / 10);
        var y = SpaceScale * 30 * Mathf.Cos(Time.time / 10);
        var z = SpaceScale * 20 * Mathf.Sin(Mathf.PI * Time.time / 10);

        transform.position = new Vector3(x, y, z);
        var velocity = (transform.position - lastPos);
        var speed    = velocity.magnitude / Time.deltaTime;

        lastPos = transform.position;
        Logdump.Log("target speed: " + speed);
        var accel = (velocity - lastVel).magnitude / Time.deltaTime;

        Logdump.Log("target accel: " + accel);
    }
Example #3
0
    void ProportionalNavigation()
    {
        //accel = N * Vc * LOS_rate
        //N = navigation gain/constant
        //Vc = closing velocity
        //line of sight rotation rate

        //to get LOS rate
        var newRTM = target.transform.position - transform.position;

        if (oldRTM == Vector3.zero)
        {
            oldRTM = newRTM;
            Logdump.Log("no oldRtm");
            return;
        }

        Vector3 aimLoc;
        {
            //thanks to Desprez from Unity forum for the pro nav implementation!
            //check out his Unity assets at: http://mobfarmgames.weebly.com/
            float   pnGain   = N;
            Vector3 dirDelta = newRTM - oldRTM;
            dirDelta -= Vector3.Project(dirDelta, newRTM);
            // basic pro nav
            //Vector3 a = dirDelta * pnGain;

            // augmented pro nav
            Vector3 a = dirDelta * (pnGain + (dirDelta.magnitude * pnGain * .5f));
            aimLoc = (newRTM.normalized * rb.velocity.magnitude * Time.fixedDeltaTime) + a;
        }

        //limit turn rate
        var turnRate = Vector3.Angle(transform.forward, aimLoc);

        Logdump.Log("Turn rate: " + turnRate);
        turnRate = Mathf.Min(turnRate, MaxTurnRate * Time.deltaTime);
        var aimLocQuat = Quaternion.LookRotation(aimLoc);

        transform.rotation = Quaternion.Slerp(transform.rotation, aimLocQuat, turnRate / MaxTurnRate);
        //transform.LookAt(aimLoc + transform.position);

        oldRTM = newRTM;
    }
Example #4
0
 // Update is called once per frame
 void FixedUpdate()
 {
     if (Time.time - BornTime > DieAfterTime)
     {
         Logdump.Log("Born time: " + BornTime + " Now: " + Time.time);
         Destroy(gameObject);
         return;
     }
     if (Time.time - BornTime > FireDelay)
     {
         if (target == null)
         {
             particles.SetActive(false);
             return;
         }
         particles.SetActive(true);
         var rocketAccel = Vector3.zero;
         //rocketAccel += ProportionalNavigation();
         if (true)  // proportional navigation
         {
             ProportionalNavigation();
             var throttle = 1;// Mathf.Min(LOSRateReal*LOSRateReal/180f, 1);
             rocketAccel += transform.forward * MaxAcceleration * (throttle) * ManualThrottle;
             //SlowDogCurve();
         }
         else        // slow dog curve
         {
             rocketAccel = SlowDogCurve();
         }
         Logdump.Log("accel: " + rocketAccel.magnitude);
         Logdump.Log("velocity: " + rb.velocity.magnitude);
         rb.velocity += rocketAccel * Time.deltaTime;
         //tail chase
         //rb.velocity += (target.transform.position - transform.position).normalized * MaxAcceleration;
         //rb.velocity = rocketAccel;
         //transform.rotation = Quaternion.LookRotation(rb.velocity);
     }
 }