add ckg
plantilla base para movimiento básico
This commit is contained in:
861
Assets/Game Kit Controller/Scripts/AI/Turret/AITurret.cs
Normal file
861
Assets/Game Kit Controller/Scripts/AI/Turret/AITurret.cs
Normal file
@@ -0,0 +1,861 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using GameKitController.Audio;
|
||||
using UnityEngine.Events;
|
||||
|
||||
public class AITurret : MonoBehaviour
|
||||
{
|
||||
[Header ("Turret Settings")]
|
||||
[Space]
|
||||
|
||||
public LayerMask layer;
|
||||
|
||||
public float rotationSpeed = 10;
|
||||
|
||||
[Space]
|
||||
|
||||
public float inputRotationSpeed = 5;
|
||||
|
||||
public Vector2 rangeAngleX;
|
||||
public float overrideRotationSpeed = 10;
|
||||
|
||||
public float raycastPositionRotationSpeed = 10;
|
||||
|
||||
[Space]
|
||||
[Header ("Sound Settings")]
|
||||
[Space]
|
||||
|
||||
public AudioClip locatedEnemy;
|
||||
public AudioElement locatedEnemyAudioElement;
|
||||
|
||||
[Space]
|
||||
[Header ("Weapons Settings")]
|
||||
[Space]
|
||||
|
||||
public string defaultWeaponActiveName;
|
||||
|
||||
public bool randomWeaponAtStart;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool useGeneralLayerToDamage;
|
||||
public LayerMask layerToDamage;
|
||||
|
||||
[Space]
|
||||
|
||||
public List<turretWeaponInfo> turretWeaponInfoList = new List<turretWeaponInfo> ();
|
||||
|
||||
[Space]
|
||||
[Header ("Debug")]
|
||||
[Space]
|
||||
|
||||
public bool dead;
|
||||
public bool shootingWeapons;
|
||||
public bool weaponsActive;
|
||||
|
||||
public Transform currentCameraTransformDirection;
|
||||
|
||||
public string currentWeaponName;
|
||||
|
||||
public int currentWeaponIndex;
|
||||
|
||||
[Space]
|
||||
[Header ("Override Elements")]
|
||||
[Space]
|
||||
|
||||
public bool controlOverriden;
|
||||
|
||||
public bool useCustomInputCameraDirection;
|
||||
|
||||
public Transform overridePositionToLook;
|
||||
|
||||
[Space]
|
||||
[Header ("Other Settings")]
|
||||
[Space]
|
||||
|
||||
public Shader transparent;
|
||||
public LayerMask layerForGravity;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool fadePiecesOnDeath = true;
|
||||
|
||||
public float fadePiecesSpeed = 5;
|
||||
|
||||
public float destroyPiecesWaitTime = 10;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool addForceToTurretPiecesOnDeath = true;
|
||||
|
||||
public float forceAmountToPieces = 500;
|
||||
|
||||
public float radiusAmountToPieces = 50;
|
||||
|
||||
[Space]
|
||||
[Header ("Turret Elements")]
|
||||
[Space]
|
||||
|
||||
public GameObject rayCastPosition;
|
||||
|
||||
public GameObject rotatingBase;
|
||||
public GameObject head;
|
||||
|
||||
public manageAITarget targetManager;
|
||||
public Rigidbody mainRigidbody;
|
||||
|
||||
public AudioSource audioSource;
|
||||
public overrideInputManager overrideInput;
|
||||
|
||||
public GameObject turretAttacker;
|
||||
|
||||
|
||||
Quaternion currentRaycastPositionRotation;
|
||||
|
||||
Vector2 currentLookAngle;
|
||||
Vector2 axisValues;
|
||||
float horizontalInput;
|
||||
float verticalInput;
|
||||
|
||||
RaycastHit hit;
|
||||
|
||||
|
||||
List<Renderer> rendererParts = new List<Renderer> ();
|
||||
|
||||
bool kinematicActive;
|
||||
float timer;
|
||||
float shootTimerLimit;
|
||||
|
||||
float orignalRotationSpeed;
|
||||
float speedMultiplier = 1;
|
||||
|
||||
GameObject currentEnemyToShoot;
|
||||
|
||||
float currentRotationSpeed;
|
||||
|
||||
float lastTimeWeaponsActivated;
|
||||
|
||||
string untaggedName = "Untagged";
|
||||
|
||||
Coroutine disableOverrideCoroutine;
|
||||
|
||||
turretWeaponInfo currentTurretWeaponInfo;
|
||||
|
||||
bool weaponInfoAssigned;
|
||||
|
||||
float lastTimeTurretDestroyed;
|
||||
|
||||
|
||||
private void InitializeAudioElements ()
|
||||
{
|
||||
if (locatedEnemy != null) {
|
||||
locatedEnemyAudioElement.clip = locatedEnemy;
|
||||
}
|
||||
|
||||
if (audioSource != null) {
|
||||
locatedEnemyAudioElement.audioSource = audioSource;
|
||||
}
|
||||
|
||||
currentWeaponName = defaultWeaponActiveName;
|
||||
}
|
||||
|
||||
void Start ()
|
||||
{
|
||||
InitializeAudioElements ();
|
||||
|
||||
if (turretAttacker == null) {
|
||||
turretAttacker = gameObject;
|
||||
}
|
||||
|
||||
currentRotationSpeed = rotationSpeed;
|
||||
orignalRotationSpeed = rotationSpeed;
|
||||
|
||||
if (randomWeaponAtStart) {
|
||||
int randomIndex = Random.Range (0, turretWeaponInfoList.Count);
|
||||
|
||||
currentWeaponName = turretWeaponInfoList [randomIndex].Name;
|
||||
}
|
||||
}
|
||||
|
||||
void Update ()
|
||||
{
|
||||
if (dead) {
|
||||
if (fadePiecesOnDeath) {
|
||||
//if the turrets is destroyed, set it to transparent smoothly to disable it from the scene
|
||||
int rendererPartsCount = rendererParts.Count;
|
||||
|
||||
int piecesFadedCounter = 0;
|
||||
|
||||
for (int i = 0; i < rendererPartsCount; i++) {
|
||||
|
||||
Color alpha = rendererParts [i].material.color;
|
||||
|
||||
alpha.a -= Time.deltaTime / fadePiecesSpeed;
|
||||
|
||||
rendererParts [i].material.color = alpha;
|
||||
|
||||
if (alpha.a <= 0) {
|
||||
piecesFadedCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (piecesFadedCounter >= rendererPartsCount) {
|
||||
Destroy (gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (destroyPiecesWaitTime > 0) {
|
||||
if (Time.time > destroyPiecesWaitTime + lastTimeTurretDestroyed) {
|
||||
Destroy (gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the turret is not destroyed, or being hacked, or paused by a black hole, then
|
||||
if (!dead && !targetManager.paused) {
|
||||
if (targetManager.onSpotted) {
|
||||
lootAtTurretTarget (targetManager.placeToShoot);
|
||||
|
||||
shootWeapon (targetManager.enemyToShoot, targetManager.placeToShoot, true);
|
||||
|
||||
}
|
||||
//if there are no enemies in the field of view, rotate in Y local axis to check new targets
|
||||
else if (!targetManager.checkingThreat) {
|
||||
rotatingBase.transform.Rotate (0, currentRotationSpeed * Time.deltaTime * 3, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//if the turret has been hacked, the player can grab it, so when he drops it, the turret will be set in the first surface that will touch
|
||||
//also checking if the gravity of the turret has been modified
|
||||
if (tag.Equals (untaggedName)) {
|
||||
if (!mainRigidbody.isKinematic && !mainRigidbody.freezeRotation) {
|
||||
mainRigidbody.freezeRotation = true;
|
||||
|
||||
StartCoroutine (rotateElement (gameObject));
|
||||
}
|
||||
} else {
|
||||
if (mainRigidbody.freezeRotation) {
|
||||
mainRigidbody.freezeRotation = false;
|
||||
kinematicActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
//when the kinematicActive has been enabled, the turret has a regular gravity again, so the first ground surface that will find, will be its new ground
|
||||
//enabling the kinematic rigidbody of the turret
|
||||
if (kinematicActive) {
|
||||
if (Physics.Raycast (transform.position, -Vector3.up, out hit, 1.2f, layerForGravity)) {
|
||||
if (!mainRigidbody.isKinematic && kinematicActive && !GetComponent<artificialObjectGravity> () && !hit.collider.isTrigger) {
|
||||
StartCoroutine (rotateToSurface (hit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (controlOverriden) {
|
||||
|
||||
if (shootingWeapons) {
|
||||
if (Physics.Raycast (rayCastPosition.transform.position, rayCastPosition.transform.forward, out hit, Mathf.Infinity, layer)) {
|
||||
currentEnemyToShoot = hit.collider.gameObject;
|
||||
} else {
|
||||
currentEnemyToShoot = null;
|
||||
}
|
||||
|
||||
shootWeapon (currentEnemyToShoot, overridePositionToLook.transform, false);
|
||||
}
|
||||
|
||||
if (useCustomInputCameraDirection) {
|
||||
currentRaycastPositionRotation = Quaternion.LookRotation (currentCameraTransformDirection.forward);
|
||||
} else {
|
||||
axisValues = overrideInput.getCustomMovementAxis ();
|
||||
horizontalInput = axisValues.x;
|
||||
verticalInput = axisValues.y;
|
||||
|
||||
currentLookAngle.x += horizontalInput * inputRotationSpeed;
|
||||
currentLookAngle.y -= verticalInput * inputRotationSpeed;
|
||||
|
||||
currentLookAngle.y = Mathf.Clamp (currentLookAngle.y, rangeAngleX.x, rangeAngleX.y);
|
||||
|
||||
currentRaycastPositionRotation = Quaternion.Euler (0, currentLookAngle.x, 0);
|
||||
|
||||
currentRaycastPositionRotation *= Quaternion.Euler (currentLookAngle.y, 0, 0);
|
||||
}
|
||||
|
||||
rayCastPosition.transform.rotation = Quaternion.Slerp (rayCastPosition.transform.rotation, currentRaycastPositionRotation, Time.deltaTime * raycastPositionRotationSpeed);
|
||||
|
||||
lootAtTurretTarget (overridePositionToLook);
|
||||
}
|
||||
}
|
||||
|
||||
public void chooseNextWeapon ()
|
||||
{
|
||||
currentWeaponIndex++;
|
||||
|
||||
if (currentWeaponIndex >= turretWeaponInfoList.Count - 1) {
|
||||
currentWeaponIndex = 0;
|
||||
}
|
||||
|
||||
setWeapon (currentWeaponIndex);
|
||||
|
||||
activateWeapon ();
|
||||
}
|
||||
|
||||
public void choosePreviousWeapon ()
|
||||
{
|
||||
currentWeaponIndex--;
|
||||
|
||||
if (currentWeaponIndex < 0) {
|
||||
currentWeaponIndex = turretWeaponInfoList.Count - 1;
|
||||
}
|
||||
|
||||
setWeapon (currentWeaponIndex);
|
||||
|
||||
activateWeapon ();
|
||||
}
|
||||
|
||||
public void enableOrDisableWeapons (bool state)
|
||||
{
|
||||
weaponsActive = state;
|
||||
|
||||
if (weaponsActive) {
|
||||
activateWeapon ();
|
||||
} else {
|
||||
deactivateWeapon ();
|
||||
}
|
||||
}
|
||||
|
||||
void cancelCheckSuspectTurret ()
|
||||
{
|
||||
setOnSpottedState (false);
|
||||
}
|
||||
|
||||
public void setOnSpottedState (bool state)
|
||||
{
|
||||
if (state) {
|
||||
activateWeapon ();
|
||||
} else {
|
||||
StartCoroutine (rotateElement (head));
|
||||
|
||||
deactivateWeapon ();
|
||||
}
|
||||
}
|
||||
|
||||
//active the fire mode
|
||||
void shootWeapon (GameObject enemyToShoot, Transform placeToShoot, bool checkTargetOnRaycast)
|
||||
{
|
||||
//if the current weapon is the machine gun or the cannon, check with a ray if the player is in front of the turret
|
||||
//if the cannon is selected, the time to shoot is 1 second, the machine gun shoots every 0.1 seconds
|
||||
bool canCheckRaycastResult = true;
|
||||
|
||||
if (weaponInfoAssigned) {
|
||||
if (currentTurretWeaponInfo.useWaitTimeToStartShootAfterActivation) {
|
||||
if (Time.time < currentTurretWeaponInfo.waitTimeToStartShootAfterActivation + lastTimeWeaponsActivated) {
|
||||
canCheckRaycastResult = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canCheckRaycastResult) {
|
||||
if (checkTargetOnRaycast) {
|
||||
if (Physics.Raycast (rayCastPosition.transform.position, rayCastPosition.transform.forward, out hit, Mathf.Infinity, layer)) {
|
||||
Debug.DrawLine (rayCastPosition.transform.position, hit.point, Color.red, 200, true);
|
||||
|
||||
if (hit.collider.gameObject == enemyToShoot || hit.collider.gameObject.transform.IsChildOf (enemyToShoot.transform)) {
|
||||
timer += Time.deltaTime * speedMultiplier;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
timer += Time.deltaTime * speedMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
if (weaponInfoAssigned) {
|
||||
if (currentTurretWeaponInfo.weaponLookAtTarget) {
|
||||
Vector3 targetDir = placeToShoot.position - currentTurretWeaponInfo.weaponLookAtTargetTransform.position;
|
||||
|
||||
Quaternion qTo = Quaternion.LookRotation (targetDir);
|
||||
|
||||
currentTurretWeaponInfo.weaponLookAtTargetTransform.rotation =
|
||||
Quaternion.Slerp (currentTurretWeaponInfo.weaponLookAtTargetTransform.rotation, qTo, currentRotationSpeed * Time.deltaTime);
|
||||
}
|
||||
|
||||
//if the timer ends, shoot
|
||||
if (timer >= shootTimerLimit) {
|
||||
timer = 0;
|
||||
|
||||
//if (controlOverriden) {
|
||||
// if (currentCameraTransformDirection != null) {
|
||||
// bool surfaceFound = false;
|
||||
|
||||
// Vector3 raycastDirection = currentCameraTransformDirection.forward;
|
||||
|
||||
// if (Physics.Raycast (currentCameraTransformDirection.position, raycastDirection, out hit, Mathf.Infinity, layer)) {
|
||||
|
||||
// if (hit.collider.gameObject != turretAttacker) {
|
||||
// surfaceFound = true;
|
||||
// } else {
|
||||
// Vector3 raycastPosition = hit.point + 0.2f * raycastDirection;
|
||||
|
||||
// if (Physics.Raycast (raycastPosition, raycastDirection, out hit, Mathf.Infinity, layer)) {
|
||||
// surfaceFound = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (surfaceFound) {
|
||||
// newProjectileGameObject.transform.LookAt (hit.point);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
if (currentTurretWeaponInfo.useAnimationOnWeapon) {
|
||||
currentTurretWeaponInfo.animationOnWeapon.Play (currentTurretWeaponInfo.weaponAnimationName);
|
||||
}
|
||||
|
||||
if (currentTurretWeaponInfo.useSimpleWeaponSystem) {
|
||||
currentTurretWeaponInfo.mainSimpleWeaponSystem.shootWeapon (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//follow the enemy position, to rotate torwards his direction
|
||||
void lootAtTurretTarget (Transform objective)
|
||||
{
|
||||
if (objective != null) {
|
||||
//there are two parts in the turret that move, the head and the middle body
|
||||
Vector3 targetDir = objective.position - rotatingBase.transform.position;
|
||||
|
||||
targetDir = targetDir - transform.InverseTransformDirection (targetDir).y * transform.up;
|
||||
|
||||
targetDir = targetDir.normalized;
|
||||
|
||||
Quaternion targetRotation = Quaternion.LookRotation (targetDir, transform.up);
|
||||
|
||||
rotatingBase.transform.rotation = Quaternion.Slerp (rotatingBase.transform.rotation, targetRotation, currentRotationSpeed * Time.deltaTime);
|
||||
|
||||
Vector3 targetDir2 = objective.position - head.transform.position;
|
||||
|
||||
Quaternion targetRotation2 = Quaternion.LookRotation (targetDir2, transform.up);
|
||||
|
||||
head.transform.rotation = Quaternion.Slerp (head.transform.rotation, targetRotation2, currentRotationSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
//the gravity of the turret is regular again
|
||||
void dropCharacter (bool state)
|
||||
{
|
||||
kinematicActive = state;
|
||||
}
|
||||
|
||||
//when the turret detects a ground surface, will rotate according to the surface normal
|
||||
IEnumerator rotateToSurface (RaycastHit hit)
|
||||
{
|
||||
//it works like the player gravity
|
||||
kinematicActive = false;
|
||||
|
||||
mainRigidbody.useGravity = true;
|
||||
mainRigidbody.isKinematic = true;
|
||||
|
||||
Quaternion rot = transform.rotation;
|
||||
Vector3 myForward = Vector3.Cross (transform.right, hit.normal);
|
||||
Quaternion dstRot = Quaternion.LookRotation (myForward, hit.normal);
|
||||
Vector3 pos = hit.point;
|
||||
|
||||
for (float t = 0; t < 1;) {
|
||||
t += Time.deltaTime * 3;
|
||||
|
||||
transform.rotation = Quaternion.Slerp (rot, dstRot, t);
|
||||
//set also the position of the turret to the hit point
|
||||
|
||||
transform.position = Vector3.MoveTowards (transform.position, pos + 0.5f * transform.up, t);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
gameObject.layer = 0;
|
||||
}
|
||||
|
||||
//return the head of the turret to its original rotation
|
||||
IEnumerator rotateElement (GameObject element)
|
||||
{
|
||||
Quaternion rot = element.transform.localRotation;
|
||||
|
||||
Vector3 myForward = Vector3.Cross (element.transform.right, Vector3.up);
|
||||
Quaternion dstRot = Quaternion.LookRotation (myForward, Vector3.up);
|
||||
|
||||
dstRot.y = 0;
|
||||
|
||||
for (float t = 0; t < 1;) {
|
||||
t += Time.deltaTime * 3 * speedMultiplier;
|
||||
|
||||
element.transform.localRotation = Quaternion.Slerp (rot, dstRot, t);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
//if one enemy or more are inside of the turret's trigger, activate the weapon selected in the inspector: machine gun, laser or cannon
|
||||
void activateWeapon ()
|
||||
{
|
||||
if (locatedEnemyAudioElement != null) {
|
||||
AudioPlayer.PlayOneShot (locatedEnemyAudioElement, gameObject, Random.Range (0.8f, 1.2f));
|
||||
}
|
||||
|
||||
setCurrentTurretWeapon (currentWeaponName);
|
||||
|
||||
lastTimeWeaponsActivated = Time.time;
|
||||
}
|
||||
|
||||
//if all the enemies in the trigger of the turret are gone, deactivate the weapons
|
||||
void deactivateWeapon ()
|
||||
{
|
||||
deactivateCurrentWeapon ();
|
||||
}
|
||||
|
||||
//the turret is destroyed, so disable all the triggers, the AI, and add a rigidbody to every object with a render, and add force to them
|
||||
public void setDeathState ()
|
||||
{
|
||||
deactivateWeapon ();
|
||||
|
||||
dead = true;
|
||||
|
||||
lastTimeTurretDestroyed = Time.time;
|
||||
|
||||
Component [] components = GetComponentsInChildren (typeof (Transform));
|
||||
|
||||
int layerToIgnoreIndex = LayerMask.NameToLayer ("Scanner");
|
||||
|
||||
int ignoreRaycastLayerIndex = LayerMask.NameToLayer ("Ignore Raycast");
|
||||
|
||||
foreach (Component c in components) {
|
||||
Renderer currentRenderer = c.GetComponent<Renderer> ();
|
||||
|
||||
if (currentRenderer != null && c.gameObject.layer != layerToIgnoreIndex) {
|
||||
if (fadePiecesOnDeath) {
|
||||
rendererParts.Add (currentRenderer);
|
||||
|
||||
currentRenderer.material.shader = transparent;
|
||||
}
|
||||
|
||||
c.transform.SetParent (transform);
|
||||
|
||||
c.gameObject.layer = ignoreRaycastLayerIndex;
|
||||
|
||||
Rigidbody currentRigidbody = c.gameObject.GetComponent<Rigidbody> ();
|
||||
|
||||
if (currentRigidbody == null) {
|
||||
currentRigidbody = c.gameObject.AddComponent<Rigidbody> ();
|
||||
}
|
||||
|
||||
Collider currentCollider = c.gameObject.GetComponent<Collider> ();
|
||||
|
||||
if (currentCollider == null) {
|
||||
c.gameObject.AddComponent<BoxCollider> ();
|
||||
}
|
||||
|
||||
if (addForceToTurretPiecesOnDeath) {
|
||||
currentRigidbody.AddExplosionForce (forceAmountToPieces, transform.position + transform.up, radiusAmountToPieces, 3);
|
||||
}
|
||||
} else {
|
||||
Collider currentCollider = c.gameObject.GetComponent<Collider> ();
|
||||
|
||||
if (currentCollider != null) {
|
||||
currentCollider.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the player uses the power of slow down, reduces the rotation speed of the turret, the rate fire and the projectile velocity
|
||||
void setReducedVelocity (float speedMultiplierValue)
|
||||
{
|
||||
currentRotationSpeed = speedMultiplierValue;
|
||||
|
||||
speedMultiplier = speedMultiplierValue;
|
||||
}
|
||||
|
||||
//set the turret speed to its normal state
|
||||
void setNormalVelocity ()
|
||||
{
|
||||
currentRotationSpeed = orignalRotationSpeed;
|
||||
|
||||
speedMultiplier = 1;
|
||||
}
|
||||
|
||||
public void setRandomWeapon ()
|
||||
{
|
||||
int random = Random.Range (0, turretWeaponInfoList.Count);
|
||||
|
||||
setWeapon (random);
|
||||
}
|
||||
|
||||
public void setWeapon (int weaponNumber)
|
||||
{
|
||||
setCurrentTurretWeapon (turretWeaponInfoList [weaponNumber].Name);
|
||||
}
|
||||
|
||||
public void startOverride ()
|
||||
{
|
||||
overrideTurretControlState (true);
|
||||
}
|
||||
|
||||
public void stopOverride ()
|
||||
{
|
||||
overrideTurretControlState (false);
|
||||
}
|
||||
|
||||
public void overrideTurretControlState (bool state)
|
||||
{
|
||||
if (controlOverriden == state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state) {
|
||||
currentLookAngle = new Vector2 (rayCastPosition.transform.eulerAngles.y, rayCastPosition.transform.eulerAngles.x);
|
||||
} else {
|
||||
currentLookAngle = Vector2.zero;
|
||||
axisValues = Vector2.zero;
|
||||
shootingWeapons = false;
|
||||
}
|
||||
|
||||
controlOverriden = state;
|
||||
|
||||
targetManager.pauseAI (controlOverriden);
|
||||
|
||||
if (controlOverriden) {
|
||||
currentRotationSpeed = overrideRotationSpeed;
|
||||
} else {
|
||||
currentRotationSpeed = orignalRotationSpeed;
|
||||
|
||||
StartCoroutine (rotateElement (head));
|
||||
|
||||
deactivateWeapon ();
|
||||
}
|
||||
|
||||
stopDisableOverrideAfterDelayCoroutine ();
|
||||
|
||||
for (int i = 0; i < turretWeaponInfoList.Count; i++) {
|
||||
if (turretWeaponInfoList [i].useSimpleWeaponSystem) {
|
||||
if (controlOverriden) {
|
||||
turretWeaponInfoList [i].mainSimpleWeaponSystem.setCustommainCameraTransform (currentCameraTransformDirection);
|
||||
} else {
|
||||
turretWeaponInfoList [i].mainSimpleWeaponSystem.setCustommainCameraTransform (null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disableOverrideAfterDelay (float delayDuration)
|
||||
{
|
||||
if (gameObject.activeSelf) {
|
||||
stopDisableOverrideAfterDelayCoroutine ();
|
||||
|
||||
disableOverrideCoroutine = StartCoroutine (updatedDisableOverrideAfterDelayCoroutine (delayDuration));
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDisableOverrideAfterDelayCoroutine ()
|
||||
{
|
||||
if (disableOverrideCoroutine != null) {
|
||||
StopCoroutine (disableOverrideCoroutine);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator updatedDisableOverrideAfterDelayCoroutine (float delayDuration)
|
||||
{
|
||||
yield return new WaitForSecondsRealtime (delayDuration);
|
||||
|
||||
stopOverride ();
|
||||
}
|
||||
|
||||
public void setNewCurrentCameraTransformDirection (Transform newTransform)
|
||||
{
|
||||
currentCameraTransformDirection = newTransform;
|
||||
}
|
||||
|
||||
public void setNewTurretAttacker (GameObject newAttacker)
|
||||
{
|
||||
turretAttacker = newAttacker;
|
||||
}
|
||||
|
||||
|
||||
void setCurrentTurretWeapon (string weaponName)
|
||||
{
|
||||
int currentIndex = turretWeaponInfoList.FindIndex (s => s.Name == weaponName);
|
||||
|
||||
if (currentIndex > -1) {
|
||||
|
||||
//if (turretWeaponInfoList [currentIndex].isCurrentWeapon) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
for (int i = 0; i < turretWeaponInfoList.Count; i++) {
|
||||
|
||||
if (i != currentIndex) {
|
||||
turretWeaponInfo currentInfo = turretWeaponInfoList [i];
|
||||
|
||||
if (currentInfo.isCurrentWeapon) {
|
||||
currentInfo.isCurrentWeapon = false;
|
||||
|
||||
if (currentInfo.useEventOnSelectWeapon) {
|
||||
currentInfo.eventOnDeactivateWeapon.Invoke ();
|
||||
}
|
||||
|
||||
if (currentInfo.weaponObject != null) {
|
||||
if (currentInfo.weaponObject.activeSelf) {
|
||||
currentInfo.weaponObject.SetActive (false);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentInfo.useWeaponActivateAnimation) {
|
||||
if (currentInfo.weaponActivationAnimationSystem != null) {
|
||||
currentInfo.weaponActivationAnimationSystem.playBackwardAnimation ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentTurretWeaponInfo = turretWeaponInfoList [currentIndex];
|
||||
|
||||
currentTurretWeaponInfo.isCurrentWeapon = true;
|
||||
|
||||
if (currentTurretWeaponInfo.useEventOnSelectWeapon) {
|
||||
currentTurretWeaponInfo.eventOnActivateWeapon.Invoke ();
|
||||
}
|
||||
|
||||
if (currentTurretWeaponInfo.weaponObject != null) {
|
||||
if (!currentTurretWeaponInfo.weaponObject.activeSelf) {
|
||||
currentTurretWeaponInfo.weaponObject.SetActive (true);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentTurretWeaponInfo.useWeaponActivateAnimation) {
|
||||
if (currentTurretWeaponInfo.weaponActivationAnimationSystem != null) {
|
||||
currentTurretWeaponInfo.weaponActivationAnimationSystem.playForwardAnimation ();
|
||||
}
|
||||
}
|
||||
|
||||
if (useGeneralLayerToDamage) {
|
||||
if (currentTurretWeaponInfo.useSimpleWeaponSystem) {
|
||||
currentTurretWeaponInfo.mainSimpleWeaponSystem.setTargetToDamageLayer (layerToDamage);
|
||||
}
|
||||
}
|
||||
|
||||
shootTimerLimit = currentTurretWeaponInfo.fireRate;
|
||||
|
||||
currentWeaponName = currentTurretWeaponInfo.Name;
|
||||
|
||||
currentWeaponIndex = currentIndex;
|
||||
|
||||
weaponInfoAssigned = true;
|
||||
}
|
||||
}
|
||||
|
||||
void deactivateCurrentWeapon ()
|
||||
{
|
||||
if (weaponInfoAssigned) {
|
||||
if (currentTurretWeaponInfo.useEventOnSelectWeapon) {
|
||||
currentTurretWeaponInfo.eventOnDeactivateWeapon.Invoke ();
|
||||
}
|
||||
|
||||
if (currentTurretWeaponInfo.weaponObject != null) {
|
||||
if (currentTurretWeaponInfo.weaponObject.activeSelf) {
|
||||
currentTurretWeaponInfo.weaponObject.SetActive (false);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentTurretWeaponInfo.useSimpleWeaponSystem) {
|
||||
currentTurretWeaponInfo.mainSimpleWeaponSystem.shootWeapon (false);
|
||||
}
|
||||
|
||||
if (currentTurretWeaponInfo.useWeaponActivateAnimation) {
|
||||
if (currentTurretWeaponInfo.weaponActivationAnimationSystem != null) {
|
||||
currentTurretWeaponInfo.weaponActivationAnimationSystem.playBackwardAnimation ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//INPUT FUNCTIONS
|
||||
public void inputSetShootState (bool state)
|
||||
{
|
||||
if (weaponsActive) {
|
||||
if (Time.time > lastTimeWeaponsActivated + 0.6f) {
|
||||
shootingWeapons = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void inputSetWeaponsState ()
|
||||
{
|
||||
enableOrDisableWeapons (!weaponsActive);
|
||||
}
|
||||
|
||||
public void inputSetNextOrPreviousWeapon (bool state)
|
||||
{
|
||||
if (state) {
|
||||
chooseNextWeapon ();
|
||||
} else {
|
||||
choosePreviousWeapon ();
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class turretWeaponInfo
|
||||
{
|
||||
[Header ("Main Settings")]
|
||||
[Space]
|
||||
|
||||
public string Name;
|
||||
|
||||
public float fireRate;
|
||||
|
||||
public bool useWaitTimeToStartShootAfterActivation;
|
||||
public float waitTimeToStartShootAfterActivation;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool useSimpleWeaponSystem;
|
||||
public simpleWeaponSystem mainSimpleWeaponSystem;
|
||||
|
||||
[Space]
|
||||
[Header ("Animation Settings")]
|
||||
[Space]
|
||||
|
||||
public bool useWeaponActivateAnimation;
|
||||
|
||||
public simpleAnimationSystem weaponActivationAnimationSystem;
|
||||
|
||||
[Space]
|
||||
|
||||
public bool useAnimationOnWeapon;
|
||||
public string weaponAnimationName;
|
||||
|
||||
public Animation animationOnWeapon;
|
||||
|
||||
[Space]
|
||||
[Header ("Other Settings")]
|
||||
[Space]
|
||||
|
||||
public bool weaponLookAtTarget;
|
||||
public Transform weaponLookAtTargetTransform;
|
||||
|
||||
public GameObject weaponObject;
|
||||
|
||||
[Space]
|
||||
[Header ("Debug")]
|
||||
[Space]
|
||||
|
||||
public bool isCurrentWeapon;
|
||||
|
||||
[Space]
|
||||
[Header ("Event Settings")]
|
||||
[Space]
|
||||
|
||||
public bool useEventOnSelectWeapon;
|
||||
|
||||
public UnityEvent eventOnActivateWeapon;
|
||||
public UnityEvent eventOnDeactivateWeapon;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4fbd3df4028083b46a0cdd170e7927b7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 40995
|
||||
packageName: Game Kit Controller - Shooter Melee Adventure Creator 3D + 2.5D
|
||||
packageVersion: 3.77g
|
||||
assetPath: Assets/Game Kit Controller/Scripts/AI/Turret/AITurret.cs
|
||||
uploadId: 814740
|
||||
111
Assets/Game Kit Controller/Scripts/AI/Turret/enemyLaser.cs
Normal file
111
Assets/Game Kit Controller/Scripts/AI/Turret/enemyLaser.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
public class enemyLaser : laser
|
||||
{
|
||||
[Space]
|
||||
[Header ("Main Settings")]
|
||||
[Space]
|
||||
|
||||
public LayerMask layer;
|
||||
|
||||
public float laserDamage = 0.2f;
|
||||
public bool ignoreShield;
|
||||
|
||||
public int damageTypeID = -1;
|
||||
|
||||
public bool damageCanBeBlocked = true;
|
||||
|
||||
public bool useDamageRate;
|
||||
public float damageRate = 0.3f;
|
||||
|
||||
[Space]
|
||||
[Header ("Other Settings")]
|
||||
[Space]
|
||||
|
||||
public GameObject hitParticles;
|
||||
public GameObject hitSparks;
|
||||
|
||||
public bool useCustomLaserPosition;
|
||||
public Transform customLaserPosition;
|
||||
|
||||
public GameObject owner;
|
||||
|
||||
RaycastHit hit;
|
||||
|
||||
Transform currentLaserPosition;
|
||||
|
||||
float lastTimeDamageActive;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
StartCoroutine (laserAnimation ());
|
||||
|
||||
if (useCustomLaserPosition) {
|
||||
currentLaserPosition = customLaserPosition;
|
||||
} else {
|
||||
currentLaserPosition = transform;
|
||||
}
|
||||
}
|
||||
|
||||
void Update ()
|
||||
{
|
||||
//check the hit collider of the raycast
|
||||
if (Physics.Raycast (currentLaserPosition.position, currentLaserPosition.forward, out hit, Mathf.Infinity, layer)) {
|
||||
bool canApplyDamageResult = true;
|
||||
|
||||
if (useDamageRate) {
|
||||
if (lastTimeDamageActive > 0 && Time.time < damageRate + lastTimeDamageActive) {
|
||||
canApplyDamageResult = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (canApplyDamageResult) {
|
||||
applyDamage.checkHealth (gameObject, hit.collider.gameObject, laserDamage, -currentLaserPosition.forward, (hit.point - (hit.normal / 4)),
|
||||
owner, true, true, ignoreShield, false, damageCanBeBlocked, false, -1, damageTypeID);
|
||||
|
||||
lastTimeDamageActive = Time.time;
|
||||
}
|
||||
|
||||
//set the sparks and .he smoke in the hit point
|
||||
laserDistance = hit.distance;
|
||||
|
||||
if (!hitSparks.activeSelf) {
|
||||
hitSparks.SetActive (true);
|
||||
}
|
||||
|
||||
if (!hitParticles.activeSelf) {
|
||||
hitParticles.SetActive (true);
|
||||
}
|
||||
|
||||
hitParticles.transform.position = hit.point + (currentLaserPosition.position - hit.point) * 0.02f;
|
||||
|
||||
hitParticles.transform.rotation = Quaternion.identity;
|
||||
|
||||
hitSparks.transform.rotation = Quaternion.LookRotation (hit.normal, currentLaserPosition.up);
|
||||
} else {
|
||||
//if the laser does not hit anything, disable the particles and set the hit point
|
||||
if (hitSparks.activeSelf) {
|
||||
hitSparks.SetActive (false);
|
||||
}
|
||||
|
||||
if (hitParticles.activeSelf) {
|
||||
hitParticles.SetActive (false);
|
||||
}
|
||||
|
||||
laserDistance = 1000;
|
||||
|
||||
lastTimeDamageActive = Time.time;
|
||||
}
|
||||
|
||||
//set the size of the laser, according to the hit position
|
||||
lRenderer.SetPosition (1, (laserDistance * Vector3.forward));
|
||||
|
||||
animateLaser ();
|
||||
}
|
||||
|
||||
public void setOwner (GameObject laserOwner)
|
||||
{
|
||||
owner = laserOwner;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32cad009bb77b5e41b751c41ee17f6c3
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 40995
|
||||
packageName: Game Kit Controller - Shooter Melee Adventure Creator 3D + 2.5D
|
||||
packageVersion: 3.77g
|
||||
assetPath: Assets/Game Kit Controller/Scripts/AI/Turret/enemyLaser.cs
|
||||
uploadId: 814740
|
||||
861
Assets/Game Kit Controller/Scripts/AI/Turret/manageAITarget.cs
Normal file
861
Assets/Game Kit Controller/Scripts/AI/Turret/manageAITarget.cs
Normal file
@@ -0,0 +1,861 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.Events;
|
||||
|
||||
public class manageAITarget : MonoBehaviour
|
||||
{
|
||||
[Header ("AI Settings")]
|
||||
[Space]
|
||||
|
||||
public float timeToCheckSuspect;
|
||||
|
||||
public LayerMask layerMask;
|
||||
public LayerMask layerToCheckTargets;
|
||||
|
||||
public string functionToShoot;
|
||||
|
||||
public float extraFieldOfViewRadiusOnSpot;
|
||||
|
||||
public bool checkRaycastToViewTarget = true;
|
||||
public LayerMask layerToCheckRaycastToViewTarget;
|
||||
|
||||
[Space]
|
||||
[Header ("Range Vision Settings")]
|
||||
[Space]
|
||||
|
||||
public float visionRange = 90;
|
||||
public float minDistanceToAdquireTarget = 2;
|
||||
public bool allowDetectionWhenTooCloseEvenNotVisible;
|
||||
|
||||
public bool ignoreVisionRangeActive;
|
||||
public float checkIfTargetIsPhysicallyVisibleRadius = 0.2f;
|
||||
|
||||
[Space]
|
||||
[Header ("Other Settings")]
|
||||
[Space]
|
||||
|
||||
public string factionToChangeName = "Friend Turrets";
|
||||
|
||||
public string surprisedCharacterStateName = "Surprised";
|
||||
public string wonderingCharacterStateName = "Wondering";
|
||||
|
||||
public bool alertFactionOnSpotted;
|
||||
public float alertFactionRadius = 10;
|
||||
|
||||
[Space]
|
||||
[Header ("AI State")]
|
||||
[Space]
|
||||
|
||||
public bool onSpotted;
|
||||
public bool paused;
|
||||
public bool hacking;
|
||||
public bool checkingThreat;
|
||||
public bool targetIsCharacter;
|
||||
public bool targetIsVehicle;
|
||||
public bool threatInfoStored;
|
||||
|
||||
public bool seeingCurrentTarget;
|
||||
|
||||
public GameObject enemyToShoot;
|
||||
|
||||
public GameObject posibleThreat;
|
||||
|
||||
public Transform placeToShoot;
|
||||
|
||||
public bool differentEnemy;
|
||||
|
||||
public GameObject currentObjectDetectedByRaycast;
|
||||
|
||||
[Space]
|
||||
[Header ("Targets Debug")]
|
||||
[Space]
|
||||
|
||||
public List<GameObject> enemies = new List<GameObject> ();
|
||||
public List<GameObject> notEnemies = new List<GameObject> ();
|
||||
|
||||
public List<GameObject> fullEnemyList = new List<GameObject> ();
|
||||
|
||||
[Space]
|
||||
[Header ("Gizmo Settings")]
|
||||
[Space]
|
||||
|
||||
public bool showGizmo;
|
||||
public Color gizmoColor = Color.red;
|
||||
|
||||
[Space]
|
||||
[Header ("Event Settings")]
|
||||
[Space]
|
||||
|
||||
public bool useEventsOnSpotted;
|
||||
public UnityEvent eventOnSpotted;
|
||||
public UnityEvent eventOnNoTargetsToAttack;
|
||||
|
||||
[Space]
|
||||
[Header ("AI Elements")]
|
||||
[Space]
|
||||
|
||||
public Transform rayCastPosition;
|
||||
public SphereCollider fovTrigger;
|
||||
|
||||
public GameObject hackDevice;
|
||||
|
||||
public checkCollisionType viewTrigger;
|
||||
public characterFactionManager factionManager;
|
||||
public characterStateIconSystem characterStateIconManager;
|
||||
|
||||
RaycastHit hit;
|
||||
float originalFOVRadius;
|
||||
float timeToCheck = 0;
|
||||
float speedMultiplier = 1;
|
||||
|
||||
bool hackFailed;
|
||||
|
||||
playerController currentPlayerController;
|
||||
vehicleHUDManager currentVehicleHUDManager;
|
||||
characterFactionManager characterFactionToCheck;
|
||||
|
||||
bool hasBeenAttacked;
|
||||
Vector3 targetDirection;
|
||||
bool enemyAlertActive;
|
||||
|
||||
float timeWithoutThreatFound;
|
||||
|
||||
Vector3 currentPosition;
|
||||
|
||||
bool targetIsDriving;
|
||||
|
||||
GameObject previousEnemy;
|
||||
|
||||
float currentDistance;
|
||||
|
||||
Vector3 targetToCheckDirection;
|
||||
Transform temporalPlaceToShoot;
|
||||
Vector3 targetToCheckPosition;
|
||||
Vector3 targetToCheckRaycastPosition;
|
||||
vehicleHUDManager temporalVehicleHUDManagerToCheck;
|
||||
|
||||
void Start ()
|
||||
{
|
||||
originalFOVRadius = fovTrigger.radius;
|
||||
|
||||
if (hackDevice != null) {
|
||||
if (tag.Equals ("friend")) {
|
||||
if (hackDevice.activeSelf) {
|
||||
hackDevice.SetActive (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Update ()
|
||||
{
|
||||
if (!hacking && !paused) {
|
||||
|
||||
closestTarget ();
|
||||
|
||||
if (onSpotted) {
|
||||
|
||||
lootAtTarget (placeToShoot);
|
||||
|
||||
if (enemyToShoot != null) {
|
||||
if (Physics.Raycast (rayCastPosition.position, rayCastPosition.forward, out hit, Mathf.Infinity, layerMask)) {
|
||||
if (hit.collider.gameObject == enemyToShoot || hit.collider.gameObject.transform.IsChildOf (enemyToShoot.transform)) {
|
||||
targetDirection = enemyToShoot.transform.position - transform.position;
|
||||
|
||||
float angleWithTarget = Vector3.SignedAngle (rayCastPosition.forward, targetDirection, enemyToShoot.transform.up);
|
||||
|
||||
if (Mathf.Abs (angleWithTarget) < visionRange / 2 || ignoreVisionRangeActive) {
|
||||
shootTarget ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if the turret detects a target, it will check if it is an enemy, and this will take 2 seconds, while the enemy choose to leave or stay in the place
|
||||
else if (checkingThreat) {
|
||||
if (posibleThreat != null) {
|
||||
if (!placeToShoot) {
|
||||
//every object with a health component, has a place to be shoot, to avoid that a enemy shoots the player in his foot, so to center the shoot
|
||||
//it is used the gameObject placetoshoot in the health script
|
||||
if (applyDamage.checkIfDead (posibleThreat)) {
|
||||
cancelCheckSuspect (posibleThreat);
|
||||
|
||||
return;
|
||||
} else {
|
||||
placeToShoot = applyDamage.getPlaceToShoot (posibleThreat);
|
||||
}
|
||||
}
|
||||
|
||||
if (!threatInfoStored) {
|
||||
currentPlayerController = posibleThreat.GetComponent<playerController> ();
|
||||
|
||||
if (currentPlayerController != null) {
|
||||
if (currentPlayerController.isCharacterVisibleToAI ()) {
|
||||
setCharacterStateIcon (wonderingCharacterStateName);
|
||||
}
|
||||
} else {
|
||||
setCharacterStateIcon (wonderingCharacterStateName);
|
||||
}
|
||||
|
||||
threatInfoStored = true;
|
||||
}
|
||||
|
||||
if (placeToShoot != null) {
|
||||
//look at the target position
|
||||
lootAtTarget (placeToShoot);
|
||||
}
|
||||
|
||||
//uses a raycast to check the posible threat
|
||||
if (Physics.Raycast (rayCastPosition.position, rayCastPosition.forward, out hit, Mathf.Infinity, layerMask)) {
|
||||
if (hit.collider.gameObject == posibleThreat || hit.collider.gameObject.transform.IsChildOf (posibleThreat.transform)) {
|
||||
timeToCheck += Time.deltaTime * speedMultiplier;
|
||||
} else {
|
||||
timeWithoutThreatFound += Time.deltaTime * speedMultiplier;
|
||||
}
|
||||
|
||||
//when the turret look at the target for a while, it will open fire
|
||||
if (timeToCheck > timeToCheckSuspect) {
|
||||
timeToCheck = 0;
|
||||
|
||||
checkingThreat = false;
|
||||
|
||||
addEnemy (posibleThreat);
|
||||
|
||||
posibleThreat = null;
|
||||
|
||||
disableCharacterStateIcon ();
|
||||
}
|
||||
|
||||
if (timeWithoutThreatFound > timeToCheckSuspect) {
|
||||
resetCheckThreatValues ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resetCheckThreatValues ()
|
||||
{
|
||||
placeToShoot = null;
|
||||
posibleThreat = null;
|
||||
checkingThreat = false;
|
||||
timeToCheck = 0;
|
||||
timeWithoutThreatFound = 0;
|
||||
|
||||
disableCharacterStateIcon ();
|
||||
}
|
||||
|
||||
//follow the enemy position, to rotate torwards his direction
|
||||
void lootAtTarget (Transform objective)
|
||||
{
|
||||
if (showGizmo) {
|
||||
Debug.DrawRay (rayCastPosition.position, rayCastPosition.forward, Color.red);
|
||||
}
|
||||
|
||||
if (objective != null) {
|
||||
Vector3 targetDir = objective.position - rayCastPosition.position;
|
||||
Quaternion targetRotation = Quaternion.LookRotation (targetDir, transform.up);
|
||||
rayCastPosition.rotation = Quaternion.Slerp (rayCastPosition.rotation, targetRotation, 10 * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
public bool checkCharacterFaction (GameObject character, bool damageReceived)
|
||||
{
|
||||
if (fullEnemyList.Contains (character)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
characterFactionToCheck = character.GetComponent<characterFactionManager> ();
|
||||
|
||||
if (characterFactionToCheck != null) {
|
||||
bool isEnemy = false;
|
||||
|
||||
if (damageReceived) {
|
||||
isEnemy = factionManager.isAttackerEnemy (characterFactionToCheck.getFactionName ());
|
||||
} else {
|
||||
isEnemy = factionManager.isCharacterEnemy (characterFactionToCheck.getFactionName ());
|
||||
}
|
||||
|
||||
if (characterFactionToCheck.isIgnoreCharacterFactionEnabled ()) {
|
||||
isEnemy = false;
|
||||
}
|
||||
|
||||
return isEnemy;
|
||||
} else {
|
||||
currentVehicleHUDManager = character.GetComponent<vehicleHUDManager> ();
|
||||
|
||||
if (currentVehicleHUDManager != null) {
|
||||
if (currentVehicleHUDManager.isVehicleBeingDriven ()) {
|
||||
GameObject currentDriver = currentVehicleHUDManager.getCurrentDriver ();
|
||||
|
||||
if (currentDriver == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
characterFactionToCheck = currentDriver.GetComponent<characterFactionManager> ();
|
||||
|
||||
if (characterFactionToCheck != null) {
|
||||
bool isEnemy = false;
|
||||
|
||||
if (damageReceived) {
|
||||
isEnemy = factionManager.isAttackerEnemy (characterFactionToCheck.getFactionName ());
|
||||
} else {
|
||||
isEnemy = factionManager.isCharacterEnemy (characterFactionToCheck.getFactionName ());
|
||||
}
|
||||
|
||||
if (characterFactionToCheck.isIgnoreCharacterFactionEnabled ()) {
|
||||
isEnemy = false;
|
||||
}
|
||||
|
||||
targetIsDriving = true;
|
||||
|
||||
return isEnemy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//check if the object which has collided with the viewTrigger (the capsule collider in the head of the turret) is an enemy checking the tag of that object
|
||||
void checkSuspect (GameObject currentSuspect)
|
||||
{
|
||||
if (canCheckSuspect (currentSuspect.layer)) {
|
||||
if (checkCharacterFaction (currentSuspect, false) && !onSpotted && posibleThreat == null) {
|
||||
|
||||
if (targetIsDriving || applyDamage.isVehicle (currentSuspect)) {
|
||||
targetIsDriving = false;
|
||||
targetIsVehicle = true;
|
||||
}
|
||||
|
||||
if (!checkRaycastToViewTarget || checkIfTargetIsPhysicallyVisible (currentSuspect, true)) {
|
||||
posibleThreat = currentSuspect;
|
||||
checkingThreat = true;
|
||||
hacking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//in the object exits from the viewTrigger, the turret rotates again to search more enemies
|
||||
void cancelCheckSuspect (GameObject col)
|
||||
{
|
||||
if (checkCharacterFaction (col, false) && !onSpotted && posibleThreat != null) {
|
||||
placeToShoot = null;
|
||||
posibleThreat = null;
|
||||
checkingThreat = false;
|
||||
timeToCheck = 0;
|
||||
|
||||
SendMessage ("cancelCheckSuspectTurret", SendMessageOptions.DontRequireReceiver);
|
||||
|
||||
disableCharacterStateIcon ();
|
||||
}
|
||||
}
|
||||
|
||||
//the sphere collider with the trigger of the turret has detected an enemy, so it is added to the list of enemies
|
||||
void enemyDetected (GameObject col)
|
||||
{
|
||||
if (checkCharacterFaction (col, false)) {
|
||||
addEnemy (col.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
//one of the enemies has left, so it is removed from the enemies list
|
||||
void enemyLost (GameObject col)
|
||||
{
|
||||
//if (onSpotted) {
|
||||
removeEnemy (col.gameObject);
|
||||
//}
|
||||
}
|
||||
|
||||
void enemyAlert (GameObject target)
|
||||
{
|
||||
enemyDetected (target);
|
||||
|
||||
enemyAlertActive = true;
|
||||
}
|
||||
|
||||
//if anyone shoot the turret, increase its field of view to search any enemy close to it
|
||||
public void checkShootOrigin (GameObject attacker)
|
||||
{
|
||||
if (!onSpotted) {
|
||||
if (checkCharacterFaction (attacker, true)) {
|
||||
addEnemy (attacker);
|
||||
|
||||
factionManager.addDetectedEnemyFromFaction (attacker);
|
||||
|
||||
hasBeenAttacked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//add an enemy to the list, checking that that enemy is not already in the list
|
||||
void addEnemy (GameObject enemy)
|
||||
{
|
||||
if (!enemies.Contains (enemy)) {
|
||||
enemies.Add (enemy);
|
||||
|
||||
if (!fullEnemyList.Contains (enemy)) {
|
||||
fullEnemyList.Add (enemy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//remove an enemy from the list
|
||||
void removeEnemy (GameObject enemy)
|
||||
{
|
||||
//remove this enemy from the faction system detected enemies for the faction of this character
|
||||
factionManager.removeDetectedEnemyFromFaction (enemy);
|
||||
|
||||
enemies.Remove (enemy);
|
||||
}
|
||||
|
||||
void addNotEnemey (GameObject notEnemy)
|
||||
{
|
||||
if (!notEnemies.Contains (notEnemy)) {
|
||||
characterFactionToCheck = notEnemy.GetComponent<characterFactionManager> ();
|
||||
|
||||
if (characterFactionToCheck != null) {
|
||||
notEnemies.Add (notEnemy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeNotEnemy (GameObject notEnemy)
|
||||
{
|
||||
if (notEnemies.Contains (notEnemy)) {
|
||||
notEnemies.Remove (notEnemy);
|
||||
}
|
||||
}
|
||||
|
||||
//when there is one enemy or more, check which is the closest to shoot it.
|
||||
void closestTarget ()
|
||||
{
|
||||
if (enemies.Count > 0) {
|
||||
currentPosition = transform.position;
|
||||
|
||||
float min = Mathf.Infinity;
|
||||
int index = -1;
|
||||
|
||||
int enemiesCount = enemies.Count;
|
||||
|
||||
for (int i = 0; i < enemiesCount; i++) {
|
||||
if (enemies [i] != null) {
|
||||
|
||||
currentDistance = GKC_Utils.distance (enemies [i].transform.position, currentPosition);
|
||||
|
||||
if (currentDistance < min) {
|
||||
min = currentDistance;
|
||||
index = i;
|
||||
}
|
||||
} else {
|
||||
enemies.RemoveAt (i);
|
||||
|
||||
i = 0;
|
||||
|
||||
enemiesCount = enemies.Count;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
enemyToShoot = enemies [index];
|
||||
|
||||
if (enemyToShoot != previousEnemy) {
|
||||
differentEnemy = true;
|
||||
} else {
|
||||
differentEnemy = false;
|
||||
}
|
||||
|
||||
if (placeToShoot == null || differentEnemy) {
|
||||
placeToShoot = applyDamage.getPlaceToShoot (enemyToShoot);
|
||||
}
|
||||
|
||||
if (applyDamage.checkIfDead (enemyToShoot)) {
|
||||
removeEnemy (enemyToShoot);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (differentEnemy) {
|
||||
currentPlayerController = enemyToShoot.GetComponent<playerController> ();
|
||||
}
|
||||
|
||||
if (currentPlayerController != null) {
|
||||
if (currentPlayerController.isPlayerDriving ()) {
|
||||
removeEnemy (enemyToShoot);
|
||||
|
||||
targetIsCharacter = false;
|
||||
|
||||
return;
|
||||
} else {
|
||||
targetIsCharacter = true;
|
||||
targetIsVehicle = false;
|
||||
}
|
||||
} else {
|
||||
if (differentEnemy) {
|
||||
currentVehicleHUDManager = enemyToShoot.GetComponent<vehicleHUDManager> ();
|
||||
}
|
||||
|
||||
if (currentVehicleHUDManager != null) {
|
||||
if (!currentVehicleHUDManager.isVehicleBeingDriven ()) {
|
||||
|
||||
removeEnemy (enemyToShoot);
|
||||
|
||||
return;
|
||||
} else {
|
||||
targetIsCharacter = false;
|
||||
targetIsVehicle = true;
|
||||
}
|
||||
} else {
|
||||
targetIsCharacter = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousEnemy != enemyToShoot) {
|
||||
previousEnemy = enemyToShoot;
|
||||
}
|
||||
|
||||
if (!onSpotted) {
|
||||
//the player can hack the turrets, but for that he has to crouch, so he can reach the back of the turret and activate the panel
|
||||
// if the player fails in the hacking or he gets up, the turret will detect the player and will start to fire him
|
||||
//check if the player fails or get up
|
||||
|
||||
seeingCurrentTarget = false;
|
||||
|
||||
if (checkRaycastToViewTarget) {
|
||||
seeingCurrentTarget = checkIfTargetIsPhysicallyVisible (enemyToShoot, false);
|
||||
} else {
|
||||
seeingCurrentTarget = true;
|
||||
}
|
||||
|
||||
if (seeingCurrentTarget) {
|
||||
//if an enemy is inside the trigger, check its position with respect the AI, if the target is in the vision range, adquire it as target
|
||||
targetDirection = enemyToShoot.transform.position - currentPosition;
|
||||
|
||||
float angleWithTarget = Vector3.SignedAngle (rayCastPosition.forward, targetDirection, enemyToShoot.transform.up);
|
||||
|
||||
if (Mathf.Abs (angleWithTarget) < visionRange / 2 || hasBeenAttacked || enemyAlertActive || ignoreVisionRangeActive) {
|
||||
if (currentPlayerController != null) {
|
||||
if ((!currentPlayerController.isCrouching () || hackFailed || checkingThreat || enemyAlertActive || hasBeenAttacked) &&
|
||||
currentPlayerController.isCharacterVisibleToAI ()) {
|
||||
|
||||
hasBeenAttacked = false;
|
||||
|
||||
enemyAlertActive = false;
|
||||
|
||||
hackFailed = false;
|
||||
targetAdquired ();
|
||||
}
|
||||
} else {
|
||||
//else, the target is a friend of the player, so shoot him
|
||||
targetAdquired ();
|
||||
}
|
||||
} else {
|
||||
//else check the distance, if the target is too close, adquire it as target too
|
||||
float distanceToTarget = GKC_Utils.distance (enemyToShoot.transform.position, currentPosition);
|
||||
|
||||
if (distanceToTarget < minDistanceToAdquireTarget && (currentPlayerController.isCharacterVisibleToAI () || allowDetectionWhenTooCloseEvenNotVisible)) {
|
||||
targetAdquired ();
|
||||
}
|
||||
//print ("out of range of vision");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if there are no enemies
|
||||
else {
|
||||
if (onSpotted) {
|
||||
placeToShoot = null;
|
||||
enemyToShoot = null;
|
||||
previousEnemy = null;
|
||||
|
||||
onSpotted = false;
|
||||
|
||||
fovTrigger.radius = originalFOVRadius;
|
||||
|
||||
viewTrigger.gameObject.SetActive (true);
|
||||
|
||||
hackFailed = false;
|
||||
|
||||
SendMessage ("setOnSpottedState", false, SendMessageOptions.DontRequireReceiver);
|
||||
|
||||
checkEventsOnSpotted (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool checkIfTargetIsPhysicallyVisible (GameObject targetToCheck, bool checkingSuspect)
|
||||
{
|
||||
targetToCheckRaycastPosition = transform.position + transform.up;
|
||||
|
||||
if (placeToShoot != null) {
|
||||
targetToCheckDirection = placeToShoot.transform.position - targetToCheckRaycastPosition;
|
||||
} else {
|
||||
temporalPlaceToShoot = applyDamage.getPlaceToShoot (targetToCheck);
|
||||
|
||||
if (temporalPlaceToShoot != null) {
|
||||
targetToCheckDirection = temporalPlaceToShoot.position - targetToCheckRaycastPosition;
|
||||
} else {
|
||||
targetToCheckDirection = (targetToCheck.transform.position + targetToCheck.transform.up) - targetToCheckRaycastPosition;
|
||||
}
|
||||
}
|
||||
|
||||
targetToCheckPosition = targetToCheckRaycastPosition + checkIfTargetIsPhysicallyVisibleRadius * targetToCheckDirection;
|
||||
|
||||
if (targetIsVehicle) {
|
||||
temporalVehicleHUDManagerToCheck = applyDamage.getVehicleHUDManager (targetToCheck);
|
||||
}
|
||||
|
||||
currentObjectDetectedByRaycast = null;
|
||||
|
||||
//Debug.DrawRay (targetToCheckPosition, targetToCheckDirection * 0.2f, Color.green);
|
||||
if (Physics.Raycast (targetToCheckPosition, targetToCheckDirection, out hit, Mathf.Infinity, layerToCheckRaycastToViewTarget)) {
|
||||
//print (hit.collider.gameObject.name + " " + targetIsVehicle);
|
||||
//print (hit.collider.name + " " + hit.transform.IsChildOf (targetToCheck.transform) + " " + targetToCheck.name);
|
||||
|
||||
if ((!targetIsVehicle && (hit.collider.gameObject == targetToCheck || hit.transform.IsChildOf (targetToCheck.transform))) ||
|
||||
(targetIsVehicle && temporalVehicleHUDManagerToCheck &&
|
||||
((temporalVehicleHUDManagerToCheck.gameObject == targetToCheck && checkingSuspect) || temporalVehicleHUDManagerToCheck.checkIfDetectSurfaceBelongToVehicle (hit.collider)))) {
|
||||
|
||||
currentObjectDetectedByRaycast = hit.collider.gameObject;
|
||||
|
||||
if (showGizmo) {
|
||||
Debug.DrawRay (rayCastPosition.position, targetToCheckDirection, Color.green, 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if (showGizmo) {
|
||||
Debug.DrawRay (rayCastPosition.position, targetToCheckDirection, Color.red, 2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (showGizmo) {
|
||||
Debug.DrawRay (rayCastPosition.position, targetToCheckDirection, Color.black, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void targetAdquired ()
|
||||
{
|
||||
//print ("target adquired");
|
||||
|
||||
onSpotted = true;
|
||||
|
||||
fovTrigger.radius = GKC_Utils.distance (enemyToShoot.transform.position, transform.position) + extraFieldOfViewRadiusOnSpot;
|
||||
|
||||
if (fovTrigger.radius < originalFOVRadius) {
|
||||
fovTrigger.radius = originalFOVRadius;
|
||||
}
|
||||
|
||||
viewTrigger.gameObject.SetActive (false);
|
||||
|
||||
SendMessage ("setOnSpottedState", true, SendMessageOptions.DontRequireReceiver);
|
||||
|
||||
//send this enemy to faction system for the detected enemies list
|
||||
factionManager.addDetectedEnemyFromFaction (enemyToShoot);
|
||||
|
||||
setCharacterStateIcon (surprisedCharacterStateName);
|
||||
|
||||
if (alertFactionOnSpotted) {
|
||||
factionManager.alertFactionOnSpotted (alertFactionRadius, enemyToShoot, transform.position);
|
||||
}
|
||||
|
||||
checkEventsOnSpotted (true);
|
||||
}
|
||||
|
||||
//active the fire mode
|
||||
public void shootTarget ()
|
||||
{
|
||||
//SendMessage (functionToShoot, true);
|
||||
}
|
||||
|
||||
public void pauseAI (bool state)
|
||||
{
|
||||
paused = state;
|
||||
|
||||
//SendMessage ("setPauseState", paused);
|
||||
}
|
||||
|
||||
void OnTriggerEnter (Collider col)
|
||||
{
|
||||
checkTriggerInfo (col, true);
|
||||
}
|
||||
|
||||
void OnTriggerExit (Collider col)
|
||||
{
|
||||
checkTriggerInfo (col, false);
|
||||
}
|
||||
|
||||
public void checkPossibleTarget (GameObject objectToCheck)
|
||||
{
|
||||
Collider currentCollider = objectToCheck.GetComponent<Collider> ();
|
||||
|
||||
if (currentCollider != null) {
|
||||
checkTriggerInfo (currentCollider, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkTriggerInfo (Collider col, bool isEnter)
|
||||
{
|
||||
if (canCheckSuspect (col.gameObject.layer)) {
|
||||
if (isEnter) {
|
||||
if (!paused) {
|
||||
if (checkCharacterFaction (col.gameObject, false)) {
|
||||
enemyDetected (col.gameObject);
|
||||
} else {
|
||||
addNotEnemey (col.gameObject);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (checkCharacterFaction (col.gameObject, false)) {
|
||||
enemyLost (col.gameObject);
|
||||
} else {
|
||||
removeNotEnemy (col.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool canCheckSuspect (int suspectLayer)
|
||||
{
|
||||
if ((1 << suspectLayer & layerToCheckTargets.value) == 1 << suspectLayer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setCorrectlyHackedState ()
|
||||
{
|
||||
setHackResult (true);
|
||||
}
|
||||
|
||||
public void setIncorrectlyHackedState ()
|
||||
{
|
||||
setHackResult (false);
|
||||
}
|
||||
|
||||
//check the result of the hacking, true the turret now is an ally, else, the turret detects the player
|
||||
public void setHackResult (bool state)
|
||||
{
|
||||
hacking = false;
|
||||
|
||||
if (state) {
|
||||
enemyHackPanel currentEnemyHackPanel = hackDevice.GetComponent<enemyHackPanel> ();
|
||||
|
||||
if (currentEnemyHackPanel != null) {
|
||||
currentEnemyHackPanel.disablePanelHack ();
|
||||
}
|
||||
|
||||
tag = "friend";
|
||||
|
||||
factionManager.changeCharacterToFaction (factionToChangeName);
|
||||
|
||||
//if the turret becomes an ally, change its icon color in the radar
|
||||
mapObjectInformation currentMapObjectInformation = GetComponent<mapObjectInformation> ();
|
||||
|
||||
if (currentMapObjectInformation != null) {
|
||||
currentMapObjectInformation.addMapObject ("Friend");
|
||||
}
|
||||
|
||||
//set in the health slider the new name and slider color
|
||||
health currentHealth = GetComponent<health> ();
|
||||
|
||||
if (currentHealth != null) {
|
||||
currentHealth.hacked ();
|
||||
}
|
||||
|
||||
enemies.Clear ();
|
||||
|
||||
notEnemies.Clear ();
|
||||
|
||||
fullEnemyList.Clear ();
|
||||
} else {
|
||||
hackFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
//the turret is been hacked
|
||||
public void activateHack ()
|
||||
{
|
||||
hacking = true;
|
||||
}
|
||||
|
||||
public void checkCharactersAroundAI ()
|
||||
{
|
||||
for (int i = 0; i < notEnemies.Count; i++) {
|
||||
enemyDetected (notEnemies [i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCharacterStateIcon (string stateName)
|
||||
{
|
||||
if (characterStateIconManager != null) {
|
||||
characterStateIconManager.setCharacterStateIcon (stateName);
|
||||
}
|
||||
}
|
||||
|
||||
public void disableCharacterStateIcon ()
|
||||
{
|
||||
if (characterStateIconManager != null) {
|
||||
characterStateIconManager.disableCharacterStateIcon ();
|
||||
}
|
||||
}
|
||||
|
||||
//disable ai when it dies
|
||||
public void setAIStateToDead ()
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
public void checkEventsOnSpotted (bool state)
|
||||
{
|
||||
if (useEventsOnSpotted) {
|
||||
if (state) {
|
||||
eventOnSpotted.Invoke ();
|
||||
} else {
|
||||
eventOnNoTargetsToAttack.Invoke ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnDrawGizmos ()
|
||||
{
|
||||
if (!showGizmo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) {
|
||||
DrawGizmos ();
|
||||
}
|
||||
}
|
||||
|
||||
void OnDrawGizmosSelected ()
|
||||
{
|
||||
DrawGizmos ();
|
||||
}
|
||||
|
||||
void DrawGizmos ()
|
||||
{
|
||||
if (showGizmo) {
|
||||
Gizmos.color = gizmoColor;
|
||||
|
||||
Gizmos.DrawWireSphere (transform.position, alertFactionRadius);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 780006d19e41485458ec445f565e7f25
|
||||
timeCreated: 1514837983
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 40995
|
||||
packageName: Game Kit Controller - Shooter Melee Adventure Creator 3D + 2.5D
|
||||
packageVersion: 3.77g
|
||||
assetPath: Assets/Game Kit Controller/Scripts/AI/Turret/manageAITarget.cs
|
||||
uploadId: 814740
|
||||
Reference in New Issue
Block a user