// // /*=============================================================================== // // Copyright (C) 2025 PhantomsXR Ltd. All Rights Reserved. // // // // This file is part of the Phantom.XRMOD.PackageTools.Editor. // // // // The XR-MOD cannot be copied, distributed, or made available to // // third-parties for commercial purposes without written permission of PhantomsXR Ltd. // // // // Contact nswell@phantomsxr.com for licensing requests. // // ===============================================================================*/ using System; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; using UnityEngine.Video; using Object = UnityEngine.Object; namespace Phantom.XRMOD.XRMODPackageTools.Editor { public class ExperienceInspectorWindow : EditorWindow { static ExperienceInspectorWindow _WINDOW; private const string _CONST_PACKAGE_PATH = "Packages/com.phantomsxr.xrmodpackagetools"; private static string _UXML_AND_USS_PATH = $"{_CONST_PACKAGE_PATH}/Editor/ExperienceInspector"; private const string _CONST_FILE_NAME = "ExperienceInspectorWindow"; private ScrollView _contentScrollView; private Button _resetButton; private ListView _assetListView; private List _assetPathList = new(); private ScrollView _assetPreviewView; private VisualElement _splitView; private PreviewRenderUtility _previewUtility; private Label _previewHintLabel; private GameObject _previewInstance; private Vector2 _previewRotation = new Vector2(120, -20); private Vector2 _previewDragStart; private bool _isDraggingPreview; private bool isPlaying = false; private List experienceObjects = new(); private static AssetBundle _currentBundle; [MenuItem("Tools/XR-MOD/Tools/Experience Inspector Window")] private static void GetWindow() { if (_WINDOW == null) { _WINDOW = (ExperienceInspectorWindow) EditorWindow.GetWindow(typeof(ExperienceInspectorWindow)); } _WINDOW.Show(); } public void CreateGUI() { // 加载 UXML var visualTree = AssetDatabase.LoadAssetAtPath($"{_UXML_AND_USS_PATH}/{_CONST_FILE_NAME}.uxml"); var styleSheet = AssetDatabase.LoadAssetAtPath($"{_UXML_AND_USS_PATH}/{_CONST_FILE_NAME}.uss"); VisualElement root = visualTree.CloneTree(); root.style.flexGrow = 1; root.styleSheets.Add(styleSheet); rootVisualElement.Add(root); _assetListView = root.Q("AssetListView"); _assetListView.makeItem = () => { var label = new Label(); label.style.unityTextAlign = TextAnchor.MiddleLeft; label.style.marginBottom = 2; return label; }; _assetListView.bindItem = (element, i) => { (element as Label).text = _assetPathList[i]; }; _assetListView.selectionType = SelectionType.Single; _assetListView.onSelectionChange += objects => { foreach (var obj in objects) // 只取第一个 { if (obj is string path) { ShowAssetPreview(_currentBundle, path); } } }; _assetPreviewView = root.Q("AssetPreviewView"); _splitView = root.Q("SplitView"); _splitView.style.display = DisplayStyle.None; _previewHintLabel = new Label("Select an object to preview") { style = { unityTextAlign = TextAnchor.MiddleCenter, marginTop = 40, marginBottom = 20, fontSize = 14, color = Color.gray, alignSelf = Align.Center } }; _assetPreviewView.Add(_previewHintLabel); _resetButton = root.Q