- Home /
AI tank keeps running into trees adn getting stuck?,AI tank running into trees
I crated an AI tank that uses ray cast to see objects in the terrain and targets to shoot at. My problem is that it is not seeing tree and that when it can not decide weather to go left or right, it just pushes forward instead of back.
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class groundScan : MonoBehaviour { GameObject tank; Transform tankTransform; public RaycastHit hitLeft, hitRight; public bool offTheEdge; public GameObject hitObject; public float distance = 0; GameObject turret; int frameNumber = 0; enum turnChoice { Left, Right, NoTurn};
// Use this for initialization
void Start () {
tank = GameObject.Find("Tank3");
turret = GameObject.Find("turret");
tankTransform = tank.GetComponent<Transform>();
}
// Update is called once per frame
void Update () {
frameNumber++;
frameNumber %= 75;
float distanceToTerrainLeft=0;
float distanceToTerrainRight=0;
RaycastHit minDistanceRC;
List<RaycastHit> stuffHit;
List<string> targetsToLookFor = new List<string>();
targetsToLookFor.Add("Cube");
if (scanForTargets(targetsToLookFor, transform.position, -30, 30, 1, -5, 5, 1, true, out stuffHit))
{
//Find the Object that is the closest
float minDistance = float.MaxValue;
minDistanceRC = stuffHit[0];
foreach(RaycastHit rc in stuffHit)
{
if (rc.distance < minDistance)
{
minDistance = rc.distance;
minDistanceRC = rc;
}
}
//Figure out which way to turn
turnChoice turn = whichSide(turret, minDistanceRC.collider.gameObject);
if (turn == turnChoice.Left) turret.transform.Rotate(0, -0.5f, 0);
else if (turn == turnChoice.Right) turret.transform.Rotate(0, 0.5f, 0);
if(minDistanceRC.distance < 20)
{
if (frameNumber == 0 ) GameObject.Find("gun").GetComponent<fireGun>().shoot();
}
}
else distance = 0;
foreach (RaycastHit rc in stuffHit)
{
}
if (lookAt(transform.position, -10, -30, true, out hitLeft) && lookAt(transform.position, -10, 30, true, out hitRight)
)
{
GameObject hitObjectLeft = hitLeft.collider.gameObject;
if (hitObjectLeft.name == "Terrain") distanceToTerrainLeft = hitLeft.distance;
GameObject hitObjectRight = hitRight.collider.gameObject;
if (hitObjectRight.name == "Terrain") distanceToTerrainRight = hitRight.distance;
{ if (distanceToTerrainLeft > distanceToTerrainRight && distanceToTerrainLeft > 1) tankTransform.Rotate(0, 4, 0); }
{ if (distanceToTerrainRight >= distanceToTerrainLeft && distanceToTerrainRight > 1) tankTransform.Rotate(0, -2, 0); }
offTheEdge = false;
}
else
{ //Gone off the edge
offTheEdge = true;
//Gone off the right edge
if (distanceToTerrainLeft > distanceToTerrainRight) { tankTransform.Rotate(0, -3, 0); }
//Gone off the left edge
else if (distanceToTerrainLeft <= distanceToTerrainRight) { tankTransform.Rotate(0, 3, 0); }
}
}
bool lookAt(Vector3 startPos, float altitude, float azimuth, bool showRay, out RaycastHit hit)
{
hit = new RaycastHit();
if (azimuth > 90 || altitude < -90) return false;
if (azimuth > 180 || altitude < -180) return false;
Vector3 directionOfScan = tankTransform.forward + tankTransform.up * Mathf.Tan(altitude * Mathf.PI/180) +
tankTransform.right * Mathf.Tan(azimuth * Mathf.PI/180);
if (showRay) Debug.DrawRay(startPos, directionOfScan, Color.red, 150f);
if (Physics.Raycast(startPos, directionOfScan, out hit)) return true;
return false;
}
//Scans to find objects in the scene
bool scan(Vector3 startPos, float azAngleStart, float azAngleEnd, float azIncrement, float altAngleStart, float altAngleEnd, float altIncrement, bool showRay, out List<RaycastHit> stuffHit)
{
float azAngle = azAngleStart;
float altAngle = altAngleStart;
bool someThingWasHit = false;
stuffHit = new List<RaycastHit>();
while(azAngle <= azAngleEnd)
{
while(altAngle <= altAngleEnd)
{
RaycastHit hit = new RaycastHit();
if (lookAt(startPos, altAngle, azAngle, showRay, out hit))
{
stuffHit.Add(hit);
someThingWasHit = true;
}
altAngle += altIncrement;
}// End while(altAngle <= altAngleEnd)
altAngle = 0;
azAngle += azIncrement;
} //End while(azAngle <= azAngleEnd)
return someThingWasHit;
} // End bool scan(....
bool scanForTargets(List<string> targetsToLookFor, Vector3 startPos, float azAngleStart, float azAngleEnd, float azIncrement, float altAngleStart, float altAngleEnd, float altIncrement, bool showRay, out List<RaycastHit> stuffHit)
{
bool stuffWasHit = false;
List<RaycastHit> hit;
stuffHit = new List<RaycastHit>();
if (scan(startPos, azAngleStart, azAngleEnd, azIncrement, altAngleStart, altAngleEnd, altIncrement, showRay, out hit))
{
foreach(RaycastHit h in hit)
{
if (targetsToLookFor.Contains(h.collider.gameObject.tag)){
stuffHit.Add(h);
stuffWasHit = true;
}
}
}
return stuffWasHit;
} //End scanForTargets
turnChoice whichSide(GameObject baseObject, GameObject sideObject)
{
Vector3 directionOfSideObject = sideObject.transform.position - baseObject.transform.position;
Vector3 cross = Vector3.Cross(-baseObject.transform.right, directionOfSideObject);
if (cross.y > 0.2) return turnChoice.Left;
else if (cross.y < -0.2) return turnChoice.Right;
else return turnChoice.NoTurn;
}
} // End public class groundScan ,I created an AI tank that uses ray caste to see objects to target and move around. My tank is running into trees but avoiding any other barriers in the terrain.
Your answer
Follow this Question
Related Questions
Please help me with AI 2 Answers
is their a way to make an AI using Wheel Collider and the Navmesh agent ? 0 Answers
trouble with my lookAt script 0 Answers
i can't set destination, using AI Navmesh via raycast 1 Answer
ZOMBIE AI SCRIPT 1 Answer