카테고리 없음

5-21 TIL - 투사체 생성 관련 연구

bugmin 2024. 5. 21. 23:56

오늘은 아래의 코드에 대한 분석을 적을 것이다.

 

아래의 코드는 투사체 생성을 주관하는 코드이다. 

 private void OnShoot(AttackSO attackSO)
    {
        RangedAttackSO rangedAttackSO = attackSO as RangedAttackSO;
        if((rangedAttackSO == null)) return; 

        float projectileAngleSpace = rangedAttackSO.multipleProjectilesAngle;
        int numberOfProjectilesPerShot = rangedAttackSO.numberOfProjectilesPerShot;

        float minAngle  = -(numberOfProjectilesPerShot / 2f) * projectileAngleSpace + 0.5f * rangedAttackSO.multipleProjectilesAngle;

        for(int i = 0; i < numberOfProjectilesPerShot; i++)
        {
            float angle = minAngle + i * projectileAngleSpace;
            float randomSpread = Random.Range(-rangedAttackSO.spread, rangedAttackSO.spread);
            angle += randomSpread;
            CreateProjectile(rangedAttackSO, angle);
        }
    }

 

그리 긴 코드가 아님에도 꽤나 이해에 오랜 시간이 걸렸는데 하나하나씩 뜯어보고자 한다.

RangedAttackSO rangedAttackSO = attackSO as RangedAttackSO;
if((rangedAttackSO == null)) return;

 

먼저 해당 이 부분이다.

이부분의 경우엔 

 

RangedAttakSO는 원거리 공격에 대한 정보를 저장하는 스크립터블 오브젝트(SO)로 AttackSO 클래스를 상속받는다.

 

투사체 관련 코드이기에 근거리 공격은 해당 메서드를 수행할 이유가 없다.

 

고로 먼저 'as' 라는 연산자를 통해 AttackSO 변수를 RangedAttackSO로 형변환을 한다.

as 연산자의 경우엔 형변환이 불가능한 경우엔 null을 뿜어내게 된다.

 

그렇기에 만일 RangedAttackSO가 아니라면 형변환이 불가하기에 null을 뿜어내어 rangedAttackSO는 null 값이 되어 

if문에 의해 return이 될 것이다.

 

즉 원거리 공격에 대해서만 해당 메서드를 수행하기 위해 as 연산자를 이용한 코드로 이해하면 된다.

float projectileAngleSpace = rangedAttackSO.multipleProjectilesAngle;
int numberOfProjectilesPerShot = rangedAttackSO.numberOfProjectilesPerShot;

 

애쉬 w 를 생각해보면 (롤을 모른다면 검색..) 화살 사이에 일정한 간격이 있다.

그러한 투사체 간격이 projectileAngleSpace이다. rangedAttackSO 변수에서 정보를 가져오는 모습이다.

 

numberOfProjectilesPerShot은 한 번 쏠 때 몇 발을 쏘는가에 대한 정보를 담고 있다.

 

그리고 내 발목을 잡았던 아래 코드가 있다..

float minAngle  = -(numberOfProjectilesPerShot / 2f) * projectileAngleSpace + 0.5f * rangedAttackSO.multipleProjectilesAngle;

 

빨간색 화살부터 쏘려면 발사되는 각도를 알아야 한다.

 

빨간색 화살과 x축과 간의 사이각이 30도지만 각도상으론 음수여야 하기에 -30도가 된다.

 

즉 minAngle은 -30도가 된다.

 

그러면 -30도를 계산을 통해 이끌어내야 한다는 말이다. 

 

어떻게 이끌어낼 수 있을까

float projectileAngleSpace = rangedAttackSO.multipleProjectilesAngle;

 

사이각은 30도이기에 해당코드를 통해 projectileAngleSpace 값은 30도가 되고

 

그러면 그냥 -projectileAngleSpace 로 하면 될 거 같다.. 허나 만일 4발을 쏜다하자

 

만일 원점에서 화살 4발을 쏠 때 x축 기준으로 대칭이 되도록 쏘고 싶고

빨간색 화살부터 쏘겠다는 것이다.

 

빨간색 화살부터 쏘려면 발사되는 각도를 알아야 한다.

 

그림을 보면 알겠지만 -60도가 된다.

 

그렇다면 -60도는 어떤식으로 이끌어 내느냐

 

화살이 4개면 사이각은 3개가 발생하게 된다.

고로 (화살 개수 - 1) * 사이각 / 2 에 - 만 달아주면 되지 않을까?

float minAngle = -(numberOfProjectilesPerShot - 1) * projectileAngleSpace / 2;

 

이런식으로 말이다.

 

뭔가 가능할거 같다.. 일단은 해당 방법은 차후에 문제 없는 지 튜터님께 여쭈어 보고자 한다.