Writing the Player Script
이번 시간에는 플레이어의 스크립트를 작성하도록 하겠습니다. 그 전에 GameManager에 몇가지 추가할 사항이 있습니다. GameManager 스크립트를 에디터로 열어 보도록 합시다.
두개의 퍼블릭 변수와, 한개의 퍼블릭 메소드를 추가하고자 합니다. 처음 부분 변수들 선언 부에
public int playerFoodPoints = 100;
[HideInInspector] public bool playersTurn = true;
| cs |
한 가지 더,
public void GameOver()
{
enabled = false;
}
| cs |
이 클래스는 MonoBehaviour가 아니라 앞에서 작성한 MovingObject를 상속받게 될 것입니다. 따라서 MonoBehaviour를 지우고 MovingObject를 넣습니다.
public class Player : MovingObject
{
...
}
| cs |
먼저 사용할 변수들을 선언합니다.
public int wallDamage = 1; // 플레이어가 벽을 쳤을 떄 한번에 받는 데미지
public int pointsPerFood = 10; // 음식 하나당 포인트
public int pointsPerSoda = 20; // 음료 하나당 포인트
public float restartLevelDelay = 1f; // 레벨 재시작 시 시간딜레이 1초
private Animator animator; // 애니메이터 레퍼런스
private int food; // 음식 포인트 저장용
| cs |
Start() 메소드는 상속 받았으므로 override 되어야 합니다. 그 안에서 레퍼런스를 연결합니다.
protected override void Start ()
{
animator = GetComponent<Animator>();
// 게임매니저에 저장된 푸드 포인트를 얻어 옴
food = GameManager.instance.playerFoodPoints;
base.Start();
}
| cs |
다음은 유니티 API의 메소드로서 게임 오브젝트가 disable될 때 호출되는 OnDisable입니다.
private void OnDisable()
{
GameManager.instance.playerFoodPoints = food;
}
| cs |
그리고 게임이 끝났는가를 판단하는 메소드인 CheckIfGameOver를 작성합니다.
private void CheckIfGameOver()
{
// 푸드 포인트가 0 이하면 GameOver호출
if (food <= 0)
GameManager.instance.GameOver();
}
| cs |
AttemptMove를 오버라이드 합니다.
protected override void AttemptMove<T>(int xDir, int yDir)
{
food--; // 한턴 움직일 때마다 푸드 포인트 1 감소
// 부모 클래스의 AttemptMove 호출
base.AttemptMove<T>(xDir, yDir);
// Move에서 사용할 hit 레퍼런스
RaycastHit2D hit;
// 게임이 끝났는지 체크
CheckIfGameOver();
// 플레이어의 턴을 false로 설정
GameManager.instance.playersTurn = false;
}
| cs |
Update()로 넘어갑니다.
void Update ()
{
if (!GameManager.instance.playersTurn)
return; // 플레이어 차례가 아니면 넘어감
// 1또는 -1로 가로, 세로 방향 저장용
int horizontal = 0;
int vertical = 0;
// Input 매니저로부터 입력받아 저장
// 현재는 standalone의 입력만 취급했고 추후 모바일용 추가 예정
horizontal = (int)Input.GetAxisRaw("Horizontal");
vertical = (int)Input.GetAxisRaw("Vertical");
// 가로로 움직였다면 세로는 0
if (horizontal != 0)
vertical = 0;
// 어느 쪽으로든 움직이라는 명령이 있었다면
if (horizontal != 0 || vertical != 0)
//플레이어는 벽과도 상호작용할 수 있으므로 제너릭에 Wall을 넘겨줌
AttemptMove<Wall>(horizontal, vertical);
}
| cs |
다음은 추상으로 선언했던 OnCantMove 차례입니다.
protected override void OnCantMove<T>(T component)
{
// 인수로 받은 component를 Wall로 캐스팅
Wall hitWall = component as Wall;
// DamageWall 메소드로 데미지를 줌
hitWall.DamageWall(wallDamage);
// animator의 상태를 변경
animator.SetTrigger("playerChop");
}
| cs |
다음은 레벨을 재로딩하는 Restart() 메소드입니다. 이것을 사용하기 위해서 먼저 네임 스페이스 선언을 추가해야 합니다.
using UnityEngine.SceneManagement;
...
private void Restart()
{
SceneManager.LoadScene(0);
}
| cs |
이제 플레이어가 공격받았을때 food point를 잃어버리는 LoseFood()차례입니다.
public void LoseFood(int loss)
{
// 애니메이터 상태 변경
animator.SetTrigger("playerHit");
food -= loss; // 음식 포인트 차감
CheckIfGameOver();
}
| cs |
다음은 Soda, Food, Exit에 도달했을 때 벌어지는 일을 구현하기 위해 유니티 내부 API인 OnTriggerEnter2D를 작성합니다.
private void OnTriggerEnter2D(Collider2D other)
{
// 감지한 것이 Exit이면 다음판 시작
if (other.tag == "Exit")
{
Invoke("Restart", restartLevelDelay);
enabled = false;
}
// Food이면 포인트 추가하고 사라지게 함
else if (other.tag == "Food")
{
food += pointsPerFood;
other.gameObject.SetActive(false);
}
// Soda도 포인트 추가, 사라지게 함
else if (other.tag == "Soda")
{
food += pointsPerSoda;
other.gameObject.SetActive(false);
}
}
| cs |
나중에 추가할 내용이 있겠지만 일단은 여기서 멈춥니다. 스크립트를 저장하고 유니티로 돌아갑니다.
Prefabs 폴더에서 Player를 선택하고 Player스크립트를 컴포넌트로 추가합니다.
그리고 스크립트가 추가되면 Blocking Layer 프로퍼티를 BlockingLayer로 지정합니다.
댓글 없음:
댓글 쓰기