유니티/게임 프로젝트

2D RPG - (15 - 3) 단검 투척 스킬 구현_03

monstro 2025. 1. 28. 01:15
728x90
반응형

이번 포스트에서는 단검 투척 시에 단검의 궤적을 그리고 궤적대로 날아가도록 구현햐보겠습니다.

따라서 기존의 단검 투척 스킬 그 자체를 의미하는 클래스인 SkillThrowingSword의 로직을 수정합니다.

 

1) SkillThrowingSword

public class SkillThrowingSword : SkillTemplate
{
    [Header("Skill Info")]
    [SerializeField]
    private GameObject _swordPrefab;
    [SerializeField]
    private Vector2 _launchForce;
    [SerializeField]
    private float _swordGravity;

    private Vector2 _finalDirection;

    [Header("Aim Dots")]
    [SerializeField]
    private int _numberOfDots;
    [SerializeField]
    private float _spaceBetweenDots;
    [SerializeField]
    private GameObject _dotPrefab;
    [SerializeField]
    private Transform _dotsParent;

    private GameObject[] _dots;

    protected override void Start()
    {
        base.Start();

        GenerateDots();
    }

    protected override void Update()
    {
        if (_playerController._isThrowSwordClicked == false)
        {
            _finalDirection = new Vector2(
                    MakeAimDirection().normalized.x * _launchForce.x,
                    MakeAimDirection().normalized.y * _launchForce.y
                );
        }

        if (_playerController._isThrowSwordClicked)
        {
            for (int i = 0; i < _dots.Length; i++)
            {
                _dots[i].transform.position = SetDotsPosition(i * _spaceBetweenDots);  
            }
        }
    }

    public void CreateSword()
    {
        GameObject newSword = Instantiate(
            _swordPrefab,
            _playerController.transform.position,
            transform.rotation
            );

        SkillThrowingSwordController _throwingSwordController = newSword.GetComponent<SkillThrowingSwordController>();

        _throwingSwordController.SetUpSword(_finalDirection, _swordGravity);

        DotsActive(false);
    }

    public Vector2 MakeAimDirection()
    {
        Vector2 playerPosition = _playerController.transform.position;
        Vector2 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        Vector2 direction = mousePosition - playerPosition;

        return direction;
    }

    public void DotsActive(bool isActive)
    {
        for (int i = 0; i < _dots.Length; i++)
        { 
            _dots[i].SetActive(isActive);
        }
    }


    private void GenerateDots()
    {
        _dots = new GameObject[_numberOfDots];
        for (int i = 0; i < _numberOfDots; i++)
        {
            _dots[i] = Instantiate(_dotPrefab, _playerController.transform.position, Quaternion.identity, _dotsParent);
            _dots[i].SetActive(false);
        }
    }

    private Vector2 SetDotsPosition(float arg)
    { 
        Vector2 position = (Vector2)_playerController.transform.position + 
            new Vector2(MakeAimDirection().normalized.x * _launchForce.x, MakeAimDirection().normalized.y * _launchForce.y) * arg + 
            0.5f * (Physics2D.gravity * _swordGravity) * (arg * arg);

        return position;
    }
}

 

Skill Info 헤더에서 이전에 사용하던 _launchDir_launchForce라는 이름으로 변경하였습니다.

 

또한 새로 추가한 프로퍼티_finalDirection검이 날아가는 방향을 의미합니다.

 

Aim Dots 헤더의 프로퍼티들은 다음을 의미합니다.

_numberOfDots그려지는 궤적의 점들의 개수를 의미합니다.

_spaceBetweenDots궤적을 구성하는 점들간의 간격을 의미합니다.

_dotPrefab점을 그리기 위한 프리팹을 의미합니다.

_dotsParent궤적을 그리기 위한 시작점을 의미합니다.

 

마지막으로 _dots궤적을 구성하는 점들을 보관하는 용도로 사용합니다.

 

우선, Start 메서드에서는 GenerateDots 메서드를 호출하여 궤적을 생성합니다.

 

Update 메서드에서는 마우스 우클릭 여부를 판단하여

뗐다면 _finalDirection을 결정하여 단검이 날아가는 방향을 결정하고

누르고 있다면 _dots를 순회하면서 궤적의 위치를 설정합니다.

 

CreateSword 메서드에서는 단검 프리팹의 인스턴스를 생성하는 것까지는 동일하지만

SetupSword에서 이전의 인자 대신, _finalDirection을 넣어줍니다.

또한 단검이 날아가므로 궤적 역시 비활성화합니다.

 

MakeAimDirection 메서드에서는 Player의 위치마우스 커서간의 위치판단하여

마우스 커서 위치 - Player 위치의 값리턴합니다.

 

DotsActive 메서드에서는 _dots를 순회하면서 인덱스들을 활성화 / 비활성화합니다.

 

GenerateDots 메서드에서는 _dots안에 _dotPrefab의 인스턴스들을 생성하여 넣어줍니다.

생성 직후에는 비활성화합니다.

 

SetDotsPosition 메서드의 경우 굉장히 복잡한데,

궤적을 구성하는 개별 점들간의 위치설정하는 함수입니다.

 

작업 내용을 참고할만한 자료주소를 올려놓겠습니다.

https://www.youtube.com/watch?v=RpeRnlLgmv8

 

- YouTube

 

www.youtube.com

 

2) PlayerStateAimSword

public class PlayerStateAimSword : PlayerState
{
   
	.
	.
	.

    public override void Enter()
    {
        base.Enter();

        _controller._skillManager._skillThrowingSword.DotsActive(true);
    }

	.
	.
	.
    
}

 

단검을 투척하기 위해 조준하는 상태AimState에 돌입하는 경우,

단검의 투척 궤적을 활성화하여 보여지도록 설정하였습니다.

 

최종 실행 결과는 다음과 같습니다.

 

728x90
반응형