private void Start() { navI = GetComponent <AIAgent>().navInterface; if (useOnlyStaticCover && shouldUseDynamicCover) { verts = navI.GetNavmeshVertices(); } myTransform = transform; //dynamicCoverMaxDistFromMeSqr = dynamicCoverMaxDistFromMe*dynamicCoverMaxDistFromMe; maxCoverDistSqrd = maxCoverDistFromEnemy * maxCoverDistFromEnemy; minCoverDistSqrd = minCoverDistFromEnemy * minCoverDistFromEnemy; layerMask = AIController.Instance.layerMask; defendingDistSquared = defendingDist * defendingDist; minDistToAdvance = minDistToAdvance * minDistToAdvance; if (AIController.Instance != null) { coverNodes = AIController.Instance.GetCovers(); } else { Debug.LogError( "No Controller has been detected! An AIController is required for the AI to work! Please create a new gameObject and attach the Paragon AI ControllerScript to it!"); } }
CoverData FindDynamicCover(Vector3 targetTransformPos, Transform transformToDefend) { if (dynamicCoverSelectionMode == DynamicCoverMethods.Raycasts) { return(FindRaycastDynamicCover(targetTransformPos, transformToDefend)); } if (!useOnlyStaticCover) { verts = navI.GetNavmeshVertices(); } Vector3 myPos; if (!transformToDefend) { myPos = myTransform.position; } else { myPos = transformToDefend.position; } myPos.y += dynamicCoverNodeHeightOffset; var hideOffset = dynamicCoverNodeFireOffset - dynamicCoverNodeHeightOffset; //int nodesFound = 0; Vector3 hidingPosCheckingNow; int x = 0; //int y; float currDistTarget; Vector3 coverHidePos = Vector3.zero; Vector3 coverFirePos = Vector3.zero; float closestDistToMeSoFarSqr = dynamicCoverMaxDistFromMe * dynamicCoverMaxDistFromMe; float distBetweenMeAndCoverNow; bool shouldCont = true; //Use each vertex on the navmesh as a potential "firing position" //Then test whether we can hide from enemy fire by either crouching or moving off to the side (distance to move is hideOffset) //If we can see the enemy from the firing position and not see them from the hiding position, then it is a valid cover spot. for (int i = 0; i < verts.Length; i++) { //random value to make sure we don't take the same cover every time if (Random.value > 0.5 && Vector3.SqrMagnitude(verts[i] - myPos) > minDistBetweenLastCover) { currDistTarget = Vector3.SqrMagnitude(verts[i] - targetTransformPos); distBetweenMeAndCoverNow = Vector3.SqrMagnitude(verts[i] - myPos); if (distBetweenMeAndCoverNow < closestDistToMeSoFarSqr && currDistTarget > minCoverDistSqrd && currDistTarget < maxCoverDistSqrd) { verts[i].y += dynamicCoverNodeFireOffset; //If we can fire from here if (!Physics.Linecast(verts[i], targetTransformPos, layerMask)) { verts[i].y -= hideOffset; //Debug.Break(); if (Physics.Raycast(verts[i], targetTransformPos - verts[i], maxDistBehindDynamicCover, layerMask) && !AIController.Instance .IsDynamicCoverSpotCurrentlyUsed(verts[i])) { shouldCont = true; //If chest high wall hidingPosCheckingNow = verts[i]; //Check to make sure we have clear LoS between the firing position and the move position. if (!Physics.Linecast(targetTransformPos, verts[i], layerMask) && Physics.Linecast(hidingPosCheckingNow, targetTransformPos, layerMask)) { closestDistToMeSoFarSqr = distBetweenMeAndCoverNow; coverHidePos = hidingPosCheckingNow; coverFirePos = verts[i]; shouldCont = false; if (useFirstDynamicCoverFound) { break; } } //Check for side cover if (shouldCont) { for (x = -1; x <= 1; x += 2) { hidingPosCheckingNow = verts[i] + myTransform.right * x * dynamicCoverWidthNeededToHide; //If we're safe if (!Physics.Linecast(hidingPosCheckingNow, verts[i], layerMask) && Physics.Linecast(hidingPosCheckingNow, targetTransformPos, layerMask)) { //lastCoverPos = hidingPosCheckingNow; //return new TacticalAI.CoverData(true, hidingPosCheckingNow, verts[i], true, null); closestDistToMeSoFarSqr = distBetweenMeAndCoverNow; coverHidePos = hidingPosCheckingNow; coverFirePos = verts[i]; shouldCont = false; if (useFirstDynamicCoverFound) { break; } } } } } } } } } if (coverHidePos != Vector3.zero) { lastCoverPos = coverHidePos; return(new CoverData(true, coverHidePos, coverFirePos, true, null)); } return(new CoverData()); }