Unity 입문 팀프로젝트 - 5

이준호·2023년 12월 6일
0

📌 2D 입문 팀프로젝트

➔ 수정된 부분

GuidedMissileBulletPrefabLogic.cs

  • LookOnCheck 메서드와 Start()에서 LookOnSearch메서드 실행 조건으로 Balls 공들이 다 사라진 경우에 GuidedMissileBullet을 발사 했을 때, Balls가 없다면 실행이 되지 않도록 하였다.
  • 처음에는 if (Balls != null)로 하였는데 계속 똑같이 오류가 떠서 뭐가 문제인지 몰랐다. 그런데 보면 LookOnCheck 메서드에서 Balls가 new로 새로운 List를 찍어내는 방식이었다. 그러면 공이 없어도, 0개여도 일단 List는 할당이 되는것이다. List의 크기가 0일 뿐, 그래서 List자체가 없는 null이 아니라 크기가 0인 List여서 Count로 체크를 해야 맞는것 이었다.
public class GuidedMissileBulletPrefabLogic : MonoBehaviour
{
    PlayerItemState _itemManager;
    List<GameObject> Balls;
    GameObject LockOnTarget;
    float nearDis;
    // LockOn Setting
    private void Awake()
    {
        _itemManager = FindObjectOfType<PlayerItemState>();
        LookOnCheck();
    }
    // LockOn Search
    private void Start()
    {
        if(Balls.Count != 0) LookOnSearch();
    }
    // LockOn Target Attack
    private void FixedUpdate()
    {
        LookOnTargetAttack();
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Ball" || collision.tag == "Wall" || collision.tag == "TopWall")
        {
            _itemManager.BulletCoolTimeReset();
            Destroy(gameObject);    // 추후 오브젝트 풀링
        }
    }
    #region Logic
    private void LookOnCheck()
    {
        Balls = new List<GameObject>(GameObject.FindGameObjectsWithTag("Ball"));
        if ( Balls.Count != 0 ) nearDis = Vector3.Distance(gameObject.transform.position, Balls[0].transform.position);
    }
    private void LookOnSearch()
    {
        // Null Value Ready
        LockOnTarget = Balls[0];
        // Search Near Distance Target
        foreach (GameObject index in Balls)
        {
            float distance = Vector3.Distance(gameObject.transform.position, index.transform.position);
            if (distance < nearDis)
            {
                LockOnTarget = index;
            }
        }
    }
    private void LookOnTargetAttack()
    {
        // LookOnTarget Null Check
        if (LockOnTarget != null)
            transform.position = Vector3.MoveTowards(transform.position, LockOnTarget.transform.position, _itemManager._player.Force * Time.deltaTime);
        else
        {
            // LookOnTarget == null ? ReSearch
            // LookOnCheck();
            // LookOnSearch();
            return;
        }
    }
    #endregion
}











BallsFreezingItem

  • BallStopItemLogic에서 너무 많은 작용이 있어서 ( 아이템 떨어지기, 색상변경, 삭제 등 ) 나누었다.
  • BallStopItemLogic에서는 공이 멈추게하는 로직과 5초뒤 사라지는 로직을 넣었다.
  • BallFreezingItem.cs에서 아이템을 먹으면 PlayerItemState클래스의 BallFreezingItem메서드를 실행하게 하였다.
  • BallFreezingItem메서드는 BallStopItemLogic이 달려있는 빈게임 오브젝트를 Instantiate하여 찍어내는것 이다.
  • 급하게 하느라 Update의 낭비와 다른 클래스들과 연관성이 이상해서 다른작업을 끝내고 다시 수정해야 할 것같다.

BallStopItemLogic

public class BallStopItemLogic : MonoBehaviour
{
    List<GameObject> Balls;
    List<GameObject> BallsCheck;

    float times = 5;

    private void Awake()
    {
        FirstCheck();
    }

    private void Start()
    {
        BallStop();
    }

    private void Update()
    {
        BallCountCheck();

        // Time Decrease
        Timer();

        // If Broken the Ball, Check again
        if (BallsCheck.Count != Balls.Count && times > 0)
        {
            BallCountCheck();
            BallStop();
        }

        // Time is zero ? Balls Activity again
        if (times <= 0)
        {
            BallStart();

            Destroy(gameObject);
        }
    }

    #region Logic
    void Timer()
    {
        times -= Time.deltaTime;
    }

    void FirstCheck()
    {
        Balls = new List<GameObject>(GameObject.FindGameObjectsWithTag("Ball"));
        BallsCheck = new List<GameObject>(GameObject.FindGameObjectsWithTag("Ball"));
    }

    void BallCountCheck()
    {
        Balls = new List<GameObject>(GameObject.FindGameObjectsWithTag("Ball"));
    }

    void BallStop()
    {
        foreach (GameObject index in Balls)
        {
            Rigidbody2D rigid = index.GetComponent<Rigidbody2D>();
            rigid.constraints = RigidbodyConstraints2D.FreezePositionX | RigidbodyConstraints2D.FreezePositionY;
        }
    }

    void BallStart()
    {
        int num = 1;
        foreach (GameObject index in Balls)
        {
            Rigidbody2D rigid = index.GetComponent<Rigidbody2D>();
            rigid.constraints = RigidbodyConstraints2D.None;
            rigid.constraints = RigidbodyConstraints2D.FreezeRotation;
            if (num == 1)
            {
                rigid.AddForce(Vector2.left * 200);
                num = 2;
            }
            else
            {
                rigid.AddForce(Vector2.right * 200);
                num = 1;
            }
        }
    }
    #endregion
}
public class BallFreezingItem : MonoBehaviour
{
    PlayerItemState _playerItemState;

    private void Awake()
    {
        _playerItemState = FindObjectOfType<PlayerItemState>();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            _playerItemState.BallFreezingItem();

            Destroy(gameObject);    // 추후 오브젝트 풀링
        }
    }
}
	// 생략
    
	GameObject FreezingItem;
    
     private void Awake()
    {
        _player = FindObjectOfType<PlayerAttackSystem>();
        FreezingItem = Resources.Load<GameObject>("Prefabs/BallFreezingLogic");
    }
    
    public void BallFreezingItem()
    {
        Instantiate(FreezingItem);
    }
    
    //생략






의심가는 버그

  • 아이템을 먹을 때 총을 발사한 상태면 총알의 발사의 텀이 이상해짐 ( 총알이 벽이나 공에 부딪히면 초기화 되긴 함 )

  • BounceBallBullet이 Bounce를 하다 가끔 구석에서 멈추는 현상













➔ 추가된 부분

오브젝트 풀링

로딩화면

  • 버그 수정후 만들어보려고 한다.
profile
No Easy Day

0개의 댓글