/// <summary> /// Vérifier le prochain mouvement du tank, et les collisions possibles avec d'autre tank. /// </summary> /// <returns> /// True si il va y avoir une collision, false sinon. /// </returns> public bool PredictCollision() { bool canMove = true; //Calculer la droite de direction du tank Vector2 selfPosition2D = new Vector2(transform.position.x, transform.position.z); Vector2 selfFoward = new Vector2(transform.forward.x, transform.forward.z); Droite2D droiteSelf = new Droite2D(selfPosition2D, selfFoward); //Vérifier les directions de chaque tank foreach (GameObject otherTank in detectedTanks) { Vector3 intersection = Vector3.zero; //Calculer la droite de la direction de l'autre tank Vector2 otherPosition2D = new Vector2(otherTank.transform.position.x, otherTank.transform.position.z); Vector2 otherFoward = new Vector2(otherTank.transform.forward.x, otherTank.transform.forward.z); Droite2D droiteOther = new Droite2D(otherPosition2D, otherFoward); //Trouver le point d'intersection Vector2 intersection2D; if (Droite2D.Intersect(droiteSelf, droiteOther, out intersection2D)) { //Calculer le point d'intersection 3D intersection.x = intersection2D.x; intersection.y = transform.position.y; intersection.z = intersection2D.y; //Calculer la distance au point d'intersection float distanceSelf = Vector3.Distance(transform.position, intersection); float distanceOther = Vector3.Distance(otherTank.transform.position, intersection); //Vérifier si le point d'intersection est devant Vector3 directionToIntersection = intersection - transform.position; if (Vector3.Angle(transform.forward, directionToIntersection) == 0) { //Vérifier si la collision est avant le prochain update if (distanceSelf <= valueScript.rayonArret) { //Le tank le plus loin du point de collision doit s'arrêter if (distanceSelf < distanceOther) { canMove = true; } else if (distanceSelf > distanceOther) { canMove = false; } } } } } return(canMove); }
/// <summary> /// Vérifier si deux droites sont parallèles. /// </summary> /// <param name='droiteA'> /// L'une des droites /// </param> /// <param name='droiteB'> /// L'une des droites /// </param> /// <returns> /// True si les droites sont parallèles. False sinon. /// </returns> public static bool areParallele(Droite2D droiteA, Droite2D droiteB) { bool areParallele = true; float constantFromX = droiteA.direction.x * droiteB.direction.y; float constantFromY = droiteA.direction.y * droiteB.direction.x; if (constantFromX != constantFromY) { areParallele = false; } return(areParallele); }
/// <summary> /// Trouver le point d'intersection entre deux droites. /// </summary> /// <param name='droiteA'> /// L'une des droites /// </param> /// <param name='droiteB'> /// L'une des droites /// </param> /// <param name='intersection'> /// Le point d'intersection entre les deux droites. S'il n'y a pas d'intersection, la valeur retournée est Vector3.zero; /// </param> /// <returns> /// True s'il y a un point d'intersection. False sinon. /// </returns> public static bool Intersect(Droite2D droiteA, Droite2D droiteB, out Vector2 intersection) { bool isIntersecting = false; if (!areParallele(droiteA, droiteB)) { //Calculer les valeurs de k et t float determinant = (droiteB.direction.x * droiteA.direction.y) - (droiteB.direction.y * droiteA.direction.x); float constantX = droiteB.pointA.x - droiteA.pointA.x; float constantY = droiteB.pointA.y - droiteA.pointA.y; float k = ((droiteB.direction.x * constantY) - (droiteB.direction.y * constantX)) / determinant; float t = ((droiteA.direction.x * constantY) - (droiteA.direction.y * constantX)) / determinant; //Trouver le point d'intersection pour la droite A Vector2 intersectionA = Vector2.zero; intersectionA.x = droiteA.pointA.x + k * droiteA.direction.x; intersectionA.y = droiteA.pointA.y + k * droiteA.direction.y; //Trouver le point d'intersection pour la droite B Vector2 intersectionB = Vector2.zero; intersectionB.x = droiteB.pointA.x + t * droiteB.direction.x; intersectionB.y = droiteB.pointA.y + t * droiteB.direction.y; //Vérifier le point d'intersection avec la droite B if (intersectionA == intersectionB) { isIntersecting = true; intersection = intersectionA; } else { intersection = Vector2.zero; } } else { intersection = Vector2.zero; } return(isIntersecting); }
/// <summary> /// Calculer le point d'intersection entre deux droites. /// </summary> /// <param name='droiteTarget'> /// La droite qui représente le direction d'un point à une cible /// </param> /// <param name='droiteWall'> /// La droite qui représente un WallVector /// </param> /// <param name='intersection'> /// Le point d'intersection des deux droites. S'il n'y a pas d'intersection, la valeur est Vector3.zero. /// </param> /// <returns> /// True s'il y a un point d'intersection. False sinon. /// </returns> private bool findIntersection(Droite2D droiteTarget, Droite2D droiteWall, out Vector3 intersection) { bool hasIntersection = false; intersection = Vector3.zero; //Trouver le point d'intersection entre les deux droites Vector2 intersection2D; if (Droite2D.Intersect(droiteTarget, droiteWall, out intersection2D)) { //Vérifier si le point d'intersection est entre les bornes if (droiteTarget.isPointWithinBorders(intersection2D) && droiteWall.isPointWithinBorders(intersection2D)) { intersection = new Vector3(intersection2D.x, 0.5f, intersection2D.y); hasIntersection = true; } } return(hasIntersection); }
/// <summary> /// Trouver le WallVector la plus proche qui agit commme obstacle entre les deux positions données /// </summary> /// <param name='startPoint'> /// La position de départ du chemin. C'est à partir de se point qu'est calculé la distance avec les obstacles. /// </param> /// <param name='endPoint'> /// La position de fin du chemin /// </param> /// <param name='walls'> /// Les WallVectors du niveau. Ce sont les murs que le tank doit éviter. /// </param> /// <returns> /// Le WallVector le plus proche /// </returns> private WallVector findFirstObstacle(Vector3 startPoint, Vector3 endPoint, WallVector[] walls) { WallVector closestObstacle = null; //Le mur obstacle le plus proche float minDistance = Mathf.Infinity; //Distance du mur obstacle le plus proche //Créer une droite entre le point et la cible Vector2 startPoint2D = new Vector2(startPoint.x, startPoint.z); Vector2 endPoint2D = new Vector2(endPoint.x, endPoint.z); Droite2D droiteToTarget = new Droite2D(startPoint2D, endPoint2D, true); //Vérifier les points d'intersections avec tous les murs de la scène foreach (WallVector wall in walls) { if (wall.startPoint != wall.endPoint) { //Créer la droite du mur Vector2 wallStartPoint2D = new Vector2(wall.startPoint.x, wall.startPoint.z); Vector2 wallEndPoint2D = new Vector2(wall.endPoint.x, wall.endPoint.z); Droite2D droiteMur = new Droite2D(wallStartPoint2D, wallEndPoint2D, true); //Trouver le point d'intersection Vector3 intersection; if (findIntersection(droiteToTarget, droiteMur, out intersection)) { //Vérifier cet obstacle est plus proche que le précédent obstacle le plus proche if (Vector3.Distance(startPoint, intersection) < minDistance) { minDistance = Vector3.Distance(startPoint, intersection); closestObstacle = wall; } } } } return(closestObstacle); }