자작 게임도 잘 부탁드려요~

adsense



유니티 2D 슈팅게임 개발일지 - 4일차 (이동 궤적-베지어 곡선과 기즈모)

적 편대의 움직임

베지어곡선

적 캐릭터가 갤러그를 연상시키는 곡선을 그리며 비행하기 위해 베지어 곡선을 사용합니다.

시작점, 끝점, 조정점 두 개를 사용하는 4점 베지어 곡선 두 개를 사용해 적의 궤적을 구현할 것입니다.
cocos2d-x에서는 BezierTo, BezierBy 같은 트윈이 있는데, 여기선 딱 정해진 건 없지만 통상 공식을 사용해서 구할 수 있네요.

  1. IEnumerator BezierLining()
  2. {
  3. for (int i = 0; i < 2; i++)
  4. {
  5. for (float t = 0; t < 1; t += Time.deltaTime * speed)
  6. {
  7. bezierPosition = Mathf.Pow(1 - t, 3) * _wayPoints[i * 4 + 0]
  8. + 3 * t * Mathf.Pow(1 - t, 2) * _wayPoints[i * 4 + 1]
  9. + 3 * t * (1 - t) * _wayPoints[i * 4 + 2]
  10. + Mathf.Pow(t, 3) * _wayPoints[i * 4 + 3];
  11.  
  12. transform.position = bezierPosition;
  13.  
  14. var ang = FuncManager.GetDegree(prePosition, transform.position);
  15. prePosition = transform.position;
  16.  
  17. transform.rotation = Quaternion.Euler(0, 0, 180 - ang);
  18.  
  19. yield return new WaitForEndOfFrame();
  20. }
  21. }
  22. bool isRot = true;
  23. while (isRot)
  24. {
  25. var rot = transform.rotation;
  26. transform.rotation = Quaternion.Lerp(transform.rotation,
  27. Quaternion.Euler(0, 0, 0),
  28. Time.deltaTime * 10f);
  29. if (rot == transform.rotation)
  30. isRot = false;
  31. yield return new WaitForEndOfFrame();
  32. }
  33. }
3 : 두 개의 베지어 곡선을 다룹니다. 곡선점 0~3까지가 첫째 베지어 곡선, 4~7까지가 둘째 곡선인데
4는 3과 같고(곡선이 끝난 점에서 시작하므로) 7은 별도로 진형을 형성하는 위치로 주어집니다.

5 : 베지어곡선 좌표를 0~1 사이에서, 프레임 단위로 구하도록 루프를 돕니다.
7~10 : 4점 베지어곡선 좌표를 구합니다.
12 : 구해진 좌표로 캐릭터를 이동
14~17 : 이전 좌표와 새 좌표를 비교해 전진하는 방향을 바라보도록 캐릭터를 회전

22~32 : 이동이 끝났을 때 수직 방향으로 회전하여 정지하도록.




기즈모 그리기

게임을 실행하지 않아도 에디터상에서 그려질 곡선을 미리 볼 수 있다는 사실에 놀랐습니다.
실행시켜보지 않아도 어떤 궤적이 될지, 눈으로 보면서 자유롭게 조절 가능하다니..
cocos2d-x때는 상상도 못하고 수작업으로 구현해야 했는데.

베지어 곡선을 기즈모로 표현
  1. public Transform[] wayPoints = new Transform[4];
  2. private Vector2 gizmoPosition;
  3. private void OnDrawGizmos()
  4. {
  5. if (wayPoints[0] == null)
  6. return;
  7.  
  8. for (float t = 0; t < 1; t += 0.05f)
  9. {
  10.  
  11. gizmoPosition =
  12. +Mathf.Pow(1 - t, 3) * wayPoints[0].position
  13. + 3 * t * Mathf.Pow(1 - t, 2) * wayPoints[1].position
  14. + 3 * t * (1 - t) * wayPoints[2].position
  15. + Mathf.Pow(t, 3) * wayPoints[3].position;
  16.  
  17. Gizmos.DrawSphere(gizmoPosition, 30f);
  18. Gizmos.DrawLine(new Vector2(wayPoints[0].position.x, wayPoints[0].position.y),
  19. new Vector2(wayPoints[1].position.x, wayPoints[1].position.y));
  20. Gizmos.DrawLine(new Vector2(wayPoints[2].position.x, wayPoints[2].position.y),
  21. new Vector2(wayPoints[3].position.x, wayPoints[3].position.y));
  22. }
  23. }
8 : 실시간이 아니니까 deltaTime 대신 적절한 간격을 주고,
17 : 구한 베지어 좌표에 기즈모를 그려줍니다.

4점 곡선이니 네 개의 좌표를 지정해주면
에디터상에 베지어곡선 궤적이 나타납니다.


4점을 이리저리 조작해 맘에 드는 곡선을 만듭니다.

실제로는 적 캐릭터가 자기 진영 위치로 돌아가는 곡선까지 있지만 일단 여기서는 보기 쉽게 첫째 곡선만 시각화.

조금 건너뛰었지만, 적을 생성하고 해당 곡선에 맞춰 움직이도록 하면
이렇게 궤적을 따라 적이 움직입니다.
(위 그림에서 빨간 점도 다른데서 그린 기즈모-적 캐릭터 배치 위치-입니다)

게임 창에서는 물론 궤적(기즈모)이 보이지 않습니다.


오늘은 기록 못한게 많지만 일단 움직임은 이런 식


플레이어 총알 발사를 코루틴으로 변경

생각해보니까 일정 간격으로 반복하는 처리니까 코루틴만한게 없네요.
터치/버튼이 눌리면 코루틴을 실행하고,
코루틴 루프는 isDrag 플래그를 보고 돌아가면 됩니다. 터치/버튼을 떼면 isDrag가 false.

  1. IEnumerator Fire()
  2. {
  3. while (isDrag)
  4. {
  5. for (int i = -1; i < 2; i++)
  6. {
  7. GameObject fire;
  8. int kind = 0;
  9. if (myBullet[kind].Count > 0)
  10. {
  11. fire = myBullet[kind].Dequeue();
  12. }
  13. else
  14. {
  15. fire = Instantiate(bullet[kind], transform.parent);
  16. }
  17. BulletInfo info = new BulletInfo();
  18. info.kind = kind;
  19. info.speed = Screen.height * 2f;
  20. info.power = 1f;
  21. info.accel = Random.Range(0f, 1f);// 0f;
  22. info.after = 0;
  23. fire.GetComponent<BulletController>().Setup(this.gameObject,
  24. transform.position + new Vector3(i * 80, 50 + Mathf.Abs(i) * (-60),
  25. 0),
  26. info);
  27. }
  28. yield return new WaitForSeconds(rapid);
  29. }
  30. }



덧글

댓글 입력 영역


Books

Geek라이프

기초부터 시작하는 모형 전자공작
박성윤 저

사이토 나오키의 일러스트 첨삭 레슨 Before & After
사이토 나오키 저/박수현 역

MSX&재믹스 퍼펙트 카탈로그
마에다 히로유키 저/조기현 역

핵심강좌! Cocos2d-x
이재환 저
예스24 | 애드온2
일본서적 전문사이트 NEPIC