• 티스토리 홈
  • 프로필사진
    SiJun-Park
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
SiJun-Park
  • 프로필사진
    SiJun-Park
    • 분류 전체보기 (121)
      • Unity (80)
        • RPG Project (39)
        • FPS Project (30)
        • 기타 - 개발 (11)
      • 개발 (35)
        • 임베디드 소프트웨어 (7)
        • 컴파일러 (6)
        • 기계학습 (8)
        • 보안 (8)
        • 그래픽스 (2)
        • 그 외 (4)
      • 코딩문제 (5)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • RPG Project - 9 [ EXP Ball 생성 및 BezierCurve 활용 ]
        2024년 10월 19일
        • SiJun-Park
        • 작성자
        • 2024.10.19.:56

        이번에 구현을 할 것은 몬스터가 죽었을 시 경험치를 주는 시스템 입니다.

         

        하지만 조금 색다르게 하기 위해서 베지어 곡선 공식을 사용 할 예정입니다.

         

        https://sijun1191.tistory.com/93

         

        베지어 곡선(Bezier Curve)을 활용한 미사일 발사

        베지어 곡선은 조절점 P0 ~ Pn (n은 차수)까지의 집합으로 이루어져 있는데, 이 조절점을 이용해 만드는 곡선입니다. 리그오브레전드의 카이사 Q, 롤토체스의 하이머딩거 미사일 등 랜덤으로 미사

        sijun1191.tistory.com

        베지어 곡선은 위 게시물에 정리를 해두었습니다.

         

        EXP BALL

        경험치 공을 가장 먼저 만들었습니다. 

         

        이제 이 공이 설정한 베지어 곡선 공식에 맞추어서 휘어지게 됩니다.

         

            Vector3[] _pos = new Vector3[4];
        
            GameObject _player;
            [Header("꺾이는 양")]
            public float _Start = 5.0f;
            public float _End = 2.0f;
            [Header("속도")]
            public float _Speed = 1.0f;
            [Header("EXP")]
            public float _exp = 0f;
            private float _CurrentTime;
            private float _MaxTime = 1.3f;
            private float y;
            private float z;
            private float x;
        
        
        
            public void Set_EXP_Ball(Transform StartPos, float value) { 
                _player = GameObject.FindGameObjectWithTag("Player");
                _exp = value;
                x = Random.Range(-2.0f, 3.0f);
                y = Random.Range(0f, 2.0f);
                z = Random.Range(0.8f, 1.2f);
        
                _pos[0] = StartPos.position; 
                _pos[1] = StartPos.position + (_Start * x * StartPos.right) + (_Start *y * StartPos.up) + (_Start * z * StartPos.forward);
                _pos[2] = _player.transform.position + (_End * x * _player.transform.right) + (_End * y * _player.transform.up) + (_End * z * _player.transform.forward);
                _pos[3] = _player.transform.position;
            }

         

        가장먼저 Set_EXP_Ball 함수는 몬스터가 죽었을 시 호출하게 될 함수입니다.

        호출을 하게 된다면 경험치를 설정을 해주고, 역동적이게 보이기 위해서 x, y, z의 값을 랜덤으로 해줍니다.

         

        그렇게 하고 가장 먼저 시작 위치를 잡아줍니다.

        그 다음 시작위치에서 꺾일 지점을 지정해주고 도착 위치에서 꺾일 위치를 지정해준 뒤

        마지막으로 도착 위치를 지정 해줍니다.

         

         

            void Update()
            {
                if (_CurrentTime > _MaxTime) return;
                if (_exp == 0) return;
                _CurrentTime += _Speed * Time.deltaTime;
        
                // 지속적으로 플레이어 추적
                _pos[2] = _player.transform.position + (_End * x * _player.transform.right) + (_End * y * _player.transform.up) + (_End * z * _player.transform.forward);
                _pos[3] = _player.transform.position;
        
        
                transform.position = new Vector3(BezierCurve(_pos[0].x, _pos[1].x, _pos[2].x, _pos[3].x), BezierCurve(_pos[0].y, _pos[1].y, _pos[2].y, _pos[3].y), BezierCurve(_pos[0].z, _pos[1].z, _pos[2].z, _pos[3].z));
        
            }

        Update에선 해당 공이 지속적으로 유저를 추적하면 좋겠다 싶어서 작성을 하였습니다.

         

        그래서 지속적으로 플레이어 위치를 찾아주고 해당 플레이어 위치에서 도착 꺾이는 위치, 도착 위치를 지속적으로 업데이트 해주어 

         

        공이 이동이 되게 해줍니다.

         

            float BezierCurve(float p0, float p1, float p2, float p3)
            {
                // 베지어 곡선의 공식 B(t)  =  (1 - t)^3 P0 + 3(1-t)^2tP1 + 3(1-t)t^2 P2 + t^3P3
                //                                  시작위치, 시작꺾이는 위치, 도착 꺽이는 위치, 도착위치
        
                float t = _CurrentTime / _MaxTime;
                return (Mathf.Pow(1 - t, 3) * p0) + (3 * Mathf.Pow(1 - t, 2) * t * p1) + (3 * (1 - t) * Mathf.Pow(t, 2) * p2) + (Mathf.Pow(t, 3) * p3);
            }

        베지어 곡선 공식에 맞도록 넣어줍니다.

         

            void OnTriggerEnter(Collider other)
            {
                if (other.CompareTag("Player"))
                {
                    UserControl._instance._EXP += _exp;
                    ExpControl._instance.GetExp(_exp);
                    Destroy(gameObject);
                }
            }

        이제 유저와 충돌을 하게 된다면 유저에게 EXP를 추가 해줍니다.

        그리고 Exp Ball은 삭제 시켜 줍니다.

         

         

            public void Hitted(float damage)
            {
                if (_isDead) return;
        
                GameObject T = Instantiate(_Text);
                T.transform.position = _HitTextPos.transform.position;
                T.GetComponent<TextControl>()._color =  Color.yellow;
                T.GetComponent<TextControl>()._Size = 5;
                T.GetComponent<TextControl>()._Text = damage.ToString();
        
        
                if (!_HpBar.gameObject.activeSelf)
                {
                    _HpBar.SetActive(true);
                }
                _SeeHpTime = 7.0f;
                if (HP <= damage)
                {
                    _isDead = true;
                    _HpBar.GetComponent<Slider>().value = 0;
                    _HPScript.ChangeHpText("0");
                    _Action.SetTrigger("Death");
                    SoundManager._instance.PrivatePlaySound(_diesound, transform,0.5f);
        
                    while(_exp > 10)
                    {
                        GameObject _ball = Instantiate(_ExpBall);
                        _ball.GetComponent<ExpBallControl>().Set_EXP_Ball(transform, 10);
                        _exp -= 10;
                    }
                    if(_exp > 0)
                    {
                        GameObject _ball = Instantiate(_ExpBall);
                        _ball.GetComponent<ExpBallControl>().Set_EXP_Ball(transform, _exp);
                    }
        
                }
                else
                {
                    HP -= damage;
                    _HPScript.ChangeHpText(HP.ToString());
                    _HpBar.GetComponent<Slider>().value = HP;
                }
            }

        몬스터가 데미지 입는 부분입니다.

         

        여기서 저가 조금 더 특색있게 하고 싶어서

         

        경험치를 10 기준으로 Ball을 생성을 해주었습니다

         

        즉 10보다 작으면 그 경험치 만큼만 생성을 해주고

         

        10보다 크면 10으로 쪼개어서 Exp Ball을 생성을 해주었습니다.

         

         

        결과

         

        'Unity > RPG Project' 카테고리의 다른 글

        RPG Project - 11 [ Quest 진행 도우미(UI) ]  (0) 2024.10.19
        RPG Project - 10 [ NPC에게 Quest 받기 ]  (0) 2024.10.19
        RPG Project - 8 [ NPC Chat System ]  (0) 2024.10.15
        RPG Project - 7 [ 상호작용 Text 구현 ]  (0) 2024.10.14
        RPG Project - 6 [ NPC가 User 바라보기 구현 ]  (0) 2024.10.10
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바