[고양이 밥주기] 게임 기본 씬 구성하기(3-1)
MainScene 구성하기
- Background 화면과 생선 가게, 강아지를 만들자.
- 이번 게임에서는 메인 카메라 설정을 추가로 해주자.
- Main Camera -> Camera Size 5 -> 25 변경 -> 카메라가 찍고 있는 범위를 넓혀준다.
- 그동안은 Background 이미지를 직접 오브젝트를 만들어서 바꿔줬는데, 이번에는 Camera 컴포넌트에 있는 Background 속성을 바꿔서 세팅해 보자.
- 카메라 컴포넌트 -> Background 속성 클릭 -> color -> Hexadecimal FFF0B2 변경
- 이제 프로젝트가 열릴 때 미리 다운로드 받아놨던 이미지 파일들을 가져와 보자.
- 다운받은 DogVsCat.unitypackage -> Assets 폴더에 추가
- unitypackage 파일을 이용하면 이렇게 손쉽게 이미지, 폰트 파일들을 가져올 수 있다.
- 이제 생선 가게를 지키는 강아지와 생선 가게를 만들어 주자.
- 'Hierarchy' -> 2D Object -> Sprites -> Square -> fish_shop 이미지를 그대로 인스펙터 창의 Sprite에 끌어다 주면 화면에 생선 가게 이미지가 생긴 모습을 볼 수 있다. 강아지도 똑같은 식으로 적용
- 이렇게 디자이너들이 미리 준비해 준 리소스를 활용하면 편하다.
StartScene 구성하기
- Background 이미지와 Start 버튼을 만들자.
- Scene 폴더 -> Create -> Scene -> 'StartScene' -> 더블클릭 -> Size 25 변경
- 'Hierarchy' -> 2D Object -> Sprites -> Square -> intro를 Sprite에 적용
- Start 버튼은 UI -> Legacy -> Button -> Source Image에 startBtn 적용
- 이제 이 StartButton(Play)을 눌렀을 때 MainScene으로 이동할 수 있는 로직을 만들어 주자.
- StartButton 스크립트를 만들고, StartBtn에 StartButton 스크립트 적용
using UnityEngine.SceneManagement;
public class StartButton : MonoBehaviour
{
public void StartGame()
{
}
}
- Scene 이동을 위한 using문을 작성하고 함수를 하나 만들어 줬다.
- Scene 이동 시에 기억해야 할 키워드는?
public void StartGame()
{
SceneManager.LoadScene("MainScene");
}
- SceneManager 지요
- 유니티로 돌아가서, StartBt을 On Click -> None에 추가 -> No Function -> StartButton -> StartGame() 적용
- 이렇게 해주면, Play 버튼을 클릭했을 때 StartGame 로직이 발동되면서 MainScene으로 이동하게 된다.
강아지 만들기 - 밥 쏘기(3-2)
강아지가 마우스를 따라 밥을 쏘게 만들기
- 밥을 만들자.
- 'Hierarchy' -> 2D Object -> Sprites -> Circle -> Sprite의 Circle을 Knob으로 변경
- 이제 밥이 위로 올라가는 로직을 만들자. Food 스크립트 생성
void Update()
{
transform.position.y += 1f;
}
- y값에 1을 계속 더해주자. 그런데 이렇게 하면 빨간 줄이 뜬다. 'position은 변수가 아니기 때문에 해당 반환 값을 수정할 수 없습니다'라고 뜸
- 이 position값에 x, y, z 각각에 접근해서 바꿔주는 것이 불가능하다. 그래서 position 자체에다가 더해줘야 함
- 이때 C# 스크립트에서 제공하는 매우 편리한 기능이 있다.
void Update()
{
transform.position += Vector3.up;
}
- up을 사용하면 (0, 1, 0). 즉 position y값에만 값이 들어가기 때문에 y position값만 계속해서 1씩 더해지게 된다.
- Food 게임 오브젝트에 Food 스크립트를 추가하고 플레이 해보면 너무 빨리 밥이 올라간다. 1이 아닌 0.5로 수정하자.
void Update()
{
transform.position += Vector3.up * 0.5f;
}
- 0.5를 곱해주니 아까보다는 느리게 올라간다.
- 이제 반복적으로 밥이 나타날 수 있게끔 로직을 짜보자.
- 반복적으로 생성하게 해 주는 함수는 InvokeRepeating.
- 밥이 강아지 몸을 기준으로 계속 나가니, 강아지 몸을 기준으로 밥을 계속해서 생성해주는 로직을 만들기 위해 Dog 스크립트를 만들어 주자.
void Start()
{
InvokeRepeating("MakeFood", 0f, 0.5f);
}
void MakeFood()
{
Debug.Log("밥 먹어");
}
- 바로 실행해 줄 거니까 0초, 0.5초마다 생성
- 스크립트를 Dog 오브젝트에 붙여주고 플레이 해보면 반복적으로 "밥 먹어" 로그가 찍히는 것을 볼 수 있다.
- 이제 "밥 먹어" 디버그 로그 대신에 Food를 생성해 주는 Instantiate를 넣어주면 되겠다.
- 밥을 반복적으로 생성해줘야 하니 밥이라고 하는 Prefab이 필요하다.
public GameObject food;
void Start()
{
InvokeRepeating("MakeFood", 0f, 0.5f);
}
void MakeFood()
{
Instantiate(food);
}
- food를 public해주고, 이 food를 Instantiate 해주는 로직으로 바꿨다.
- 그리고 Instantiate를 써줄 때 어떤 위치에서 생성할지까지 정해줄 수 있다. 위치는 강아지의 위치여야 한다.
void MakeFood()
{
float x = transform.position.x;
float y = transform.position.y;
Instantiate(food, new Vector2(x, y), Quaternion.identity);
}
- 강아지의 x, y값을 가져왔다.
- Quaternion.identity: 별도의 회전값을 주지 않겠다는 뜻
- 미리 만들어 놓은 Food Prefab 그대로 회전값 없이 생성하겠다는 의미
- 이제 이 게임 오브젝트 Food에다가 Food Prefab을 넣어줘야 한다.
- Dog Prefab화: Prefabs 폴더 생성 후 Food 오브젝트 드래그 드롭
- Dog 오브젝트에 있는 Food 변수에 Dog Prefab을 넣어주자.
- 플레이 해보면, 강아지 위치에서 Food가 반복적으로 잘 생성이 되는 걸 볼 수 있다.
- 그런데 강아지 머리 중앙에서 생성이 되고 있으니, 강아지 머리 위에서 생성될 수 있게끔 위치 값을 조절해 주자.
void MakeFood()
{
float x = transform.position.x;
float y = transform.position.y + 2.0f;
Instantiate(food, new Vector2(x, y), Quaternion.identity);
}
- 이렇게 해주면 강아지 머리 조금 위에서 생성이 되는 걸 볼 수 있다.
- 그런데 문제는 Food가 계속 생성되고 있다. Food가 화면 밖(y 27)으로 나가면 Destroy 해주자.
void Update()
{
if(transform.position.y > 27)
{
Destroy(gameObject);
}
}
- Food 스크립트에서, Position y값이 27보다 커질 때 게임 오브젝트를 파괴시키는 로직을 작성했다.
- 이제 Food가 화면 밖으로 나가도 누적되지 않고 잘 파괴된다.
- 다음엔 강아지를 움직여 줘야 한다. 강아지는 마우스 위치와 동일하게 움직이게 하자.
private void Update()
{
Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
- Dog 스크립트에 Update를 만들어 줬다.
- 스크린 상의 위치를 게임 월드 상의 위치로 = ScreenToWorldPoint
- 게임 월드 상에 있는 건 메인 카메라로 찍으니 Camera.main
- 마우스의 위치를 받아 오는 입력장치는 Input 키워드 사용
- 이렇게 mousePosition을 World 좌표로 바꿔줬다.
private void Update()
{
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
- 이 값을 잠시 mousePos라고 하는 변수에다가 담아주자.
- 그리고 강아지는 좌, 우로만 움직이니 여기서 필요한 건 오직 x값.
private void Update()
{
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector2(mousePos.x, transform.position.y);
}
- mousePos의 x값만 가져와 주고, y값은 강아지 위치 그대로, 즉 transform.position.y 값을 그대로 가져온다.
- 플레이 해보면, 마우스를 위로 올려도 강아지는 좌우로만 움직이게 된다.
- 그런데 또 문제는, 마우스가 화면 밖으로 가면 강아지도 같이 나가버린다.
- 일정 값 이상과 이하(-8.5, 8.5)로 가게 되면 강아지의 위치가 고정되게 로직을 만들어 주자.
private void Update()
{
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
float x = mousePos.x;
if(x > 8.5f)
{
x = 8.5f;
}
if(x < -8.5f)
{
x = -8.5f;
}
transform.position = new Vector2(mousePos.x, transform.position.y);
}
- float로 마우스 x값을 받아오고, x가 8.5보다 커져도 x값이 8.5로 고정(강제로 이동)되게 했다. (-8.5도 같은 방식으로 작성)
private void Update()
{
Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
float x = mousePos.x;
if(x > 8.5f)
{
x = 8.5f;
}
if(x < -8.5f)
{
x = -8.5f;
}
transform.position = new Vector2(x, transform.position.y);
}
- 그리고 new Vector2에 있는 mousePos.x를 변수로 뽑아준 x로 변경해 준다.
- 플레이 해보면, 마우스가 화면 밖으로 나가도 강아지는 고정돼 있는 걸 볼 수 있다.