예를 들어, 3가지의 음식이 준비되어 있으며, 칼로리가 적은 순서대로 1번 음식을 3개, 2번 음식을 4개, 3번 음식을 6개 준비했으며, 물을 편의상 0번 음식이라고 칭한다면, 두 선수는 1번 음식 1개, 2번 음식 2개, 3번 음식 3개씩을 먹게 되므로 음식의 배치는 "1223330333221"이 됩니다. 따라서 1번 음식 1개는 대회에 사용하지 못합니다.
일단 C#도 공부를 좀 해야할 필요가 있고 유니티에서 제공하는 기능들도 더 알아봐야할 것 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
//public 변수로 설정하면 Inspector에서 실행 중에도 값 변경 가능
public float maxSpeed;
Rigidbody2D rigid;
void Awake()
{
rigid = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
//FixedUpdate는 보통 1초에 약 50회 돈다.
//1초 동안 방향키를 누르고 있으면 AddForce가 50번 입력된다.
//Move By Key Control
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);
//Vector2의 첫번째 파라미터는 x축 속도, 두번째 파라미터는 y축 속도?
if (rigid.velocity.x > maxSpeed) // Right Max Speed
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
else if (rigid.velocity.x < maxSpeed*(-1)) // Left Max Speed
// 왼쪽은 마이너스 속도기 때문에 맥스 스피드에 -1 곱
rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
}
}
그리고 Assets 폴더에서 우클릭해서
Create -> 2D -> Physics Material 2D를 생성해서 Friction(마찰력)을 0으로 설정하고
모든 floor를 선택하고 Box Collider 2D에서 Material에 새로 만든 Physics Material을 드래그해서 적용해준다.
그럼 플레이어가 방향키를 한번만 눌러도 미끄러진다. 마찰력이 없기 때문에
이렇게 해주는 이유는 다음 강의에서 경사로를 올라가기 위해서라고 한다.
이 부분은 실제로 이 방법 밖에 없는건지 한번 찾아봐야겠다.
다음은 마찰력이 없는 것을 보완하기 위해 공기저항을 추가하는 것이다.
플레이어를 선택하면 Rigidbody 2D에 Linear Drag가 있다. 말그대로 해석하면 선형저항 같은데
이게 2D 게임에서는 공기저항같은 것으로 표현되나 보다.
공기저항이기 때문에 점프하고 공중에서 내려올 때도 천천히 내려오게 만들기 때문에 너무 큰 값을 주면 안된다.
Rigidbody 2D에서 Freeze Rotation에서 z축을 체크를 꼭해야 플레이어가 넘어지지 않는다.
처음에 키 입력을 하고 나서 좌우로 막 움직이니 플레이어가 넘어지고 날라가고 그랬는데 이 옵션을 줘야지 그런 현상을 막을 수 있나보다.
다음은 애니메이션 적용하기
방향키를 입력받을 때 Run 애니메이션 적용하는 방법이다.
Parameter 탭에서 +를 누르면 타입이 나오는데 이것이 애니메이션 state를 바꿀 때 필요한 변수의 타입이라고 한다.
여기서 변수를 하나 추가해주고 transition을 누르면 inspector에서 Conditions에서 +를 누르면 추가했던 파라미터를 설정할 수 있다.
그리고 아래 코드에서 보면 업데이트 부분에서 anim.setBool함수로 이용하고 있다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
//public 변수로 설정하면 Inspector에서 실행 중에도 값 변경 가능
public float maxSpeed;
Rigidbody2D rigid;
SpriteRenderer spriteRenderer;
Animator anim;
void Awake()
{
rigid = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
}
//단발적인 키 입력은 Update에서 하는 것이 좋다
void Update()
{
//Stop speed
if(Input.GetButtonUp("Horizontal"))
{
//normalized : 벡터 크기를 1로 만든 상태(단위벡터) GetAxisRaw랑 비슷하다?
//normalized에 곱해주는 값이 크면 버튼을 떼도 미끄러진다.
rigid.velocity = new Vector2(rigid.velocity.normalized.x * 0.001f, rigid.velocity.y);
}
//Direction Sprite
//flipX는 bool값으로 default는 false
if (Input.GetButton("Horizontal"))
{
spriteRenderer.flipX = Input.GetAxisRaw("Horizontal") == -1;
}
//Run animation 적용
if (Mathf.Abs(rigid.velocity.x) < 0.3)
{
anim.SetBool("isRunning", false);
}
else
{
anim.SetBool("isRunning", true);
}
}
//지속적인 키 입력은 FixedUpdate에서 하는 것
void FixedUpdate()
{
//FixedUpdate는 보통 1초에 약 50회 돈다.
//1초 동안 방향키를 누르고 있으면 AddForce가 50번 입력된다.
//Move Speed
float h = Input.GetAxisRaw("Horizontal");
rigid.AddForce(Vector2.right * h, ForceMode2D.Impulse);
//Vector2의 첫번째 파라미터는 x축 속도, 두번째 파라미터는 y축 속도?
//Max Speed
if (rigid.velocity.x > maxSpeed) // Right Max Speed
rigid.velocity = new Vector2(maxSpeed, rigid.velocity.y);
else if (rigid.velocity.x < maxSpeed*(-1)) // Left Max Speed
// 왼쪽은 마이너스 속도기 때문에 맥스 스피드에 -1 곱
rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
}
}
Sprite를 만들기 위한 Asset을 하나의 파일을 나누어서 구성을 할 수 있다고 한다.
Sprite editor 버튼을 누르면 한 파일을 slice 할 수 있다. 이 것을 아틀라스라고 한다.
Sprite editor
이게 중요한 이유는 batch라는 것 때문인데 게임의 그래픽을 그릴 때 메모리와 CPU를 사용한 횟수를 의미한다고 한다.
하나의 아틀라스에서 가져오는 경우 batch가 증가하지 않는다. 다른 말로 각각의 object를 모두 다른 파일에서 가져오면 batch가 많아져 리소스를 많이 잡아먹을 수 있다.
모바일 게임에서는 절대 필수라고 한다.
2. 애니메이션
애니메이션을 만들 파일을 드래그 선택해서 그대로 애니메이션을 넣고 싶은 sprite에 넣으면 애니메이션 파일이 생성된다.
그리고 해당 sprite에 자동으로 Animator component가 생긴다.
Window -> Animation 을 열면 애니메이션의 프레임을 조정할 수 있다.
그리고 애니메이션 파일의 옵션에서 Loop time을 체크 해제하면 반복하지 않는다.
여기서 Add Property를 이용하여 추가적인 이벤트들을 설정할 수 있는 것 같다.
Window -> Animator를 열면 state machine 같은게 나온다.
여기서 처음에 run animation을 만들었기 때문에 Entry에서 run으로 연결되어 있는데 idle animation을 default로 하고 싶다면 우클릭해서 Set as Layer Default State를 누르면 된다. 아래 캡처에서는 이미 default로 설정되어 있어 비활성화 되어 있다.