실행 이미지

 

using System.Collections;
using UnityEngine;

public class Tank : MonoBehaviour
{
    [SerializeField] GameObject indicator;
    [SerializeField] GameObject explosionPrefab;

    [SerializeField] Sprite tank_mode;
    [SerializeField] Sprite siege_mode;

    public LayerMask enemyLayer;

    [SerializeField] float tank_mode_attack_range = 3f;
    [SerializeField] float siege_mode_attack_range = 5f;
    [SerializeField] float splashRange = 2f;

    public float speed = 5.0f;
    private Vector3 targetPosition;
    private bool isMoving = false;
    private bool isSiege = false;
    private Camera mainCamera;

    private Vector3 currentMousePosition;

    void Start()
    {
        indicator.SetActive(false);
        StartCoroutine(CoMove());
        StartCoroutine(ChangeMode());
        mainCamera = Camera.main;
    }

    void Update()
    {
        // 마우스 위치를 월드 좌표계로 변환하여 저장
        Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        currentMousePosition = mousePosition;

        if (Input.GetKey(KeyCode.A))
        {
            if(Input.GetMouseButtonDown(0) && isSiege)
            {
                StartCoroutine("CoSiegeAttack");

            }
            else if (Input.GetMouseButtonDown(0) && !isSiege)
            {
                StartCoroutine("CoAttack");
            }
        }
    }

    IEnumerator CoMove()
    {
        while (true)
        {
            if (Input.GetMouseButtonDown(1) && !isSiege)
            {
                targetPosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
                targetPosition.z = transform.position.z;

                StopCoroutine(MoveIndicator(targetPosition));
                StartCoroutine(MoveIndicator(targetPosition));

                if (transform.position.x < targetPosition.x) this.gameObject.transform.localScale = new Vector3(1, 1, 1);
                else this.gameObject.transform.localScale = new Vector3(-1, 1, 1);
                isMoving = true;
            }

            if (isMoving && !isSiege)
            {
                transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);

                if (Vector3.Distance(transform.position, targetPosition) < 0.01f)
                {
                    isMoving = false;
                }
            }

            yield return null;
        }
    }

    IEnumerator ChangeMode()
    {
        while (true)
        {
            if (Input.GetKeyDown(KeyCode.O))
            {
                isSiege = !isSiege;
                GetComponent<SpriteRenderer>().sprite = isSiege ? siege_mode : tank_mode;
                isMoving = false;
            }
            yield return null;
        }
    }

    IEnumerator MoveIndicator(Vector3 position)
    {
        indicator.SetActive(true);
        indicator.transform.position = position;
        yield return new WaitForSeconds(0.5f);
        indicator.SetActive(false);
    }

    IEnumerator CoAttack()
    {
        Vector3 mousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
        Collider2D clickedCollider = Physics2D.OverlapPoint(mousePosition, enemyLayer);

        if (clickedCollider != null)
        {
            float distance = Vector2.Distance(transform.position, clickedCollider.transform.position);
            if (!isSiege && distance <= tank_mode_attack_range)
            {
                Instantiate(explosionPrefab, clickedCollider.transform.position, Quaternion.identity);
                Destroy(clickedCollider.gameObject);
                 isMoving = false;
            }
        }

        yield return null;
    }

    IEnumerator CoSiegeAttack()
    {
        // 마우스 위치를 월드 좌표로 변환
        Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        // splashRange 내에 있는 모든 적 탐지
        Collider2D[] enemies = Physics2D.OverlapCircleAll(mousePosition, splashRange, enemyLayer);
        foreach (Collider2D enemy in enemies)
        {
            // 폭발 이펙트 생성 및 적 파괴
            Instantiate(explosionPrefab, enemy.transform.position, Quaternion.identity);
            Destroy(enemy.gameObject);
        }

        yield return null;
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, isSiege ? siege_mode_attack_range : tank_mode_attack_range);

        if (Input.GetKey(KeyCode.A) && isSiege)
        {
            Gizmos.color = Color.yellow;
            Gizmos.DrawWireSphere(currentMousePosition, splashRange);
        }
    }
}

Tank.cs

 

 

Enemy는 Layer를 Enemy로 설정해주자.

반응형

+ Recent posts