1인 개발/나홀로 성 지키기

나홀로 성 지키기 개인 프로젝트 5일차

잼잼재미 2024. 3. 22. 19:51

구현 내용


1. MeleeSkill 구현

 

근접 스킬을 구현

 

 

 

기본 공격과 마찬가지로 새로운 공격 콜라이더를 생성

 

if(collision.CompareTag("Enemy"))
{
    Vector2 _dir = collision.transform.position - _playerController.transform.position;
    collision.transform.GetComponent<EnemyController>().Ishit = true;

    if(transform.CompareTag("AttackCollider"))
    {
        collision.transform.GetComponent<EnemyController>().Hp -= _playerController.PlayerData.Atk;
        if (_dir.x > 0)
        {
            collision.GetComponent<EnemyController>().Rigdbody.AddForce(new Vector2(1, 1) * _playerController.PlayerData.NuckbackPower, ForceMode2D.Impulse);
        }
        else
        {
            collision.GetComponent<EnemyController>().Rigdbody.AddForce(new Vector2(-1, 1) * _playerController.PlayerData.NuckbackPower, ForceMode2D.Impulse);
        }
    }
    else if(transform.CompareTag("StrikeCollider"))
    {
        collision.transform.GetComponent<EnemyController>().Hp -= _skillData.Atk;
        if (_dir.x > 0)
        {
            collision.GetComponent<EnemyController>().Rigdbody.AddForce(new Vector2(1, 1) * _skillData.NuckbackPower, ForceMode2D.Impulse);
        }
        else
        {
            collision.GetComponent<EnemyController>().Rigdbody.AddForce(new Vector2(-1, 1) * _skillData.NuckbackPower, ForceMode2D.Impulse);
        }
    }
}

 

IEnumerator COSkillStart()
{
    yield return new WaitForSeconds(1f);
    gameObject.SetActive(false);
}

 

오브젝트풀 사용으로 Destroy 대신 SetActive(false) 해줌

 

 

2. RangedSkill 구현

 

원거리 스킬 구현

 

private void Targetting()
{
    int layerMask = (1 << _layerMask);  // Layer 설정
    _targets = Physics2D.OverlapCircleAll(transform.position - new Vector3(0, 2, 0), _skillSO.ExplosionRange, layerMask);

    for (int i = 0; i < _targets.Length; i++)
    {
        _dir = _targets[i].gameObject.transform.position - transform.position;
        _targets[i].gameObject.GetComponent<EnemyController>().Ishit = true;
        _targets[i].gameObject.GetComponent<EnemyController>().Hp -= _skillData.Atk;
        if (_dir.x > 0)
        {
            _targets[i].gameObject.GetComponent<EnemyController>().Rigdbody.AddForce(new Vector2(1, 1) * _skillData.NuckbackPower, ForceMode2D.Impulse);
        }
        else
        {
            _targets[i].gameObject.GetComponent<EnemyController>().Rigdbody.AddForce(new Vector2(-1, 1) * _skillData.NuckbackPower, ForceMode2D.Impulse);
        }
    }
}

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.CompareTag("Enemy"))
    { 
    	StartCoroutine(COInactiveSkill(_inactiveTime));
        _isMove = false;
        _animator.SetTrigger("Hit");
        Targetting();
    }
}

IEnumerator COInactiveSkill(float time)
{
    yield return new WaitForSeconds(time);
    gameObject.SetActive(false);
}

 

Physics2D.OverlapCircleAll로 주위 범위의 콜라이더를 감지, 데미지 적용 했다. 오브젝트풀 사용으로 Destroy 대신 SetActive(false) 해줌

 

 

https://kkln2486.tistory.com/248

 

범위 내 콜라이더 판별 (OverlapSphere)

OverlapSphere (3D) 3D 공간에서 구 형태의 영역 안의 모든 콜라이더를 검출 Layer 설정으로 원하는 Layer만 검출 가능 (설정하지 않으면 모든 콜라이더 검출) 중심 위치와 반지름으로 구 생성 Collider 배열

kkln2486.tistory.com

 

 

3. AreaSkill 구현

 

범위 스킬 구현. RangedSkill과 같은 방식으로 구현

 

 

IEnumerator COShootAreaSkill(SkillData areaSkillData)
{
    int count = 0;
    while (true)
    {
        count++;
        GameManager.I.ObjectPoolManager.ActivePrefab(areaSkillData.Tag, transform.position);

        if (count == areaSkillData.Count) break;
        yield return new WaitForSeconds(areaSkillData.Interval);
    }
}

 

Interval 초 간격으로 Count 수 만큼 반복해서 오브젝트풀로 SetActive(true)

 

 

private void Start()
{
    float random = Random.Range(_player.transform.position.x - 10f, _player.transform.position.x + 10f);
    _startPos = new Vector3(random, 10f, 0);
    transform.position = _startPos;
}

private void Update()
{
    transform.position += new Vector3(0, -_skillSO.Speed, 0) * Time.deltaTime;
}

 

오브젝트풀로 스킬을 SetActive(true)하면, 주위 범위 내, 랜덤으로 생성하고 아래로 이동하도록 구현

 

 

트러블 슈팅


1. ObjectPool을 이용한 Skill 초당 프레임 개선


Instantiate / Destroy 구현
ObjectPool 구현

 

기존에는 Skill 프리팹의 Instantiate/Destroy 로 Skill을 구현했다. 하지만 이번 프로젝트부터 최적화에 신경쓰기 위해, 이미 구현했던, ObjectPool을 이용해서 구현하기로 했다. 사진과 같이 초당 프레임을 약 175 FPS -> 약 190 FPS 개선할 수 있었다. 현재 사진에서는 Skill의 ObjectPool 적용에 대한 초당 프레임만을 테스트 한 것이기 때문에 큰 차이를 확인할 수 없었지만, Enemy Spawn, Item, Skill 등 모두 ObjectPool을 적용하면 확실한 차이를 확인할 수 있을 것이다!

 

 

회고


3가지 종류의 스킬을 구현하는 것이 생각보다 많이 어려웠다. 원래는 다양한 종류의 스킬 (대쉬, 회복 등등) 만들어서 1단계, 2단계, 3단계 스킬로 구분하려고 했으나, 그렇게 하게 되면 각각 스킬에 맞는 애니메이션을 모두 만들어야하고 스킬 특성에 맞게 구현을 여러가지로 해야했다. 이 부분에서 아직 복잡한 게임을 만드는 것이 정말 대단하다라는 것을 다시 한번 느낄 수 있었다.. 결국, 3가지 종류의 스킬을 각각 1단계는 근접 스킬, 2단계는 원거리 스킬, 3단계는 광역 스킬로 구분을 하고, 각각 종류는 같은 특성을 가진 스킬로 구현을 했다. 오늘은 각각 한가지 씩 구현했지만 여기서 스킬 종류를 더 추가하고 각각 밸런스 조절을 하게 되면 꽤 그럴싸한 게임이 나올 것 같다!