{"record":{"id":"8149e182f25532d5","repo":"Unity-Technologies/UnityCsReference","slug":"type-should-derive-from-playmodeview","errorCode":null,"errorMessage":"Type should derive from PlayModeView","messagePattern":"Type should derive from PlayModeView","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/PlayModeView/PlayModeView.cs","lineNumber":306,"sourceCode":"        }\n\n        private string GetTypeName()\n        {\n            return GetType().ToString();\n        }\n\n        private Dictionary<string, string> ListsToDictionary(List<string> keys, List<string> values)\n        {\n#pragma warning disable UA2001 // The Banned API Analyzer produces compile errors for any new Linq code. This pre-existing usage has been suppressed, but should be rewritten if possible.\n            var dict = keys.Select((key, val) => new { key, val = values[val] }).ToDictionary(x => x.key, x => x.val);\n#pragma warning restore UA2001\n            return dict;\n        }\n\n        protected internal void SwapMainWindow(Type type)\n        {\n            if (type.BaseType != typeof(PlayModeView))\n                throw new ArgumentException(\"Type should derive from \" + typeof(PlayModeView).Name);\n            if (type.Name != GetType().Name)\n            {\n                var serializedViews = ListsToDictionary(m_SerializedViewNames, m_SerializedViewValues);\n\n                // Clear serialized views so they wouldn't be serialized again\n                m_SerializedViewNames.Clear();\n                m_SerializedViewValues.Clear();\n\n                var guid = GUID.Generate();\n                var serializedViewPath = Path.GetFullPath(Path.Combine(m_ViewsCache, guid.ToString()));\n                if (!Directory.Exists(m_ViewsCache))\n                    Directory.CreateDirectory(m_ViewsCache);\n\n                InternalEditorUtility.SaveToSerializedFileAndForget(new[] {this}, serializedViewPath, true);\n                serializedViews.Add(GetTypeName(), serializedViewPath);\n\n                PlayModeView window = null;\n                if (serializedViews.ContainsKey(type.ToString()))","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/PlayModeView/PlayModeView.cs#L288-L324","documentation":"Thrown by PlayModeView.SwapMainWindow(Type type) when the provided type's direct base class is not exactly PlayModeView. The method performs a strict BaseType check (not an IsAssignableFrom check), so only types that directly inherit from PlayModeView are accepted. This is a design constraint ensuring the window serialization and view-cache mechanism works correctly.","triggerScenarios":"Calling SwapMainWindow with a type whose BaseType != typeof(PlayModeView). This includes types that inherit from GameView or SimulatorWindow (indirect inheritance), types that inherit from EditorWindow directly, or any unrelated type. Even a valid descendant like a subclass of GameView will fail because its BaseType is GameView, not PlayModeView.","commonSituations":"Custom play mode view implementations; editor extensions that try to swap to a derived window type; passing typeof(GameView) from a context where the type system resolves to a different assembly version.","solutions":["Ensure the type you pass directly inherits from PlayModeView — use typeof(GameView) or typeof(SimulatorWindow) which are the built-in direct subclasses.","If you have a custom view, make sure its class declaration is 'class MyView : PlayModeView' not 'class MyView : GameView'.","Use PlayModeWindow.SetViewType with the enum value instead of calling SwapMainWindow directly, as it handles type resolution internally."],"exampleFix":"// before\nview.SwapMainWindow(typeof(MyCustomGameView)); // inherits GameView, not PlayModeView\n\n// after\nview.SwapMainWindow(typeof(GameView)); // direct subclass of PlayModeView","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool IsValidPlayModeViewType(Type type) => type != null && type.BaseType == typeof(PlayModeView);","tryCatchPattern":null,"preventionTips":["Ensure the type directly inherits from PlayModeView (not from a subclass like GameView).","Prefer using PlayModeWindow.SetViewType with the enum instead of calling SwapMainWindow directly.","Remember SwapMainWindow checks BaseType, not IsAssignableFrom — only direct children pass."],"tags":["unity-editor","playmode","type-validation","argument-validation"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}