게임이 줄 수 있는 재미 중에 큰 부분으로 도전과 성장을 자극하는 것이 있습니다. 유저에게 그러한 성취감을 주려면 기존보다 더 발전했다는 것을 보여줄 수 있어야 합니다. 그러기 위해서는 이전 플레이에서 얻은 재화, 현재 진행도 등을 저장할 수 있어야 이전과 비교하여 현재 어느 정도 발전했는지 확인이 가능합니다. 게임에서는 언급한 데이터 외에도 사용자 편의 설정이라든지 개발자가 직접 만든 데이터가 아닌 유저로 부터 나오는 데이터들을 각각 저장하고 관리할 수 있어야 합니다.
그러나 각각의 데이터들은 서로 다른 형태와 모습을 하고 있습니다. 물론 제 각각 다른 형태의 타입을 정의하고 만들어 줄 수도 있지만, 다른 와중에도 동일한 지점을 정의해 이 모든 것을 한 번에 관리할 수 있다면 좀 더 효율적이고 효과적으로 관리할 수 있을 것입니다. 이를 가능하게 하는 것이 인터페이스입니다.
과거에 처음 개발을 배울 당시에는 인터페이스의 용도에 대해 크게 와닿지 않았습니다. '이게 왜 필요하지? 클래스로 다 상속시켜버릴 수도 있는 것 아닐까? 조금 더 추상화를 원한다면 추상 클래스를 활용할 수도 있지 않을까?'라는 생각에서였는데 지금 봐도 그렇게 틀리지 않은 부분이 있습니다.
그러나 인터페이스와 클래스의 가장 큰 차이는 다중 상속 이 가능하다는 점 입니다. 애초에 설계부터 같은 속성과 비슷한 동작을 가졌다면 처음부터 같은 부모 클래스를 상속받아 구현하도록 설계되었을 것 입니다. 그러나 전혀 유사한 점 없이 특정 동작 몇 가지만 공유하는데 이를 같은 클래스로 묶어서 설계하긴 어렵습니다. 또한 이미 개발된 기능 위에 새로운 기능을 추가해야하는 상황이라면 더더욱 인터페이스가 유의미해집니다.
처음 인터페이스를 배울 때 그렇게 스위치 비유를 많이 들었습니다. 우리는 '스위치를 누르면 전기가 들어오고 불이 켜질 것이다.'라는 사고를 어렵지 않게 할 수 있습니다. 스위치의 모양이 어떤 지 실제로 어떤 절차를 거쳐 불이 들어오는 지는 중요하지 않습니다. 이렇게 '동작' 또는 '기능'을 중심으로 인터페이스는 그 '기능'이 존재함을 보장합니다. 저장이 필요한 데이터들은 어떤 형태를 하고 있든 반드시 '저장한다'와 '불러온다'라는 동작을 수행할 수 있을 것을 예상할 수 있습니다. 이런 동작을 기준으로 인터페이스를 구성하여 데이터를 한 데 모아 관리할 수 있게 됩니다.
실제로 사용자의 데이터를 저장하는 방식 역시 수많은 방법이 존재합니다. 그 중 유니티가 제공하는 PlayerPref 활용하면 객체 하나를 다루듯 이 간단하게 데이터를 저장할 수 있습니다. 단순한 구조의 작은 데이터를 저장하기에 적합하며 int, float, string 타입을 지원합니다. 사용도 Save()와 GetInt() 이런식으로 단순한 메서드 호출로 이루어지기 때문에 굉장히 편리하지만, 그만큼 보안은 보장하지 못하고 복잡한 형태의 데이터는 다루기 어렵습니다.
기본적으로 PlayerPrefs는 플랫폼 별로 유니티가 지정한 경로로 저장이 됩니다.