Files
FueraDeEscala/Assets/Game Kit Controller/Scripts/Weapons/Projectiles/arrowProjectile.cs
Robii Aragon fd87a6ffd5 add ckg
plantilla base para movimiento básico
2026-02-05 05:07:55 -08:00

305 lines
10 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class arrowProjectile : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public bool rotateArrowWithGravity = true;
public float gravityForceRotationSpeed = 5;
public float extraRotationAmount;
public string movingObjectsTag = "moving";
public bool useGravityOnArrow = true;
public float gravityForceDownAmount = 5;
[Space]
[Header ("Adjust On Surface Settings")]
[Space]
public float adjustToSurfaceSpeed = 4;
public float offsetOnCharacterBodyParent = 0.15f;
public float attachProjectileToSurfaceOffset = 0.5f;
[Space]
[Header ("Events Settings")]
[Space]
public bool useEventOnArrowImpact;
public UnityEvent eventOnArrowImpact;
public UnityEvent eventToDropArrowPickupOnBounce;
public bool showDebugPrint;
[Space]
[Header ("Components")]
[Space]
public projectileSystem mainProjectileSystem;
public Rigidbody mainRigidbody;
public spawnObject mainSpawnObject;
Quaternion targetRotation;
bool applyArrowForces = true;
bool checkSurfaceTypeDetected;
List<bowSystem.arrowSurfaceTypeInfo> arrowSurfaceTypeInfoList = new List<bowSystem.arrowSurfaceTypeInfo> ();
Coroutine adjustArrowCoroutine;
float currentArrowDownForce = 1;
void OnEnable ()
{
resetProjectile ();
}
void FixedUpdate ()
{
if (!mainProjectileSystem.isProjectileUsed ()) {
if (showDebugPrint) {
print ("searching");
}
if (applyArrowForces) {
if (mainProjectileSystem.currentProjectileInfo.isSeeker || mainProjectileSystem.currentProjectileInfo.isHommingProjectile) {
applyArrowForces = false;
}
}
if (applyArrowForces) {
if (!useGravityOnArrow && gravityForceDownAmount > 0) {
mainRigidbody.AddForce (-Vector3.up * (gravityForceDownAmount * currentArrowDownForce * mainRigidbody.mass));
}
if (rotateArrowWithGravity) {
if (gravityForceRotationSpeed > 0) {
if (!mainRigidbody.isKinematic) {
targetRotation = Quaternion.LookRotation (mainRigidbody.linearVelocity - Vector3.up * extraRotationAmount);
transform.rotation = Quaternion.Lerp (transform.rotation, targetRotation, Time.deltaTime * gravityForceRotationSpeed * currentArrowDownForce);
}
}
}
}
}
if (mainProjectileSystem.disableProjectileMeshOnImpact) {
mainProjectileSystem.disableProjectileMeshOnImpact = false;
}
}
//when the bullet touchs a surface, then
public void checkObjectDetected (GameObject objectToDamage)
{
if (showDebugPrint) {
print ("detected " + objectToDamage.name);
}
mainProjectileSystem.setProjectileUsedState (true);
mainProjectileSystem.enableOrDisableMainTrailRenderer (false);
mainProjectileSystem.projectilePaused = true;
//set the bullet kinematic
mainRigidbody.isKinematic = true;
Rigidbody objectToDamageRigidbody = objectToDamage.GetComponent<Rigidbody> ();
bool isAttachedToCharacter = false;
bool surfaceDetectedIsDead = false;
if (applyDamage.objectCanBeDamaged (objectToDamage)) {
Vector3 projectilePosition = Vector3.zero;
if (attachProjectileToSurfaceOffset != 0) {
projectilePosition = transform.position + transform.forward * attachProjectileToSurfaceOffset;
}
isAttachedToCharacter = applyDamage.attachObjectToSurfaceFound (objectToDamage.transform, transform,
transform.position, true, projectilePosition);
surfaceDetectedIsDead = applyDamage.checkIfDead (objectToDamage);
}
mainRigidbody.useGravity = false;
mainRigidbody.isKinematic = true;
if (!surfaceDetectedIsDead && !isAttachedToCharacter && (objectToDamage.CompareTag (movingObjectsTag) || objectToDamageRigidbody != null)) {
applyDamage.checkParentToAssign (transform, objectToDamage.transform);
}
mainProjectileSystem.setIgnoreParentDestroyedState (true);
mainProjectileSystem.checkProjectilesParent ();
if (useEventOnArrowImpact) {
eventOnArrowImpact.Invoke ();
}
if (checkSurfaceTypeDetected) {
meleeAttackSurfaceInfo currentMeleeAttackSurfaceInfo = objectToDamage.GetComponent<meleeAttackSurfaceInfo> ();
if (currentMeleeAttackSurfaceInfo != null) {
bool surfaceLocated = false;
string surfaceName = currentMeleeAttackSurfaceInfo.getSurfaceName ();
for (int i = 0; i < arrowSurfaceTypeInfoList.Count; i++) {
if (!surfaceLocated && arrowSurfaceTypeInfoList [i].Name.Equals (surfaceName)) {
surfaceLocated = true;
if (arrowSurfaceTypeInfoList [i].isObstacle) {
if (arrowSurfaceTypeInfoList [i].arrowBounceOnSurface) {
if (arrowSurfaceTypeInfoList [i].dropArrowPickupOnBounce) {
gameObject.SetActive (false);
eventToDropArrowPickupOnBounce.Invoke ();
if (arrowSurfaceTypeInfoList [i].addExtraForceOnBounce) {
GameObject arrowPickup = mainSpawnObject.getLastObjectSpawned ();
if (arrowPickup != null) {
Rigidbody mainArrowRigidbody = arrowPickup.GetComponent<Rigidbody> ();
if (mainArrowRigidbody != null) {
mainArrowRigidbody.AddForce (-mainArrowRigidbody.transform.forward * arrowSurfaceTypeInfoList [i].extraForceOnBounce, ForceMode.Impulse);
float randomRightDirection = Random.Range (0, 1);
if (randomRightDirection == 0) {
randomRightDirection = -1;
}
mainArrowRigidbody.AddTorque (mainRigidbody.transform.right * 10 * randomRightDirection, ForceMode.Impulse);
mainArrowRigidbody.AddTorque (mainRigidbody.transform.up * 5 * (-1 * randomRightDirection), ForceMode.Impulse);
}
}
}
} else {
mainRigidbody.useGravity = true;
mainRigidbody.isKinematic = false;
mainProjectileSystem.enableOrDisableSecondaryMeshCollider (true);
}
}
}
}
}
}
}
playerComponentsManager mainPlayerComponentsManager = objectToDamage.GetComponent<playerComponentsManager> ();
if (mainPlayerComponentsManager != null) {
projectilesOnCharacterBodyManager mainProjectilesOnCharacterBodyManager = mainPlayerComponentsManager.getProjectilesOnCharacterBodyManager ();
if (mainProjectilesOnCharacterBodyManager != null) {
mainProjectilesOnCharacterBodyManager.addProjectileToCharacterBody (gameObject);
}
} else {
projectilesOnCharacterBodyManager mainProjectilesOnCharacterBodyManager = objectToDamage.GetComponent<projectilesOnCharacterBodyManager> ();
if (mainProjectilesOnCharacterBodyManager != null) {
mainProjectilesOnCharacterBodyManager.addProjectileToCharacterBody (gameObject);
}
}
if (isAttachedToCharacter) {
stopAdjustArrowToSurfaceDetectedCoroutine ();
adjustArrowCoroutine = StartCoroutine (adjustArrowToSurfaceDetectedCoroutine ());
}
mainProjectileSystem.currentProjectileInfo.isSeeker = false;
mainProjectileSystem.currentProjectileInfo.isHommingProjectile = false;
}
public void resetProjectile ()
{
applyArrowForces = true;
stopAdjustArrowToSurfaceDetectedCoroutine ();
transform.SetParent (null);
currentArrowDownForce = 1;
}
public void setNewArrowDownForce (float newValue)
{
currentArrowDownForce = newValue;
}
public void setArrowSurfaceTypeInfoList (List<bowSystem.arrowSurfaceTypeInfo> newArrowSurfaceTypeInfoList)
{
arrowSurfaceTypeInfoList = newArrowSurfaceTypeInfoList;
checkSurfaceTypeDetected = true;
}
public void disableCheckSurfaceTypeDetected ()
{
checkSurfaceTypeDetected = false;
}
void stopAdjustArrowToSurfaceDetectedCoroutine ()
{
if (adjustArrowCoroutine != null) {
StopCoroutine (adjustArrowCoroutine);
}
}
IEnumerator adjustArrowToSurfaceDetectedCoroutine ()
{
bool targetReached = false;
float t = 0;
float positionDifference = 0;
float movementTimer = 0;
Vector3 targetPosition = transform.position + transform.forward * offsetOnCharacterBodyParent;
Transform currentParent = transform.parent;
targetPosition = currentParent.InverseTransformPoint (targetPosition);
while (!targetReached) {
t += Time.deltaTime / adjustToSurfaceSpeed;
transform.localPosition = Vector3.Lerp (transform.localPosition, targetPosition, t);
positionDifference = GKC_Utils.distance (transform.localPosition, targetPosition);
movementTimer += Time.deltaTime;
if (positionDifference < 0.01f || movementTimer > 3) {
targetReached = true;
if (showDebugPrint) {
print ("target reached " + targetPosition);
}
}
yield return null;
}
}
}