기능 구현 방법 정리

~초 동안 무적 및 깜빡거림으로 무적 상태 알림

ybbro 2024. 9. 13. 18:41

게임을 하다 보면 연속으로 공격을 맞는 불합리한 판정을 없애기 위해 피격 대미지 계산 후 일정 시간 동안 무적을 두고는 합니다.

 

주로 무적 시간 동안 깜빡이는 효과로 플레이어들에게 무적 상태임을 알려주고는 했습니다.

 

따라서 이를 구현해 보았습니다.

 

1. 무적은 코루틴으로 처리해주기로 했기에 필요한 아래 네임스페이스가 필요합니다.

    using System.Collections;

 

2. 글로벌 bool 변수를 하나 선언해 줍니다

     bool isInvincilbe = false;

 

3. 무적 상태 진입/해제 및 효과를 아래 메서드 하나로 만들어 줍니다. 

    // 매개변수(초) 동안 무적 상태 처리
    IEnumerator Invincible(float second)
    {
        // 무적 상태 진입
        isInvincible = true;

        // 깜빡깜빡 무적 상태 표시
        
        // 반투명하게 해주기 위해서는 색상의 알파 값을 조정해줘야 하는데
        // 스프라이트/메터리얼 색상 알파값에 직접 접근하여 바꿀 수 없음
        
        // 하지만! 항상 방법은 있는 법
        // 색상 변수를 하나 만들어서 알파 값을 변경
        // > 반투명하게 된 색상 값을 집어넣어 변경

        // 현재 반투명도를 나타낼 색상
        Color tempColor = Color.white;
        // 코루틴 시작(무적 시작) 후 얼마나 진행되었나 세어줄 카운터
        float loopCount = 0f;
        
        // 알파값(투명도) 변화량
        float alphaChange = 0.1f;

        // 무적 시간 내내 반복
        while (isInvincible)
        {
            // 루프 1번당 = 0.02초
            // 20번 반복하면 1번 깜빡임 = 0.4초

            // 좀 더 천천히 깜빡이게 하고 싶으면
            // 알파값 변화량을 줄이고, 루프 횟수를 늘리면 됨
            for (int j = 0; j < 20; j++)
            {
            	// 투명도 변화
                if (j < 10)
                    tempColor.a -= alphaChange;
                else
                    tempColor.a += alphaChange;
                Leon_mat1.color = Leon_mat2.color = tempColor;
                
                // 0.02초 대기
                yield return new WaitForFixedUpdate();
                loopCount += 0.02f;
                
                // 설정한 무적 시간이 지났다면
                if(loopCount >= second)
                {
                    // while 루프를 벗어날 수 있도록 설정 및 무적 시간 종료 
                    isInvincible = false;
                    // for루프 즉시 벗어나게끔
                    break;
                }
            }
        }
        // 마지막에는 원래 색상으로 복구
        Leon_mat1.color = Leon_mat2.color = Color.white;
    }

 

4. 무적 상태로 진입할 상황에서 사용해주기

예시로 제가 만들고 있던 코드 일부를 가져왔습니다.

            // 창병 > 체력 -2
            case "Spearman":
                // 무적 상태에서는 처리하지 않음
                if (isInvincible)
                    break;
                // 돌격 스킬 사용 가능한 상태에서는 스킬만 발동하고 맞지 않음
                if (GameManager.instance.GetChargeReady)
                {
                    StartCoroutine(Invincible(1.5f));
                    GameManager.instance.player_Exp.AddExp(1);
                }
                // 예외 상황이 아니라면 대미지
                else
                    HpChange_Current(-2);
                GameManager.instance.InitSpeed();
                other.gameObject.SetActive(false);
                soldier_hit.SummonHit(soldier_hit.Spearmans);
                break;

 

<< 결과 >> 

처음 충돌한 창병은 스킬 발동 후 무적 상태로 진입

뒤의 창병은 무적 중 상호작용 없이 통과