plantilla base para movimiento básico
This commit is contained in:
Robii Aragon
2026-02-05 05:07:55 -08:00
parent 195b696771
commit 779f2c8b20
14443 changed files with 23840465 additions and 452 deletions

View 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;
}
}

View File

@@ -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

View 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;
}
}

View File

@@ -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

View 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
}

View File

@@ -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