/
arti4
/
CourseWork
Обзор
Документация
Войти
/
arti4
/
CourseWork
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Scriptes/Rifleman.cs
496 строк
16 KB
arti4
Загрузить файлы в «Scriptes»
01 июн 2025, 11:57
01 июн 2025, 11:57
3eddd7a
Код
Авторство
О чём код?
using NUnit.Framework.Internal; using UnityEngine; public class Rifleman : MonoBehaviour { public int health; public float speed; public float deathDelay = 2f; public float attackRadius = 5f; public float attackCooldown = 1f; public float patrolDistance = 5f; public int attackDamage = 10; public float attackBoss = 1f; public bool Boss; private Vector2 startPoint; private bool movingRight = true; private Animator animator; private Transform player; private bool isIdle = false; private bool stoppedByBarbwire = false; private bool stoppedByRifleman = false; private Collider2D currentBarbwire; private bool isDead = false; private float fixedYPosition; private bool isDying = false; public Transform weaponTransform; public GameObject bulletPrefab; public float shootCooldown = 1f; public float shootForce = 10f; private float lastShootTime = -Mathf.Infinity; public Transform shotPoint; private PlayerHealth playerHealth; [SerializeField] private GameObject medicine; [SerializeField] private int medicineSpawnChance; [SerializeField] private BoxCollider2D boxCollider; [SerializeField] private AudioSource audioSourceShoot; [SerializeField] private AudioClip shootSound; [SerializeField] private AudioSource audioSourceHit; [SerializeField] private AudioClip hitSound; [SerializeField] private AudioSource audioSourceWalk; [SerializeField] private AudioClip walkSound; [SerializeField] private float basePitch = 0.7f; [SerializeField] private float maxHearingDistance = 15f; private bool anybody; private Rigidbody2D rb; private void Start() { boxCollider = GetComponentInChildren<BoxCollider2D>(); startPoint = transform.position; rb = GetComponent<Rigidbody2D>(); animator = transform.Find("Body")?.GetComponent<Animator>(); GameObject playerObject = GameObject.FindWithTag("Player"); if (playerObject != null) { player = playerObject.transform; playerHealth = playerObject.GetComponentInParent<PlayerHealth>() ?? playerObject.GetComponentInChildren<PlayerHealth>(); } audioSourceWalk.pitch = basePitch; } private void Update() { if (isDying) { transform.position = new Vector3(transform.position.x, fixedYPosition, transform.position.z); return; } if (health > 0) { IsObstacleAhead(); float distanceToPlayer = player != null ? Vector2.Distance(transform.position, player.position) : Mathf.Infinity; if (stoppedByBarbwire && (currentBarbwire == null || !currentBarbwire.gameObject.activeInHierarchy)) { stoppedByBarbwire = false; } //���� ���������� ������������ if (stoppedByBarbwire || stoppedByRifleman) { if (distanceToPlayer > 3 * patrolDistance) { Flip(); movingRight = !movingRight; stoppedByBarbwire = false; stoppedByRifleman = false; } if (distanceToPlayer <= attackRadius) { rb.linearVelocity = Vector2.zero; animator.SetBool("Running", false); audioSourceWalk.Stop(); FlipTowardsPlayer(); RotateWeaponTowardsPlayer(); if (Time.time >= lastShootTime + shootCooldown) { Shoot(); } } if (!anybody) { if (transform.position.x < player.position.x && stoppedByBarbwire) { stoppedByRifleman = false; } if (transform.position.x > player.position.x && !stoppedByBarbwire) { stoppedByRifleman = false; } } } if (stoppedByBarbwire) return; if (stoppedByRifleman) return; if (player != null) { //��� ����� if (Boss) { if (distanceToPlayer <= attackBoss) { animator.SetBool("Running", false); animator.SetBool("Idle", false); animator.SetBool("Attacking", true); FlipTowardsPlayer(); if (Time.time >= lastShootTime + shootCooldown) { audioSourceHit.PlayOneShot(hitSound); BossAttack(); } } else if (distanceToPlayer <= attackRadius && distanceToPlayer > attackBoss) { animator.SetBool("Running", true); animator.SetBool("Attacking", false); animator.SetBool("Idle", false); FlipTowardsPlayer(); RotateWeaponTowardsPlayer(); FollowPlayer(); if (Time.time >= lastShootTime + shootCooldown) { Shoot(); } } else if (distanceToPlayer <= 3 * patrolDistance) { animator.SetBool("Attacking", false); animator.SetBool("Running", true); FollowPlayer(); } else { animator.SetBool("Attacking", false); animator.SetBool("Running", true); Patrol(); } } //��� ������� �������� else if (distanceToPlayer <= attackRadius) { animator.SetBool("Running", false); animator.SetBool("Idle", true); FlipTowardsPlayer(); RotateWeaponTowardsPlayer(); if (Time.time >= lastShootTime + shootCooldown) { Shoot(); } } else if (distanceToPlayer <= 3 * patrolDistance && !stoppedByRifleman) { FollowPlayer(); } else if (distanceToPlayer > 3 * patrolDistance && !stoppedByRifleman) { Patrol(); } } else { Patrol(); } AdjustSoundVolume(); } else { Die(); } } //��������� ������������� � ������� ��������� private void IsObstacleAhead() { Vector2 offset = new Vector2(movingRight ? 0.8f : -0.8f, 0); Vector2 direction = movingRight ? Vector2.right : Vector2.left; / float distance = 1f; Debug.DrawRay((Vector2)transform.position + offset, direction * distance, Color.red); RaycastHit2D hit = Physics2D.Raycast((Vector2)transform.position + offset, direction, distance); if (hit.collider != null) { string hitObjectName = hit.collider.gameObject.name; if (hitObjectName == "Body" && hit.collider.CompareTag("Rifleman")) { anybody = true; stoppedByRifleman = true; rb.linearVelocity = Vector2.zero; animator.SetBool("Running", false); animator.SetBool("Idle", true); audioSourceWalk.Stop(); } else { anybody = false; stoppedByRifleman = false; } } else { anybody = false; stoppedByRifleman = false; } } //��������� ��������� private void AdjustSoundVolume() { if (audioSourceWalk == null || player == null) return; float distance = Vector2.Distance(transform.position, player.position); if (distance > maxHearingDistance) { audioSourceWalk.volume = 0; return; } if (distance <= maxHearingDistance / 2) { audioSourceWalk.volume = 1; return; } float volumeFactor = Mathf.Clamp01(1 - ((distance - (maxHearingDistance / 2)) / (maxHearingDistance / 2))); audioSourceWalk.volume = volumeFactor; } //������� ����� ����� private void BossAttack() { lastShootTime = Time.time; animator.SetBool("Attacking", true); playerHealth.TakeDamage(attackDamage); } //������������� ������ private void FlipTowardsPlayer() { if (player != null) { bool playerIsRight = transform.position.x < player.position.x; if (playerIsRight && !movingRight) Flip(); if (!playerIsRight && movingRight) Flip(); movingRight = playerIsRight; } } //��������� ������ ��� ������� private void OnDrawGizmosSelected() { if (Boss) { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, attackBoss); } Gizmos.color = Color.blue; Gizmos.DrawWireSphere(transform.position, attackRadius); Gizmos.color = Color.green; Gizmos.DrawWireSphere(transform.position, maxHearingDistance); } //������������ � ������� ������ private void RotateWeaponTowardsPlayer() { Vector2 directionToPlayer = player.position - weaponTransform.position; float angle = Mathf.Atan2(directionToPlayer.y, directionToPlayer.x) * Mathf.Rad2Deg; bool playerIsLeft = player.position.x < transform.position.x; bool playerIsBelow = player.position.y < transform.position.y; if (playerIsLeft) { if (!movingRight) { weaponTransform.localScale = new Vector3(-1, -1, 1); } else { Flip(); weaponTransform.localScale = new Vector3(-1, -1, 1); } if (playerIsBelow) { angle = -Mathf.Clamp(Mathf.Abs(angle), 135f, 225f); } else { angle = Mathf.Clamp(Mathf.Abs(angle), 135f, 225f); } } else { if (movingRight) { weaponTransform.localScale = new Vector3(1, 1, 1); } else { Flip(); weaponTransform.localScale = new Vector3(1, 1, 1); } angle = Mathf.Clamp(angle, -45f, 45f); } weaponTransform.rotation = Quaternion.Euler(0, 0, angle); shotPoint.rotation = weaponTransform.rotation; } //�������� private void Shoot() { if (Time.time >= lastShootTime + shootCooldown) { lastShootTime = Time.time; audioSourceShoot.PlayOneShot(shootSound); GameObject bullet = Instantiate(bulletPrefab, shotPoint.position, shotPoint.rotation); Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>(); if (rb != null) { rb.linearVelocity = (player.position - shotPoint.position).normalized * shootForce; } } } //�������������� private void Patrol() { if (animator != null && !isIdle) { animator.SetBool("Running", true); animator.SetBool("Idle", false); } float targetX = movingRight ? startPoint.x + patrolDistance : startPoint.x - patrolDistance; if (movingRight && transform.position.x >= targetX) { Flip(); movingRight = false; } else if (!movingRight && transform.position.x <= targetX) { Flip(); movingRight = true; } Vector2 direction = movingRight ? Vector2.right : Vector2.left; rb.linearVelocity = new Vector2(direction.x * speed, rb.linearVelocity.y); } //�������� �� ������������ �������� private bool IsAnimationPlaying(string animationName) { return animator.GetCurrentAnimatorStateInfo(0).IsName(animationName) && animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1f; } //������� private void Flip() { Vector3 scale = transform.localScale; scale.x *= -1; transform.localScale = scale; } //������ �������� ������ private void Die() { if (isDead) return; isDead = true; audioSourceWalk.Stop(); if (animator != null) { if (!IsAnimationPlaying("Die")) { animator.SetTrigger("Die"); animator.SetBool("Running", false); animator.SetBool("Idle", false); fixedYPosition = transform.position.y + 0.483353f; isDying = true; Collider2D col = GetComponent<Collider2D>(); if (col != null) col.enabled = false; if (Random.Range(0f, 100f) <= medicineSpawnChance) { Instantiate(medicine, transform.position, transform.rotation); } Invoke("OnDeathAnimationEnd", deathDelay); } } } //��������� ����� public void TakeDamage(int damage) { health -= damage; if (health <= 0) { Die(); } } //����������� ������� � ��������� public void OnDeathAnimationEnd() { isDying = false; Destroy(gameObject); } //������������� ������ private void FollowPlayer() { if (animator != null) { animator.SetBool("Running", true); animator.SetBool("Idle", false); } FlipTowardsPlayer(); Vector2 direction = (player.position - transform.position).normalized; rb.linearVelocity = new Vector2(direction.x * speed, rb.linearVelocity.y); } //������������ �� ��������� ��� ������� ���������� private void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Barbwire") || other.CompareTag("Stopper")) { stoppedByBarbwire = true; currentBarbwire = other; float distanceToPlayer = player != null ? Vector2.Distance(transform.position, player.position) : Mathf.Infinity; if (distanceToPlayer <= 3 * patrolDistance) { animator.SetBool("Running", false); animator.SetBool("Idle", true); } else { Flip(); movingRight = !movingRight; stoppedByBarbwire = false; } } } //����� �� ���� �������� ��� ������� ��������� private void OnTriggerExit2D(Collider2D other) { if (other.CompareTag("Barbwire") || other.CompareTag("Stopper")) { if (other == currentBarbwire) { stoppedByBarbwire = false; currentBarbwire = null; Patrol(); } } } }