Pose mode improvements

This commit is contained in:
Katboi01
2023-12-18 17:20:34 +01:00
parent f928a802d7
commit 9405816231
31 changed files with 8225 additions and 387 deletions
+146
View File
@@ -0,0 +1,146 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-920117762517378301
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 4
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: LineRenderer
m_Shader: {fileID: 4800000, guid: c657963988cda87498e6109600174edf, type: 3}
m_ShaderKeywords: _ALPHAPREMULTIPLY_ON
m_LightmapFlags: 6
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- SHADOWCASTER
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaClip: 0
- _Blend: 1
- _BlendOp: 0
- _BumpScale: 1
- _CameraFadingEnabled: 0
- _CameraFarFadeDistance: 2
- _CameraNearFadeDistance: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _ColorMode: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DistortionBlend: 0.5
- _DistortionEnabled: 0
- _DistortionStrength: 1
- _DistortionStrengthScaled: 0
- _DstBlend: 10
- _EmissionEnabled: 0
- _EnvironmentReflections: 1
- _FlipbookBlending: 0
- _FlipbookMode: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _LightingEnabled: 0
- _Metallic: 0
- _Mode: 3
- _OcclusionStrength: 1
- _Parallax: 0.02
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SoftParticlesEnabled: 0
- _SoftParticlesFarFadeDistance: 1
- _SoftParticlesNearFadeDistance: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Surface: 1
- _UVSec: 0
- _WorkflowMode: 1
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 0.46666667}
- _BaseColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0}
- _Color: {r: 1, g: 0, b: 0, a: 0.14901961}
- _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}
- _SpecColor: {r: 0.2, g: 0.2, b: 0.2, a: 1}
m_BuildTextureStacks: []
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 61428e99656e4544aa16be34cad7a789
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -213,15 +213,15 @@ MonoBehaviour:
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 22
m_fontSize: 10
m_fontSizeBase: 22
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_enableAutoSizing: 1
m_fontSizeMin: 10
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
+7057 -126
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,7 +1,6 @@
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine.Rendering.PostProcessing;
public class CameraOrbit : MonoBehaviour
{
@@ -54,6 +53,8 @@ public class CameraOrbit : MonoBehaviour
void Update()
{
if (HandleManager.InteractionInProgress) return;
if(CameraMode != CameraModeDropdown.value)
{
switch (CameraMode) //old
@@ -1,9 +1,103 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using static SerializableBone;
public class HandleManager : MonoBehaviour
{
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<RuntimeGizmoUndoData> RegisterRuntimeGizmoUndoAction;
public static System.Action<List<RuntimeGizmoUndoData>> RegisterRuntimeGizmoUndoActions;
public struct RuntimeGizmoUndoData
{
public Transform NewPosition;
public SerializableTransform OldPosition;
}
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 = UmaViewerUI.Instance.HandleManager;
if (hm.AllHandles.Contains(handle))
{
return;
}
hm.AllHandles.Add(handle);
}
public static void UnregisterHandle(UIHandle handle)
{
var hm = UmaViewerUI.Instance.HandleManager;
if (!hm.AllHandles.Contains(handle))
{
return;
}
hm.AllHandles.Remove(handle);
}
public static void CloseAllPopups()
{
var hm = UmaViewerUI.Instance.HandleManager;
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;
}
}
+101 -44
View File
@@ -1,10 +1,5 @@
using I18N.Common;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using static UnityEngine.Rendering.VirtualTexturing.Debugging;
public class UIHandle : MonoBehaviour
{
@@ -12,7 +7,7 @@ public class UIHandle : MonoBehaviour
public GameObject Owner;
/// <summary> Object that the handle refers to. Cast in inheriting class </summary>
public object Target;
public Transform Target;
/// <summary> Display object on the UI </summary>
public GameObject Handle;
@@ -23,11 +18,13 @@ public class UIHandle : MonoBehaviour
/// <summary> Object that appears when right-clicking the handle </summary>
public UIPopupPanel Popup;
public LineRenderer LineRenderer;
protected SerializableTransform _defaultTransform;
protected float _baseScale = 4;
protected float _baseScale = 1;
protected bool _forceDisplayOff = false;
public virtual UIHandle Init(GameObject owner, object target)
public virtual UIHandle Init(GameObject owner, Transform target)
{
Target = target;
return Init(owner);
@@ -35,17 +32,19 @@ public class UIHandle : MonoBehaviour
public virtual UIHandle Init(GameObject owner)
{
gameObject.layer = LayerMask.NameToLayer("UIHandle");
Target = Target == null? owner : Target;
Owner = owner;
HandleManager.RegisterHandle(this);
Popup = Instantiate(UmaViewerUI.Instance.HandleManager.Pfb_Popup, UmaViewerUI.Instance.HandlesPanel).Init(this);
Popup.gameObject.SetActive(false);
gameObject.layer = LayerMask.NameToLayer("UIHandle");
Target = Target == null? owner.transform : Target;
Owner = owner;
Handle = Instantiate(UmaViewerUI.Instance.HandleManager.Pfb_HandleDisplay, UmaViewerUI.Instance.HandlesPanel);
Handle.transform.SetAsFirstSibling();
_defaultTransform = new SerializableTransform(transform, Space.Self);
Popup = Instantiate(UmaViewerUI.Instance.HandleManager.Pfb_Popup, UmaViewerUI.Instance.HandlesPanel).Init(this);
Popup.gameObject.SetActive(false);
_defaultTransform = new SerializableTransform(Target, Space.Self);
var collider = gameObject.AddComponent<SphereCollider>();
collider.center = Vector3.zero;
@@ -55,25 +54,26 @@ public class UIHandle : MonoBehaviour
return this;
}
protected virtual void Update()
public virtual void UpdateManual(Camera camera, bool linesEnabled)
{
var cam = Camera.main;
if (Handle != null && cam != null && transform != null)
//Made it like this to minimize calls to Camera.main and UI.Inst.Manager.LinesEnabled. Done by HandleManager.
if (Handle != null && camera != null && transform != null)
{
Handle.transform.localScale = Vector3.one * Mathf.Clamp(_baseScale / Vector3.Distance(cam.transform.position, transform.position), 0.1f, 1);
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(Collider.transform.position, Handle.transform.localScale.x);
Collider.radius = 35 /* magic number */ * (1 / transform.lossyScale.x) * GetRadiusOnScreen(camera, Collider.transform.position, Handle.transform.localScale.x);
}
Handle.transform.position = cam.WorldToScreenPoint(Collider.transform.TransformPoint(Collider.center));
Handle.transform.position = camera.WorldToScreenPoint(Collider.transform.TransformPoint(Collider.center));
if (_forceDisplayOff)
if (ShouldBeHidden())
{
if (Handle.activeSelf == true)
{
Handle.SetActive(false);
ToggleActive(false);
}
}
else
@@ -84,15 +84,33 @@ public class UIHandle : MonoBehaviour
if (Handle.activeSelf != isOnScreen)
{
Handle.SetActive(!Handle.activeSelf);
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 });
}
}
}
public void TogglePopup(int offset)
protected virtual bool ShouldBeHidden()
{
//Popup.GetComponent<PopupController>().offset = offset * Popup.GetComponent<RectTransform>().sizeDelta.x;
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;
UmaViewerUI.Instance.ToggleVisible(Popup.gameObject);
}
@@ -120,7 +138,7 @@ public class UIHandle : MonoBehaviour
public UIHandle SetName(string name)
{
Handle.gameObject.name = name;
Popup.GetComponentInChildren<Text>().text = name;
Popup.NameLabel.text = name;
return this;
}
@@ -130,21 +148,24 @@ public class UIHandle : MonoBehaviour
return this;
}
public float GetRadiusOnScreen(Vector3 position, float screenSize)
public float GetRadiusOnScreen(Camera cam, Vector3 position, float screenSize)
{
Vector3 a = Camera.main.WorldToScreenPoint(position);
Vector3 a = cam.WorldToScreenPoint(position);
Vector3 b = new Vector3(a.x, a.y + screenSize, a.z);
Vector3 aa = Camera.main.ScreenToWorldPoint(a);
Vector3 bb = Camera.main.ScreenToWorldPoint(b);
Vector3 aa = cam.ScreenToWorldPoint(a);
Vector3 bb = cam.ScreenToWorldPoint(b);
return (aa - bb).magnitude;
}
public UIHandle ClearForDeletion()
public UIHandle WithLineRenderer()
{
Popup = null;
Handle = null;
LineRenderer = Handle.gameObject.AddComponent<LineRenderer>();
LineRenderer.positionCount = 2;
LineRenderer.startWidth = LineRenderer.endWidth = 0.005f;
LineRenderer.material = UmaViewerUI.Instance.HandleManager.LineRendererMaterial;
LineRenderer.startColor = LineRenderer.endColor = Handle.GetComponent<Image>().color;
return this;
}
@@ -158,35 +179,71 @@ public class UIHandle : MonoBehaviour
{
Destroy(Handle);
}
HandleManager.UnregisterHandle(this);
}
public UIHandle PositionReset()
public void TransformReset(PoseLoadOptions options = null)
{
transform.localPosition = _defaultTransform.Position;
return this;
if(options == null)
{
options = PoseLoadOptions.All();
}
_defaultTransform.ApplyTo(Target);
}
public UIHandle RotationReset()
public void TransformResetAll()
{
transform.localEulerAngles = _defaultTransform.Rotation;
return this;
var undoData = new HandleManager.RuntimeGizmoUndoData();
undoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset();
undoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(undoData);
}
public UIHandle ScaleReset()
public void TransformResetPosition()
{
transform.localScale = _defaultTransform.Scale;
return this;
var undoData = new HandleManager.RuntimeGizmoUndoData();
undoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset(new PoseLoadOptions() { Position = true });
undoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(undoData);
}
public void TransformResetRotation()
{
var undoData = new HandleManager.RuntimeGizmoUndoData();
undoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset(new PoseLoadOptions() { Rotation = true });
undoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(undoData);
}
public void TransformResetScale()
{
var undoData = new HandleManager.RuntimeGizmoUndoData();
undoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset(new PoseLoadOptions() { Scale = true });
undoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(undoData);
}
public void ToggleActive(bool value)
{
this.enabled = value;
Handle.SetActive(value);
Collider.enabled = value;
Popup.gameObject.SetActive(false);
}
public void ToggleVisible(bool value)
public void ForceDisplayOff(bool value)
{
_forceDisplayOff = value;
}
+29 -3
View File
@@ -1,21 +1,47 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static SerializableBone;
public class UIHandleBone : UIHandle
{
public Transform Bone => Target as Transform;
public Transform Bone => Target;
public List<BoneTags> Tags;
public static UIHandleBone CreateAsChild(Transform owner, List<BoneTags> boneTags)
{
return CreateAsChild(owner.gameObject, boneTags);
}
public static UIHandleBone CreateAsChild(GameObject owner, List<BoneTags> boneTags)
{
var handle = new GameObject(owner.name + "_Handle").AddComponent<UIHandleBone>();
handle.transform.parent = owner.transform;
handle.transform.localPosition = Vector3.zero;
handle.transform.localScale = Vector3.one;
handle.Init(owner, boneTags).SetScale(0.8f);
return handle;
}
public UIHandleBone Init(GameObject owner, List<BoneTags> boneTags)
{
Target = owner.transform;
Tags = boneTags;
Init(owner);
base.Init(owner);
if (Tags.Contains(BoneTags.Left)) SetColor(Color.green);
if (Tags.Contains(BoneTags.Right)) SetColor(Color.blue);
SetScale(2f);
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 || !UmaViewerUI.Instance.HandleManager.EnabledHandles.Intersect(Tags).Any();
}
}
@@ -0,0 +1,51 @@
using System.Collections.Generic;
using UnityEngine;
public class UIHandleCharacterRoot : UIHandle
{
public List<UIHandle> ChildHandles = new List<UIHandle>();
public static UIHandleCharacterRoot CreateAsChild(UmaContainer owner)
{
var handle = new GameObject(owner.name + "_Handle").AddComponent<UIHandleCharacterRoot>();
handle.transform.parent = owner.Position;
handle.transform.localPosition = Vector3.zero;
handle.transform.localScale = Vector3.one;
handle.Target = owner.Position;
handle.Init(owner.Position.gameObject).SetColor(Color.red).SetScale(0.8f);
return handle;
}
public override UIHandle Init(GameObject 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("Reset to T-Pose", TransformResetAllChildren);
return this;
}
public void TransformResetAllChildren()
{
List<HandleManager.RuntimeGizmoUndoData> datas = new List<HandleManager.RuntimeGizmoUndoData>();
for(int i = 0; i < ChildHandles.Count; i++)
{
var handle = ChildHandles[i];
var bone = handle.Target;
var undoData = new HandleManager.RuntimeGizmoUndoData();
undoData.OldPosition = new SerializableTransform(bone, Space.World);
handle.TransformReset();
undoData.NewPosition = bone;
datas.Add(undoData);
}
HandleManager.RegisterRuntimeGizmoUndoActions.Invoke(datas);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 38509b8f63b3b4e4f9fc2cfcbf8cae5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+7 -11
View File
@@ -1,6 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
@@ -18,15 +16,13 @@ public class UIPopupPanel : MonoBehaviour
{
Owner = owner;
transform.SetAsFirstSibling();
NameLabel.text = owner.name;
NameLabel.text = owner.Target.name;
return this;
}
private void Update()
public void UpdateManual(Camera camera)
{
var cam = Camera.current;
if (cam.WorldToScreenPoint(Owner.transform.position).x < cam.pixelWidth / 2 - _side)
if (camera.WorldToScreenPoint(Owner.transform.position).x < camera.pixelWidth / 2 - _side)
{
_side = -1;
}
@@ -35,8 +31,8 @@ public class UIPopupPanel : MonoBehaviour
_side = 1;
}
float pos = _side * cam.pixelWidth / 20 + Offset;
transform.position = cam.WorldToScreenPoint(Owner.transform.position) + pos * Vector3.right;
float pos = _side * camera.pixelWidth / 20 + Offset;
transform.position = camera.WorldToScreenPoint(Owner.transform.position) + pos * Vector3.right;
foreach (var kv in ConditionalButtons)
{
@@ -48,14 +44,14 @@ public class UIPopupPanel : MonoBehaviour
{
Button b = Instantiate(UmaViewerUI.Instance.HandleManager.Pfb_PopupButton, Content).GetComponent<Button>();
b.onClick.AddListener(()=>callback.Invoke());
b.GetComponentInChildren<Text>().text = name;
b.GetComponentInChildren<TMPro.TMP_Text>().text = name;
}
public void AddConditionalButton(string name, System.Func<bool> condition, System.Action callback)
{
Button b = Instantiate(UmaViewerUI.Instance.HandleManager.Pfb_PopupButton, Content).GetComponent<Button>();
b.onClick.AddListener(() => callback.Invoke());
b.GetComponentInChildren<Text>().text = name;
b.GetComponentInChildren<TMPro.TMP_Text>().text = name;
ConditionalButtons.Add(b.gameObject, condition);
}
}
+2
View File
@@ -9,5 +9,7 @@ public class PoseData
public string Description;
public string ViewerVersion;
public SerializableBone Root;
public List<SerializableBone> Bones = new List<SerializableBone>();
public List<SerializableMorph> Morphs = new List<SerializableMorph>();
}
+39
View File
@@ -0,0 +1,39 @@
public class PoseLoadOptions
{
public bool
Root,
Position,
Rotation,
Scale,
Morphs,
FaceBones,
Physics;
public static PoseLoadOptions None()
{
return new PoseLoadOptions()
{
Root = false,
Position = false,
Rotation = false,
Scale = false,
Morphs = false,
FaceBones = false,
Physics = false
};
}
public static PoseLoadOptions All()
{
return new PoseLoadOptions()
{
Root = true,
Position = true,
Rotation = true,
Scale = true,
Morphs = true,
FaceBones = true,
Physics = true
};
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 37b2041fb7f624d4abdceb5516aab0ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+98 -9
View File
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
@@ -10,11 +11,57 @@ public class PoseManager : MonoBehaviour
public UIPoseContainer Pfb_PoseContainer;
private bool _isPoseMode = false;
public TMPro.TMP_Text[] TooltipLabels;
public void LoadPoses()
[NonSerialized]
public bool PoseModeOn = false;
[SerializeField]
[Header("Toggles")]
private Toggle
_loadRoot;
[SerializeField]
private Toggle
_loadPosition,
_loadRotation,
_loadScale,
_loadMorphs,
_loadFaceBones,
_loadPhysics;
public List<UIPoseContainer> SavedPoses = new List<UIPoseContainer>();
public GameObject HandleCanvas;
public GameObject HelpPanel;
private void Update()
{
foreach(var file in Directory.GetFiles($"{Application.dataPath}/../Poses/"))
if (Input.GetKeyDown(KeyCode.H))
{
HelpPanel.SetActive(!HelpPanel.activeSelf);
}
}
public static PoseLoadOptions GetLoadOptions()
{
var pm = UmaViewerUI.Instance.PoseManager;
return new PoseLoadOptions()
{
Root = pm._loadRoot.isOn,
Position = pm._loadPosition.isOn,
Rotation = pm._loadRotation.isOn,
Scale = pm._loadScale.isOn,
Morphs = pm._loadMorphs.isOn,
FaceBones = pm._loadFaceBones.isOn,
Physics = pm._loadPhysics.isOn
};
}
public void LoadLocalPoseFiles()
{
Directory.CreateDirectory(Application.dataPath + "/../Poses");
foreach (var file in Directory.GetFiles($"{Application.dataPath}/../Poses/"))
{
Debug.Log(file);
try
@@ -33,20 +80,62 @@ public class PoseManager : MonoBehaviour
}
}
public static void SetPoseModeStatic(bool value)
{
UmaViewerUI.Instance.PoseManager.SetPoseMode(value);
}
/// <summary> Used on UI buttons </summary>
public void SetPoseMode(bool value)
{
if (value == _isPoseMode) return;
if (UmaViewerBuilder.Instance.CurrentUMAContainer == null) return;
if (value == PoseModeOn) return;
if (value)
{
_isPoseMode = true;
UmaViewerBuilder.Instance.CurrentUMAContainer.UmaAnimator.enabled = false;
EnablePoseMode();
}
else
{
_isPoseMode = false;
UmaViewerBuilder.Instance.CurrentUMAContainer.UmaAnimator.enabled = true;
DisablePoseMode();
}
}
public static void SetTooltip(int panelId, string text)
{
UmaViewerUI.Instance.PoseManager.TooltipLabels[panelId].text = text;
}
public void EnablePoseMode()
{
var ui = UmaViewerUI.Instance;
var builder = UmaViewerBuilder.Instance;
ui.SetEyeTrackingEnable(false);
ui.SetDynamicBoneEnable(false);
HandleCanvas.SetActive(true);
if (builder.CurrentUMAContainer != null && builder.CurrentUMAContainer.UmaAnimator != null)
{
builder.CurrentUMAContainer.UmaAnimator.enabled = false;
}
PoseModeOn = true;
}
public void DisablePoseMode()
{
UIPoseContainer.CreateBackupFromScene();
var ui = UmaViewerUI.Instance;
var builder = UmaViewerBuilder.Instance;
ui.SetEyeTrackingEnable(true);
ui.SetDynamicBoneEnable(true);
HandleCanvas.SetActive(false);
if (builder.CurrentUMAContainer != null && builder.CurrentUMAContainer.UmaAnimator != null)
{
builder.CurrentUMAContainer.UmaAnimator.enabled = true;
}
PoseModeOn = false;
}
}
@@ -18,9 +18,18 @@ namespace RuntimeGizmos
this.transform = transform;
oldValues = new TransformValues() {position=transform.position, rotation=transform.rotation, scale=transform.localScale};
}
}
public void StoreNewTransformValues()
public TransformCommand(TransformGizmo transformGizmo, HandleManager.RuntimeGizmoUndoData data)
{
this.transformGizmo = transformGizmo;
this.transform = data.NewPosition;
oldValues = new TransformValues() { position = data.OldPosition.Position, rotation = Quaternion.Euler(data.OldPosition.Rotation), scale = data.OldPosition.Scale };
newValues = new TransformValues() { position = transform.position, rotation = transform.rotation, scale = transform.localScale };
}
public void StoreNewTransformValues()
{
newValues = new TransformValues() {position=transform.position, rotation=transform.rotation, scale=transform.localScale};
}
@@ -1,3 +1,16 @@
{
"name": "RuntimeGizmo"
}
"name": "RuntimeGizmo",
"rootNamespace": "",
"references": [
"GUID:4bfbe5f35cfda4e488c0fb232ba9c5ce"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -4,6 +4,7 @@ using UnityEngine.Rendering;
using System.Collections.Generic;
using System.Collections;
using CommandUndoRedo;
using System.Linq;
namespace RuntimeGizmos
{
@@ -20,6 +21,7 @@ namespace RuntimeGizmos
public CenterType centerType = CenterType.All;
public ScaleType scaleType = ScaleType.FromPoint;
public KeyCode changeModeHotkey = KeyCode.LeftAlt;
//These are the same as the unity editor hotkeys
public KeyCode SetMoveType = KeyCode.W;
public KeyCode SetRotateType = KeyCode.E;
@@ -33,6 +35,7 @@ namespace RuntimeGizmos
public KeyCode translationSnapping = KeyCode.LeftControl;
public KeyCode AddSelection = KeyCode.LeftShift;
public KeyCode RemoveSelection = KeyCode.LeftControl;
public string DevNote = "Action key is set to LeftControl at runtime! It's in Awake()";
public KeyCode ActionKey = KeyCode.LeftShift; //Its set to shift instead of control so that while in the editor we dont accidentally undo editor changes =/
public KeyCode UndoAction = KeyCode.Z;
public KeyCode RedoAction = KeyCode.Y;
@@ -133,7 +136,31 @@ namespace RuntimeGizmos
{
myCamera = GetComponent<Camera>();
SetMaterial();
#if !UNITY_EDITOR
ActionKey = KeyCode.LeftControl;
#endif
}
private void Start()
{
HandleManager.RegisterRuntimeGizmoUndoAction = (data) =>
{
var transformCommand = new TransformCommand(this, data);
UndoRedoManager.Insert(transformCommand);
};
HandleManager.RegisterRuntimeGizmoUndoActions = (data) =>
{
CommandGroup commandGroup = new CommandGroup();
commandGroup.Set(data.Select(d=> new TransformCommand(this, d)).ToList<ICommand>());
UndoRedoManager.Insert(commandGroup);
};
PoseManager.SetTooltip(0, $"H - show/hide this\r\n\r\nUndo:\t\t{ActionKey} + {UndoAction}\r\nRedo:\t\t{ActionKey} + {RedoAction}\r\n\r\nMove only: \t{changeModeHotkey} + {SetMoveType}\r\nRotate only: {changeModeHotkey} + {SetRotateType}\r\nScale only: \t{changeModeHotkey} + {SetScaleType}\r\nAll:\t \t{changeModeHotkey} + {SetAllTransformType}");
PoseManager.SetTooltip(1, $"\r\n\r\nSpace Toggle:\t{changeModeHotkey} + {SetSpaceToggle}\r\nPivot Toggle:\t{changeModeHotkey} + {SetPivotModeToggle}\r\nScale type toggle: \t{changeModeHotkey} + {SetScaleTypeToggle}\r\nCenter type toggle:{changeModeHotkey} + {SetCenterTypeToggle}");
}
private void RenderPipelineManager_endFrameRendering(ScriptableRenderContext context, Camera[] camera)
{
OnPostRender();
@@ -174,6 +201,8 @@ namespace RuntimeGizmos
GetTarget();
PoseManager.SetTooltip(2, $"\n\nSpace:\t{space}\nPivot:\t\t{pivot}\nScale:\t\t{scaleType}\nCenter:\t{centerType}");
if (mainTargetRoot == null) return;
TransformSelected();
@@ -319,40 +348,46 @@ namespace RuntimeGizmos
{
if (Input.GetKey(ActionKey)) return;
if (Input.GetKeyDown(SetMoveType)) transformType = TransformType.Move;
else if (Input.GetKeyDown(SetRotateType)) transformType = TransformType.Rotate;
else if (Input.GetKeyDown(SetScaleType)) transformType = TransformType.Scale;
//else if(Input.GetKeyDown(SetRectToolType)) type = TransformType.RectTool;
else if (Input.GetKeyDown(SetAllTransformType)) transformType = TransformType.All;
if (Input.GetKey(changeModeHotkey))
{
if (Input.GetKeyDown(SetMoveType)) transformType = TransformType.Move;
else if (Input.GetKeyDown(SetRotateType)) transformType = TransformType.Rotate;
else if (Input.GetKeyDown(SetScaleType)) transformType = TransformType.Scale;
//else if(Input.GetKeyDown(SetRectToolType)) type = TransformType.RectTool;
else if (Input.GetKeyDown(SetAllTransformType)) transformType = TransformType.All;
}
if (!isTransforming) translatingType = transformType;
if (Input.GetKeyDown(SetPivotModeToggle))
if (Input.GetKey(changeModeHotkey))
{
if (pivot == TransformPivot.Pivot) pivot = TransformPivot.Center;
else if (pivot == TransformPivot.Center) pivot = TransformPivot.Pivot;
if (Input.GetKeyDown(SetPivotModeToggle))
{
if (pivot == TransformPivot.Pivot) pivot = TransformPivot.Center;
else if (pivot == TransformPivot.Center) pivot = TransformPivot.Pivot;
SetPivotPoint();
}
SetPivotPoint();
}
if (Input.GetKeyDown(SetCenterTypeToggle))
{
if (centerType == CenterType.All) centerType = CenterType.Solo;
else if (centerType == CenterType.Solo) centerType = CenterType.All;
if (Input.GetKeyDown(SetCenterTypeToggle))
{
if (centerType == CenterType.All) centerType = CenterType.Solo;
else if (centerType == CenterType.Solo) centerType = CenterType.All;
SetPivotPoint();
}
SetPivotPoint();
}
if (Input.GetKeyDown(SetSpaceToggle))
{
if (space == TransformSpace.Global) space = TransformSpace.Local;
else if (space == TransformSpace.Local) space = TransformSpace.Global;
}
if (Input.GetKeyDown(SetSpaceToggle))
{
if (space == TransformSpace.Global) space = TransformSpace.Local;
else if (space == TransformSpace.Local) space = TransformSpace.Global;
}
if (Input.GetKeyDown(SetScaleTypeToggle))
{
if (scaleType == ScaleType.FromPoint) scaleType = ScaleType.FromPointOffset;
else if (scaleType == ScaleType.FromPointOffset) scaleType = ScaleType.FromPoint;
if (Input.GetKeyDown(SetScaleTypeToggle))
{
if (scaleType == ScaleType.FromPoint) scaleType = ScaleType.FromPointOffset;
else if (scaleType == ScaleType.FromPointOffset) scaleType = ScaleType.FromPoint;
}
}
if (transformType == TransformType.Scale)
@@ -374,7 +409,7 @@ namespace RuntimeGizmos
IEnumerator TransformSelected(TransformType transType)
{
isTransforming = true;
SetTransforming(true);
totalScaleAmount = 0;
totalRotationAmount = Quaternion.identity;
@@ -593,7 +628,7 @@ namespace RuntimeGizmos
totalRotationAmount = Quaternion.identity;
totalScaleAmount = 0;
isTransforming = false;
SetTransforming(false);
SetTranslatingAxis(transformType, Axis.None);
SetPivotPoint();
@@ -649,8 +684,13 @@ namespace RuntimeGizmos
void GetTarget()
{
if (nearAxis == Axis.None && Input.GetMouseButtonDown(0))
if (nearAxis == Axis.None)
{
bool leftClick = Input.GetMouseButtonDown(0);
bool rightClick = Input.GetMouseButtonDown(1);
if (!leftClick && !rightClick) return;
bool isAdding = Input.GetKey(AddSelection);
bool isRemoving = Input.GetKey(RemoveSelection);
@@ -658,28 +698,34 @@ namespace RuntimeGizmos
if (Physics.Raycast(myCamera.ScreenPointToRay(Input.mousePosition), out hitInfo, Mathf.Infinity, selectionMask))
{
Transform target = hitInfo.transform;
//UIHandle handle = target.GetComponent<UIHandle>();
//target = handle.Target as Transform;
UIHandle handle = target.GetComponent<UIHandle>();
target = handle.Target as Transform;
if (isAdding)
if (rightClick)
{
AddTarget(target);
HandleManager.CloseAllPopups();
handle.TogglePopup(0);
}
else if (isRemoving)
else if (leftClick)
{
RemoveTarget(target);
}
else if (!isAdding && !isRemoving)
{
ClearAndAddTarget(target);
if (isAdding)
{
AddTarget(target);
}
else if (isRemoving)
{
RemoveTarget(target);
}
else if (!isAdding && !isRemoving)
{
ClearAndAddTarget(target);
}
}
}
else
else if (rightClick)
{
if (!isAdding && !isRemoving)
{
ClearTargets();
}
HandleManager.CloseAllPopups();
ClearTargets();
}
}
}
@@ -1443,5 +1489,11 @@ namespace RuntimeGizmos
outlineMaterial = new Material(Shader.Find("Custom/Outline"));
}
}
void SetTransforming(bool value)
{
isTransforming = value;
HandleManager.InteractionInProgress = value;
}
}
}
@@ -0,0 +1,15 @@
using CommandUndoRedo;
using UnityEngine;
public class TransformGizmoHotkeys : MonoBehaviour
{
public void Undo()
{
UndoRedoManager.Undo();
}
public void Redo()
{
UndoRedoManager.Redo();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c9a2023f1ce29ab4dad6a65ea603cdd0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+6 -15
View File
@@ -23,16 +23,16 @@ public class SerializableBone
{
if (t.name.EndsWith("_L"))
{
Tags.Add(BoneTags.Left);
tags.Add(BoneTags.Left);
}
else if (t.name.EndsWith("_R"))
{
Tags.Add(BoneTags.Right);
tags.Add(BoneTags.Right);
}
if(t.GetComponentInParent<DynamicBone>() != null)
{
Tags.Add(BoneTags.Dynamic);
tags.Add(BoneTags.Dynamic);
}
}
@@ -44,23 +44,14 @@ public class SerializableBone
Bone = t;
}
public void ApplyTo(SerializableBone target)
{
if(target.Bone == null)
{
Debug.LogError($"Target bone {target.Name} does not reference a bone in the scene.");
return;
}
Transform.ApplyTo(target.Bone);
}
//feel free to add more
//feel free to add more. do not change order!
public enum BoneTags
{
Left,
Right,
Dynamic,
Humanoid,
Finger,
Face
}
}
+34
View File
@@ -0,0 +1,34 @@
using Gallop;
using System;
[System.Serializable]
public class SerializableMorph
{
public string Name = "";
public float Value = 0;
/// <summary> Reference to original morph for runtime. Not saved to file. </summary>
[NonSerialized] public FacialMorph Morph;
public SerializableMorph() { }
public SerializableMorph(FacialMorph morph)
{
Name = morph.name;
Value = morph.weight;
Morph = morph;
}
public void ApplyTo(UmaContainerCharacter character, FacialMorph morph, bool applyImmediately = true)
{
if (applyImmediately)
{
character.FaceDrivenKeyTarget.ChangeMorphWeight(morph, Value);
}
else
{
morph.weight = Value;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4e4eff844b7703a43a9540a331eddbeb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -50,4 +50,20 @@ public class SerializableTransform
t.localScale = Scale;
}
}
public void ApplyTo(Transform t, PoseLoadOptions options)
{
if (Space == Space.World)
{
if (options.Position) t.position = Position;
if (options.Rotation) t.eulerAngles = Rotation;
if (options.Scale) t.localScale = Scale;
}
else
{
if (options.Position) t.localPosition = Position;
if (options.Rotation) t.localEulerAngles = Rotation;
if (options.Scale) t.localScale = Scale;
}
}
}
+120 -4
View File
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
@@ -28,6 +29,50 @@ public class UIPoseContainer : MonoBehaviour
return poseContainer;
}
public static void CreateBackupFromScene()
{
UmaContainerCharacter container = UmaViewerBuilder.Instance.CurrentUMAContainer;
if (container == null) return;
var poseData = new PoseData();
poseData.Name = "AutoBackup";
poseData.Date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
poseData.Character = container.name;
poseData.Description = "Last created pose";
poseData.ViewerVersion = Application.version;
poseData.Bones = container.SaveBones();
poseData.Morphs = container.SaveMorphs(true);
string fullpath = $"{Application.dataPath}/../Poses/{poseData.Name}.umaPose";
fullpath = Path.GetFullPath(fullpath);
try
{
Directory.CreateDirectory(Application.dataPath + "/../Poses");
File.WriteAllText(fullpath, JsonConvert.SerializeObject(poseData));
UmaViewerUI.Instance.ShowMessage($"Saved pose: {fullpath}", UIMessageType.Success);
var poseContainers = UmaViewerUI.Instance.PoseManager.SavedPoseList.content.GetComponentsInChildren<UIPoseContainer>();
var poseContainer = poseContainers.FirstOrDefault(c => c.NameLabel.text == "AutoBackup");
if (poseContainer != null)
{
poseContainer.Init(poseData);
}
else
{
UIPoseContainer.Create(poseData);
}
}
catch (Exception e)
{
UmaViewerUI.Instance.ShowMessage(e.Message, UIMessageType.Error);
}
}
public void Init(PoseData data)
{
PoseData = data;
@@ -37,6 +82,47 @@ public class UIPoseContainer : MonoBehaviour
InfoLabel.text = $"Version: {data.ViewerVersion}\nCharacter: {data.Character}\nSave date: {data.Date}";
}
public void SaveNew()
{
UmaContainerCharacter container = UmaViewerBuilder.Instance.CurrentUMAContainer;
if (container == null) return;
var poseData = new PoseData();
poseData.Name = NameLabel.text;
poseData.Date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
poseData.Character = container.name;
poseData.Description = DescriptionLabel.text;
poseData.ViewerVersion = Application.version;
poseData.Bones = container.SaveBones();
poseData.Morphs = container.SaveMorphs(true);
var duplicateContainer = CheckIfContainerExists(poseData.Name);
if (duplicateContainer != this)
{
UmaViewerUI.Instance.ShowMessage($"Another save exists with name {poseData.Name}", UIMessageType.Error);
return;
}
string fullpath = $"{Application.dataPath}/../Poses/{poseData.Name}.umaPose";
fullpath = Path.GetFullPath(fullpath);
try
{
Directory.CreateDirectory(Application.dataPath + "/../Poses");
File.WriteAllText(fullpath, JsonConvert.SerializeObject(poseData));
UmaViewerUI.Instance.ShowMessage($"Saved pose: {fullpath}", UIMessageType.Success);
UIPoseContainer.Create(poseData);
}
catch (Exception e)
{
UmaViewerUI.Instance.ShowMessage(e.Message, UIMessageType.Error);
}
}
public void Save()
{
UmaContainerCharacter container = UmaViewerBuilder.Instance.CurrentUMAContainer;
@@ -50,6 +136,14 @@ public class UIPoseContainer : MonoBehaviour
poseData.Description = DescriptionLabel.text;
poseData.ViewerVersion = Application.version;
poseData.Bones = container.SaveBones();
poseData.Morphs = container.SaveMorphs(true);
var duplicateContainer = CheckIfContainerExists(poseData.Name);
if (duplicateContainer != this)
{
UmaViewerUI.Instance.ShowMessage($"Another save exists with name {poseData.Name}", UIMessageType.Error);
return;
}
string fullpath = $"{Application.dataPath}/../Poses/{poseData.Name}.umaPose";
fullpath = Path.GetFullPath(fullpath);
@@ -62,8 +156,15 @@ public class UIPoseContainer : MonoBehaviour
UmaViewerUI.Instance.ShowMessage($"Saved pose: {fullpath}", UIMessageType.Success);
//Only replace the data if everything succeeded
Init(poseData);
if(poseData.Name != PoseData.Name)
{
UIPoseContainer.Create(poseData);
}
else
{
//Only replace the data if everything succeeded
Init(poseData);
}
}
catch (Exception e)
{
@@ -73,13 +174,20 @@ public class UIPoseContainer : MonoBehaviour
public void Load()
{
UmaViewerUI.Instance.PoseManager.SetPoseMode(true);
PoseManager.SetPoseModeStatic(true);
UmaContainerCharacter container = UmaViewerBuilder.Instance.CurrentUMAContainer;
if (container == null) return;
container.LoadBones(PoseData);
var loadOptions = PoseManager.GetLoadOptions();
container.LoadBones(PoseData, loadOptions);
if (loadOptions.Morphs)
{
container.LoadMorphs(PoseData);
}
}
public void Delete()
@@ -96,4 +204,12 @@ public class UIPoseContainer : MonoBehaviour
UmaViewerUI.Instance.ShowMessage($"Deleted pose: {fullpath}", UIMessageType.Success);
}
private UIPoseContainer CheckIfContainerExists(string poseName)
{
var poseContainers = UmaViewerUI.Instance.PoseManager.SavedPoseList.content.GetComponentsInChildren<UIPoseContainer>();
var poseContainer = poseContainers.FirstOrDefault(c => c.NameLabel.text == poseName);
return poseContainer;
}
}
+209 -107
View File
@@ -84,7 +84,7 @@ public class UmaContainerCharacter : UmaContainer
private Collider dragCollider;
private BipedIK IK;
private PuppetMaster PuppetMaster;
private HashSet<Transform> _humanoidBones;
private List<Transform> _humanoidBones;
public void Initialize(bool smile)
{
@@ -99,7 +99,7 @@ public class UmaContainerCharacter : UmaContainer
if (FaceDrivenKeyTarget && smile)
FaceDrivenKeyTarget.ChangeMorphWeight(FaceDrivenKeyTarget.MouthMorphs[3], 1);
//CreateIK();
CreateIK();
}
public void MergeModel()
@@ -280,6 +280,11 @@ public class UmaContainerCharacter : UmaContainer
}
}
public void SetPuppetMasterMode(PuppetMaster.Mode mode)
{
PuppetMaster.mode = mode;
}
public void SetDynamicBoneEnable(bool isOn)
{
if (IsMini) return;
@@ -297,121 +302,120 @@ public class UmaContainerCharacter : UmaContainer
public void SetFaceOverrideData(bool isOn)
{
FaceOverrideData.SetEnable(isOn);
FaceOverrideData?.SetEnable(isOn);
}
private void FixedUpdate()
{
if (!IsMini)
if (IsMini) return;
if (TrackTarget && EnableEyeTracking && !isAnimatorControl)
{
if (TrackTarget && EnableEyeTracking && !isAnimatorControl)
if (IK && !IK.enabled)
{
if (IK && !IK.enabled)
IK.enabled = true;
if (PuppetMaster.mode != PuppetMaster.Mode.Active)
{
IK.enabled = true;
if (PuppetMaster.mode != PuppetMaster.Mode.Active)
{
PuppetMaster.mode = PuppetMaster.Mode.Active;
}
SetPuppetMasterMode(PuppetMaster.Mode.Active);
}
}
var finalRotation = FaceDrivenKeyTarget.GetEyeTrackRotation(TrackTarget.transform.position);
FaceDrivenKeyTarget.SetEyeTrack(finalRotation);
var finalRotation = FaceDrivenKeyTarget.GetEyeTrackRotation(TrackTarget.transform.position);
FaceDrivenKeyTarget.SetEyeTrack(finalRotation);
var cam = Camera.main;
var distance = Mathf.Clamp(cam.transform.InverseTransformPoint(HeadBone.transform.position).magnitude - 0.1f, 0, 2);
var mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance);
var worldPos = cam.ScreenToWorldPoint(mousePos);
var cam = Camera.main;
var distance = Mathf.Clamp(cam.transform.InverseTransformPoint(HeadBone.transform.position).magnitude - 0.1f, 0, 2);
var mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance);
var worldPos = cam.ScreenToWorldPoint(mousePos);
//Hold D key to Drag Body
if (Input.GetKey(KeyCode.D))
{
if (dragCollider && dragCollider.attachedRigidbody)
{
if (PuppetMaster)
{
PuppetMaster.pinWeight = 0.75f;
PuppetMaster.muscleWeight = 0.25f;
}
dragCollider.attachedRigidbody.isKinematic = true;
dragCollider.transform.position = Vector3.Lerp(dragCollider.transform.position, cam.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, dragdistance)) - dragStartPos, Time.fixedDeltaTime * 4);
//LookAt Mouse when Dragging
TrackTarget.position = Vector3.Lerp(TrackTarget.position, dragCollider.transform.position, Time.fixedDeltaTime * 3);
}
else
{
if (Physics.Raycast(cam.ScreenPointToRay(mousePos), out RaycastHit hit))
{
dragCollider = hit.collider;
dragStartPos = (hit.point - hit.collider.transform.position);
dragdistance = cam.transform.InverseTransformPoint(hit.point).magnitude;
}
//LookAt Camera
TrackTarget.position = Vector3.Lerp(TrackTarget.position, cam.transform.position, Time.fixedDeltaTime * 3);
}
}
else
//Hold D key to Drag Body
if (Input.GetKey(KeyCode.D))
{
if (dragCollider && dragCollider.attachedRigidbody)
{
if (PuppetMaster)
{
PuppetMaster.pinWeight = 1;
PuppetMaster.muscleWeight = 1;
PuppetMaster.pinWeight = 0.75f;
PuppetMaster.muscleWeight = 0.25f;
}
dragCollider.attachedRigidbody.isKinematic = true;
dragCollider.transform.position = Vector3.Lerp(dragCollider.transform.position, cam.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, dragdistance)) - dragStartPos, Time.fixedDeltaTime * 4);
//LookAt Mouse when Dragging
TrackTarget.position = Vector3.Lerp(TrackTarget.position, dragCollider.transform.position, Time.fixedDeltaTime * 3);
}
else
{
if (Physics.Raycast(cam.ScreenPointToRay(mousePos), out RaycastHit hit))
{
dragCollider = hit.collider;
dragStartPos = (hit.point - hit.collider.transform.position);
dragdistance = cam.transform.InverseTransformPoint(hit.point).magnitude;
}
//LookAt Camera
TrackTarget.position = Vector3.Lerp(TrackTarget.position, cam.transform.position, Time.fixedDeltaTime * 3);
if (dragCollider && dragCollider.attachedRigidbody) dragCollider.attachedRigidbody.isKinematic = false;
dragCollider = null;
}
}
else
{
if (IK && IK.enabled)
if (PuppetMaster)
{
IK.enabled = false;
if (PuppetMaster.mode != PuppetMaster.Mode.Kinematic)
{
PuppetMaster.mode = PuppetMaster.Mode.Kinematic;
}
PuppetMaster.pinWeight = 1;
PuppetMaster.muscleWeight = 1;
}
//LookAt Camera
TrackTarget.position = Vector3.Lerp(TrackTarget.position, cam.transform.position, Time.fixedDeltaTime * 3);
if (dragCollider && dragCollider.attachedRigidbody) dragCollider.attachedRigidbody.isKinematic = false;
dragCollider = null;
}
}
else
{
if (IK && IK.enabled)
{
IK.enabled = false;
if (PuppetMaster && PuppetMaster.mode != PuppetMaster.Mode.Kinematic)
{
SetPuppetMasterMode(PuppetMaster.Mode.Kinematic);
}
}
}
if (isAnimatorControl)
{
FaceDrivenKeyTarget.ProcessLocator();
}
if (FaceMaterial)
{
if (isAnimatorControl)
{
FaceDrivenKeyTarget.ProcessLocator();
}
FaceMaterial.SetVector("_FaceForward", Vector3.zero);
FaceMaterial.SetVector("_FaceUp", Vector3.zero);
FaceMaterial.SetVector("_FaceCenterPos", Vector3.zero);
if (FaceMaterial)
}
else
{
if (isAnimatorControl)
{
FaceMaterial.SetVector("_FaceForward", Vector3.zero);
FaceMaterial.SetVector("_FaceUp", Vector3.zero);
FaceMaterial.SetVector("_FaceCenterPos", Vector3.zero);
}
else
{
//Used to calculate facial shadows
FaceMaterial.SetVector("_FaceForward", HeadBone.transform.forward);
FaceMaterial.SetVector("_FaceUp", HeadBone.transform.up);
FaceMaterial.SetVector("_FaceCenterPos", HeadBone.transform.position);
}
FaceMaterial.SetMatrix("_faceShadowHeadMat", HeadBone.transform.worldToLocalMatrix);
//Used to calculate facial shadows
FaceMaterial.SetVector("_FaceForward", HeadBone.transform.forward);
FaceMaterial.SetVector("_FaceUp", HeadBone.transform.up);
FaceMaterial.SetVector("_FaceCenterPos", HeadBone.transform.position);
}
FaceMaterial.SetMatrix("_faceShadowHeadMat", HeadBone.transform.worldToLocalMatrix);
}
TearControllers.ForEach(a => a.UpdateOffset());
TearControllers.ForEach(a => a.UpdateOffset());
//Apply UV Animation
//Apply UV Animation
if(HeadShaderEffectData != null)
{
HeadShaderEffectData.updateUV(Time.fixedDeltaTime);
}
if(HeadShaderEffectData != null)
{
HeadShaderEffectData.updateUV(Time.fixedDeltaTime);
}
if(BodyShaderEffectData != null)
{
BodyShaderEffectData.updateUV(Time.fixedDeltaTime);
}
if(BodyShaderEffectData != null)
{
BodyShaderEffectData.updateUV(Time.fixedDeltaTime);
}
}
@@ -1361,6 +1365,8 @@ public class UmaContainerCharacter : UmaContainer
public void SetupBoneHandles()
{
UIHandleCharacterRoot rootHandle = UIHandleCharacterRoot.CreateAsChild(this);
var humanBones = GetHumanBones();
foreach(var bone in humanBones)
{
@@ -1368,11 +1374,47 @@ public class UmaContainerCharacter : UmaContainer
if (bone.name.EndsWith("_L")) tags.Add(BoneTags.Left);
if (bone.name.EndsWith("_R")) tags.Add(BoneTags.Right);
var handle = new GameObject(bone.name + "_Handle").AddComponent<UIHandleBone>();
handle.transform.parent = bone;
handle.transform.localPosition = Vector3.zero;
handle.transform.localScale = Vector3.one;
handle.Init(bone.gameObject, tags);
if(bone.name != "Hip")
{
var handle = UIHandleBone.CreateAsChild(bone, tags).WithLineRenderer();
rootHandle.ChildHandles.Add(handle);
}
else
{
var handle = UIHandleBone.CreateAsChild(bone, tags);
rootHandle.ChildHandles.Add(handle);
}
}
var wrist_L = humanBones.Find(b => b.name == "Wrist_L");
foreach(var fingerBone in wrist_L.transform.GetComponentsInChildren<Transform>())
{
if(fingerBone.name.StartsWith("Index") || fingerBone.name.StartsWith("Middle") || fingerBone.name.StartsWith("Ring") || fingerBone.name.StartsWith("Pinky") || fingerBone.name.StartsWith("Thumb"))
{
List<BoneTags> tags = new List<BoneTags>() { BoneTags.Left, BoneTags.Finger };
var handle = UIHandleBone.CreateAsChild(fingerBone, tags).SetScale(0.25f).WithLineRenderer();
rootHandle.ChildHandles.Add(handle);
}
}
var wrist_R = humanBones.Find(b => b.name == "Wrist_R");
foreach (var fingerBone in wrist_R.transform.GetComponentsInChildren<Transform>())
{
if (fingerBone.name.StartsWith("Index") || fingerBone.name.StartsWith("Middle") || fingerBone.name.StartsWith("Ring") || fingerBone.name.StartsWith("Pinky") || fingerBone.name.StartsWith("Thumb"))
{
List<BoneTags> tags = new List<BoneTags>() { BoneTags.Right, BoneTags.Finger };
var handle = UIHandleBone.CreateAsChild(fingerBone, tags).SetScale(0.25f).WithLineRenderer();
rootHandle.ChildHandles.Add(handle);
}
}
var allBones = SaveBones();
foreach(var bone in allBones.Where(b => b.Tags.Contains(BoneTags.Dynamic)))
{
var handle = UIHandleBone.CreateAsChild(bone.Bone, bone.Tags).SetColor(Color.gray).SetScale(0.15f).WithLineRenderer();
rootHandle.ChildHandles.Add(handle);
}
}
@@ -1406,49 +1448,109 @@ public class UmaContainerCharacter : UmaContainer
bones.Add(bone);
}
public bool LoadBones(PoseData data)
public bool LoadBones(PoseData data, PoseLoadOptions options)
{
var currentBones = SaveBones();
foreach (var bone in currentBones)
{
if (!options.Root && bone.ParentName == "root") continue;
if (!options.Physics && bone.Tags.Contains(BoneTags.Dynamic)) continue;
if (bone.Bone == null)
{
Debug.LogError($"Target bone {bone.Name} does not reference a bone in the scene.");
continue;
}
var savedBone = data.Bones.FirstOrDefault(b => b.Name == bone.Name && b.ParentName == bone.ParentName);
if (savedBone == null) continue;
savedBone.ApplyTo(bone);
savedBone.Transform.ApplyTo(bone.Bone, options);
}
//could add a 'bone not found' threshold for returning false
return true;
}
public HashSet<Transform> GetHumanBones()
public List<Transform> GetHumanBones()
{
if(_humanoidBones == null)
{
var animator = UmaAnimator;
HashSet<Transform> humanBones = new HashSet<Transform>();
//foreach (HumanBodyBones boneName in Enum.GetValues(typeof(HumanBodyBones)))
//{
// if (boneName == HumanBodyBones.LastBone) break;
List<Transform> list = new List<Transform>(animator.gameObject.GetComponentsInChildren<Transform>());
// var bone = animator.GetBoneTransform(boneName);
// if (bone != null)
// {
// humanBones.Add(bone);
// }
//}
BipedRagdollReferences r = BipedRagdollReferences.FromAvatar(animator);
foreach(var bone in r.GetRagdollTransforms())
_humanoidBones = new List<Transform>()
{
humanBones.Add(bone);
}
list.Find(t => t.name.Equals("Hip")),
list.Find(t => t.name.Equals("Waist")),
list.Find(t => t.name.Equals("Spine")),
list.Find(t => t.name.Equals("Chest")),
list.Find(t => t.name.Equals("Neck")),
list.Find(t => t.name.Equals("Head")),
_humanoidBones = humanBones;
list.Find(t => t.name.Equals("Shoulder_L")),
list.Find(t => t.name.Equals("Arm_L")),
list.Find(t => t.name.Equals("Elbow_L")),
list.Find(t => t.name.Equals("Wrist_L")),
list.Find(t => t.name.Equals("Shoulder_R")),
list.Find(t => t.name.Equals("Arm_R")),
list.Find(t => t.name.Equals("Elbow_R")),
list.Find(t => t.name.Equals("Wrist_R")),
list.Find(t => t.name.Equals("Thigh_L")),
list.Find(t => t.name.Equals("Knee_L")),
list.Find(t => t.name.Equals("Ankle_L")),
list.Find(t => t.name.Equals("Toe_L")),
list.Find(t => t.name.Equals("Thigh_R")),
list.Find(t => t.name.Equals("Knee_R")),
list.Find(t => t.name.Equals("Ankle_R")),
list.Find(t => t.name.Equals("Toe_R"))
};
}
return _humanoidBones;
}
public List<SerializableMorph> SaveMorphs(bool changedOnly)
{
if (FaceDrivenKeyTarget == null)
{
return new List<SerializableMorph>();
}
if (changedOnly)
{
return FaceDrivenKeyTarget.AllMorphs.Where(morph => morph.weight != 0).Select(morph => new SerializableMorph(morph)).ToList();
}
else
{
return FaceDrivenKeyTarget.AllMorphs.Select(morph => new SerializableMorph(morph)).ToList();
}
}
public bool LoadMorphs(PoseData data)
{
var currentMorphs = SaveMorphs(false);
foreach (var morph in currentMorphs)
{
var savedMorph = data.Morphs.FirstOrDefault(b => b.Name == morph.Name);
if (savedMorph == null)
{
morph.Morph.weight = 0;
}
else
{
savedMorph.ApplyTo(this, morph.Morph, false);
}
}
this.FaceDrivenKeyTarget.ChangeMorph();
return true;
}
}
+5 -6
View File
@@ -5,7 +5,6 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UmaMusumeAudio;
@@ -17,8 +16,8 @@ using Random = UnityEngine.Random;
public class UmaViewerBuilder : MonoBehaviour
{
public static UmaViewerBuilder Instance;
public static UmaViewerMain Main => UmaViewerMain.Instance;
UmaViewerUI UI => UmaViewerUI.Instance;
static UmaViewerMain Main => UmaViewerMain.Instance;
static UmaViewerUI UI => UmaViewerUI.Instance;
public List<AssetBundle> Loaded;
public List<Shader> ShaderList = new List<Shader>();
@@ -47,12 +46,12 @@ public class UmaViewerBuilder : MonoBehaviour
public IEnumerator LoadUma(CharaEntry chara, string costumeId, bool mini)
{
PoseManager.SetPoseModeStatic(false);
int id = chara.Id;
var umaContainer = new GameObject($"Chara_{id}_{costumeId}").AddComponent<UmaContainerCharacter>();
CurrentUMAContainer = umaContainer;
UmaViewerUI.Instance.PoseManager.SetPoseMode(false);
if (mini)
{
umaContainer.CharaData = UmaDatabaseController.ReadCharaData(chara);
@@ -303,9 +302,9 @@ public class UmaViewerBuilder : MonoBehaviour
umaContainer.MergeModel();
umaContainer.SetHeight(-1);
umaContainer.Initialize(!UI.isTPose);
umaContainer.SetupBoneHandles();
umaContainer.Position = umaContainer.transform.Find("Position");
umaContainer.SetupBoneHandles();
if (!UI.isTPose && loadMotion)
{
+5 -4
View File
@@ -10,6 +10,7 @@ using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Debug = UnityEngine.Debug;
public class UmaViewerUI : MonoBehaviour
{
@@ -163,7 +164,7 @@ public class UmaViewerUI : MonoBehaviour
UmaAssetManager.OnLoadedBundleUpdate += LoadedAssetsAdd;
UmaAssetManager.OnLoadedBundleClear += LoadedAssetsClear;
PoseManager.LoadPoses();
PoseManager.LoadLocalPoseFiles();
}
private void OnDestroy()
@@ -1057,19 +1058,19 @@ public class UmaViewerUI : MonoBehaviour
public void SetDynamicBoneEnable(bool isOn)
{
DynamicBoneEnable = isOn;
(Builder.CurrentUMAContainer)?.SetDynamicBoneEnable(isOn);
Builder.CurrentUMAContainer?.SetDynamicBoneEnable(isOn);
}
public void SetEyeTrackingEnable(bool isOn)
{
EnableEyeTracking = isOn;
(Builder.CurrentUMAContainer)?.SetEyeTracking(isOn);
Builder.CurrentUMAContainer?.SetEyeTracking(isOn);
}
public void SetFaceOverrideEnable(bool isOn)
{
EnableFaceOverride = isOn;
(Builder.CurrentUMAContainer)?.SetFaceOverrideData(isOn);
Builder.CurrentUMAContainer?.SetFaceOverrideData(isOn);
}
public void AudioPause()
@@ -1,12 +1,11 @@
using Gallop.Live.Cutt;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static DynamicBone;
using static Gallop.DrivenKeyComponent;
using static Gallop.FaceDrivenKeyTarget;
using static Gallop.Live.Cutt.LiveTimelineDefine;
using static RootMotion.FinalIK.FBBIKHeadEffector;
namespace Gallop
{
@@ -32,6 +31,7 @@ namespace Gallop
public List<FacialMorph> EyeMorphs = new List<FacialMorph>();
public List<FacialMorph> MouthMorphs = new List<FacialMorph>();
public List<FacialOtherMorph> OtherMorphs = new List<FacialOtherMorph>();
public List<FacialMorph> AllMorphs => EarMorphs.Concat(EyeBrowMorphs).Concat(EyeMorphs).Concat(MouthMorphs).Concat(OtherMorphs).ToList();
public Transform DrivenKeyLocator;
public Transform EyeballCtrl_L_Locator, EyeballCtrl_R_Locator, EyeballCtrl_All_Locator;
+1 -1
View File
@@ -18,7 +18,7 @@ PhysicsManager:
m_ClothInterCollisionDistance: 0
m_ClothInterCollisionStiffness: 0
m_ContactsGeneration: 1
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_LayerCollisionMatrix: fffffffefffffffefffffffefffffffffffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffe080000feffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_AutoSimulation: 1
m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 1
+8 -2
View File
@@ -3,7 +3,7 @@
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 22
serializedVersion: 23
productGUID: 466286cbc59748b4ca46e7b05d5929c2
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
@@ -134,7 +134,7 @@ PlayerSettings:
16:10: 1
16:9: 1
Others: 1
bundleVersion: 2.1.9
bundleVersion: 2.1.10
preloadedAssets: []
metroInputSource: 0
wsaTransparentSwapchain: 0
@@ -150,6 +150,7 @@ PlayerSettings:
m_ColorGamuts: 00000000
targetPixelDensity: 392
resolutionScalingMode: 1
resetResolutionOnWindowResize: 0
androidSupportedAspectRatio: 1
androidMaxAspectRatio: 2.1
applicationIdentifier:
@@ -593,8 +594,11 @@ PlayerSettings:
switchNetworkInterfaceManagerInitializeEnabled: 1
switchPlayerConnectionEnabled: 1
switchUseNewStyleFilepaths: 0
switchUseLegacyFmodPriorities: 1
switchUseMicroSleepForYield: 1
switchEnableRamDiskSupport: 0
switchMicroSleepForYieldTime: 25
switchRamDiskSpaceSize: 12
ps4NPAgeRating: 12
ps4NPTitleSecret:
ps4NPTrophyPackPath:
@@ -753,6 +757,7 @@ PlayerSettings:
metroFTAName:
metroFTAFileTypes: []
metroProtocolName:
vcxProjDefaultLanguage:
XboxOneProductId:
XboxOneUpdateKey:
XboxOneSandboxId:
@@ -796,6 +801,7 @@ PlayerSettings:
m_VersionName:
apiCompatibilityLevel: 6
activeInputHandler: 0
windowsGamepadBackendHint: 0
cloudProjectId:
framebufferDepthMemorylessMode: 0
qualitySettingsNames: []