목차

반응형

AchievementManager라는 파일을 새로 생성하였다.

이 파일에서 도전과제에 대한 기능들이 정의되어있다.


아래는 도전과제 기능을 구현하기 위해 필요한 기능들이다.


도전과제 데이터에 대한 정의

public class AchievementData
{
public int ScoreN { get; set; }
public int PlayN { get; set; }
public static int BoostCount = 0; }

위와같이 도전과제 데이터에 대한 정의를 내린다.

ScoreN은 N점이상 달성시 해제되는 도전과제이고 PlayN은 N회이상 플레이해야 해제되는 도전과제이다.

ScoreN과 PlayN이 의미하는 값은 해당 도전과제를 달성하기 위한 수치를 의미한다.

PlayN이 5일경우 5회이상 플레이시 도전과제를 달성할 수 있도록 하는 것이다.

BoostCount는 한 게임 내에서 사용한 부스트의 횟수인데 아래에서 설명하겠다.

위와 같이 각 도전과제의 달성수치에 대한 정의를 내린다.


그리고 저장하기 위한 데이터에 대하여 클래스를 생성한다.

public class SaveData
{
[SerializeField] public int MaxLevel;
[SerializeField] public int[] StageScore;

[SerializeField] public bool unlockScoreN;
[SerializeField] public int pointScoreN;

[SerializeField] public bool unlockPlayN;
[SerializeField] public int pointPlayN;

public SaveData()
{
MaxLevel = 0;
StageScore = new int[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
PlayCount = 0;
unlockScoreN = false;
pointScoreN = 0;
unlockPlayN = false;
pointPlayN = 0;
}
}

해당 클래스는 게임내의 저장데이터를 가지고 있다.

MaxLevel이나 StageScore 같은 값은 도전과제와는 상관없는 게임 데이터이며

ScoreN을 놓고 봤을때

unlockScoreN은 도전과제에 대한 달성 여부를 의미한다.

pointScoreN은 도전과제에 대하여 얼마나 달성하였는지 나타내는 수치다.(해당 데이터가 저장되어야하는 이유는 유저가 도전과제를 얼마나 달성하였는지 게임이 종료되어도 해당 데이터의 기록이 남아있어야 하기 때문이다. 그리고 유저가 저장되어 있는 수치보다 높은 수치를 기록하면 해당 수치로 덮어씌우고 저장해준다.)


데이터의 갱신

도전과제 데이터에 대하여 지속적으로 갱신이 필요하다.

예를들면 위의 소스에서 PlayN을 5로 지정하였을때

pointPlayN은 0, unlockPlayN은 false로 초기화 된다.

5번을 플레이하면 unlockPlayN이 true가 되어야한다.(도전과제 달성여부 검사하는 부분은 아래에서 한다.)


유저가 게임을 플레이할때마다 휘발성 데이터인 PlayCount 값을 증가시켜준다.

그리고 아래 스크립트를 통하여 도전과제에 대하여 얼마나 성취하였는지 기존 데이터와 비교하여 기존보다 수치가 높으면 저장해준다.


게임에 대한 플레이 횟수는 계속해서 누적해서 카운트가 되어야하기때문에 아래와 같이 saveData에서 직접적으로 증가시켜준다.


AchievementManager.saveData.pointPlayN++;


하지만 한 게임내에서 부스트를 N회이상 사용하는 도전과제를 예시로 들면 해당 도전과제의 데이터는 누적되는 데이터가 아니라 게임마다 데이터가 바뀌어야하는 휘발성 데이터이기 때문에 아래와 같이 데이터를 갱신한다.

AchievementManager.BoostCount++;


도전과제 달성 현황 화면이다. 위 수치를 나타내기 위해서는 saveData에 저장을 해둬야한다.



도전과제 달성여부 확인

도전과제 데이터에 대한 갱신이 되었으면 도전과제가 달성되었는지 확인해주는 부분이 필요하다.

더불어 도전과제 데이터가 현재 저장되어있는 도전과제 데이터 수치보다 더 높은 수치면 데이터를 바꿔주는 부분도 포함되어있다.

//도전과제 달성여부 확인
public void checkAchievement()
{
if (gameManager.
play)
{
checkMaxScore();
checkStageScore();
checkDefault();
checkScoreN();
checkPlayN();
checkBoostNInAGame();
checkScoreN2();
checkExactN();
checkNoBoostTillN();
checkScoreN3();
checkBoostN2InAGame();
if (hasModified)
{
hasModified = false;
SaveData();
}
}
}

위와 같이 checkAchievement 함수를 update 부분에서 지속적으로 호출하여 도전과제 데이터에 대한 달성 여부를 확인한다.

hasModified는 도전과제를 달성하면 true로 바뀐다.

도전과제를 달성하면 자동적으로 저장되게끔 하기 위해서이다.


check함수에 대하여 예시를 보여주자면

//도전과제 확인
public void checkPlayN()
{
//도전과제 달성률 확인용
if (saveData.pointPlayN < saveData.pointPlayN)
{
saveData.pointPlayN = saveData.pointPlayN;
}
if (!saveData.unlockPlayN)
{
if (AchievementData.PlayN <= saveData.pointPlayN)
{
Achieve(out saveData.unlockPlayN, "Play 100 Times");
}
}
}

위와 같다.


//도전과제 달성률 확인용
if (saveData.pointPlayN < saveData.pointPlayN)
{
saveData.pointPlayN = saveData.pointPlayN;
}

해당 코드는 기존 도전과제 데이터에 비하여 더 향상된 수치를 가지면 수치를 업데이트 시켜주는 것 이다.(해당 데이터가 바로 저장이 되지는 않지만 게임 종료시, 시작시 데이터를 저장해주도록 하였기 때문에 게임 종료시 알아서 저장이 된다.)


 if (!saveData.unlockPlayN)
{
if (AchievementData.PlayN <= saveData.pointPlayN)
{
Achieve(out saveData.unlockPlayN, "Play 100 Times");
}
}

달성한 도전과제가 아닐시 달성여부를 확인하고 달성하였으면 Achieve함수를 통하여 도전과제 달성 함수를 호출한다.

Achieve 함수 내용은 아래에서 설명한다.


도전과제 달성

도전과제를 달성하면 유저에게 달성했다는 표시를 해야한다.

Achieve 함수를 통하여 아래와 같은 애니메이션을 표출하도록 하였다.


Achieve 함수의 내용은 아래와 같다.

//도전과제 달성 - 안내창 보여주기
public void Achieve(out bool achieve, string mention)
{
achieve = true;
hasModified = true;
_EffectManager.Achieve();
_EffectManager.LockOff();
_EffectManager.setAchieveText(mention);
Debug.Log(mention);
}

먼저 out을 통하여 해당 도전과제 bool 데이터에 대하여 true로 바꿔주고 이펙트 매니저에서 애니메이션의 텍스트를 바꿔주고 애니메이션을 호출한다.

Achieve 함수는 아래와 같이 호출한다.

 Achieve(out saveData.unlockPlayN, "Play 100 Times");


비슷하지만 단순히 도전과제만 달성하고 유저에게는 표출될 필요가 없는 부분은 아래와 같이 처리한다.

//도전과제 달성 - 안내창 없이
public void AchieveQuiet(out bool achieve, string mention)
{
achieve = true;
hasModified = true;
Debug.Log(mention);
}


도전과제 달성 데이터 저장 및 불러오기

데이터 저장과 불러오기는 아래 블로그 포스트를 참고하도록 한다.

Unity 안드로이드 파일 읽고 쓰기 streamingAssetsPath persistentDataPath








아무래도 단순히 내 생각만으로 잘 모르는 도전과제 시스템에 대하여 만들어보고 작업해보았는데 글을 쓰기전에 다른 사람들은 도전과제 시스템을 어떻게 구현하나 확인해봤다.


아래 글은 매우 정리가 잘 되어있고 체계적으로 구현이 되어있는데 언어는 다르지만 내용 자체는 매우 좋아서 다음 글은 해당 시스템에 대하여 공부하고 실제로 구현하려고한다.

https://gamedevelopment.tutsplus.com/tutorials/how-to-code-unlockable-achievements-for-your-game-a-simple-approach--gamedev-6012

반응형