using UnityEngine; using System.Collections; public class PirateShip : MonoBehaviour { [Header("随机移动设置")] public float moveSpeed = 0.8f; public float minMoveTime = 1f; public float maxMoveTime = 3f; public Vector2 areaCenter; public float areaRadius = 5f; [Header("转向设置")] public float rotateSpeed = 90f; [Header("攻击设置")] public float attackRange = 5f; public float warningTime = 0.8f; public float fireInterval = 3f; public float bulletSpeed = 4f; public GameObject bulletPrefab; private Rigidbody2D rb; private Transform player; private bool isAttacking = false; private bool isPaused = false; private LineRenderer warningLine; private Vector2 currentDirection; private Quaternion targetRotation; void Start() { rb = GetComponent(); areaCenter = transform.position; currentDirection = transform.right; GameObject boat = GameObject.FindWithTag("Boat"); if (boat != null) player = boat.transform; // 创建预警线 warningLine = gameObject.AddComponent(); warningLine.startWidth = 0.1f; warningLine.endWidth = 0.1f; warningLine.material = new Material( Shader.Find("Sprites/Default") ); warningLine.startColor = new Color(1, 0, 0, 1); warningLine.endColor = new Color(1, 0, 0, 1); warningLine.sortingLayerName = "Default"; warningLine.sortingOrder = 99; warningLine.positionCount = 2; warningLine.useWorldSpace = true; warningLine.enabled = false; StartCoroutine(RandomMove()); StartCoroutine(AttackLoop()); } public void SetPaused(bool paused) { isPaused = paused; if (isPaused) { rb.velocity = Vector2.zero; warningLine.enabled = false; } } void Update() { if (isPaused) return; SmoothRotate(); } void SmoothRotate() { if (rb.velocity.magnitude > 0.1f) { float angle = Mathf.Atan2( rb.velocity.y, rb.velocity.x ) * Mathf.Rad2Deg; targetRotation = Quaternion.Euler( 0, 0, angle ); } transform.rotation = Quaternion.RotateTowards( transform.rotation, targetRotation, rotateSpeed * Time.deltaTime ); } IEnumerator RandomMove() { while (true) { if (isPaused) { rb.velocity = Vector2.zero; yield return null; continue; } if (!isAttacking) { Vector2 randomPoint = GetRandomPoint(); Vector2 dir = (randomPoint - (Vector2)transform.position) .normalized; float moveTime = Random.Range( minMoveTime, maxMoveTime ); float elapsed = 0f; while (elapsed < moveTime) { if (isPaused) { rb.velocity = Vector2.zero; yield return null; continue; } if (!isAttacking) { float distToCenter = Vector2.Distance( transform.position, areaCenter ); if (distToCenter > areaRadius) { dir = (areaCenter - (Vector2)transform .position).normalized; } currentDirection = Vector2.Lerp( currentDirection, dir, Time.deltaTime * 2f ).normalized; rb.velocity = currentDirection * moveSpeed; } elapsed += Time.deltaTime; yield return null; } rb.velocity = Vector2.zero; yield return new WaitForSeconds( Random.Range(0.3f, 1f) ); } else { yield return null; } } } IEnumerator AttackLoop() { while (true) { yield return new WaitForSeconds( fireInterval ); if (isPaused) continue; if (player == null) continue; float distToPlayer = Vector2.Distance( transform.position, player.position ); Debug.Log("距离玩家:" + distToPlayer + " 攻击范围:" + attackRange); if (distToPlayer < attackRange) { Debug.Log("✅ 进入攻击范围!"); yield return StartCoroutine( FireAtPlayer() ); } } } IEnumerator FireAtPlayer() { isAttacking = true; rb.velocity = Vector2.zero; float aimTime = 0f; while (aimTime < warningTime) { if (isPaused) { warningLine.enabled = false; yield return null; continue; } // 转向玩家 Vector2 dirToPlayer = (player.position - transform.position).normalized; float angle = Mathf.Atan2( dirToPlayer.y, dirToPlayer.x ) * Mathf.Rad2Deg; targetRotation = Quaternion.Euler( 0, 0, angle ); // 预警线闪烁 bool show = Mathf.Sin(aimTime * 20f) > 0; warningLine.enabled = show; if (show) { warningLine.SetPosition( 0, transform.position ); warningLine.SetPosition( 1, player.position ); } Debug.Log("红线状态:" + warningLine.enabled); aimTime += Time.deltaTime; yield return null; } // 关闭预警线 warningLine.enabled = false; // 发射炮弹 if (!isPaused && bulletPrefab != null) { Vector2 fireDir = (player.position - transform.position).normalized; GameObject bullet = Instantiate( bulletPrefab, transform.position, Quaternion.identity ); Rigidbody2D bulletRb = bullet.GetComponent(); if (bulletRb != null) bulletRb.velocity = fireDir * bulletSpeed; Destroy(bullet, 5f); Debug.Log("✅ 炮弹发射!"); } isAttacking = false; } Vector2 GetRandomPoint() { Vector2 randomDir = Random.insideUnitCircle.normalized; float randomDist = Random.Range( 1f, areaRadius * 0.8f ); return areaCenter + randomDir * randomDist; } void OnDrawGizmosSelected() { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere( Application.isPlaying ? (Vector3)areaCenter : transform.position, areaRadius ); Gizmos.color = Color.red; Gizmos.DrawWireSphere( transform.position, attackRange ); } }