You've already forked UniversalViewer
Eversoul support WIP
Updated line renderer material for handles Handle fixes Fixes
This commit is contained in:
@@ -7,13 +7,24 @@ using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.ResourceManagement.ResourceLocations;
|
||||
using System.IO;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class AssetLibrary : MonoBehaviour
|
||||
{
|
||||
protected static AssetLibrary _mainInstance;
|
||||
public ResourceLocationMap AddressableResourceMap;
|
||||
private List<string> _addressableKeys;
|
||||
public List<Shader> Shaders;
|
||||
public string LocalFilesPath;
|
||||
private List<string> _addressableKeys;
|
||||
|
||||
public Dictionary<string, AssetBundle> LoadedAssets = new Dictionary<string, AssetBundle>();
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_mainInstance = this;
|
||||
}
|
||||
|
||||
public static T GetInstance<T>() where T : AssetLibrary
|
||||
{
|
||||
@@ -48,30 +59,102 @@ public class AssetLibrary : MonoBehaviour
|
||||
{
|
||||
throw opHandle.OperationException;
|
||||
}
|
||||
|
||||
//var keys = AddressableResourceMap.Keys.Where(k=>k.ToString().Contains("chara_100_0001")).ToList();
|
||||
//for (int i = 0; i < keys.Count; i++)
|
||||
//{
|
||||
// Debug.Log(keys[i].ToString());
|
||||
// Debug.Log(JObject.FromObject(AddressableResourceMap.Locations[keys[i]][0]).ToString());
|
||||
// Debug.Log(AddressableResourceMap.Locations[keys[i]][0].Data.GetType());
|
||||
// //switch (AddressableResourceMap.Locations[keys[i]][0])
|
||||
// //{
|
||||
// // case CompactLocation cl:
|
||||
// // break;
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
|
||||
public string GetResourcePath(string resourceName)
|
||||
public string GetResourcePath(string resourceName, out List<string> dependencies)
|
||||
{
|
||||
dependencies = new List<string>();
|
||||
var locator = AddressableResourceMap.Locations[resourceName][0]; // AddressableResourceMap.Locations[resourceName][0].Dependencies[0].Data as AssetBundleRequestOptions;
|
||||
if (locator.HasDependencies)
|
||||
{
|
||||
return "";
|
||||
GatherDependencies(locator, dependencies);
|
||||
var data = locator.Dependencies[0].Data as AssetBundleRequestOptions;
|
||||
var filePath = data.BundleName + "/" + data.Hash + "/" + "__data";
|
||||
dependencies.Remove(filePath);
|
||||
return filePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = locator.Data as AssetBundleRequestOptions;
|
||||
var filePath = data.BundleName + "/" + data.Hash + "/" + "__data";
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
|
||||
private void GatherDependencies(IResourceLocation resource, List<string> dependencies)
|
||||
{
|
||||
if (!resource.HasDependencies)
|
||||
{
|
||||
var data = resource.Data as AssetBundleRequestOptions;
|
||||
var filePath = data.BundleName + "/" + data.Hash + "/" + "__data";
|
||||
if (!dependencies.Contains(filePath))
|
||||
{
|
||||
dependencies.Add(filePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dep in resource.Dependencies)
|
||||
{
|
||||
GatherDependencies(dep, dependencies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator LoadAssets(List<string> paths)
|
||||
{
|
||||
var progressBar = ModelViewerInterface.GetInstance().ProgressBar;
|
||||
|
||||
for (int i = paths.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!File.Exists(paths[i]))
|
||||
{
|
||||
paths.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
List<AssetBundleCreateRequest> routines = new List<AssetBundleCreateRequest>();
|
||||
foreach(var path in paths)
|
||||
{
|
||||
routines.Add(AssetBundle.LoadFromFileAsync(path));
|
||||
}
|
||||
|
||||
while (routines.Any(r => !r.isDone))
|
||||
{
|
||||
int finished = routines.Count(r => r.isDone);
|
||||
progressBar?.SetProgress($"Reading files ({finished}/{routines.Count})", (float)finished / routines.Count);
|
||||
yield return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < routines.Count; i++)
|
||||
{
|
||||
LoadedAssets.Add(paths[i], routines[i].assetBundle);
|
||||
}
|
||||
|
||||
progressBar?.SetProgress("", 1);
|
||||
}
|
||||
|
||||
public static AssetBundle LoadFromFile(string path)
|
||||
{
|
||||
var bundle = AssetBundle.LoadFromFile(path);
|
||||
_mainInstance.LoadedAssets.Add(path, bundle);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public void UnloadAssets(List<string> paths)
|
||||
{
|
||||
for (int i = 0; i < paths.Count; i++)
|
||||
{
|
||||
UnloadAsset(paths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnloadAsset(string path)
|
||||
{
|
||||
if (LoadedAssets.ContainsKey(path))
|
||||
{
|
||||
LoadedAssets[path].Unload(false);
|
||||
LoadedAssets.Remove(path);
|
||||
}
|
||||
var data = locator.Data as AssetBundleRequestOptions;
|
||||
var filePath = data.BundleName + "/" + data.Hash + "/" + "__data";
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,5 @@
|
||||
{
|
||||
public AssetTypes AssetType;
|
||||
public string FilePath;
|
||||
public string ResourceName;
|
||||
}
|
||||
|
||||
@@ -134,4 +134,11 @@ public class CameraContainer: ObjectContainer
|
||||
|
||||
Camera.UpdateImmediate();
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
//Do not destroy cameras
|
||||
Frames.Clear();
|
||||
SetDefaultFrame();
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ public class ObjectContainer : MonoBehaviour, IKeyframeSetter
|
||||
{
|
||||
SetKeyframe();
|
||||
}
|
||||
|
||||
ModelViewerMain.RegisterObject(this);
|
||||
}
|
||||
|
||||
public virtual void PasteContainer(ObjectContainerSerializable bones, PoseLoadOptions pasteParams)
|
||||
@@ -92,6 +94,7 @@ public class ObjectContainer : MonoBehaviour, IKeyframeSetter
|
||||
ModelViewerMain.UnregisterObject(this);
|
||||
if (gameObject != null)
|
||||
Destroy(gameObject);
|
||||
ModelViewerMain.OnObjectDeleteEvent.Invoke(this);
|
||||
Resources.UnloadUnusedAssets();
|
||||
System.GC.Collect();
|
||||
}
|
||||
@@ -234,7 +237,7 @@ public class ObjectContainer : MonoBehaviour, IKeyframeSetter
|
||||
throw new NotImplementedException(this.GetType().FullName);
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
public virtual void Destroy()
|
||||
{
|
||||
Destroy(this.gameObject);
|
||||
}
|
||||
|
||||
@@ -34,4 +34,16 @@ public class SceneContainer : ObjectContainer
|
||||
{
|
||||
return new SceneSerializable(this);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
if (_applicationQuitting) return;
|
||||
|
||||
for (int i = AllObjects.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var obj = AllObjects[i];
|
||||
if (obj == this) continue;
|
||||
obj.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,11 @@ public class ModelBuilder : MonoBehaviour
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_mainInstance = this;
|
||||
}
|
||||
|
||||
public virtual IEnumerator SpawnSerialized(ObjectContainerSerializable oc, Action<GameObject> callback = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using UIPanels;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
public class ModelViewerInterface : MonoBehaviour
|
||||
{
|
||||
@@ -14,12 +13,14 @@ public class ModelViewerInterface : MonoBehaviour
|
||||
|
||||
public ScrollRect ScenePresetToggle;
|
||||
public ScrollRect PosePresetToggle;
|
||||
public ScrollRect SelectedHandlesPanel;
|
||||
|
||||
public List<UIToolbarPanel> TopbarPanels;
|
||||
|
||||
public UIPanels.UIToolbarPanel TogglesContent;
|
||||
public UIPanels.UISaveLoadPanel SaveLoadPanel;
|
||||
public UIPanels.UICameraSettingsPanel CameraSettingsPanel;
|
||||
public ProgressBar ProgressBar;
|
||||
|
||||
public Canvas MainCanvas;
|
||||
|
||||
@@ -39,6 +40,10 @@ public class ModelViewerInterface : MonoBehaviour
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_mainInstance = this;
|
||||
}
|
||||
|
||||
protected void Update()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,8 @@ using System;
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.Events;
|
||||
|
||||
public class ModelViewerMain : MonoBehaviour
|
||||
{
|
||||
@@ -16,6 +18,7 @@ public class ModelViewerMain : MonoBehaviour
|
||||
public SceneContainer CurrentScene;
|
||||
public ObjectContainer SelectedObject;
|
||||
public List<ObjectContainer> SelectedObjects = new List<ObjectContainer>();
|
||||
public static UnityEvent<ObjectContainer> OnObjectDeleteEvent = new UnityEvent<ObjectContainer>();
|
||||
|
||||
protected float[] _backupTimes = new float[] { 15 * 60, 5 * 60, 60 };
|
||||
protected float[] _backupTimers;
|
||||
@@ -36,6 +39,17 @@ public class ModelViewerMain : MonoBehaviour
|
||||
return _mainInstance as T;
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_backupTimers = _backupTimes.ToArray();
|
||||
CurrentScene = SceneContainer.Create<SceneContainer>(this);
|
||||
|
||||
if (!MainCameraOrbit.Frames.Any())
|
||||
MainCameraOrbit.SetDefaultFrame();
|
||||
|
||||
_mainInstance = this;
|
||||
}
|
||||
|
||||
public CameraOrbit GetCamera()
|
||||
{
|
||||
return CurrentScene.MainCameraOrbit.Camera;
|
||||
@@ -74,23 +88,21 @@ public class ModelViewerMain : MonoBehaviour
|
||||
{
|
||||
if (SelectedObject == container) return;
|
||||
|
||||
Debug.Log(SelectedObject);
|
||||
|
||||
if(Mode == OperationMode.Single)
|
||||
{
|
||||
SelectedObject?.Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedObject?.Deselect();
|
||||
}
|
||||
|
||||
SelectedObject?.Deselect();
|
||||
SelectedObject = container;
|
||||
SelectedObject?.Select();
|
||||
|
||||
TimelineController.UpdateTimeline();
|
||||
}
|
||||
|
||||
public void PrepareForLoad()
|
||||
{
|
||||
if (Mode == OperationMode.Single)
|
||||
{
|
||||
EmptyScene<SceneContainer>();
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectionAdd(ObjectContainer container)
|
||||
{
|
||||
if (container == null) return;
|
||||
@@ -136,7 +148,7 @@ public class ModelViewerMain : MonoBehaviour
|
||||
|
||||
public void EmptyScene<T>() where T : SceneContainer
|
||||
{
|
||||
DestroyImmediate(CurrentScene);
|
||||
CurrentScene.Destroy();
|
||||
CurrentScene = SceneContainer.Create<T>(this);
|
||||
|
||||
ModelViewerMain.GetInstance().SelectionClear();
|
||||
|
||||
@@ -80,7 +80,7 @@ public class UIHandle : MonoBehaviour
|
||||
|
||||
if (Collider.transform.localScale.x != 0 && transform.lossyScale.x != 0)
|
||||
{
|
||||
Collider.radius = 35 /* magic number */ * (1 / transform.lossyScale.x) * GetRadiusOnScreen(camera, Collider.transform.position, Handle.transform.localScale.x);
|
||||
Collider.radius = Mathf.Abs(35 /* magic number */ * (1 / transform.lossyScale.x) * GetRadiusOnScreen(camera, Collider.transform.position, Handle.transform.localScale.x));
|
||||
Collider.radius = Mathf.Clamp(Collider.radius, 0.001f, 2);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public class UIHandle : MonoBehaviour
|
||||
/// <summary> For future, `offset` param will allow popups to be spaced out when selecting more than 1 handle at a time. </summary>
|
||||
public void TogglePopup(int offset = 0)
|
||||
{
|
||||
Popup.Offset = offset * Popup.GetComponent<RectTransform>().sizeDelta.x;
|
||||
Popup.Offset = offset * (Popup.transform as RectTransform).sizeDelta.x * ModelViewerInterface.GetInstance().MainCanvas.scaleFactor;
|
||||
ModelViewerInterface.ToggleVisible(Popup.gameObject);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class UIHandleMain : UIHandle
|
||||
@@ -17,9 +18,26 @@ public class UIHandleMain : UIHandle
|
||||
Popup.AddButton("Reset Position", TransformResetPosition);
|
||||
Popup.AddButton("Reset Rotation", TransformResetRotation);
|
||||
Popup.AddButton("Reset Scale", TransformResetScale);
|
||||
Popup.AddButton("Reset Children", ResetBones);
|
||||
Popup.AddButton("Delete", () => Destroy(Owner));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ResetBones()
|
||||
{
|
||||
using (var context = new KeyframeToggleContext(Owner, false))
|
||||
{
|
||||
foreach (var bone in Owner.GetComponentsInChildren<UIHandle>())
|
||||
{
|
||||
bone.TransformResetAll();
|
||||
}
|
||||
}
|
||||
Owner.SetKeyframe();
|
||||
}
|
||||
|
||||
protected override bool ShouldBeHidden()
|
||||
{
|
||||
return _forceDisplayOff || !HandleManager.Instance.EnabledHandles.Contains(SerializableBone.BoneTags.Root);
|
||||
}
|
||||
}
|
||||
|
||||
32
Assets/Scripts/ModelViewerBase/UI/ProgressBar.cs
Normal file
32
Assets/Scripts/ModelViewerBase/UI/ProgressBar.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ProgressBar : MonoBehaviour
|
||||
{
|
||||
public TMPro.TMP_Text Label;
|
||||
public Slider Progress;
|
||||
|
||||
public void SetProgress(string task, float progress)
|
||||
{
|
||||
bool active = gameObject.activeSelf;
|
||||
|
||||
if(progress == 0 || progress == 1)
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!active)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
Label.text = task;
|
||||
Progress.value = progress;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/ModelViewerBase/UI/ProgressBar.cs.meta
Normal file
11
Assets/Scripts/ModelViewerBase/UI/ProgressBar.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f95da0c1d0b9a5042a41865b5d0b3e60
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -102,7 +102,8 @@ public class UIElementDragger : MonoBehaviour, IDragHandler, IEndDragHandler, IP
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
var rectTsf = GetComponent<RectTransform>();
|
||||
var rectTsf = transform as RectTransform;
|
||||
var canvas = ModelViewerInterface.GetInstance().MainCanvas;
|
||||
|
||||
switch (LastDragAction)
|
||||
{
|
||||
@@ -116,9 +117,9 @@ public class UIElementDragger : MonoBehaviour, IDragHandler, IEndDragHandler, IP
|
||||
{
|
||||
var mousePos = (Vector2)Input.mousePosition;
|
||||
mousePos.y = -(Screen.height - mousePos.y); //convert anchor from bottom-left to top-left
|
||||
var sizeDelta = mousePos - rectTsf.anchoredPosition;
|
||||
sizeDelta.x = Mathf.Clamp(sizeDelta.x, SizeMin.x, Mathf.Min(Screen.width, SizeMax.x));
|
||||
sizeDelta.y = Mathf.Clamp(-sizeDelta.y, SizeMin.y, Mathf.Min(Screen.height, SizeMax.y));
|
||||
var sizeDelta = mousePos / canvas.scaleFactor - (Vector2)rectTsf.anchoredPosition;
|
||||
sizeDelta.x = Mathf.Clamp(sizeDelta.x, SizeMin.x, Mathf.Min(Screen.width / canvas.scaleFactor, SizeMax.x));
|
||||
sizeDelta.y = Mathf.Clamp(-sizeDelta.y, SizeMin.y, Mathf.Min(Screen.height / canvas.scaleFactor, SizeMax.y));
|
||||
if (currentScale > 0)
|
||||
{
|
||||
sizeDelta *= currentScale;
|
||||
|
||||
Reference in New Issue
Block a user