이번 포스트에서는 단검 투척 시에 단검의 궤적을 그리고 궤적대로 날아가도록 구현햐보겠습니다.
따라서 기존의 단검 투척 스킬 그 자체를 의미하는 클래스인 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에 돌입하는 경우,
단검의 투척 궤적을 활성화하여 보여지도록 설정하였습니다.
최종 실행 결과는 다음과 같습니다.
'유니티 > 게임 프로젝트' 카테고리의 다른 글
2D RPG - (15 - 5) 단검 투척 스킬 구현_05 (0) | 2025.02.04 |
---|---|
2D RPG - (15 - 4) 단검 투척 스킬 구현_04 (0) | 2025.01.29 |
2D RPG - (15 - 2) 단검 투척 스킬 구현_02 (0) | 2025.01.28 |
2D RPG - (15 - 1) 단검 투척 스킬 구현_01 (0) | 2025.01.27 |
2D RPG - (14) 분신술 스킬 구현 (0) | 2025.01.07 |