} // end radar() /// <summary> /// Realiza un scan en numDirections direcciones en torno al objeto. /// En caso de obstáculo, rota el transform hacia la primera dirección libre que encuentra. /// </summary> /// <returns> /// Devuelve true si encuentra un obstáculo. /// </returns> Vector3 prefixedScan() { if (trace) { Debug.Log("Escaneando..."); } // bucle de scanning for (int index = 0; index < numDirections; index++) { Vector3 fwd = tr.TransformDirection(directions[index]); //Dibujo un rayo (debug) if (trace) { Debug.DrawRay(tr.position + offset, fwd * distanciaVision, color[index]); } //Lanzo el rayo RaycastHit hit; bool impacto = Physics.Raycast(tr.position + offset, fwd, out hit, distanciaVision, layerMask); //si encuentro una dirección libre (sin impacto dentro de mi distancia de visión) if (!impacto) { //Disminuyo la velocidad speedMove = maxSpeed / 1; //Actualizo estado evasionState = EvasionState.orienting; //Devuelvo la dirección de escape return(fwd); } } //Bloqueo. (No hay ruta de escape) evasionState = EvasionState.blocked; return(tr.forward); } // end prefixedScan
} // end Start() void Update() { //Si no hay player al que seguir, no hacer nada if (trPlayer == null) { return; } //Si hay obstáculos if (checkCollision()) { moveDirection = prefixedScan(); //PrefixedScan me devuelve una posición de escape } //Radar (sólo visual, no tiene ningún efecto) //radar(); //Comprueba el estado del companion if (evasionState == EvasionState.orienting) { if (trace) { Debug.DrawRay(tr.position, tr.forward * distanciaVision, Color.magenta); } if (LookThrough(moveDirection)) //Continúo orientándome hasta llegar a la dirección requerida { evasionState = EvasionState.histeresis; //Entro en histéresis remanenciaActual = remanenciaInicial; //Asigno la remanencia inicial } } else if (evasionState == EvasionState.blocked) { moveDirection = prefixedScan(); //Si estoy bloqueado busco una dirección de escape speedMove = 0; //Me detengo } else if (evasionState == EvasionState.histeresis) { if (trace) { Debug.DrawRay(tr.position, tr.forward * distanciaVision, Color.yellow); } //Me muevo hacia adelante moveDirection = tr.forward; //Disminuyo la velocidad de movimiento speedMove = maxSpeed / 1; //Disminuyo la remanancia remanenciaActual -= Time.deltaTime; //Si ya no hay remanencia, dejo libre al companion if (remanenciaActual <= 0) { evasionState = EvasionState.free; } } else if (evasionState == EvasionState.free) { //Actúo normalmente, obtengo la dirección de movimiento moveDirection = GetDirection(); //restablezco la velocidad speedMove = maxSpeed; } // Me desplazo if (moveDirection != Vector3.zero) { controller.Move(moveDirection.normalized * (speedMove * ((healthController.health * 100) / healthController.maxHealth) / 100) * Time.deltaTime); } } // end Update()
void Start() { //Sólo detecta la capa 9 layerMask = 1 << 9; //Detecta todo excepto la capa 9 layerMask = ~layerMask; //Asigno mi transform tr = this.gameObject.transform; GameObject.FindWithTag("Display").SendMessage("liveEnemy"); //Asigno mi character controller controller = this.gameObject.GetComponent <CharacterController>(); direction_radar = Vector3.forward; //Frente (coordenadas de mundo) //Inicializo las direcciones en un array temporal que luego será copiado a direction[] con un orden especial Vector3[] temp_directions = new Vector3[numDirections]; temp_directions[0] = Vector3.forward; //Frente (coordenadas de mundo) //Dinesión del array de direciones directions = new Vector3[numDirections]; directions[0] = Vector3.forward; //Frente (coordenadas de mundo) float prefixedAngleStep = 360 / numDirections; //Se puebla el array con las direcciones for (int currDirection = 1; currDirection < numDirections; currDirection++) { temp_directions[currDirection] = Quaternion.Euler(0, prefixedAngleStep, 0) * temp_directions[currDirection - 1]; } //Variables auxiliares //Índice que aumentará a favor de las agujas del reloj int firstIndex = 1; //Índice que disminuirá en contra de las agujas del reloj int lastIndex = numDirections - 1; //Este bucle copia a directions[] el array temporal reordenándolo //de manera que se lancen primero los rayos hacia la parte delantera del companion for (int currDirection = 1; currDirection < numDirections; currDirection++) { if (currDirection % 2 != 0) { directions[currDirection] = temp_directions[firstIndex]; firstIndex++; } else { directions[currDirection] = temp_directions[lastIndex]; lastIndex--; } } //Inicialización de estado y velocidad speedMove = maxSpeed; evasionState = EvasionState.free; healthController = GetComponent <healthClass>(); } // end Start()