Eversoul:

-compatibility improvements
Core:
-new settings class
This commit is contained in:
2024-04-25 02:16:49 +02:00
parent fc64500158
commit c922584d38
39 changed files with 4302 additions and 219 deletions

View File

@@ -16,7 +16,7 @@ public class AssetLibrary : MonoBehaviour
protected static AssetLibrary _mainInstance;
public ResourceLocationMap AddressableResourceMap;
public List<Shader> Shaders;
public string LocalFilesPath;
public string LocalFilesPath => ModelViewerSettings.Get("AssetsPath");
private List<string> _addressableKeys;
public Dictionary<string, AssetBundle> LoadedAssets = new Dictionary<string, AssetBundle>();

View File

@@ -7,7 +7,8 @@
"GUID:aee7fa92e14bf364ebccdd24623e1764",
"GUID:ee695b84b4c90104b9367eebc6b0d70d",
"GUID:9e24947de15b9834991c9d8411ea37cf",
"GUID:84651a3751eca9349aac36a66bba901b"
"GUID:84651a3751eca9349aac36a66bba901b",
"GUID:605c065ed537aa34fa525e662cb3d117"
],
"includePlatforms": [],
"excludePlatforms": [],

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using UIPanels;
using UnityEngine;
using UnityEngine.UI;
@@ -15,11 +14,7 @@ public class ModelViewerInterface : MonoBehaviour
public ScrollRect PosePresetToggle;
public ScrollRect SelectedHandlesPanel;
public List<UIToolbarPanel> TopbarPanels;
public UIPanels.UIToolbarPanel TogglesContent;
public UIPanels.UISaveLoadPanel SaveLoadPanel;
public UIPanels.UICameraSettingsPanel CameraSettingsPanel;
public UISaveLoadPanel SaveLoadPanel;
public ProgressBar ProgressBar;
public Canvas MainCanvas;

View File

@@ -41,8 +41,15 @@ public class ModelViewerMain : MonoBehaviour
protected virtual void Awake()
{
ModelViewerSettings.Load();
_backupTimers = _backupTimes.ToArray();
CurrentScene = SceneContainer.Create<SceneContainer>(this);
if(CurrentScene == null)
{
Debug.LogError("Custom model viewer should create a new scene in Awake()");
CurrentScene = SceneContainer.Create<SceneContainer>(this);
}
if (!MainCameraOrbit.Frames.Any())
MainCameraOrbit.SetDefaultFrame();

View File

@@ -0,0 +1,122 @@

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using static ModelViewerSettings;
public class ModelViewerSettings
{
public enum SettingType
{
Text,
FilePath,
FolderPath
}
public class Setting
{
public SettingType Type;
public string Value;
public bool Editable;
public Setting(string value, SettingType type = SettingType.Text, bool editable = true)
{
Value = value;
Editable = editable;
Type = type;
}
}
public static ModelViewerSettings Instance;
public Dictionary<string, Setting> Settings = new Dictionary<string, Setting>();
public static System.Action<ModelViewerSettings> OnSettingsSaved;
public void SetValues(Dictionary<string, Setting> defaultSettings)
{
foreach (var keyvalue in defaultSettings)
{
Set(keyvalue.Key, keyvalue.Value);
}
Save();
}
public static string Get(string key, string defaultValue = "")
{
var settings = Instance;
if (!settings.Settings.ContainsKey(key))
{
settings.Settings[key] = new Setting(defaultValue);
}
return settings.Settings[key].Value;
}
public static string Get(string key, Setting defaultSetting)
{
var settings = Instance;
if (!settings.Settings.ContainsKey(key))
{
settings.Settings[key] = defaultSetting;
}
return settings.Settings[key].Value;
}
public static void Set(string key, Setting setting, bool save = false)
{
Instance.Settings[key] = setting;
if (save) Save();
}
public static void Set(string key, string value, bool save = false)
{
Debug.Log("Updating " + key + " to " + value);
if (Instance.Settings.ContainsKey(key))
{
Instance.Settings[key].Value = value;
}
else
{
Instance.Settings[key] = new Setting(value);
}
if (save) Save();
}
public static void Load()
{
if (Instance != null) return;
var filePath = Application.dataPath + "/../_settings.json";
if(File.Exists(filePath))
{
var settings = File.ReadAllText(filePath);
try
{
Instance = JsonConvert.DeserializeObject<ModelViewerSettings>(settings);
}
catch
{
Instance = new ModelViewerSettings();
}
}
else
{
Instance = new ModelViewerSettings();
Save();
}
}
public static void Save()
{
if(Instance == null)
{
Debug.LogError("Settings have not been initialized!");
return;
}
var filePath = Application.dataPath + "/../_settings.json";
File.WriteAllText(filePath, JsonConvert.SerializeObject(Instance));
OnSettingsSaved?.Invoke(Instance);
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 3825ca5014b129b41995262f1d361a57
guid: 78e36c43349eaa84ebf1e3ae316b57b5
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -14,6 +14,7 @@ public partial class SharedResources : MonoBehaviour
public TimelineFrameContainer TimelineFrame ;
public UIPopupMessage PopupMessage ;
public PopupController HandlePopup ;
public UITextInput UITextInput ;
public SliderPanel SliderPanel ;
public SliderPanel TogglePanel ;
public MorphPanel MorphPanel ;

View File

@@ -1,10 +1,11 @@
using System;
using UnityEngine;
using UnityEngine.UI;
using static SerializableBone;
namespace KF3.UI.Panels
{
public class HandleSettingsPanel : UIPanels.UIToolbarPanel
public class HandleSettingsPanel : MonoBehaviour
{
public ScrollRect HandleVisibilityToggles;

View File

@@ -1,12 +0,0 @@
using UIPanels;
using UnityEngine;
using UnityEngine.UI;
namespace UIPanels
{
public class UICameraSettingsPanel : UIToolbarPanel
{
}
}

View File

@@ -1,4 +1,3 @@
using UIPanels;
using UnityEngine;
using UnityEngine.EventSystems;

View File

@@ -8,113 +8,110 @@ using System.Linq;
using UnityEngine;
using UnityEngine.UI;
namespace UIPanels
public class UISaveLoadPanel : MonoBehaviour
{
public class UISaveLoadPanel : UIToolbarPanel
public ScrollRect ScrollScene;
public ScrollRect ScrollPose;
public Button ButtonScene;
public Button ButtonPose;
public List<UISceneContainer> ScenePresetEntries = new List<UISceneContainer>();
public List<UIPoseContainer> PosePresetEntries = new List<UIPoseContainer>();
public void AddPose(UIPoseContainer pose)
{
public ScrollRect ScrollScene;
public ScrollRect ScrollPose;
PosePresetEntries.Add(pose);
}
public Button ButtonScene;
public Button ButtonPose;
public void AddScene(UISceneContainer scene)
{
ScenePresetEntries.Add(scene);
}
public List<UISceneContainer> ScenePresetEntries = new List<UISceneContainer>();
public List<UIPoseContainer> PosePresetEntries = new List<UIPoseContainer>();
public void OnPoseButton()
{
ButtonScene.interactable = true;
ButtonPose.interactable = false;
ScrollScene.gameObject.SetActive(false);
ScrollPose.gameObject.SetActive(true);
}
public void AddPose(UIPoseContainer pose)
public void OnSceneButton()
{
ButtonScene.interactable = false;
ButtonPose.interactable = true;
ScrollScene.gameObject.SetActive(true);
ScrollPose.gameObject.SetActive(false);
}
public bool GetPoseByName(string name, out UIPoseContainer pose)
{
pose = PosePresetEntries.FirstOrDefault(p => p.PoseName == name);
return pose != null;
}
public bool GetSceneByName(string name, out UISceneContainer scene)
{
scene = ScenePresetEntries.FirstOrDefault(p => p.SceneData.Filename == name);
return scene != null;
}
public void Init()
{
InitPoses();
InitScenes();
}
private void InitPoses()
{
string path = Settings.SavePoseDirectory;
foreach (var fileName in Directory.GetFiles(path).Where(f => f.EndsWith(".pose")))
{
PosePresetEntries.Add(pose);
}
public void AddScene(UISceneContainer scene)
{
ScenePresetEntries.Add(scene);
}
public void OnPoseButton()
{
ButtonScene.interactable = true;
ButtonPose.interactable = false;
ScrollScene.gameObject.SetActive(false);
ScrollPose.gameObject.SetActive(true);
}
public void OnSceneButton()
{
ButtonScene.interactable = false;
ButtonPose.interactable = true;
ScrollScene.gameObject.SetActive(true);
ScrollPose.gameObject.SetActive(false);
}
public bool GetPoseByName(string name, out UIPoseContainer pose)
{
pose = PosePresetEntries.FirstOrDefault(p => p.PoseName == name);
return pose != null;
}
public bool GetSceneByName(string name, out UISceneContainer scene)
{
scene = ScenePresetEntries.FirstOrDefault(p => p.SceneData.Filename == name);
return scene != null;
}
public void Init()
{
InitPoses();
InitScenes();
}
private void InitPoses()
{
string path = Settings.SavePoseDirectory;
foreach (var fileName in Directory.GetFiles(path).Where(f => f.EndsWith(".pose")))
try
{
try
{
string fName = Path.GetFileNameWithoutExtension(fileName);
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto };
var bc = JsonConvert.DeserializeObject<KeyframeData>(File.ReadAllText(fileName), settings);
UIPoseContainer.CreateNew(fName, bc, false);
}
catch (Exception e)
{
Debug.LogWarning(e);
Error.Log(Color.red, "Loading " + fileName + " failed!");
}
string fName = Path.GetFileNameWithoutExtension(fileName);
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto };
var bc = JsonConvert.DeserializeObject<KeyframeData>(File.ReadAllText(fileName), settings);
UIPoseContainer.CreateNew(fName, bc, false);
}
}
private void InitScenes()
{
string path = Settings.SaveSceneDirectory;
List<SceneSerializable> scenes = new List<SceneSerializable>();
foreach (var fileName in Directory.GetFiles(path).Where(f => f.EndsWith(".scene")))
catch (Exception e)
{
try
{
string fName = Path.GetFileNameWithoutExtension(fileName);
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto };
var bc = JsonConvert.DeserializeObject<SceneSerializable>(File.ReadAllText(fileName), settings);
if (string.IsNullOrEmpty(bc.Date))
{
bc.Date = "1990-01-01 00:00";
}
scenes.Add(bc);
}
catch (Exception e)
{
Debug.LogWarning(e);
Error.Log(Color.red, "Loading " + fileName + " failed!");
}
}
foreach(var scene in scenes.OrderBy(s => DateTime.ParseExact(s.Date, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)).ThenBy(s=>s.Filename))
{
UISceneContainer.CreateNew(scene, false);
Debug.LogWarning(e);
Error.Log(Color.red, "Loading " + fileName + " failed!");
}
}
}
private void InitScenes()
{
string path = Settings.SaveSceneDirectory;
List<SceneSerializable> scenes = new List<SceneSerializable>();
foreach (var fileName in Directory.GetFiles(path).Where(f => f.EndsWith(".scene")))
{
try
{
string fName = Path.GetFileNameWithoutExtension(fileName);
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto };
var bc = JsonConvert.DeserializeObject<SceneSerializable>(File.ReadAllText(fileName), settings);
if (string.IsNullOrEmpty(bc.Date))
{
bc.Date = "1990-01-01 00:00";
}
scenes.Add(bc);
}
catch (Exception e)
{
Debug.LogWarning(e);
Error.Log(Color.red, "Loading " + fileName + " failed!");
}
}
foreach (var scene in scenes.OrderBy(s => DateTime.ParseExact(s.Date, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)).ThenBy(s => s.Filename))
{
UISceneContainer.CreateNew(scene, false);
}
}
}

View File

@@ -0,0 +1,43 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UISettingsPanel : MonoBehaviour
{
public Transform Content;
private void Start()
{
ModelViewerSettings.OnSettingsSaved += UpdateSettings;
}
private void OnEnable()
{
if(ModelViewerSettings.Instance != null)
{
UpdateSettings(ModelViewerSettings.Instance);
}
}
public void UpdateSettings(ModelViewerSettings settings)
{
Debug.Log("Updating");
for(int i = Content.childCount -1; i >= 0; i--)
{
Destroy(Content.GetChild(i).gameObject);
}
foreach(var entry in settings.Settings)
{
var setting = entry.Value;
var inputMode = setting.Type == ModelViewerSettings.SettingType.FilePath ? UITextInput.InputMode.FilePicker
: setting.Type == ModelViewerSettings.SettingType.FolderPath ? UITextInput.InputMode.FolderPicker
: UITextInput.InputMode.Text;
UITextInput.Create(entry.Key, setting.Value, setting.Editable, Content, inputMode).SetOnTextChanged((value) =>
{
ModelViewerSettings.Set(entry.Key, value, true);
});
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 075750077de5e3b4088ca0c9f1fdb524
guid: 4220394708fad7d4782a9f356cb06010
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -0,0 +1,67 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class UITextInput : MonoBehaviour
{
public bool Editable => InputField.interactable;
public TMPro.TMP_Text Label;
public TMPro.TMP_InputField InputField;
public InputMode Mode;
public enum InputMode
{
Text,
FilePicker,
FolderPicker
}
public static UITextInput Create(string name, string defaultText, bool editable, Transform parent, InputMode mode = InputMode.Text)
{
var input = Instantiate(SharedResources.Instance.UITextInput, parent);
input.Init(name, defaultText, editable, mode);
return input;
}
public void Init(string name, string defaultText, bool editable, InputMode mode)
{
Mode = mode;
Label.text = name;
InputField.text = defaultText;
InputField.interactable = editable;
switch (mode)
{
case InputMode.FilePicker:
{
InputField.onSelect.AddListener(
(text) =>
{
var result = SFB.StandaloneFileBrowser.OpenFilePanel(name, InputField.text, "", false);
if (result.Length == 0) return;
InputField.text = result[0];
}
);
break;
}
case InputMode.FolderPicker:
{
InputField.onSelect.AddListener(
(text) =>
{
var result = SFB.StandaloneFileBrowser.OpenFolderPanel(name, InputField.text, false);
if (result.Length == 0) return;
InputField.text = result[0] + "//";
}
);
break;
}
}
}
public void SetOnTextChanged(UnityAction<string> action)
{
InputField.onEndEdit.RemoveAllListeners();
InputField.onEndEdit.AddListener(action);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce06bef1f916b3d45882cede8f8b1a07
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,20 +0,0 @@
using UnityEngine;
namespace UIPanels
{
public class UIToolbarPanel : MonoBehaviour
{
public bool IsOpen => gameObject.activeSelf;
public virtual void Open()
{
gameObject.SetActive(true);
}
public virtual void Close()
{
gameObject.SetActive(false);
}
}
}

View File

@@ -6,9 +6,6 @@ using System.Collections;
using CommandUndoRedo;
using System.Linq;
using UnityEngine.EventSystems;
using UnityEditor.PackageManager;
using static UnityEngine.Rendering.VirtualTexturing.Debugging;
using static UnityEngine.GraphicsBuffer;
namespace RuntimeGizmos
{
@@ -411,7 +408,9 @@ namespace RuntimeGizmos
{
if (mainTargetRoot != null)
{
if (nearAxis != Axis.None && Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
bool isModifyingSelection = Input.GetKey(AddSelection) || Input.GetKey(RemoveSelection);
if (nearAxis != Axis.None && !isModifyingSelection && Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
{
StartCoroutine(TransformSelected(translatingType));
}
@@ -701,16 +700,16 @@ namespace RuntimeGizmos
void GetTarget()
{
if (nearAxis == Axis.None && !EventSystem.current.IsPointerOverGameObject())
bool isAdding = Input.GetKey(AddSelection);
bool isRemoving = Input.GetKey(RemoveSelection);
if ((nearAxis == Axis.None || isAdding || isRemoving) && !EventSystem.current.IsPointerOverGameObject())
{
bool leftClick = Input.GetMouseButtonDown(0);
bool rightClick = Input.GetMouseButtonDown(1);
if (!leftClick && !rightClick) return;
bool isAdding = Input.GetKey(AddSelection);
bool isRemoving = Input.GetKey(RemoveSelection);
RaycastHit[] hits = Physics.RaycastAll(myCamera.ScreenPointToRay(Input.mousePosition), Mathf.Infinity, selectionMask);
if (hits.Length > 0)
{