1
votes

Ok, so, i've been stuck on this for ages. Im working on an AI that will navigate a tank to a waypoint, defined as a Vector3. the position of the tank is also defines as a Vector3, both these have their Y position set to 0, as to ignore terrain elevation, the current rotation of the tank is also a Vector3, though only the Y rotation is needed, as i'm effectively projecting the 3d position onto a 2d navigational grid.

The AI passes anywhere between -1 and 1 into the control for the tank, which then handles the physics operations. so, i need to somehow calculate the angle, positive or negative in relation to the current heading angle of the tank to the position of the waypoint, then send the rotation value to the controls. At the moment I simply cant get it working, I feel like iv'e pretty much tried everything.

This is my code currently, it doesn't work, at all, and is about the 20th revision:

void driveToTarget()
{

    Vector3 target0 = driveTarget;
    target0.y = 0;
    GameObject current0Obj = new GameObject();
    Vector3 current0 = this.transform.position;
    current0.y = 0;
    print(current0);
    print(target0);
    Vector3 current0Angle = this.transform.eulerAngles;
    print(current0Angle.y);
    current0Angle.x = 0;
    current0Angle.z = 0;

    Vector3 heading = target0 - current0;

    Quaternion headingAngle = Quaternion.LookRotation(heading);
    print("headingAngle" + headingAngle);
    print("heading direction, allegidly: " + Quaternion.Euler(heading).ToEulerAngles());
    Quaternion distanceToGo = Quaternion.Lerp(Quaternion.Euler(current0Angle), headingAngle, 0.01f);

    float angle = Vector3.SignedAngle(current0, target0, Vector3.up);
    float difference = Mathf.Abs(angle - current0Angle.y);



    print("heading angle " + angle);
    if (current0 != driveTarget)
    {
        steeringVal = Mathf.Abs(1.5f-(1f/Mathf.Abs(distanceToGo.y))) * -Mathf.Sign(distanceToGo.y); ;
        throttleVal = 0f;
    } else
    {
        throttleVal = 0;
    }

}

--EDIT--

So, I've partially solved it, and now encountered another problem, I've managded to get the tank to detect the angle between itself and the waypoint, BUT, rather than orienting forward towards the waypoint, the right side of the tank orients towards it, so it orbits the waypoint. I actually know why this is, becasue the forward vector of the tank is technically the right vector because of unity's stupid axis ruining my blender import, anyway, heres the updated code:

void driveToTarget()
{

    Vector3 target0 = driveTarget;
    target0.y = 0;
    Vector3 current0 = this.transform.position;
    current0.y = 0;
    print("Current: " + current0);
    print("Target: " + target0);
    Vector3 current0Angle = this.transform.rotation.eulerAngles;
    print("Curret rotation:" + current0Angle.y);
    current0Angle.x = 0;
    current0Angle.z = 0;

    Vector3 heading = target0 - current0;

    Quaternion headingAngle = Quaternion.LookRotation(heading);
    print("heading angle: " + headingAngle.ToEuler());

    float distanceToGo = (current0Angle.y) - headingAngle.eulerAngles.y;
    print("DistanceToGo: " + distanceToGo);




    if (current0 != driveTarget)
    {

            steeringVal = 1 * -Mathf.Sign(distanceToGo);


        throttleVal = 0f;
    } else
    {
        throttleVal = 0;
    }
    Debug.DrawRay(current0, heading, Color.red, 1);
    Debug.DrawRay(current0, this.transform.up, Color.red, 1);

}
1

1 Answers

0
votes

I'm not sure exactly how your code is setup or how the steering works. You may want to look into using the Unity NavMeshAgent to simplify this.

Regardless here is some code I wrote up that takes a destination and rotates an object towards it. All you'd have to do from there is move the object forwards.

 Vector3 nextDestination = //destination;
        Vector3 direction = nextDestination - transform.position;
        direction = new Vector3(direction.x, 0, direction.z);
        var newRotation = Quaternion.LookRotation(direction);
        var finalRotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime); //smoothes out rotation
        transform.rotation = finalRotation;

Sorry if this isn't what you needed. Have you been able to figure out which part of the code is behaving unexpectedly from your print statements?