//Start new AI and create a equivalent struct void StartAI(int i) { Vector3 randomPosition = new Vector3(Random.Range(-terrainDistance, terrainDistance), 1.0f, Random.Range(-terrainDistance, terrainDistance)); listOfAiObjects[i] = (GameObject)Instantiate(prefabGameObject); listOfAiObjects[i].transform.position = randomPosition; listOfAiStructs[i] = new aiStruct(randomPosition, Vector3.zero); }
//Helps struct rotate via LERP, checks if we are looking at the new position //We round with a precision variable to create a proper interpolation public bool isLookingAt(float p, aiStruct automat) { Vector3 randomPos = automat.randomPos; Vector3 autDir = Vector3.Normalize(automat.dir); autDir = new Vector3(Mathf.Round(autDir.x * p) / p, Mathf.Round(autDir.y * p) / p, Mathf.Round(autDir.z * p) / p); Vector3 direction = Vector3.Normalize(randomPos - automat.pos); direction = new Vector3(Mathf.Round(direction.x * p) / p, Mathf.Round(direction.y * p) / p, Mathf.Round(direction.z * p) / p); return(direction == autDir); }
//For generating new positions for our struct aiStruct updateStruct(aiStruct automat) { RaycastHit hit; //If we reached our destination, create new target position if ((automat.pos - automat.randomPos).magnitude <= 0.2f || automat.randomPos == Vector3.zero) { automat.randomPos = new Vector3(Random.Range(-terrainDistance, terrainDistance), automat.pos.y, Random.Range(-terrainDistance, terrainDistance)); //If this created position hits an obstacle, stay where we are if (Physics.Raycast(automat.pos, automat.randomPos - automat.pos, out hit, 20, -1)) { automat.randomPos = automat.pos; return(automat); } } Vector3 randomPos = automat.randomPos; //If poisition inside the terrain if (isInside(randomPos, terrainDistance)) { Vector3 randir = (randomPos - automat.pos).normalized; //Are we looking at the new target position? if ((automat.dir - randir).magnitude > 0.05f) { //If no, interpolate till we looking at it automat.dir = Vector3.Lerp(automat.dir, randir, 0.2f).normalized; } else { //If yes, move towards that position automat.pos += automat.dir * forwardVel * Time.deltaTime; } } else { automat.randomPos = automat.pos; } return(automat); }
//Used to check whether a GameObject AI is on the field of view of our camera void manageRendering() { for (int i = 0; i < listOfAiObjects.Length; i++) { //We turn our AI position into a Viewport point, //If the x,y elements of this point are between 0 and 1 //and the y between 0 and 50 (Basically the far and near planes) //means that this point is on the field of view of the camera Vector3 pointOnScreen; bool isInsideSphere; //Is the AI GameObject is the one active if (listOfAiObjects [i].activeSelf) { //we save its position pointOnScreen = Camera.main.WorldToViewportPoint(listOfAiObjects [i].transform.position); isInsideSphere = isOnLeichtgewichtRender(listOfAiObjects [i].transform.position); } else { pointOnScreen = Camera.main.WorldToViewportPoint(listOfAiStructs [i].pos); isInsideSphere = isOnLeichtgewichtRender(listOfAiStructs[i].pos); } //If AI or Struct inside of the field of view if (pointOnScreen.z > 0 && pointOnScreen.z < 50 && pointOnScreen.x > 0 && pointOnScreen.x < 1 && pointOnScreen.y > 0 && pointOnScreen.y < 1) { listOfAiObjects [i].SetActive(true); //If the struct is the one active if (listOfAiStructs [i].isActivated) { aiStruct currentAi = listOfAiStructs [i]; //We pass this values to the GameObject itself //And deactive the struct listOfAiObjects [i].transform.forward = currentAi.dir; listOfAiObjects [i].transform.position = currentAi.pos; listOfAiObjects [i].GetComponent <AIController> ().randomPos = currentAi.randomPos; //This line is to pass the new destination to the NavMesh. //If we send this to our NavMesh before our AIController script gets fired //We get a nullpoint exception, since the other in which the values get started //Change from one script to the other listOfAiObjects [i].GetComponent <AIController> ().setValue(currentAi.randomPos); listOfAiStructs [i].isActivated = false; } //If inside the sphere but not inside the field of view } else if (isInsideSphere) { //If our struct isnt active yet if (!listOfAiStructs [i].isActivated) { //And our GameObject is if (listOfAiObjects [i].activeSelf) { //We pass those values to the struct and deactive the GameObject listOfAiStructs [i].pos = listOfAiObjects [i].transform.position; listOfAiStructs [i].dir = listOfAiObjects [i].transform.forward; listOfAiStructs [i].randomPos = listOfAiObjects [i].GetComponent <AIController> ().randomPos; listOfAiObjects [i].SetActive(false); } //We start the struct listOfAiStructs [i].isActivated = true; } //And update its position listOfAiStructs [i] = updateStruct(listOfAiStructs [i]); } else { //If AI outside of everything, deactivate them listOfAiObjects [i].SetActive(false); listOfAiStructs [i].isActivated = false; } } }