# Unity 프로젝트 설정 가이드 ## 📋 개요 Unity MVVM 프로젝트를 처음부터 설정하는 완전한 가이드입니다. 개발 환경 구축부터 첫 번째 기능 구현까지 단계별로 안내합니다. ## 🎯 설정 목표 - **MVVM + DI + 메시징** 아키텍처 구축 - **모듈화된 폴더 구조** 생성 - **필수 패키지** 설치 및 설정 - **개발 환경** 최적화 --- ## 1️⃣ Unity 프로젝트 생성 ### Unity Hub에서 프로젝트 생성 ```bash 1. Unity Hub 실행 2. "New Project" 클릭 3. Template: "3D Core" 또는 "2D Core" 선택 4. Project Name: [프로젝트명] 5. Location: C:\Projects\[프로젝트명]\ 6. Unity Version: 2022.3 LTS 이상 7. "Create project" 클릭 ``` ### 기본 프로젝트 설정 ```csharp // Player Settings 설정 1. Edit → Project Settings → Player 2. Configuration: - Company Name: [회사명] - Product Name: [제품명] - Version: 1.0.0 - API Compatibility Level: .NET Standard 2.1 3. Resolution and Presentation: - Default Screen Width: 1920 - Default Screen Height: 1080 - Run In Background: true ``` --- ## 2️⃣ 폴더 구조 생성 ### Assets 폴더 구조 생성 ``` Assets/ ├── Features/ # 기능별 모듈 │ ├── Common/ # 공통 모듈 │ │ ├── Models/ │ │ ├── ViewModels/ │ │ ├── Views/ │ │ ├── Controllers/ │ │ └── Services/ │ ├── Player/ # 플레이어 시스템 │ │ ├── Models/ │ │ ├── ViewModels/ │ │ ├── Views/ │ │ └── Controllers/ │ └── UI/ # UI 시스템 │ ├── Models/ │ ├── ViewModels/ │ ├── Views/ │ └── Controllers/ ├── Core/ # 핵심 시스템 │ ├── DI/ # 의존성 주입 │ ├── Messaging/ # 메시징 시스템 │ ├── Extensions/ # 확장 메서드 │ └── Utils/ # 유틸리티 ├── Prefabs/ # 프리팹 │ ├── UI/ │ ├── Characters/ │ └── Environment/ ├── Resources/ # 리소스 │ ├── Data/ │ ├── Prefabs/ │ └── UI/ ├── Scenes/ # 씬 파일 │ ├── Bootstrap.unity │ ├── MainMenu.unity │ └── Game.unity ├── ScriptableObjects/ # 데이터 에셋 │ ├── Settings/ │ └── GameData/ └── Tests/ # 테스트 ├── EditMode/ └── PlayMode/ ``` ### 폴더 생성 스크립트 ```csharp // Editor/FolderStructureCreator.cs using UnityEngine; using UnityEditor; using System.IO; public class FolderStructureCreator : EditorWindow { [MenuItem("Tools/Create Project Structure")] public static void CreateFolderStructure() { string[] folders = { "Assets/Features/Common/Models", "Assets/Features/Common/ViewModels", "Assets/Features/Common/Views", "Assets/Features/Common/Controllers", "Assets/Features/Common/Services", "Assets/Features/Player/Models", "Assets/Features/Player/ViewModels", "Assets/Features/Player/Views", "Assets/Features/Player/Controllers", "Assets/Features/UI/Models", "Assets/Features/UI/ViewModels", "Assets/Features/UI/Views", "Assets/Features/UI/Controllers", "Assets/Core/DI", "Assets/Core/Messaging", "Assets/Core/Extensions", "Assets/Core/Utils", "Assets/Prefabs/UI", "Assets/Prefabs/Characters", "Assets/Prefabs/Environment", "Assets/Resources/Data", "Assets/Resources/Prefabs", "Assets/Resources/UI", "Assets/Scenes", "Assets/ScriptableObjects/Settings", "Assets/ScriptableObjects/GameData", "Assets/Tests/EditMode", "Assets/Tests/PlayMode" }; foreach (string folder in folders) { if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); Debug.Log(quot;Created folder: {folder}"); } } AssetDatabase.Refresh(); Debug.Log("Project structure created successfully!"); } } ``` --- ## 3️⃣ 필수 패키지 설치 ### Package Manager 설정 ```json // Packages/manifest.json { "dependencies": { "com.cysharp.unitask": "2.5.4", "com.cysharp.messagepipe": "1.8.1", "jp.hadashikick.vcontainer": "1.15.4", "com.google.protobuf": "3.21.12", "com.unity.inputsystem": "1.7.0", "com.unity.addressables": "1.21.19", "com.unity.test-framework": "1.3.9" }, "scopedRegistries": [ { "name": "Cysharp", "url": "https://package.openupm.com", "scopes": [ "com.cysharp" ] }, { "name": "VContainer", "url": "https://package.openupm.com", "scopes": [ "jp.hadashikick" ] } ] } ``` ### R3 (UniRx) 설치 ```bash # Git Package로 설치 Window → Package Manager → + → Add package from git URL https://github.com/Cysharp/R3.git?path=src/R3.Unity#2.4.0 ``` ### 패키지 설치 확인 스크립트 ```csharp // Editor/PackageValidator.cs using UnityEngine; using UnityEditor; public class PackageValidator : EditorWindow { [MenuItem("Tools/Validate Packages")] public static void ValidatePackages() { string[] requiredPackages = { "com.cysharp.unitask", "com.cysharp.messagepipe", "jp.hadashikick.vcontainer", "com.google.protobuf", "com.unity.inputsystem" }; bool allInstalled = true; foreach (string package in requiredPackages) { if (!HasPackage(package)) { Debug.LogError(quot;Missing package: {package}"); allInstalled = false; } else { Debug.Log(quot;✓ Package installed: {package}"); } } if (allInstalled) { Debug.Log("All required packages are installed!"); } else { Debug.LogError("Some packages are missing. Please install them."); } } private static bool HasPackage(string packageName) { var request = UnityEditor.PackageManager.Client.List(); while (!request.IsCompleted) { } foreach (var package in request.Result) { if (package.name == packageName) return true; } return false; } } ``` --- ## 4️⃣ 기본 아키텍처 설정 ### VContainer DI 설정 ```csharp // Core/DI/GameLifetimeScope.cs using VContainer; using VContainer.Unity; using UnityEngine; public class GameLifetimeScope : LifetimeScope { [SerializeField] private GameSettings _gameSettings; [SerializeField] private PlayerModel _playerModel; protected override void Configure(IContainerBuilder builder) { // Settings builder.RegisterInstance(_gameSettings); // Models builder.RegisterInstance(_playerModel).As<IPlayerModel>(); // Services builder.Register<GameManager>(Lifetime.Singleton); builder.Register<AudioManager>(Lifetime.Singleton); builder.Register<InputManager>(Lifetime.Singleton); // MessagePipe builder.AddMessagePipe(); Debug.Log("DI Container configured successfully!"); } } ``` ### 기본 ScriptableObject 생성 ```csharp // ScriptableObjects/GameSettings.cs using UnityEngine; [CreateAssetMenu(fileName = "GameSettings", menuName = "Game/Settings")] public class GameSettings : ScriptableObject { [Header("Audio Settings")] public float masterVolume = 1.0f; public float musicVolume = 0.8f; public float sfxVolume = 1.0f; [Header("Graphics Settings")] public bool vSyncEnabled = true; public int targetFrameRate = 60; [Header("Debug Settings")] public bool showDebugInfo = false; public LogLevel logLevel = LogLevel.Info; } public enum LogLevel { None = 0, Error = 1, Warning = 2, Info = 3, Debug = 4 } ``` ### Bootstrap Scene 설정 ```csharp // Core/Bootstrap.cs using UnityEngine; using UnityEngine.SceneManagement; using VContainer.Unity; using Cysharp.Threading.Tasks; public class Bootstrap : MonoBehaviour { [SerializeField] private string nextSceneName = "MainMenu"; private async void Start() { await InitializeGame(); await LoadNextScene(); } private async UniTask InitializeGame() { Debug.Log("Initializing game systems..."); // 기본 Unity 설정 Application.targetFrameRate = 60; Screen.sleepTimeout = SleepTimeout.NeverSleep; // DI Container 초기화는 GameLifetimeScope에서 자동으로 처리 await UniTask.Delay(1000); // 초기화 시뮬레이션 Debug.Log("Game systems initialized!"); } private async UniTask LoadNextScene() { Debug.Log(quot;Loading scene: {nextSceneName}"); await SceneManager.LoadSceneAsync(nextSceneName); } } ``` --- ## 5️⃣ IDE 설정 ### Visual Studio 설정 ```xml <!-- .editorconfig --> root = true [*.cs] indent_style = space indent_size = 4 end_of_line = crlf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true # Unity naming conventions dotnet_naming_rule.unity_serialized_field_rule.severity = warning dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field dotnet_naming_rule.unity_serialized_field_rule.style = camel_case_underscore_prefix dotnet_naming_symbols.unity_serialized_field.applicable_kinds = field dotnet_naming_symbols.unity_serialized_field.applicable_accessibilities = private dotnet_naming_symbols.unity_serialized_field.required_modifiers = dotnet_naming_style.camel_case_underscore_prefix.required_prefix = _ dotnet_naming_style.camel_case_underscore_prefix.capitalization = camel_case ``` ### Rider 설정 ```json // .idea/codeStyleSettings.xml { "unity_naming_conventions": { "serialized_fields": { "prefix": "_", "style": "camelCase" }, "public_fields": { "style": "PascalCase" }, "methods": { "style": "PascalCase" } } } ``` --- ## 6️⃣ 첫 번째 기능 구현 ### 간단한 MVVM 예제 - HelloWorld ```csharp // Features/Common/Models/HelloWorldModel.cs using R3; [CreateAssetMenu(fileName = "HelloWorldModel", menuName = "Game/HelloWorld")] public class HelloWorldModel : ScriptableObject { private ReactiveProperty<string> _message = new("Hello, Unity MVVM!"); public ReadOnlyReactiveProperty<string> Message => _message; public void UpdateMessage(string newMessage) { _message.Value = newMessage; } } ``` ```csharp // Features/Common/ViewModels/HelloWorldViewModel.cs using R3; using VContainer; public class HelloWorldViewModel : System.IDisposable { [Inject] private HelloWorldModel _model; public ReadOnlyReactiveProperty<string> DisplayMessage { get; private set; } public ReactiveCommand UpdateMessageCommand { get; private set; } private readonly CompositeDisposable _disposables = new(); public void Initialize() { DisplayMessage = _model.Message.ToReadOnlyReactiveProperty().AddTo(_disposables); UpdateMessageCommand = new ReactiveCommand().AddTo(_disposables); UpdateMessageCommand.Subscribe(_ => _model.UpdateMessage("Updated!")).AddTo(_disposables); } public void Dispose() { _disposables?.Dispose(); } } ``` ```csharp // Features/Common/Views/HelloWorldView.cs using UnityEngine; using UnityEngine.UI; using R3; using VContainer; public class HelloWorldView : MonoBehaviour { [SerializeField] private Text _messageText; [SerializeField] private Button _updateButton; [Inject] private HelloWorldViewModel _viewModel; private readonly CompositeDisposable _disposables = new(); private void Start() { _viewModel.Initialize(); // Data Binding _viewModel.DisplayMessage .Subscribe(message => _messageText.text = message) .AddTo(_disposables); // Command Binding _updateButton.onClick.AsObservable() .Subscribe(_ => _viewModel.UpdateMessageCommand.Execute()) .AddTo(_disposables); } private void OnDestroy() { _disposables?.Dispose(); } } ``` --- ## 7️⃣ 검증 및 테스트 ### 설정 검증 체크리스트 - [ ] Unity 2022.3 LTS 이상으로 프로젝트 생성 - [ ] 폴더 구조가 모듈화 구조로 생성됨 - [ ] 모든 필수 패키지 설치 완료 - [ ] VContainer DI 컨테이너 동작 확인 - [ ] Bootstrap 씬에서 초기화 성공 - [ ] HelloWorld MVVM 예제 동작 확인 ### 기본 테스트 실행 ```csharp // Tests/EditMode/ArchitectureTests.cs using NUnit.Framework; using VContainer; public class ArchitectureTests { [Test] public void DI_Container_Should_Be_Configured() { var builder = new ContainerBuilder(); var scope = new GameLifetimeScope(); Assert.DoesNotThrow(() => scope.Configure(builder)); } [Test] public void MVVM_Components_Should_Be_Available() { Assert.IsNotNull(typeof(HelloWorldModel)); Assert.IsNotNull(typeof(HelloWorldViewModel)); Assert.IsNotNull(typeof(HelloWorldView)); } } ``` --- ## 🚀 다음 단계 ### 즉시 시작 가능한 개발 1. **새로운 기능 모듈 추가**: Features 폴더에 기능별 모듈 생성 2. **UI 시스템 확장**: UGUI 기반 MVVM UI 컴포넌트 개발 3. **데이터 시스템 구축**: ScriptableObject 기반 게임 데이터 관리 4. **네트워크 통신**: Protobuf 기반 서버 통신 구현 ### 권장 학습 순서 1. [Code Architecture Guide](Code_Architecture_Guide.md) - MVVM 패턴 심화 2. [Data Architecture](Data_Architecture.md) - 데이터 관리 전략 3. [Protobuf Integration Guide](Protobuf_Integration_Guide.md) - 네트워크 통신 --- **🎉 축하합니다! Unity MVVM 프로젝트 기본 설정이 완료되었습니다.** 이제 체계적이고 확장 가능한 Unity 게임 개발을 시작할 수 있습니다! --- *최종 업데이트: 2024-01-03* *작성자: Unity Setup Team*