복제 게임 : 아이작의 번제

youtu.be/27Le3kOOFQk

[복제 목표]

  • 튜토리얼 화면 구성
  • 이동 구현
  • 공격 구현

[구현 설계]

  1. 튜토리얼 맵 배치 // 완료
  2. 캐릭터 배치 // 완료
  3. 캐릭터 이동 // 완료
    1. 난제 : ASDW에 방향키를 둘다 쓰는 사양이라 GetAxis의 사용 난제
      • 유니티 에디터 상에서 수정하면 되겠지만,
        유니티 한정으로 생각하지 않기 위해 GetAxis 대신 다른 것을 고려
      • 속도 문제 : 왜 갑자기 속도가 변하는지 확인 필요
  4. 캐릭터 애니메이션 제작 // 완료
  5. 공격 구현 // 진행중 시간초과
  6. 완성

[추정 소요시간] : 8H

[실제 소요시간] : 9H(미완)

블로그 이미지

RIsN

,

복제 게임 : 쿠키런 : 오븐 브레이크

youtu.be/4yritPZC7Vg

 

[복제 목표]

  • Unity2D가 아닌 Unity3D를 사용해서 2D 느낌을 구현
  • 1단 점프
  • 슬라이드 구현
  • 움직이는 배경 구현

[구현 설계]

  1. 캐릭터 배치 : 완료
  2. 점프, 슬라이드 버튼 배치 : 완료
  3. 캐릭터 애니메이션 제작 : 완료
  4. 버튼을 캐릭터 애니메이션과 연동 : 완료
  5. 점프 구현
    1. 점프 공식 확인 : 완료
    2. 구현 : 완료
  6. 슬라이드 구현
    1. Collider 사이즈 조정 테스트 : 완료
    2. Collider 이동 테스트 : 완료
  7. 움직이는 배경 구현
    1. 배경 리소스 확인 및 적용 : 완료
    2. 배경 움직임 구현 : 완료
  8. 버그 제거
    1. 점프 시에 슬라이드 애니메이션 돌입하지 못하도록 : 완료
    2. 점프 후에 누르고 있으면 슬라이드로 돌입하도록 : 완료
  9. 완성
  10. 타 클로닝 완료 후, 시간적 여유가 있을 경우 추가적 활동 : 진행중

[추정 소요시간] : 6H

[실제 소요시간] : 5H

 

[완성]

youtu.be/wLSpruromYo

 

블로그 이미지

RIsN

,

:: プラットフォームゲームテスト

:: 上に上がる時は衝突無視

youtu.be/hzvA86wAHAo

>>改善すべき:UpdateのたびにBoxColliderを探すのは非効率的。

using UnityEngine;

// PlayerController는 플레이어 캐릭터로서 Player 게임 오브젝트를 제어한다.
public class PlayerController : MonoBehaviour {
   public AudioClip deathClip; // 사망시 재생할 오디오 클립
   public float jumpForce = 700f; // 점프 힘

   private int jumpCount = 0; // 누적 점프 횟수
   private bool isGrounded = false; // 바닥에 닿았는지 나타냄
   private bool isDead = false; // 사망 상태

   private Rigidbody2D playerRigidbody; // 사용할 리지드바디 컴포넌트
   private Animator animator; // 사용할 애니메이터 컴포넌트
   private AudioSource playerAudio; // 사용할 오디오 소스 컴포넌트


   private void Start() {
        // 초기화
        // 게임 오브젝트로부터 사용할 컴포넌트들을 가져와 변수에 할당
        this.playerRigidbody = this.GetComponent<Rigidbody2D>();
        this.animator = this.GetComponent<Animator>();
        this.playerAudio = this.GetComponent<AudioSource>();
   }

    private Vector2 playerVelocity;
    private void Update() {
        // 사용자 입력을 감지하고 점프하는 처리
        // 사망 시 처리를 더 이상 진행하지 않고 종료
        if(isDead)
        {
            return;
        }

        this.playerVelocity = playerRigidbody.velocity;
        if(playerRigidbody.velocity.y > 0)
        {
            // :: Find all BoxCollider2D
            foreach (var itm in GameObject.FindObjectsOfType<BoxCollider2D>())
            {
                // :: Player : Ignore it
                Physics2D.IgnoreCollision(playerRigidbody.gameObject.GetComponent<CircleCollider2D>(), itm, true);
            }
        } else if(playerRigidbody.velocity.y < 0)
        {
            foreach(var itm in GameObject.FindObjectsOfType<BoxCollider2D>())
            {
                Physics2D.IgnoreCollision(playerRigidbody.gameObject.GetComponent<CircleCollider2D>(), itm, false);
            }
        }

        // :: When Mouse Right Button Clicking
        if(Input.GetMouseButton(1))
        {
            // :: Igonore all Box Collider
            foreach (var itm in GameObject.FindObjectsOfType<BoxCollider2D>())
            {
                // :: If it's not Start Block
                if(!itm.gameObject.name.Contains("Start"))
                    Physics2D.IgnoreCollision(playerRigidbody.gameObject.GetComponent<CircleCollider2D>(), itm, true);
            }
        }

        if(Input.GetMouseButtonDown(0) && jumpCount < 2)
        {
            // 점프 횟수 증가
            jumpCount++;
            // 점프 직전에 속도를 순간적으로 제로(0, 0)로 변경
            playerRigidbody.velocity = Vector2.zero;
            // 리지드 바디에 위쪽으로 힘 주기
            playerRigidbody.AddForce(new Vector2(0, jumpForce));
            // 오디오 소스 재생
            playerAudio.Play();
        } else if(Input.GetMouseButtonUp(0) && playerRigidbody.velocity.y > 0)
        {
            // 마우스 왼쪽 버튼에서 손을 떼는 순간 && 속도의 y 값이 양수라면(위로 상승 중)
            // 현재 속도를 절반으로 변경
            playerRigidbody.velocity = playerRigidbody.velocity * 0.5f;
        }

        // 애니메이터의 Grounded 파라미터를 isGrounded 값으로 갱신
        animator.SetBool("Grounded", isGrounded);
   }

   private void Die() {
        // 사망 처리
        // 애니메이터의 Die 트리거 파라미터를 셋
        animator.SetTrigger("Die");

        // 오디오 소스에 할당된 오디오 클립을 deathClip으로 변경
        playerAudio.clip = deathClip;
        // 사망 효과음 재생
        playerAudio.Play();

        // 속도를 제로(0, 0)으로 변경
        playerRigidbody.velocity = Vector2.zero;
        // 사망 상태를 true로 변경
        isDead = true;
   }

   private void OnTriggerEnter2D(Collider2D other)
    {

        Debug.LogFormat("OnTriggerEnter2D : {0}", other.gameObject.name);

        // 트리거 콜라이더를 가진 장애물과의 충돌을 감지
        if (other.tag == "Dead" && !isDead)
        {
            // 충돌한 상대방의 태그가 Dead이며 아직 사망하지 않았다면 Die() 실행
            Die();
        }
   }

   private void OnCollisionEnter2D(Collision2D collision)
    {

        Debug.LogFormat("OnCollisionEnter2D : {0} / {1}", playerRigidbody.velocity.y, collision.contacts[0].normal.y);

        // 바닥에 닿았음을 감지하는 처리
        // 어떤 콜라이더와 닿았으며, 충돌 표면이 위쪽을 보고 있으면
        if (collision.contacts[0].normal.y > 0.7f)
        {
            // isGrounded를 true로 변경하고, 누적 점프 횟수를 0으로 리셋
            isGrounded = true;
            jumpCount = 0;
        }
   }

   private void OnCollisionExit2D(Collision2D collision) {

        Debug.LogFormat("OnCollisionExit2D : {0}", collision.gameObject.name);

        // 바닥에서 벗어났음을 감지하는 처리
        // 어떤 콜라이더에서 떼어진 경우 isGrounded를 false로 변경
        isGrounded = false;
   }
}
블로그 이미지

RIsN

,