maus234

archerShooting

Apr 14th, 2024
2,566
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.00 KB | Gaming | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using TMPro;
  4. using UnityEngine;
  5.  
  6. namespace Archer
  7. {
  8.     public class archerShooting : MonoBehaviour
  9.     {
  10.         public GameObject arrowPrefab; // Assign your arrow prefab in the inspector
  11.         public Transform firePoint; // Assign the position from which arrows are fired
  12.         public float launchForce = 20f; // Adjustable force to apply for arrow shooting
  13.         public float launchAngle = 45f; // Angle at which the arrow is launched  
  14.         public DetectionZone detectionZone;
  15.         private bool isMovingRight = true;
  16.         private float fireDelay = 1f;
  17.         public float shootCooldownSeconds; // Time in seconds between shots
  18.         private float lastShotTime = 0f; // When the last shot was fired
  19.         public float deviationAngle = 5f;
  20.         private Animator animator;
  21.         ArcherController archerController;
  22.  
  23.  
  24.         private void Start()
  25.         {
  26.             animator = GetComponent<Animator>();
  27.             lastShotTime = Time.time; // Initialize lastShotTime with the current time
  28.         }
  29.  
  30.         private void Awake()
  31.         {
  32.             archerController = GetComponent<ArcherController>();
  33.         }
  34.  
  35.         private void AdjustFacingDirection(bool shouldFaceRight)
  36.         {
  37.             // Set isMovingRight based on the parameter
  38.             isMovingRight = shouldFaceRight;
  39.  
  40.             // Adjust the facing direction of the NPC based on isMovingRight
  41.             Vector3 localScale = transform.localScale;
  42.             localScale.x = isMovingRight ? Mathf.Abs(localScale.x) : -Mathf.Abs(localScale.x);
  43.             transform.localScale = localScale;
  44.         }
  45.         public void CheckDetectionZone()
  46.         {
  47.             List<Transform> enemies = new List<Transform>();
  48.  
  49.             foreach (Collider2D collider in detectionZone.detectedColliders)
  50.             {
  51.                 if (collider.CompareTag("Animal"))
  52.                 {
  53.                     Transform targetEnemy = enemies[Random.Range(0, enemies.Count)];
  54.                     bool shouldFaceRight = targetEnemy.position.x > transform.position.x;
  55.                     AdjustFacingDirection(shouldFaceRight);
  56.                     ShootArrowDirectly(targetEnemy.position);
  57.                     lastShotTime = Time.time;
  58.                 }
  59.                 else if (collider.CompareTag("Enemy"))
  60.                 {
  61.                     archerController.PauseMovement();
  62.                     enemies.Add(collider.transform);
  63.                 }
  64.  
  65.             }
  66.             // Check if there are any enemies detected
  67.             if (enemies.Count > 0 && Time.time >= lastShotTime + shootCooldownSeconds)
  68.             {
  69.                 Transform targetEnemy = enemies[Random.Range(0, enemies.Count)];
  70.                 bool shouldFaceRight = targetEnemy.position.x > transform.position.x;
  71.                 AdjustFacingDirection(shouldFaceRight);
  72.  
  73.                 // Define a LayerMask for the Wall layer (adjust the layer number as needed)
  74.                 LayerMask wallLayer = LayerMask.GetMask("Wall");
  75.  
  76.                 // Adjust the Raycast to use the LayerMask
  77.                 RaycastHit2D hit = Physics2D.Raycast(firePoint.position, (targetEnemy.position - firePoint.position).normalized, Mathf.Infinity, wallLayer);
  78.                 Debug.DrawLine(firePoint.position, targetEnemy.position, Color.red, 5f);
  79.  
  80.  
  81.                 if (hit.collider != null && hit.collider.CompareTag("Wall"))
  82.                 {
  83.  
  84.                     // If there's a wall, shoot over it
  85.                     animator.SetBool("isMove", false);
  86.                     animator.SetBool("isRun", false);
  87.                     float angleOfLaunch = 72f; // Adjust as necessary for your game
  88.                     ShootArrowAtTarget(targetEnemy.position, angleOfLaunch);
  89.                     lastShotTime = Time.time;
  90.                 }
  91.                 else
  92.                 {
  93.                     // No wall detected, proceed with direct shot
  94.                     ShootArrowDirectly(targetEnemy.position);
  95.                     lastShotTime = Time.time;
  96.                 }
  97.             }
  98.         }
  99.  
  100.         private void ShootArrowDirectly(Vector3 targetPosition)
  101.         {
  102.             GameObject arrow = Instantiate(arrowPrefab, firePoint.position, Quaternion.identity);
  103.             Rigidbody2D rb = arrow.GetComponent<Rigidbody2D>();
  104.             if (rb != null)
  105.             {
  106.                 Vector2 shootingDirection = (targetPosition - firePoint.position).normalized;
  107.  
  108.                 // Randomize the shooting direction slightly for inaccuracy
  109.                 float deviation = UnityEngine.Random.Range(-deviationAngle, deviationAngle); // Define 'deviationAngle' as the max deviation you want in degrees
  110.                 shootingDirection = Quaternion.Euler(0, 0, deviation) * shootingDirection;
  111.  
  112.                 rb.velocity = shootingDirection * launchForce;
  113.                 float angleDegrees = Mathf.Atan2(shootingDirection.y, shootingDirection.x) * Mathf.Rad2Deg;
  114.                 arrow.transform.rotation = Quaternion.AngleAxis(angleDegrees, Vector3.forward);
  115.  
  116.                 // After shooting, resume movement if you have such logic
  117.                 archerController.ResumeMovement();
  118.             }
  119.         }
  120.  
  121.  
  122.  
  123.         private void ShootArrowAtTarget(Vector3 targetPosition, float angleOflaunch)
  124.         {
  125.             if (arrowPrefab && firePoint)
  126.             {
  127.  
  128.                 animator.SetBool("isFire", true);
  129.                 archerController.PauseMovement();
  130.                 StartCoroutine(FireArrowAfterDelay(targetPosition, angleOflaunch, fireDelay));
  131.  
  132.             }
  133.         }
  134.         IEnumerator FireArrowAfterDelay(Vector3 targetPosition, float angleOfLaunch, float delay)
  135.         {
  136.             yield return new WaitForSeconds(delay);
  137.  
  138.             // Here, the arrow is about to be fired...
  139.             Vector3 startPosition = firePoint.position;
  140.             float gravity = Physics2D.gravity.magnitude;
  141.             float angleVariation = Random.Range(-10f, 10f);
  142.             float angle = angleOfLaunch + angleVariation; // Adjusted angle with randomness
  143.             float randomFactor = Random.Range(0.9f, 1.1f);
  144.             Vector2 velocity = CalculateVelocity(targetPosition, startPosition, gravity * randomFactor, angle); // Apply randomness in gravity effect
  145.             GameObject arrow = Instantiate(arrowPrefab, startPosition, Quaternion.identity);
  146.             Rigidbody2D rb = arrow.GetComponent<Rigidbody2D>();
  147.             if (rb != null)
  148.             {
  149.                 rb.velocity = velocity;
  150.                 float angleDegrees = Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg;
  151.                 arrow.transform.rotation = Quaternion.AngleAxis(angleDegrees, Vector3.forward);
  152.             }
  153.  
  154.             // Arrow has been fired; now adjust the shoot cooldown for the next shot.
  155.             lastShotTime = Time.time;
  156.             shootCooldownSeconds = Random.Range(1f, 2.5f); // Set new random cooldown between 1 and 2.5 seconds
  157.             archerController.ResumeMovement();
  158.             animator.SetBool("isFire", false);
  159.         }
  160.  
  161.         private Vector2 CalculateVelocity(Vector3 target, Vector3 source, float gravity, float angle)
  162.         {
  163.             // Distance between target and source
  164.             float distance = Vector2.Distance(target, source);
  165.  
  166.             // Convert angle to radians
  167.             float angleRad = angle * Mathf.Deg2Rad;
  168.  
  169.             // Calculate velocity
  170.             float velocity = Mathf.Sqrt(distance * gravity / Mathf.Sin(2 * angleRad));
  171.  
  172.             // Get velocity components in 2D
  173.             float velocityX = velocity * Mathf.Cos(angleRad);
  174.             float velocityY = velocity * Mathf.Sin(angleRad);
  175.  
  176.             // Adjust direction based on target and source positions
  177.             Vector2 direction = (target - source).normalized;
  178.             float sign = (target.x > source.x) ? 1f : -1f;
  179.  
  180.             // Return velocity vector
  181.             return new Vector2(velocityX * sign, velocityY) * direction.magnitude;
  182.         }
  183.     }
  184. }
Advertisement
Add Comment
Please, Sign In to add comment