Initial files

This commit is contained in:
2024-04-21 16:38:26 +02:00
parent c69c668ae6
commit cf04700131
554 changed files with 131197 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
public class ExtendedDropdown : MonoBehaviour
{
public bool LoopAround;
[SerializeField] private TMPro.TMP_Dropdown _dropdown;
public UnityEvent<int> OnValueChangedEvent;
public List<TMPro.TMP_Dropdown.OptionData> options => _dropdown.options;
public KeyCode PreviousKey = KeyCode.None;
public KeyCode NextKey = KeyCode.None;
private void Update()
{
if(Input.GetKeyDown(PreviousKey))
{
DropdownPrevious();
}
if (Input.GetKeyDown(NextKey))
{
DropdownNext();
}
}
public void OnValueChanged(int index)
{
OnValueChangedEvent.Invoke(index);
}
public void SetValueWithoutNotify(string value)
{
var option = options.FindIndex(v => v.text == value);
SetValueWithoutNotify(option);
}
public void SetValueWithoutNotify(int value)
{
_dropdown.SetValueWithoutNotify(value);
}
public void DropdownPrevious()
{
if (LoopAround)
{
_dropdown.value = _dropdown.value - 1 < 0 ? _dropdown.options.Count - 1 : _dropdown.value - 1;
}
else
{
_dropdown.value = Mathf.Clamp(_dropdown.value - 1, 0, _dropdown.options.Count - 1);
}
}
public void DropdownNext()
{
if (LoopAround)
{
_dropdown.value = _dropdown.value + 1 >= _dropdown.options.Count ? 0 : _dropdown.value + 1;
}
else
{
_dropdown.value = Mathf.Clamp(_dropdown.value + 1, 0, _dropdown.options.Count - 1);
}
}
public void SetOptions(List<string> values, bool nullValue = false, bool sortValues = false)
{
var dd = _dropdown;
dd.ClearOptions();
if (nullValue)
dd.AddOptions(new List<string>() { Strings.NoValueSelectedString });
if (values != null)
{
if (sortValues)
{
values = new List<string>(values);
values.Sort();
}
dd.AddOptions(values);
}
}
}

View File

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

View File

@@ -0,0 +1,35 @@
[System.Serializable]
public class FrameContent
{
public int FrameNum;
public KeyframeData ObjectData;
#if UNITY_EDITOR
//public KeyframeDataCharacter AsCharacter;
//public KeyframeDataCamera AsCamera;
//public KeyframeDataScene AsScene;
#endif
public FrameContent() { }
public FrameContent(int frameNum)
{
FrameNum = frameNum;
}
public FrameContent(FrameContent frame)
{
FrameNum = frame.FrameNum;
ObjectData = frame.ObjectData.Clone();
}
public FrameContent SetObjectData(KeyframeData data)
{
ObjectData = data;
#if UNITY_EDITOR
//AsCharacter = ObjectData as KeyframeDataCharacter;
//AsCamera = ObjectData as KeyframeDataCamera;
//AsScene = ObjectData as KeyframeDataScene;
#endif
return this;
}
}

View File

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

View File

@@ -0,0 +1,30 @@
using System;
using UnityEngine.UI;
using static SerializableBone;
namespace KF3.UI.Panels
{
public class HandleSettingsPanel : UIPanels.UIToolbarPanel
{
public ScrollRect HandleVisibilityToggles;
private void Start()
{
var handleManager = HandleManager.Instance;
foreach (BoneTags en in Enum.GetValues(typeof(BoneTags)))
{
var handle = SliderPanel.CreateToggle(en.ToString(), handleManager.EnabledHandles.Contains(en), HandleVisibilityToggles.content, (value)=>
{
if (value)
{
handleManager.EnabledHandles.Add(en);
}
else
{
handleManager.EnabledHandles.Remove(en);
}
});
}
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8b6140bc0ba26f246b92786a4448449d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,105 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using static SerializableBone;
public class HandleManager : MonoBehaviour
{
public static HandleManager Instance;
public GameObject HandlesPanel;
public GameObject Pfb_HandleDisplay;
public UIPopupPanel Pfb_Popup;
public Button Pfb_PopupButton;
public Material LineRendererMaterial;
public List<BoneTags> EnabledHandles = new List<BoneTags>() { BoneTags.Humanoid };
public bool EnabledLines = true;
public static bool InteractionInProgress;
private List<UIHandle> AllHandles = new List<UIHandle>();
public static System.Action<HandleUndoData> RegisterRuntimeGizmoUndoAction;
public static System.Action<List<HandleUndoData>> RegisterRuntimeGizmoUndoActions;
private void Awake()
{
Instance = this;
}
private void Update()
{
var camera = Camera.main;
//var poseModeOn = UmaViewerUI.Instance.PoseManager.PoseModeOn;
foreach (var handle in AllHandles)
{
//handle.ForceDisplayOff(!poseModeOn);
handle.UpdateManual(camera, EnabledLines);
if (handle.Popup.gameObject.activeInHierarchy)
{
handle.Popup.UpdateManual(camera);
}
}
}
public static void RegisterHandle(UIHandle handle)
{
var hm = HandleManager.Instance;
if (hm.AllHandles.Contains(handle))
{
return;
}
hm.AllHandles.Add(handle);
}
public static void UnregisterHandle(UIHandle handle)
{
var hm = HandleManager.Instance;
if (!hm.AllHandles.Contains(handle))
{
return;
}
hm.AllHandles.Remove(handle);
}
public static void CloseAllPopups()
{
var hm = HandleManager.Instance;
foreach(var handle in hm.AllHandles)
{
if (handle.Popup.gameObject.activeInHierarchy)
{
handle.TogglePopup();
}
}
}
/// <summary> Used on UI buttons </summary>
public void ToggleBonesVisible(string tag)
{
var enumTag = (BoneTags)System.Enum.Parse(typeof(BoneTags), tag);
if (EnabledHandles.Contains(enumTag))
{
EnabledHandles.Remove(enumTag);
}
else
{
EnabledHandles.Add(enumTag);
}
}
/// <summary> Used on UI buttons </summary>
public void ToggleLinesVisible(bool value)
{
EnabledLines = value;
}
}

View File

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

View File

@@ -0,0 +1,277 @@
using UnityEngine;
using UnityEngine.UI;
public class UIHandle : MonoBehaviour
{
/// <summary> Object that "owns" the handle </summary>
public ObjectContainer Owner;
/// <summary> Object that the handle refers to. Cast in inheriting class </summary>
public Transform Target;
/// <summary> Display object on the UI </summary>
public GameObject Handle;
/// <summary> Collider for selecting the handle on UI </summary>
public SphereCollider Collider;
/// <summary> Object that appears when right-clicking the handle </summary>
public UIPopupPanel Popup;
public LineRenderer LineRenderer;
protected SerializableTransform _defaultTransform;
protected float _baseScale = 1;
protected bool _forceDisplayOff = false;
protected ModelViewerMain Main => ModelViewerMain.GetInstance();
public static T CreateAsChild<T>(Transform parent) where T : UIHandle
{
var handle = new GameObject(parent.name + "_Handle").AddComponent<T>();
handle.transform.parent = parent.transform;
handle.transform.localPosition = Vector3.zero;
handle.transform.localScale = Vector3.one;
handle.transform.rotation = parent.rotation;
handle.Target = parent.transform;
return handle;
}
public virtual UIHandle Init(ObjectContainer owner, Transform target)
{
Target = target;
return Init(owner);
}
public virtual UIHandle Init(ObjectContainer owner)
{
HandleManager.RegisterHandle(this);
gameObject.layer = LayerMask.NameToLayer("UIHandle");
Target = Target == null? owner.transform : Target;
Owner = owner;
Owner.Handles.Add(this);
Handle = Instantiate(HandleManager.Instance.Pfb_HandleDisplay, HandleManager.Instance.HandlesPanel.transform);
Handle.transform.SetAsFirstSibling();
Popup = Instantiate(HandleManager.Instance.Pfb_Popup, HandleManager.Instance.HandlesPanel.transform).Init(this);
Popup.gameObject.SetActive(false);
_defaultTransform = new SerializableTransform(Target, Space.Self);
var collider = gameObject.AddComponent<SphereCollider>();
collider.center = Vector3.zero;
Collider = collider;
return this;
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position + Collider.center, transform.lossyScale.x * Collider.radius);
}
public virtual void UpdateManual(Camera camera, bool linesEnabled)
{
if (Handle != null && camera != null && transform != null)
{
Handle.transform.localScale = Vector3.one * Mathf.Clamp(_baseScale / Vector3.Distance(camera.transform.position, transform.position), 0.1f, 1);
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.Clamp(Collider.radius, 0.001f, 2);
}
Handle.transform.position = camera.WorldToScreenPoint(Collider.transform.TransformPoint(Collider.center));
if (ShouldBeHidden())
{
if (Handle.activeSelf == true)
{
ToggleActive(false);
}
}
else
{
bool isOnScreen =
!(Handle.transform.position.x < 0 || Handle.transform.position.y < 0 || Handle.transform.position.z < 0
|| Handle.transform.position.x > Screen.width || Handle.transform.position.y > Screen.height);
if (Handle.activeSelf != isOnScreen)
{
ToggleActive(!Handle.activeSelf);
}
}
}
if(Handle.activeSelf && LineRenderer != null)
{
if (LineRenderer.enabled != linesEnabled)
{
LineRenderer.enabled = linesEnabled;
}
if (linesEnabled)
{
LineRenderer.SetPositions(new Vector3[] { (Target).position, (Target).parent.position });
}
}
}
protected virtual bool ShouldBeHidden()
{
return _forceDisplayOff;
}
/// <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;
ModelViewerInterface.ToggleVisible(Popup.gameObject);
}
public UIHandle SetDefaults(Vector3 localPos, Vector3 localRot, Vector3 localScale)
{
_defaultTransform.Position = localPos;
_defaultTransform.Rotation = localRot;
_defaultTransform.Scale = localScale;
return this;
}
public UIHandle SetColor(Color color)
{
color.a = Handle.GetComponent<Image>().color.a;
Handle.GetComponent<Image>().color = color;
return this;
}
public UIHandle SetScale(float scale)
{
this._baseScale = scale;
return this;
}
public UIHandle SetName(string name)
{
Handle.gameObject.name = name;
Popup.NameLabel.text = name;
return this;
}
public UIHandle SetOffset(Vector3 offset)
{
Collider.center = offset;
return this;
}
public UIHandle SetContainer(ObjectContainer container)
{
Owner = container;
return this;
}
public float GetRadiusOnScreen(Camera cam, Vector3 position, float screenSize)
{
Vector3 a = cam.WorldToScreenPoint(position);
Vector3 b = new Vector3(a.x, a.y + screenSize, a.z);
Vector3 aa = cam.ScreenToWorldPoint(a);
Vector3 bb = cam.ScreenToWorldPoint(b);
return (aa - bb).magnitude;
}
public UIHandle WithLineRenderer()
{
LineRenderer = Handle.gameObject.AddComponent<LineRenderer>();
LineRenderer.positionCount = 2;
LineRenderer.startWidth = LineRenderer.endWidth = 0.005f;
LineRenderer.material = HandleManager.Instance.LineRendererMaterial;
LineRenderer.startColor = LineRenderer.endColor = Handle.GetComponent<Image>().color;
return this;
}
private void OnDestroy()
{
if (Popup)
{
Destroy(Popup.gameObject);
}
if (Handle)
{
Destroy(Handle);
}
HandleManager.UnregisterHandle(this);
}
private void TransformReset(PoseLoadOptions options = null)
{
if(options == null)
{
options = PoseLoadOptions.All();
}
_defaultTransform.ApplyTo(Target, options);
}
public void TransformResetAll()
{
var HandleUndoData = new HandleUndoData(this);
HandleUndoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset();
HandleUndoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(HandleUndoData);
Owner.SetKeyframe();
}
public void TransformResetPosition()
{
var HandleUndoData = new HandleUndoData(this);
HandleUndoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset(new PoseLoadOptions(false) { Position = true });
HandleUndoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(HandleUndoData);
Owner.SetKeyframe();
}
public void TransformResetRotation()
{
var HandleUndoData = new HandleUndoData(this);
HandleUndoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset(new PoseLoadOptions(false) { Rotation = true });
HandleUndoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(HandleUndoData);
Owner.SetKeyframe();
}
public void TransformResetScale()
{
var HandleUndoData = new HandleUndoData(this);
HandleUndoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset(new PoseLoadOptions(false) { Scale = true });
HandleUndoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(HandleUndoData);
Owner.SetKeyframe();
}
public void ToggleActive(bool value)
{
Handle.SetActive(value);
Collider.enabled = value;
Popup.gameObject.SetActive(false);
}
public void ForceDisplayOff(bool value)
{
_forceDisplayOff = value;
}
}

View File

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

View File

@@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static SerializableBone;
public class UIHandleBone : UIHandle
{
public Transform Bone => Target;
public List<BoneTags> Tags;
public static UIHandleBone CreateAsChild(ObjectContainer owner, Transform parent, List<BoneTags> boneTags)
{
var handle = CreateAsChild<UIHandleBone>(parent);
handle.Init(owner, boneTags);
return handle;
}
public override UIHandle Init(ObjectContainer owner)
{
throw new System.Exception("Use ObjectContainer, List<BoneTags> constructor!");
}
public UIHandleBone Init(ObjectContainer owner, List<BoneTags> boneTags)
{
if (boneTags == null || !boneTags.Any())
{
boneTags = new List<BoneTags>() { BoneTags.Untagged };
}
Tags = boneTags.ToList();
base.Init(owner);
SetScale(0.5f);
if (Tags.Contains(BoneTags.Left)) SetColor(Color.green);
else if (Tags.Contains(BoneTags.Right)) SetColor(Color.blue);
else SetColor(Color.white);
Popup.AddButton("Reset All", TransformResetAll);
Popup.AddButton("Reset Position", TransformResetPosition);
Popup.AddButton("Reset Rotation", TransformResetRotation);
Popup.AddButton("Reset Scale", TransformResetScale);
return this;
}
protected override bool ShouldBeHidden()
{
return _forceDisplayOff || !HandleManager.Instance.EnabledHandles.Intersect(Tags).Any();
}
}

View File

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

View File

@@ -0,0 +1,50 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class UIHandleIK : UIHandle
{
public List<UIHandle> HiddenHandles = new List<UIHandle>();
public static Transform CreateTransform(string handleName, Transform parent, Vector3 position)
{
var go = new GameObject(handleName);
go.transform.SetParent(parent);
go.transform.position = position;
return go.transform;
}
public static Transform CreateTransform(string handleName, Transform parent, Vector3 position, Vector3 eulerAngles)
{
var go = CreateTransform(handleName, parent, position);
go.eulerAngles = eulerAngles;
return go;
}
public static UIHandleIK CreateAsChild(ObjectContainer owner, Transform parent, Color color, string name, float scale)
{
var handle = CreateAsChild<UIHandleIK>(parent);
handle.Init(owner).SetName(name).SetColor(color).SetScale(scale);
return handle;
}
public override UIHandle Init(ObjectContainer owner)
{
base.Init(owner);
Popup.AddButton("Reset Position", () => TransformResetPosition());
Popup.AddButton("Reset Rotation", () => TransformResetRotation());
Popup.AddButton("Toggle Helper Lines", () =>
{
foreach (var c in owner.GetComponents<InverseKinematics>())
{
c.forceLinesInvisible = !c.forceLinesInvisible;
}
});
return this;
}
protected override bool ShouldBeHidden()
{
return _forceDisplayOff || !HandleManager.Instance.EnabledHandles.Contains(SerializableBone.BoneTags.IK);
}
}

View File

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

View File

@@ -0,0 +1,25 @@
using UnityEngine;
public class UIHandleMain : UIHandle
{
public static UIHandleMain CreateAsChild(ObjectContainer owner)
{
var handle = CreateAsChild<UIHandleMain>(owner.transform);
handle.Init(owner).SetColor(Color.yellow).SetScale(1.5f);
return handle;
}
public override UIHandle Init(ObjectContainer owner)
{
base.Init(owner);
Popup.AddButton("Reset All", TransformResetAll);
Popup.AddButton("Reset Position", TransformResetPosition);
Popup.AddButton("Reset Rotation", TransformResetRotation);
Popup.AddButton("Reset Scale", TransformResetScale);
Popup.AddButton("Delete", () => Destroy(Owner));
return this;
}
}

View File

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

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static SerializableBone;
public class UIHandlePhysicsBone : UIHandleBone
{
new public static UIHandlePhysicsBone CreateAsChild(ObjectContainer owner, Transform parent, List<BoneTags> boneTags)
{
var handle = CreateAsChild<UIHandlePhysicsBone>(parent);
handle.Init(owner, boneTags).SetScale(0.5f);
return handle;
}
}

View File

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

View File

@@ -0,0 +1,23 @@
using UnityEngine;
public class UIHandleProp : UIHandle
{
public static UIHandleProp CreateAsChild(ObjectContainer owner, Transform parent)
{
var handle = CreateAsChild<UIHandleProp>(parent);
handle.Init(owner).SetScale(0.65f);
return handle;
}
public override UIHandle Init(ObjectContainer owner)
{
base.Init(owner);
Popup.AddButton("Reset All", TransformResetAll);
Popup.AddButton("Reset Position", TransformResetPosition);
Popup.AddButton("Reset Rotation", TransformResetRotation);
Popup.AddButton("Reset Scale", TransformResetScale);
return this;
}
}

View File

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

View File

@@ -0,0 +1,57 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIPopupPanel : MonoBehaviour
{
public UIHandle Owner;
public float Offset;
public Transform Content;
public TMPro.TMP_Text NameLabel;
public Dictionary<GameObject, System.Func<bool>> ConditionalButtons = new Dictionary<GameObject, System.Func<bool>>();
private int _side;
public UIPopupPanel Init(UIHandle owner)
{
Owner = owner;
transform.SetAsFirstSibling();
NameLabel.text = owner.Target.name;
return this;
}
public void UpdateManual(Camera camera)
{
if (camera.WorldToScreenPoint(Owner.transform.position).x < camera.pixelWidth / 2 - _side)
{
_side = -1;
}
else
{
_side = 1;
}
float pos = _side * camera.pixelWidth / 20 + Offset;
transform.position = camera.WorldToScreenPoint(Owner.transform.position) + pos * Vector3.right;
foreach (var kv in ConditionalButtons)
{
kv.Key.gameObject.SetActive(kv.Value.Invoke());
}
}
public void AddButton(string name, System.Action callback)
{
Button b = Instantiate(HandleManager.Instance.Pfb_PopupButton, Content).GetComponent<Button>();
b.onClick.AddListener(()=>callback.Invoke());
b.GetComponentInChildren<TMPro.TMP_Text>().text = name;
}
public void AddConditionalButton(string name, System.Func<bool> condition, System.Action callback)
{
Button b = Instantiate(HandleManager.Instance.Pfb_PopupButton, Content).GetComponent<Button>();
b.onClick.AddListener(() => callback.Invoke());
b.GetComponentInChildren<TMPro.TMP_Text>().text = name;
ConditionalButtons.Add(b.gameObject, condition);
}
}

View File

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

View File

@@ -0,0 +1,52 @@
using System;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.UI;
[Serializable]
public class MorphHelper
{
public string Name;
[DefaultValue("")]
public string ParentName;
public float Strength;
public bool Value;
[NonSerialized]
public SkinnedMeshRenderer Renderer;
[NonSerialized]
public Slider Slider;
public MorphHelper() { }
public MorphHelper(SkinnedMeshRenderer parent, string name, Slider slider = null)
{
this.ParentName = parent.name;
this.Name = name;
this.Renderer = parent;
this.Slider = slider;
}
/// <summary> Used for serialization! </summary>
public MorphHelper(string parent, string name, float strength, bool value, Slider slider = null)
{
this.ParentName = parent;
this.Name = name;
this.Strength = strength;
this.Value = value;
this.Slider = slider;
}
public void SetSlider(Slider slider)
{
this.Slider = slider;
}
public void UpdateMorph(float value)
{
var id = Renderer.sharedMesh.GetBlendShapeIndex(Name);
Renderer.SetBlendShapeWeight(id, value);
Strength = value;
if (Slider)
Slider.SetValueWithoutNotify(value);
}
}

View File

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

View File

@@ -0,0 +1,32 @@
using UnityEngine;
using System.Collections.Generic;
public class MorphPanel : MonoBehaviour
{
[SerializeField] private MorphPanelCategory _morphPanelCategoryPfb;
[SerializeField] private Transform _categoryPanels;
public Dictionary<string, MorphPanelCategory> Categories = new Dictionary<string, MorphPanelCategory>();
public static MorphPanel Create(List<string> categories)
{
var panel = Instantiate(SharedResources.Instance.MorphPanel, ModelViewerInterface.GetInstance().DynamicPanels.transform);
panel.Init(categories);
return panel;
}
public void Init(List<string> categories)
{
Categories.Clear();
foreach (var category in categories)
{
var categoryPanel = Instantiate(_morphPanelCategoryPfb, _categoryPanels);
categoryPanel.Label.text = category;
Categories[category] = categoryPanel;
}
}
public void CreateMorph(string category, ObjectContainer container, SkinnedMeshRenderer meshRenderer, int index, string displayName)
{
SliderPanel.CreateMorph(container, meshRenderer, index, displayName, this.Categories[category].Content);
}
}

View File

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

View File

@@ -0,0 +1,9 @@
using UnityEngine;
using UnityEngine.UI;
public class MorphPanelCategory : MonoBehaviour
{
public TMPro.TMP_Text Label;
public Transform Content => _scrollRect.content;
[SerializeField] ScrollRect _scrollRect;
}

View File

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

View File

@@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class PopupController : MonoBehaviour
{
public Transform PopupPanel;
public float offset;
public int side;
public UIHandle Owner;
GameObject ButtonPrefab;
public Dictionary<GameObject, System.Func<bool>> ConditionalButtons = new Dictionary<GameObject, System.Func<bool>>();
public void AddButton(string name, System.Action callback)
{
Button b = Instantiate(ButtonPrefab, PopupPanel).GetComponent<Button>();
b.onClick.AddListener(()=>callback.Invoke());
b.GetComponentInChildren<Text>().text = name;
}
public void AddConditionalButton(string name, System.Func<bool> condition, System.Action callback)
{
Button b = Instantiate(ButtonPrefab, PopupPanel).GetComponent<Button>();
b.onClick.AddListener(() => callback.Invoke());
b.GetComponentInChildren<Text>().text = name;
ConditionalButtons.Add(b.gameObject, condition);
}
private void Update()
{
float pos;
if(Camera.main.WorldToScreenPoint(Owner.transform.position).x < Camera.main.pixelWidth / 2 - side)
{
side = -1;
}
else
{
side = 1;
}
pos = side * Camera.main.pixelWidth / 20 + offset;
transform.position = Camera.main.WorldToScreenPoint(Owner.transform.position) + pos * Vector3.right;
foreach(var kv in ConditionalButtons)
{
kv.Key.gameObject.SetActive(kv.Value.Invoke());
}
}
public PopupController Init(UIHandle owner)
{
Owner = owner;
transform.SetAsFirstSibling();
GetComponentInChildren<Text>().text = owner.name;
PopupPanel = transform.Find("PopupPanel");
ButtonPrefab = Resources.Load(Strings.PopupButtonPrefab) as GameObject;
return this;
}
}

View File

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

View File

@@ -0,0 +1,38 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class SliderCallbackExtension : MonoBehaviour, IPointerClickHandler, IPointerUpHandler
{
private Slider _slider;
public UnityEvent RightClickAction = new UnityEvent();
public UnityEvent<float> PointerUpAction = new UnityEvent<float>();
public UnityEvent<float> ValueChangedAction = new UnityEvent<float>();
private void Awake()
{
_slider = GetComponent<Slider>();
}
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
RightClickAction?.Invoke();
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Left)
{
PointerUpAction?.Invoke(_slider.value);
}
}
public void OnValueChanged(float value)
{
ValueChangedAction.Invoke(value);
}
}

View File

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

View File

@@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SliderDisplay : MonoBehaviour
{
public TMPro.TMP_Text Text;
public void UpdateDisplay(float value)
{
if (Text == null) //Legacy, some UI needs to be updated
{
this.GetComponent<Text>().text = value.ToString("F2");
}
else
{
Text.text = value.ToString("F2");
}
}
}

View File

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

View File

@@ -0,0 +1,103 @@
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.Events;
public class SliderPanel : MonoBehaviour
{
public static SliderPanel Prefab;
public Slider Slider;
//public UICallbacks ToggleCallbacks;
public TMPro.TMP_Text Text;
public Toggle Toggle;
public float DefaultValue;
public float value {
get { return Slider.value; }
set { Slider.value = value; }
}
public float maxValue
{
get { return Slider.maxValue; }
set { Slider.maxValue = value; }
}
public float minValue
{
get { return Slider.minValue; }
set { Slider.minValue = value; }
}
[Header("private")]
[SerializeField] private SliderDisplay _display;
[SerializeField] private SliderCallbackExtension _sliderCallbacks;
private void Awake()
{
_display.UpdateDisplay(Slider.value);
}
public static SliderPanel CreateMorph(ObjectContainer container, SkinnedMeshRenderer meshRenderer, int index, string displayName, Transform parent)
{
SliderPanel panel = Instantiate(SharedResources.Instance.SliderPanel, parent);
var helper = new MorphHelper(meshRenderer, meshRenderer.sharedMesh.GetBlendShapeName(index), panel.Slider);
if (container.Morphs.ContainsKey(meshRenderer))
container.Morphs[meshRenderer].Add(helper);
else
container.Morphs.Add(meshRenderer, new List<MorphHelper>() { helper });
panel.Text.text = displayName;
panel.Slider.value = meshRenderer.GetBlendShapeWeight(index);
panel.SetOnValueChanged((value) => {helper.UpdateMorph(value);});
panel.SetOnRelease((value) => { container.SetKeyframe(); });
panel.SetOnRightClick(null);
return panel;
}
public static SliderPanel CreateToggle(string label, bool isOn, Transform parent, UnityAction<bool> callback)
{
SliderPanel panel = Instantiate(SharedResources.Instance.TogglePanel, parent);
panel.Slider.gameObject.SetActive(false);
panel.Toggle.gameObject.SetActive(true);
panel.Toggle.SetIsOnWithoutNotify(isOn);
panel.Text.text = label;
panel.Toggle.onValueChanged.AddListener(callback);
return panel;
}
public SliderPanel SetOnValueChanged(UnityAction<float> action)
{
_sliderCallbacks.ValueChangedAction.RemoveAllListeners();
if (action != null)
{
_sliderCallbacks.ValueChangedAction.AddListener(action);
}
return this;
}
public SliderPanel SetOnRelease(UnityAction<float> action)
{
_sliderCallbacks.PointerUpAction.RemoveAllListeners();
if (action != null)
{
_sliderCallbacks.PointerUpAction.AddListener(action);
}
return this;
}
public SliderPanel SetOnRightClick(UnityAction action)
{
_sliderCallbacks.RightClickAction.RemoveAllListeners();
_sliderCallbacks.RightClickAction.AddListener(ResetSlider);
if(action != null)
{
_sliderCallbacks.RightClickAction.AddListener(action);
}
return this;
}
public void ResetSlider()
{
Slider.value = DefaultValue;
_sliderCallbacks.PointerUpAction.Invoke(DefaultValue);
}
}

View File

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

View File

@@ -0,0 +1,320 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;
public class TimelineController : MonoBehaviour
{
[System.Serializable]
public class CopyBufferData
{
public ObjectContainer TrackedObject;
public FrameContent Content;
}
public static TimelineController Instance;
public TMPro.TMP_InputField FrameCountInput;
public TMPro.TMP_Text SelectedObjectLabel;
public TMPro.TMP_InputField
InputFrameRate,
InputFrameDelay;
public int FrameCount;
public int CurrentFrame;
public ScrollRect Timeline;
public ScrollRect ObjectsList;
public Slider TimelineSlider;
public CopyBufferData CopyBuffer = null;
public List<TimelineFrameContainer> Frames;
public bool Play;
public float FrameDelayMS = 33;
public float FrameRate = 30;
private void Awake()
{
Instance = this;
}
IEnumerator Start()
{
while(ModelViewerMain.GetInstance() == null)
{
yield return 0;
}
SetFrameRate("30");
FrameCount = (int)float.Parse(FrameCountInput.text, CultureInfo.InvariantCulture);
FillTimeline(FrameCount);
UpdateTimeline();
StartCoroutine(UpdateLoop());
}
IEnumerator UpdateLoop()
{
while (true)
{
if (Play)
{
ChangeCurrentFrame(1, false);
}
yield return new WaitForSeconds(FrameDelayMS/1000);
}
}
public void TogglePlay()
{
Play = !Play;
}
public void ChangeCurrentFrame(int frameChange)
{
TimelineController.ChangeCurrentFrame(frameChange, true);
}
public static void ChangeCurrentFrame(int frameChange, bool stopPlayback)
{
int frame = Instance.CurrentFrame + frameChange;
if (frame < 0)
frame = Instance.FrameCount - 1;
if (frame >= Instance.FrameCount)
frame = 0;
if (stopPlayback)
Instance.Play = false;
SetCurrentFrame(frame);
}
public static void SetCurrentFrame(int frameIndex)
{
var main = ModelViewerMain.GetInstance();
Instance.CurrentFrame = frameIndex;
//Debug.Log(frameIndex);
foreach (var container in main.CurrentScene.AllObjects)
{
container.GetClosestFrames(frameIndex, out var previousFrame, out var nextFrame);
var blendAmount = previousFrame == nextFrame? 0 : 1 - (float)(nextFrame.FrameNum - frameIndex) / (nextFrame.FrameNum - previousFrame.FrameNum);
container.Lerp(previousFrame.ObjectData, nextFrame.ObjectData, blendAmount);
}
UpdateTimeline();
}
public static void SetCurrentFrame(ObjectContainer container)
{
int frameIndex = Instance.CurrentFrame;
container.GetClosestFrames(frameIndex, out var previousFrame, out var nextFrame);
var blendAmount = previousFrame == nextFrame ? 0 : 1 - (float)(nextFrame.FrameNum - frameIndex) / (nextFrame.FrameNum - previousFrame.FrameNum);
container.Lerp(previousFrame.ObjectData, nextFrame.ObjectData, blendAmount);
}
public void FillTimeline(int frames)
{
if (frames > Frames.Count)
{
int diff = frames - Frames.Count;
for (int i = 0; i < diff; i++)
{
var frame = Instantiate(SharedResources.Instance.TimelineFrame, Timeline.content).SetNum(Frames.Count);
frame.name = Frames.Count.ToString();
Frames.Add(frame);
}
}
foreach (var frame in Frames)
{
frame.gameObject.SetActive(frame.FrameIndex < frames);
}
}
public void OnSliderScroll()
{
var sliderPos = TimelineSlider.handleRect.position;
var newFrame = Frames.Where(f => f.gameObject.activeInHierarchy).OrderBy(frame => Vector3.Distance(sliderPos, frame.GetComponent<RectTransform>().position)).First();
if (CurrentFrame != newFrame.FrameIndex)
{
SetCurrentFrame(newFrame.FrameIndex);
}
}
public void SetFrameCount(string text)
{
FrameCount = int.Parse(text);
FillTimeline(FrameCount);
UpdateTimeline();
}
public void SetFrameDelay(string text)
{
FrameDelayMS = (int)float.Parse(text, CultureInfo.InvariantCulture);
if (FrameDelayMS == 0)
{
FrameDelayMS = 1;
}
FrameRate = 1 / (FrameDelayMS / 1000);
InputFrameRate.SetTextWithoutNotify(Mathf.Round(FrameRate).ToString());
InputFrameDelay.SetTextWithoutNotify(Mathf.Round(FrameDelayMS).ToString());
}
public void SetFrameRate(string text)
{
FrameRate = (int)float.Parse(text, CultureInfo.InvariantCulture);
if(FrameRate == 0)
{
FrameRate = 1;
}
FrameDelayMS = (1 / FrameRate) * 1000;
InputFrameRate.SetTextWithoutNotify(Mathf.Round(FrameRate).ToString());
InputFrameDelay.SetTextWithoutNotify(Mathf.Round(FrameDelayMS).ToString());
}
public static void SwapFrames(int frameNum1, int frameNum2)
{
if (frameNum1 < 0 || frameNum1 >= Instance.FrameCount) return;
if (frameNum2 < 0 || frameNum2 >= Instance.FrameCount) return;
var selectedObject = GetCurrentObject();
var frames = selectedObject.Frames;
var frame1 = selectedObject.TryGetFrame(frameNum1);
var frame2 = selectedObject.TryGetFrame(frameNum2);
if (frame1 != null)
{
frame1.FrameNum = frameNum2;
}
if (frame2 != null)
{
frame2.FrameNum = frameNum1;
}
selectedObject.Frames = selectedObject.Frames.OrderBy(f => f.FrameNum).ToList();
SetCurrentFrame(Instance.CurrentFrame);
}
public static void UpdateTimeline()
{
var container = GetCurrentObject();
Instance.SelectedObjectLabel.text = container.name;
var frames = Instance.Frames.ToList();
for (int i = 0; i < container.Frames.Count; i++)
{
var frameNum = container.Frames[i].FrameNum;
if (frameNum >= frames.Count) return;
var frame = frames[frameNum];
frame.UpdateContent(container, container.Frames[i]);
frames[frameNum] = null;
}
foreach(var frame in frames)
{
if (frame == null) continue;
frame.UpdateContent(container, null);
}
}
public static ObjectContainer GetCurrentObject()
{
ObjectContainer container = ModelViewerMain.GetInstance().SelectedObject;
if (container == null)
{
container = ModelViewerMain.GetInstance().MainCameraOrbit;
}
return container;
}
public void OnButtonSet()
{
GetCurrentObject().SetKeyframe(CurrentFrame);
}
public void OnButtonDelete()
{
Frames[CurrentFrame].DeleteFrame();
}
public void OnButtonCopy()
{
Frames[CurrentFrame].CopyFrame();
}
public void OnButtonPaste()
{
var data = CopyBuffer;
if (data == null) return;
if (GetCurrentObject() == data.TrackedObject)
{
if (Input.GetKey(KeyCode.LeftShift)) PasteStep0(data);
else PasteStep1(data, new PoseLoadOptions(true));
return;
}
UIPopupMessage.Create("You're pasting from a different object. Continue?",
() =>
{
if (Input.GetKey(KeyCode.LeftShift)) PasteStep0(data);
else PasteStep1(data, new PoseLoadOptions(true));
},
() => { }
);
}
private void PasteStep0(CopyBufferData data)
{
UIPopupPastePanel.Create(
(pasteOptions) => { PasteStep1(data, pasteOptions); Debug.Log(pasteOptions.Root); },
() => { });
}
private void PasteStep1(CopyBufferData data, PoseLoadOptions options)
{
int frameNum = CurrentFrame;
var trackedObject = data.TrackedObject;
if (trackedObject == null)
{
Error.Log(Color.red, "Object has been deleted?");
return;
}
if (!trackedObject.GetCurrentFrame(frameNum, out var currentFrame))
{
trackedObject.PastePose(data.Content.ObjectData, options);
currentFrame.SetObjectData(trackedObject.SerializeFrame());
SetCurrentFrame(trackedObject);
return;
}
UIPopupMessage.Create($"Replace existing data for {trackedObject.name}?",
() => {
trackedObject.PastePose(data.Content.ObjectData, options);
currentFrame.SetObjectData(trackedObject.SerializeFrame());
SetCurrentFrame(trackedObject);
},
() =>{}
);
}
}

View File

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

View File

@@ -0,0 +1,25 @@
[System.Serializable]
public class TimelineControllerSerializable
{
public int FrameCount;
public float FrameDelay;
public int CurrentFrame;
public TimelineControllerSerializable() { }
public TimelineControllerSerializable(TimelineController tc)
{
FrameCount = tc.FrameCount;
FrameDelay = tc.FrameDelayMS;
CurrentFrame = tc.CurrentFrame;
}
public void Deserialize(TimelineController tc)
{
tc.FrameCount = FrameCount;
tc.SetFrameDelay(FrameDelay.ToString());
tc.CurrentFrame = CurrentFrame;
tc.FillTimeline(TimelineController.Instance.FrameCount);
TimelineController.UpdateTimeline();
}
}

View File

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

View File

@@ -0,0 +1,128 @@
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using static TimelineController;
public enum DataType
{
None,
Object,
Character,
Camera,
Scene
}
public class TimelineFrameContainer : MonoBehaviour
{
public int FrameIndex;
public TMPro.TextMeshProUGUI FrameLabel;
public ObjectContainer TrackedObject;
public FrameContent FrameContents;
public Button DeleteButton;
public Button CopyButton;
public GameObject Controls;
private bool
_copyEnabled,
_deleteEnabled;
public Color Color
{
get => GetComponent<Image>().color;
set => GetComponent<Image>().color = value;
}
public TimelineFrameContainer SetNum(int frameNum)
{
FrameIndex = frameNum;
FrameLabel.text = frameNum.ToString();
return this;
}
public void UpdateContent(ObjectContainer trackedObject, FrameContent content)
{
TrackedObject = trackedObject;
FrameContents = content;
if(trackedObject == null || content == null)
{
_copyEnabled = false;
_deleteEnabled = false;
Color = (FrameIndex == TimelineController.Instance.CurrentFrame) ? Color.white : Color.gray / 2;
DeleteButton.gameObject.SetActive(false);
CopyButton.gameObject.SetActive(false);
Controls.SetActive(false);
}
else
{
_copyEnabled = true;
_deleteEnabled = true;
Color = (FrameIndex == TimelineController.Instance.CurrentFrame) ? Color.white : Color.gray;
DeleteButton.gameObject.SetActive(true);
CopyButton.gameObject.SetActive(true);
Controls.SetActive(true);
}
}
public void SwapFrame(int dir)
{
TimelineController.SwapFrames(FrameIndex, FrameIndex + dir);
}
public void PasteFrame()
{
int frameNum = FrameIndex;
var data = TimelineController.Instance.CopyBuffer;
if (data == null) return;
if (GetCurrentObject() != data.TrackedObject)
{
Error.Log(Color.red, "You can only paste to the same object.");
Debug.Log("Buffer: " + data.TrackedObject);
Debug.Log("Current: " + GetCurrentObject());
return;
}
var trackedObject = data.TrackedObject;
if (trackedObject == null)
{
Error.Log(Color.red, "Object has been deleted?");
return;
}
if (!trackedObject.GetCurrentFrame(frameNum, out var currentFrame))
{
currentFrame.SetObjectData(data.Content.ObjectData);
SetCurrentFrame(frameNum);
return;
}
UIPopupMessage.Create($"Replace existing data for {trackedObject.name}?",
() => {
currentFrame.SetObjectData(data.Content.ObjectData);
SetCurrentFrame(frameNum);
},
() => { }
);
}
public void CopyFrame()
{
if (!_copyEnabled) return;
TimelineController.Instance.CopyBuffer = new CopyBufferData()
{
Content = FrameContents,
TrackedObject = TrackedObject
};
}
public void DeleteFrame()
{
if (!_deleteEnabled) return;
if (TrackedObject.Frames.Count <= 1) return;
TrackedObject.Frames.Remove(FrameContents);
TimelineController.SetCurrentFrame(TimelineController.Instance.CurrentFrame);
}
}

View File

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

View File

@@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class UICallbacks : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
public UnityEvent MouseHover;
public UnityEvent MouseHoverEnd;
public void OnPointerEnter(PointerEventData eventData)
{
MouseHover.Invoke();
}
public void OnPointerExit(PointerEventData eventData)
{
MouseHoverEnd.Invoke();
}
public void SetTooltipText(string text)
{
ModelViewerInterface.GetInstance().Tooltip.SetAsLastSibling();
ModelViewerInterface.GetInstance().TooltipText.text = text;
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,73 @@
using UIPanels;
using UnityEngine;
using UnityEngine.EventSystems;
public class UIDraggableProxy : MonoBehaviour, IEndDragHandler, IDragHandler
{
public bool InitializeOnAwake;
public UIElementDragger Draggable;
public TMPro.TMP_Text Label;
public static UIDraggableProxy Create(Transform parent)
{
var proxy = Instantiate(SharedResources.Instance.UIDraggableProxy, parent);
return proxy;
}
private void Awake()
{
if (InitializeOnAwake)
{
Link(Draggable);
}
}
public UIDraggableProxy Link(UIElementDragger obj)
{
Label.text = string.IsNullOrEmpty(obj.ProxyName)? obj.name : obj.ProxyName;
Draggable = obj;
obj.SetProxyMode(this);
obj.ProxySetVisible(false);
return this;
}
public void OnDrag(PointerEventData eventData)
{
}
public void OnEndDrag(PointerEventData eventData)
{
if (Draggable.LockProxyState) return;
Draggable.SetProxyMode(null);
Draggable.transform.position = Input.mousePosition;
Destroy(this.gameObject);
}
public void ToggleDraggableVisible()
{
CloseSiblingProxies();
Draggable.ProxySetVisible(!Draggable.gameObject.activeSelf);
}
public void SetDraggableVisible(bool visible)
{
if (visible)
{
CloseSiblingProxies();
}
Draggable.ProxySetVisible(visible);
}
private void CloseSiblingProxies()
{
var toolbar = GetComponentInParent<UIToolbar>();
var siblings = toolbar.GetComponentsInChildren<UIDraggableProxy>();
foreach (var sibling in siblings)
{
if (sibling.gameObject != this.gameObject)
{
sibling.Draggable.ProxySetVisible(false);
}
}
}
}

View File

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

View File

@@ -0,0 +1,187 @@
using UnityEngine;
using UnityEngine.EventSystems;
using static UnityEngine.Rendering.VirtualTexturing.Debugging;
[RequireComponent(typeof(CanvasGroup))]
public class UIElementDragger : MonoBehaviour, IDragHandler, IEndDragHandler, IPointerDownHandler, IPointerUpHandler
{
public bool LockSize;
[ShowIf("LockSize", false)]
public Vector2
SizeMin = new Vector2(100, 100),
SizeMax = new Vector2(1920, 1080);
//Prevent the element for being attached or detached from a toolbar
public bool LockProxyState;
public string ProxyName;
public UIDraggableProxy Proxy;
public UIToolbar.ElementType ElementType;
public GameObject HandlePosition, HandleSize;
private Vector2 mouseOffset;
private float currentScale = 1;
private float sizeWhenClicked;
private Vector2 savedMousePos;
private bool _awake;
private CanvasGroup _canvasGroup;
public DragAction LastDragAction;
public enum DragAction
{
None,
Position,
Scale,
Size
}
private void Awake()
{
if (_awake) return;
_awake = true;
_canvasGroup = GetComponent<CanvasGroup>();
if (LockSize)
{
HandleSize.SetActive(false);
}
}
private void OnEnable()
{
var handle = HandlePosition.GetComponent<RectTransform>();
transform.position = new Vector2(
Mathf.Clamp(transform.position.x, 0, Screen.width - handle.rect.width),
Mathf.Clamp(transform.position.y, handle.sizeDelta.y, Screen.height));
}
public void SetProxyMode(UIDraggableProxy proxy)
{
Awake();
OnEndDrag(null);
Proxy = proxy;
if (proxy != null)
{
transform.position = proxy.GetComponent<RectTransform>().position;
HandlePosition.gameObject.SetActive(false);
}
else
{
gameObject.SetActive(true);
HandlePosition.gameObject.SetActive(true);
}
}
public void ProxySetVisible(bool visible)
{
if (!visible)
{
gameObject.SetActive(false);
}
else
{
var proxyRect = Proxy.transform as RectTransform;
var handleRect = HandlePosition.transform as RectTransform;
var handleOffset = handleRect.sizeDelta.y * Vector3.up;
if (Proxy.GetComponentInParent<UIToolbar>().Layout == UIToolbar.LayoutMode.Vertical)
{
//anchor to top-right of button
transform.position = proxyRect.position + proxyRect.sizeDelta.x * Vector3.right + handleOffset;
}
else
{
//anchor to bottom-left of button
transform.position = proxyRect.position + proxyRect.sizeDelta.y * Vector3.up - handleOffset;
}
gameObject.SetActive(true);
}
}
public void OnDrag(PointerEventData eventData)
{
var rectTsf = GetComponent<RectTransform>();
switch (LastDragAction)
{
case DragAction.Scale:
{
currentScale = Mathf.Clamp((Input.mousePosition.x - savedMousePos.x) / Screen.width + sizeWhenClicked, 0.5f, 1);
transform.localScale = Vector3.one * currentScale;
break;
}
case DragAction.Size:
{
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));
if (currentScale > 0)
{
sizeDelta *= currentScale;
}
rectTsf.sizeDelta = sizeDelta;
break;
}
case DragAction.Position:
{
var handle = HandlePosition.GetComponent<RectTransform>();
transform.position = new Vector2(
Mathf.Clamp(Input.mousePosition.x + mouseOffset.x, 0, Screen.width - handle.rect.width),
Mathf.Clamp(Input.mousePosition.y + mouseOffset.y, handle.sizeDelta.y, Screen.height));
break;
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
_canvasGroup.blocksRaycasts = true;
}
private void OnDestroy()
{
if(Proxy != null)
{
Destroy(Proxy.gameObject);
}
}
public void OnPointerDown(PointerEventData eventData)
{
eventData.pointerDrag = this.gameObject;
_canvasGroup.blocksRaycasts = false;
if (eventData.button == PointerEventData.InputButton.Right)
{
LastDragAction = DragAction.Scale;
ModelViewerMain.GetInstance().GetCamera().LightLock = true;
savedMousePos = Input.mousePosition;
sizeWhenClicked = currentScale;
transform.SetAsLastSibling();
}
else if (eventData.hovered.Contains(HandlePosition))
{
LastDragAction = DragAction.Position;
mouseOffset = transform.position - Input.mousePosition;
transform.SetAsLastSibling();
}
else if (eventData.hovered.Contains(HandleSize))
{
LastDragAction = DragAction.Size;
mouseOffset = transform.position - Input.mousePosition;
}
else
{
LastDragAction = DragAction.None;
_canvasGroup.blocksRaycasts = true;
eventData.pointerDrag = null;
}
}
public void OnPointerUp(PointerEventData eventData)
{
OnEndDrag(null);
}
}

View File

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

View File

@@ -0,0 +1,70 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class UIHandleBinder : MonoBehaviour
{
public static UIHandleBinder Instance;
public bool BindingInProgress = false;
public UIHandle TempHandle1;
public UIHandle TempHandle2;
/// <summary>[0]-child [1]-parent [2]-original parent</summary>
public List<Binding> Bindings = new List<Binding>();
private void Awake()
{
Instance = this;
}
public void StartBinding(UIHandle handle)
{
TempHandle1 = handle;
BindingInProgress = true;
}
public void EndBinding(UIHandle handle)
{
TempHandle2 = handle;
Binding row = Bindings.FirstOrDefault(b => b.Child == TempHandle1);
if (row != null)
{
row.Parent = TempHandle2;
}
else
{
Bindings.Add(new Binding( TempHandle1, TempHandle2, TempHandle1.Owner.transform.parent));
}
TempHandle1.Owner.transform.SetParent(TempHandle2.Owner.transform);
BindingInProgress = false;
}
public List<Binding> GetBindings(UIHandle handle)
{
return Bindings.Where(b => b.Child == handle || b.Parent == handle).ToList();
}
public bool Unparent(UIHandle handle)
{
var bindings = GetBindings(handle);
if (bindings == null) return false;
var binding = bindings.FirstOrDefault(b => b.Child == handle);
if (binding == null) return false;
handle.Owner.transform.SetParent(binding.OriginalParent);
Bindings.Remove(binding);
return true;
}
public class Binding{
public UIHandle Child;
public UIHandle Parent;
public Transform OriginalParent;
public Binding(UIHandle child, UIHandle parent, Transform origParent)
{
Child = child;
Parent = parent;
OriginalParent = origParent;
}
}
}

View File

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

View File

@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIPopupMessage : MonoBehaviour
{
public UnityEngine.Events.UnityEvent OnConfirm;
public UnityEngine.Events.UnityEvent OnDeny;
public TMPro.TextMeshProUGUI Text;
public static UIPopupMessage Create(string message, System.Action onConfirm, System.Action onDeny)
{
var popup = Instantiate(SharedResources.Instance.PopupMessage, ModelViewerInterface.GetInstance().MainCanvas.transform);
popup.transform.SetAsLastSibling();
popup.SetMessage(message);
popup.OnConfirm.AddListener(() => onConfirm.Invoke());
popup.OnDeny.AddListener(() => onDeny.Invoke());
return popup;
}
public void SetMessage(string text)
{
Text.text = text;
}
public void Deny()
{
OnDeny?.Invoke();
Destroy(this.gameObject);
}
public void Confirm()
{
OnConfirm?.Invoke();
Destroy(this.gameObject);
}
}

View File

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

View File

@@ -0,0 +1,46 @@
using UnityEngine;
using UnityEngine.UI;
public class UIPopupPastePanel : UIPopupMessage
{
public Toggle
Root,
Morphs,
Body,
Ears,
//EarsAlt,
Tail,
//TailAlt,
Other,
Position,
Rotation,
Scale;
public PoseLoadOptions GetResult()
{
return new PoseLoadOptions(false)
{
Root = Root.isOn,
Morphs = Morphs.isOn,
Body = Body.isOn,
Ears = Ears.isOn,
//EarsAlt = EarsAlt.isOn,
Tail = Tail.isOn,
//TailAlt = TailAlt.isOn,
Other = Other.isOn,
Position = Position.isOn,
Rotation = Rotation.isOn,
Scale = Scale.isOn
};
}
public static UIPopupPastePanel Create(System.Action<PoseLoadOptions> onConfirm, System.Action onDeny)
{
var popup = Instantiate(SharedResources.Instance.PopupPastePanel, ModelViewerInterface.GetInstance().MainCanvas.transform);
popup.transform.SetAsLastSibling();
//popup.SetMessage(message);
popup.OnConfirm.AddListener(() => onConfirm.Invoke(popup.GetResult()));
popup.OnDeny.AddListener(() => onDeny.Invoke());
return popup;
}
}

View File

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

View File

@@ -0,0 +1,130 @@
using UnityEngine;
using System.Linq;
using Newtonsoft.Json;
using System.IO;
using System;
public class UIPoseContainer : MonoBehaviour
{
public DataType Type;
public string PoseName;
public KeyframeData KeyframeData;
public TMPro.TMP_InputField NameLabel;
static ModelViewerInterface UI => ModelViewerInterface.GetInstance();
static ModelViewerMain Main => ModelViewerMain.GetInstance();
public static UIPoseContainer CreateNew(string poseName, KeyframeData poseData, bool forceOverride)
{
if (poseData == null) return null;
if (string.IsNullOrEmpty(poseName))
{
Error.Log(Color.red, "Name the pose first");
return null;
}
if (UI.SaveLoadPanel.GetPoseByName(poseName, out var savedPose))
{
if (!forceOverride)
{
Error.Log(Color.red, "Preset with this name already exists");
return null;
}
}
else
{
savedPose = Instantiate(SharedResources.Instance.UIPoseContainer, UI.PosePresetToggle.content);
UI.SaveLoadPanel.AddPose(savedPose);
}
savedPose.Init(poseName, poseData);
return savedPose;
}
public void Init(string poseName, KeyframeData poseData)
{
NameLabel.text = poseName;
NameLabel.interactable = false;
KeyframeData = poseData;
transform.SetAsFirstSibling();
}
public void SaveNew()
{
var poseName = NameLabel.text;
if (UI.SaveLoadPanel.GetPoseByName(poseName, out var savedPose))
{
Error.Log(Color.red, "Preset with this name already exists");
return;
}
else
{
savedPose = Instantiate(SharedResources.Instance.UIPoseContainer, UI.PosePresetToggle.content);
savedPose.NameLabel.text = poseName;
UI.SaveLoadPanel.AddPose(savedPose);
}
savedPose.Save();
}
public void Save()
{
Error.Log(Color.blue, $"Saving pose...");
var poseData = Main.SelectedObject.SerializeFrame();
string poseName = NameLabel.text;
string fileName = Path.GetFullPath(Path.Combine(Settings.SavePoseDirectory, $"{poseName}.pose"));
try
{
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto, DefaultValueHandling = DefaultValueHandling.Ignore };
var json = JsonConvert.SerializeObject(poseData, Formatting.Indented, settings);
File.WriteAllText(fileName, json);
Error.Log(Color.green, $"Pose saved to {fileName}");
}
catch (Exception ex)
{
Error.Log(Color.red, ex.Message);
return;
}
Init(poseName, poseData);
}
public void Load()
{
if (Main.SelectedObject == null) return;
if (Input.GetKey(KeyCode.LeftShift))
{
LoadAdvanced();
}
else
{
Main.SelectedObject.PastePose(KeyframeData, new PoseLoadOptions(true));
}
}
public void LoadAdvanced()
{
if (Main.SelectedObject == null) return;
UIPopupPastePanel.Create(
(pasteOption) => { Main.SelectedObject.PastePose(KeyframeData, pasteOption); Debug.Log(pasteOption.Root); },
() => { });
}
public void Delete()
{
Destroy(this.gameObject);
string path = Path.GetFullPath(Path.Combine(Settings.SavePoseDirectory, $"{PoseName}.pose"));
if (File.Exists(path))
File.Delete(path);
Error.Log(Color.yellow, "Deleted " + path);
}
}

View File

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

View File

@@ -0,0 +1,120 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
namespace UIPanels
{
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)
{
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
{
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!");
}
}
}
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,11 @@
fileFormatVersion: 2
guid: 1684a7328e3296b4a9642cc6327de734
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,119 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using UnityEngine;
public class UISceneContainer : MonoBehaviour
{
public SceneSerializable SceneData;
public TMPro.TMP_InputField NameLabel;
public TMPro.TMP_Text DateLabel;
public TMPro.TMP_Text VersionLabel;
static ModelViewerInterface UI => ModelViewerInterface.GetInstance();
static ModelViewerMain Main => ModelViewerMain.GetInstance();
public static UISceneContainer CreateNew(SceneSerializable sceneData, bool forceOverride)
{
if(sceneData == null) return null;
if (string.IsNullOrEmpty(sceneData.Filename))
{
Error.Log(Color.red, "Name the scene first");
return null;
}
if (UI.SaveLoadPanel.GetSceneByName(sceneData.Filename, out var savedScene))
{
if (!forceOverride)
{
Error.Log(Color.red, "Preset with this name already exists");
return null;
}
}
else
{
savedScene = Instantiate(SharedResources.Instance.UISceneContainer, UI.ScenePresetToggle.content);
UI.SaveLoadPanel.AddScene(savedScene);
}
savedScene.Init(sceneData);
return savedScene;
}
public void Init(SceneSerializable scene)
{
NameLabel.text = scene.Filename;
NameLabel.interactable = false;
DateLabel.text = "Save date: " + scene.Date;
VersionLabel.text = "Version: " + scene.Version;
SceneData = scene;
transform.SetAsFirstSibling();
}
public void SaveNew()
{
var sceneName = NameLabel.text;
if (UI.SaveLoadPanel.GetSceneByName(sceneName, out var savedScene))
{
Error.Log(Color.red, "Preset with this name already exists");
return;
}
else
{
savedScene = Instantiate(SharedResources.Instance.UISceneContainer, UI.ScenePresetToggle.content);
savedScene.NameLabel.text = sceneName;
UI.SaveLoadPanel.AddScene(savedScene);
}
savedScene.Save();
}
public void Save(bool silenceMessage = false)
{
if (!silenceMessage)
{
Error.Log(Color.blue, $"Saving scene...");
}
var sceneData = Main.SaveScene();
sceneData.Filename = NameLabel.text;
string fileName = Path.GetFullPath(Path.Combine(Settings.SaveSceneDirectory, $"{sceneData.Filename}.scene"));
try
{
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto, DefaultValueHandling = DefaultValueHandling.Ignore };
var json = JsonConvert.SerializeObject(sceneData, Formatting.Indented, settings);
File.WriteAllText(fileName, json);
if (!silenceMessage)
{
Error.Log(Color.green, $"Scene saved to {fileName}");
}
}
catch (Exception ex)
{
Error.Log(Color.red, ex.Message);
return;
}
Init(sceneData);
}
public void Load()
{
StartCoroutine(Main.LoadScene(SceneData));
}
public void Delete()
{
Destroy(this.gameObject);
string path = Path.GetFullPath(Path.Combine(Settings.SaveSceneDirectory, $"{SceneData.Filename}.scene"));
if (File.Exists(path))
File.Delete(path);
Error.Log(Color.yellow, "Deleted " + path);
}
}

View File

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

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UISelectionEntry : MonoBehaviour
{
public Transform Target;
public TMPro.TextMeshProUGUI TargetName;
public Toggle Toggle;
public Button Button;
public void SetTarget(Transform t)
{
Target = t;
TargetName.text = t.name;
Toggle.isOn = true;
Toggle.onValueChanged.AddListener((value) => {
throw new NotImplementedException();
//CameraOrbit.RuntimeGizmo.RemoveTarget(t, true);
//Destroy(this.gameObject);
});
if (t.TryGetComponent(out ObjectContainer container))
{
Button.onClick.AddListener(() => {
throw new NotImplementedException();
//CameraOrbit.RuntimeGizmo.ClearTargets();
//CameraOrbit.RuntimeGizmo.AddTarget(t);
});
}
}
}

View File

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

View File

@@ -0,0 +1,45 @@
using UnityEngine;
using UnityEngine.EventSystems;
public class UIToolbar : MonoBehaviour, IDropHandler
{
public ElementType ElementMask;
public LayoutMode Layout;
[System.Flags]
public enum ElementType
{
None = 0,
Toolbar = 1,
Dynamic = 2
}
public enum LayoutMode
{
Horizontal,
Vertical
}
public void OnDrop(PointerEventData eventData)
{
if (eventData.pointerDrag.TryGetComponent<UIElementDragger>(out var draggable))
{
if (!ElementMask.HasFlag(draggable.ElementType) || draggable.LockProxyState || draggable.LastDragAction != UIElementDragger.DragAction.Position) return;
AttachToThis(draggable);
}
}
public void AttachToThis(UIElementDragger draggable)
{
var proxy = UIDraggableProxy.Create(transform).Link(draggable);
draggable.gameObject.SetActive(false);
}
private void OnDisable()
{
foreach(var proxy in GetComponentsInChildren<UIDraggableProxy>())
{
proxy.SetDraggableVisible(false);
}
}
}

View File

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

View File

@@ -0,0 +1,20 @@
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

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