Merge branch 'katboi01:master' into master

This commit is contained in:
CroakFang
2024-01-02 10:34:54 +08:00
committed by GitHub
2872 changed files with 16088 additions and 1488512 deletions
+3 -5
View File
@@ -1,10 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine.Rendering.PostProcessing;
public class CameraOrbit : MonoBehaviour
{
@@ -57,6 +53,8 @@ public class CameraOrbit : MonoBehaviour
void Update()
{
if (HandleManager.InteractionInProgress) return;
if(CameraMode != CameraModeDropdown.value)
{
switch (CameraMode) //old
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: db92d939bae9b7a428f4312afd2069c2
guid: 3f19855477d867747adb8589646d818b
folderAsset: yes
DefaultImporter:
externalObjects: {}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: aaf76cab8a038d047bff6965417ce565
guid: 4ccbd2977bf371d489f029f85a5d5fad
folderAsset: yes
DefaultImporter:
externalObjects: {}
@@ -0,0 +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;
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 53fac0a0edbb582439eb08670f03a121
guid: 680fe9049a075f24ba054f7c26301bc5
MonoImporter:
externalObjects: {}
serializedVersion: 2
+250
View File
@@ -0,0 +1,250 @@
using UnityEngine;
using UnityEngine.UI;
public class UIHandle : MonoBehaviour
{
/// <summary> Object that "owns" the handle </summary>
public GameObject 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;
public virtual UIHandle Init(GameObject owner, Transform target)
{
Target = target;
return Init(owner);
}
public virtual UIHandle Init(GameObject owner)
{
HandleManager.RegisterHandle(this);
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();
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;
Collider = collider;
return this;
}
public virtual void UpdateManual(Camera camera, bool linesEnabled)
{
//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(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);
}
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;
UmaViewerUI.Instance.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 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 = UmaViewerUI.Instance.HandleManager.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);
}
public void TransformReset(PoseLoadOptions options = null)
{
if(options == null)
{
options = PoseLoadOptions.All();
}
_defaultTransform.ApplyTo(Target);
}
public void TransformResetAll()
{
var undoData = new HandleManager.RuntimeGizmoUndoData();
undoData.OldPosition = new SerializableTransform(Target, Space.World);
TransformReset();
undoData.NewPosition = Target;
HandleManager.RegisterRuntimeGizmoUndoAction.Invoke(undoData);
}
public void TransformResetPosition()
{
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)
{
Handle.SetActive(value);
Collider.enabled = value;
Popup.gameObject.SetActive(false);
}
public void ForceDisplayOff(bool value)
{
_forceDisplayOff = value;
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e256de223a005bd4d86ba3c32ee917d1
guid: 64e74a5cd001d6241afcdd289f83d99e
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -0,0 +1,47 @@
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(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.65f);
return handle;
}
public UIHandleBone Init(GameObject owner, List<BoneTags> boneTags)
{
Target = owner.transform;
Tags = boneTags;
base.Init(owner);
if (Tags.Contains(BoneTags.Left)) SetColor(Color.green);
if (Tags.Contains(BoneTags.Right)) SetColor(Color.blue);
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();
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f0b8bcd1bcd67764d93c854a0f61660b
guid: 2e45ca6a865252645b2cf30521de7c97
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -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);
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ad24e221a99993948ae4740c38a0a377
guid: 38509b8f63b3b4e4f9fc2cfcbf8cae5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -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(UmaViewerUI.Instance.HandleManager.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(UmaViewerUI.Instance.HandleManager.Pfb_PopupButton, Content).GetComponent<Button>();
b.onClick.AddListener(() => callback.Invoke());
b.GetComponentInChildren<TMPro.TMP_Text>().text = name;
ConditionalButtons.Add(b.gameObject, condition);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18cb0955b9e60dc4983b1f33b3878ff8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+15
View File
@@ -0,0 +1,15 @@
using System.Collections.Generic;
[System.Serializable]
public class PoseData
{
public string Name;
public string Date;
public string Character;
public string Description;
public string ViewerVersion;
public SerializableBone Root;
public List<SerializableBone> Bones = new List<SerializableBone>();
public List<SerializableMorph> Morphs = new List<SerializableMorph>();
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 514d72c0e78fd5740b8c84ce379049a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+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:
+145
View File
@@ -0,0 +1,145 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;
public class PoseManager : MonoBehaviour
{
public ScrollRect SavedPoseList;
public UIPoseContainer Pfb_PoseContainer;
public TMPro.TMP_Text[] TooltipLabels;
[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()
{
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
{
var data = JsonConvert.DeserializeObject<PoseData>(File.ReadAllText(file));
if (data != null)
{
UIPoseContainer.Create(data);
}
}
catch(Exception e)
{
Debug.LogException(e);
Debug.LogError(file + " is not a valid pose file.");
}
}
}
public static void SetPoseModeStatic(bool value)
{
UmaViewerUI.Instance.PoseManager.SetPoseMode(value);
}
/// <summary> Used on UI buttons </summary>
public void SetPoseMode(bool value)
{
if (value == PoseModeOn) return;
if (value)
{
EnablePoseMode();
}
else
{
DisablePoseMode();
}
}
public static void SetTooltip(int panelId, string text)
{
UmaViewerUI.Instance.PoseManager.TooltipLabels[panelId].text = text;
}
public void EnablePoseMode()
{
if (PoseModeOn) return;
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()
{
if (!PoseModeOn) return;
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;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 92fc8fa5c06c99b458a211fe2390d12f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e9b28411580b23c4892cd0526e51b70e
guid: 3ed582a162aaebb4f9552d1828f0ad67
folderAsset: yes
DefaultImporter:
externalObjects: {}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: df43ba63ee786d641baadb4a831db2b8
guid: 02add3303ecb32144b1c8a22f959da4d
folderAsset: yes
DefaultImporter:
externalObjects: {}
@@ -0,0 +1,228 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
//Currently doesnt really handle TransformType.All
public class TransformGizmoCustomGizmo : MonoBehaviour
{
public bool autoFindTransformGizmo = true;
public TransformGizmo transformGizmo;
public CustomTransformGizmos customTranslationGizmos = new CustomTransformGizmos();
public CustomTransformGizmos customRotationGizmos = new CustomTransformGizmos();
public CustomTransformGizmos customScaleGizmos = new CustomTransformGizmos();
public bool scaleBasedOnDistance = true;
public float scaleMultiplier = .4f;
public int gizmoLayer = 2; //2 is the ignoreRaycast layer. Set to whatever you want.
LayerMask mask;
void Awake()
{
if(transformGizmo == null && autoFindTransformGizmo)
{
transformGizmo = GameObject.FindObjectOfType<TransformGizmo>();
}
transformGizmo.manuallyHandleGizmo = true;
//Since we are using a mesh, rotating can get weird due to how the rotation method works,
//so we use a different rotation method that will let us rotate by acting like our custom rotation gizmo is a wheel.
//Can still give weird results depending on camera angle, but I think its more understanding for the user as to why its messing up.
transformGizmo.circularRotationMethod = true;
mask = LayerMask.GetMask(LayerMask.LayerToName(gizmoLayer));
customTranslationGizmos.Init(gizmoLayer);
customRotationGizmos.Init(gizmoLayer);
customScaleGizmos.Init(gizmoLayer);
}
void OnEnable()
{
transformGizmo.onCheckForSelectedAxis += CheckForSelectedAxis;
transformGizmo.onDrawCustomGizmo += OnDrawCustomGizmos;
}
void OnDisable()
{
transformGizmo.onCheckForSelectedAxis -= CheckForSelectedAxis;
transformGizmo.onDrawCustomGizmo -= OnDrawCustomGizmos;
}
void CheckForSelectedAxis()
{
ShowProperGizmoType();
if(Input.GetMouseButtonDown(0))
{
RaycastHit hitInfo;
if(Physics.Raycast(transformGizmo.myCamera.ScreenPointToRay(Input.mousePosition), out hitInfo, Mathf.Infinity, mask))
{
Axis selectedAxis = Axis.None;
TransformType type = transformGizmo.transformType;
if(selectedAxis == Axis.None && transformGizmo.TransformTypeContains(TransformType.Move))
{
selectedAxis = customTranslationGizmos.GetSelectedAxis(hitInfo.collider);
type = TransformType.Move;
}
if(selectedAxis == Axis.None && transformGizmo.TransformTypeContains(TransformType.Rotate))
{
selectedAxis = customRotationGizmos.GetSelectedAxis(hitInfo.collider);
type = TransformType.Rotate;
}
if(selectedAxis == Axis.None && transformGizmo.TransformTypeContains(TransformType.Scale))
{
selectedAxis = customScaleGizmos.GetSelectedAxis(hitInfo.collider);
type = TransformType.Scale;
}
transformGizmo.SetTranslatingAxis(type, selectedAxis);
}
}
}
void OnDrawCustomGizmos()
{
if(transformGizmo.TranslatingTypeContains(TransformType.Move)) DrawCustomGizmo(customTranslationGizmos);
if(transformGizmo.TranslatingTypeContains(TransformType.Rotate)) DrawCustomGizmo(customRotationGizmos);
if(transformGizmo.TranslatingTypeContains(TransformType.Scale)) DrawCustomGizmo(customScaleGizmos);
}
void DrawCustomGizmo(CustomTransformGizmos customGizmo)
{
AxisInfo axisInfo = transformGizmo.GetAxisInfo();
customGizmo.SetAxis(axisInfo);
customGizmo.SetPosition(transformGizmo.pivotPoint);
Vector4 totalScaleMultiplier = Vector4.one;
if(scaleBasedOnDistance)
{
totalScaleMultiplier.w *= (scaleMultiplier * transformGizmo.GetDistanceMultiplier());
}
if(transformGizmo.transformingType == TransformType.Scale)
{
float totalScaleAmount = 1f + transformGizmo.totalScaleAmount;
if(transformGizmo.translatingAxis == Axis.Any) totalScaleMultiplier += (Vector4.one * totalScaleAmount);
else if(transformGizmo.translatingAxis == Axis.X) totalScaleMultiplier.x *= totalScaleAmount;
else if(transformGizmo.translatingAxis == Axis.Y) totalScaleMultiplier.y *= totalScaleAmount;
else if(transformGizmo.translatingAxis == Axis.Z) totalScaleMultiplier.z *= totalScaleAmount;
}
customGizmo.ScaleMultiply(totalScaleMultiplier);
}
void ShowProperGizmoType()
{
bool hasSelection = transformGizmo.mainTargetRoot != null;
customTranslationGizmos.SetEnable(hasSelection && transformGizmo.TranslatingTypeContains(TransformType.Move));
customRotationGizmos.SetEnable(hasSelection && transformGizmo.TranslatingTypeContains(TransformType.Rotate));
customScaleGizmos.SetEnable(hasSelection && transformGizmo.TranslatingTypeContains(TransformType.Scale));
}
}
[Serializable]
public class CustomTransformGizmos
{
public Transform xAxisGizmo;
public Transform yAxisGizmo;
public Transform zAxisGizmo;
public Transform anyAxisGizmo;
Collider xAxisGizmoCollider;
Collider yAxisGizmoCollider;
Collider zAxisGizmoCollider;
Collider anyAxisGizmoCollider;
Vector3 originalXAxisScale;
Vector3 originalYAxisScale;
Vector3 originalZAxisScale;
Vector3 originalAnyAxisScale;
public void Init(int layer)
{
if(xAxisGizmo != null)
{
SetLayerRecursively(xAxisGizmo.gameObject, layer);
xAxisGizmoCollider = xAxisGizmo.GetComponentInChildren<Collider>();
originalXAxisScale = xAxisGizmo.localScale;
}
if(yAxisGizmo != null)
{
SetLayerRecursively(yAxisGizmo.gameObject, layer);
yAxisGizmoCollider = yAxisGizmo.GetComponentInChildren<Collider>();
originalYAxisScale = yAxisGizmo.localScale;
}
if(zAxisGizmo != null)
{
SetLayerRecursively(zAxisGizmo.gameObject, layer);
zAxisGizmoCollider = zAxisGizmo.GetComponentInChildren<Collider>();
originalZAxisScale = zAxisGizmo.localScale;
}
if(anyAxisGizmo != null)
{
SetLayerRecursively(anyAxisGizmo.gameObject, layer);
anyAxisGizmoCollider = anyAxisGizmo.GetComponentInChildren<Collider>();
originalAnyAxisScale = anyAxisGizmo.localScale;
}
}
public void SetEnable(bool enable)
{
if(xAxisGizmo != null && xAxisGizmo.gameObject.activeSelf != enable) xAxisGizmo.gameObject.SetActive(enable);
if(yAxisGizmo != null && yAxisGizmo.gameObject.activeSelf != enable) yAxisGizmo.gameObject.SetActive(enable);
if(zAxisGizmo != null && zAxisGizmo.gameObject.activeSelf != enable) zAxisGizmo.gameObject.SetActive(enable);
if(anyAxisGizmo != null && anyAxisGizmo.gameObject.activeSelf != enable) anyAxisGizmo.gameObject.SetActive(enable);
}
public void SetAxis(AxisInfo axisInfo)
{
Quaternion lookRotation = Quaternion.LookRotation(axisInfo.zDirection, axisInfo.yDirection);
if(xAxisGizmo != null) xAxisGizmo.rotation = lookRotation;
if(yAxisGizmo != null) yAxisGizmo.rotation = lookRotation;
if(zAxisGizmo != null) zAxisGizmo.rotation = lookRotation;
if(anyAxisGizmo != null) anyAxisGizmo.rotation = lookRotation;
}
public void SetPosition(Vector3 position)
{
if(xAxisGizmo != null) xAxisGizmo.position = position;
if(yAxisGizmo != null) yAxisGizmo.position = position;
if(zAxisGizmo != null) zAxisGizmo.position = position;
if(anyAxisGizmo != null) anyAxisGizmo.position = position;
}
public void ScaleMultiply(Vector4 scaleMultiplier)
{
if(xAxisGizmo != null) xAxisGizmo.localScale = Vector3.Scale(originalXAxisScale, new Vector3(scaleMultiplier.w + scaleMultiplier.x, scaleMultiplier.w, scaleMultiplier.w));
if(yAxisGizmo != null) yAxisGizmo.localScale = Vector3.Scale(originalYAxisScale, new Vector3(scaleMultiplier.w, scaleMultiplier.w + scaleMultiplier.y, scaleMultiplier.w));
if(zAxisGizmo != null) zAxisGizmo.localScale = Vector3.Scale(originalZAxisScale, new Vector3(scaleMultiplier.w, scaleMultiplier.w, scaleMultiplier.w + scaleMultiplier.z));
if(anyAxisGizmo != null) anyAxisGizmo.localScale = originalAnyAxisScale * scaleMultiplier.w;
}
public Axis GetSelectedAxis(Collider selectedCollider)
{
if(xAxisGizmoCollider != null && xAxisGizmoCollider == selectedCollider) return Axis.X;
if(yAxisGizmoCollider != null && yAxisGizmoCollider == selectedCollider) return Axis.Y;
if(zAxisGizmoCollider != null && zAxisGizmoCollider == selectedCollider) return Axis.Z;
if(anyAxisGizmoCollider != null && anyAxisGizmoCollider == selectedCollider) return Axis.Any;
return Axis.None;
}
void SetLayerRecursively(GameObject gameObject, int layer)
{
Transform[] selfAndChildren = gameObject.GetComponentsInChildren<Transform>(true);
for(int i = 0; i < selfAndChildren.Length; i++)
{
selfAndChildren[i].gameObject.layer = layer;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bfa7f2475900ffc4aa2b2ccb469da4cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,461 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 512
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 0
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 4890085278179872738, guid: d7c0db705ef44be448cee924bf7e4fc9,
type: 2}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &343817361
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 343817366}
- component: {fileID: 343817365}
- component: {fileID: 343817363}
- component: {fileID: 343817362}
m_Layer: 0
m_Name: TransformGizmoCamera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &343817362
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 343817361}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 1c0ad0e8e55c95c4e931911c4b943a64, type: 3}
m_Name:
m_EditorClassIdentifier:
space: 0
transformType: 0
pivot: 0
centerType: 0
scaleType: 0
SetMoveType: 119
SetRotateType: 101
SetScaleType: 114
SetAllTransformType: 121
SetSpaceToggle: 120
SetPivotModeToggle: 122
SetCenterTypeToggle: 99
SetScaleTypeToggle: 115
translationSnapping: 306
AddSelection: 304
RemoveSelection: 306
ActionKey: 304
UndoAction: 122
RedoAction: 121
xColor: {r: 1, g: 0, b: 0, a: 0.8}
yColor: {r: 0, g: 1, b: 0, a: 0.8}
zColor: {r: 0, g: 0, b: 1, a: 0.8}
allColor: {r: 0.7, g: 0.7, b: 0.7, a: 0.8}
selectedColor: {r: 1, g: 1, b: 0, a: 0.8}
hoverColor: {r: 1, g: 0.75, b: 0, a: 0.8}
planesOpacity: 0.5
movementSnap: 0.25
rotationSnap: 15
scaleSnap: 1
handleLength: 0.25
handleWidth: 0.003
planeSize: 0.035
triangleSize: 0.03
boxSize: 0.03
circleDetail: 40
allMoveHandleLengthMultiplier: 1
allRotateHandleLengthMultiplier: 1.4
allScaleHandleLengthMultiplier: 1.6
minSelectedDistanceCheck: 0.01
moveSpeedMultiplier: 1
scaleSpeedMultiplier: 1
rotateSpeedMultiplier: 1
allRotateSpeedMultiplier: 20
useFirstSelectedAsMain: 1
circularRotationMethod: 0
forceUpdatePivotPointOnChange: 1
maxUndoStored: 100
manuallyHandleGizmo: 0
selectionMask:
serializedVersion: 2
m_Bits: 4294967291
--- !u!124 &343817363
Behaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 343817361}
m_Enabled: 1
--- !u!20 &343817365
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 343817361}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &343817366
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 343817361}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1138828411
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1138828413}
- component: {fileID: 1138828412}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &1138828412
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1138828411}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 0.8
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1138828413
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1138828411}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 15.92, y: -23.72, z: -27.58}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &1755359865
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1755359869}
- component: {fileID: 1755359868}
- component: {fileID: 1755359867}
- component: {fileID: 1755359866}
m_Layer: 0
m_Name: Cube
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!23 &1755359866
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1755359865}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 1
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!65 &1755359867
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1755359865}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!33 &1755359868
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1755359865}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &1755359869
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1755359865}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -2.48, y: 0.3, z: -4.1958246}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -1,7 +1,6 @@
fileFormatVersion: 2
guid: 009868f8c43db7746b02378159830aa2
folderAsset: yes
timeCreated: 1531897074
guid: 678d4f03f0bd01b4faf0609706d37c25
timeCreated: 1476929737
licenseType: Free
DefaultImporter:
userData:
@@ -0,0 +1,63 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!850595691 &4890085278179872738
LightingSettings:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ExampleSceneSettings
serializedVersion: 3
m_GIWorkflowMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_RealtimeEnvironmentLighting: 1
m_BounceScale: 1
m_AlbedoBoost: 1
m_IndirectOutputScale: 1
m_UsingShadowmask: 0
m_BakeBackend: 0
m_LightmapMaxSize: 1024
m_BakeResolution: 40
m_Padding: 2
m_TextureCompression: 1
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAO: 0
m_MixedBakeMode: 1
m_LightmapsBakeMode: 1
m_FilterMode: 1
m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0}
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_RealtimeResolution: 2
m_ForceWhiteAlbedo: 0
m_ForceUpdates: 0
m_FinalGather: 0
m_FinalGatherRayCount: 256
m_FinalGatherFiltering: 1
m_PVRCulling: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVREnvironmentSampleCount: 512
m_PVREnvironmentReferencePointCount: 2048
m_LightProbeSampleCountMultiplier: 4
m_PVRBounces: 2
m_PVRMinBounces: 2
m_PVREnvironmentMIS: 0
m_PVRFilteringMode: 0
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d7c0db705ef44be448cee924bf7e4fc9
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 564032cd9c8272a499ad143c1e847fc0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,18 @@
using System;
namespace RuntimeGizmos
{
public static class ExtMathf
{
public static float Squared(this float value)
{
return value * value;
}
public static float SafeDivide(float value, float divider)
{
if(divider == 0) return 0;
return value / divider;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d42edb042caf1e740a983f5b2c8157aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,87 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public static class ExtTransform
{
//This acts as if you are using a parent transform as your new pivot and transforming that parent instead of the child.
//So instead of creating a gameobject and parenting "target" to it and translating only the parent gameobject, we can use this method.
public static void SetScaleFrom(this Transform target, Vector3 worldPivot, Vector3 newScale)
{
Vector3 localOffset = target.InverseTransformPoint(worldPivot);
Vector3 localScale = target.localScale;
Vector3 scaleRatio = new Vector3(ExtMathf.SafeDivide(newScale.x, localScale.x), ExtMathf.SafeDivide(newScale.y, localScale.y), ExtMathf.SafeDivide(newScale.z, localScale.z));
Vector3 scaledLocalOffset = Vector3.Scale(localOffset, scaleRatio);
Vector3 newPosition = target.TransformPoint(localOffset - scaledLocalOffset);
target.localScale = newScale;
target.position = newPosition;
}
//This acts as if you are scaling based on a point that is offset from the actual pivot.
//It gives results similar to when you scale an object in the unity editor when in Center mode instead of Pivot mode.
//The Center was an offset from the actual Pivot.
public static void SetScaleFromOffset(this Transform target, Vector3 worldPivot, Vector3 newScale)
{
//Seemed to work, except when under a parent that has a non uniform scale and rotation it was a bit off.
//This might be due to transform.lossyScale not being accurate under those conditions, or possibly something else is wrong...
//Maybe things can work if we can find a way to convert the "newPosition = ..." line to use Matrix4x4 for possibly more scale accuracy.
//However, I have tried and tried and have no idea how to do that kind of math =/
//Seems like unity editor also has some inaccuracies with skewed scales, such as scaling little by little compared to scaling one large scale.
//
//Will mess up or give undesired results if the target.localScale or target.lossyScale has any set to 0.
//Unity editor doesnt even allow you to scale an axis when it is set to 0.
Vector3 localOffset = target.InverseTransformPoint(worldPivot);
Vector3 localScale = target.localScale;
Vector3 scaleRatio = new Vector3(ExtMathf.SafeDivide(newScale.x, localScale.x), ExtMathf.SafeDivide(newScale.y, localScale.y), ExtMathf.SafeDivide(newScale.z, localScale.z));
Vector3 scaledLocalOffset = Vector3.Scale(localOffset, scaleRatio);
Vector3 newPosition = target.rotation * Vector3.Scale(localOffset - scaledLocalOffset, target.lossyScale) + target.position;
target.localScale = newScale;
target.position = newPosition;
}
public static Vector3 GetCenter(this Transform transform, CenterType centerType)
{
if(centerType == CenterType.Solo)
{
Renderer renderer = transform.GetComponent<Renderer>();
if(renderer != null)
{
return renderer.bounds.center;
}else{
return transform.position;
}
}
else if(centerType == CenterType.All)
{
Bounds totalBounds = new Bounds(transform.position, Vector3.zero);
GetCenterAll(transform, ref totalBounds);
return totalBounds.center;
}
return transform.position;
}
static void GetCenterAll(this Transform transform, ref Bounds currentTotalBounds)
{
Renderer renderer = transform.GetComponent<Renderer>();
if(renderer != null)
{
currentTotalBounds.Encapsulate(renderer.bounds);
}else{
currentTotalBounds.Encapsulate(transform.position);
}
for(int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).GetCenterAll(ref currentTotalBounds);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86d846e8790207640a34223ce37b13ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,22 @@
using System;
namespace RuntimeGizmos
{
public static class ExtTransformType
{
public static bool TransformTypeContains(this TransformType mainType, TransformType type, TransformSpace space)
{
if(type == mainType) return true;
if(mainType == TransformType.All)
{
if(type == TransformType.Move) return true;
else if(type == TransformType.Rotate) return true;
//else if(type == TransformType.RectTool) return false;
else if(type == TransformType.Scale && space == TransformSpace.Local) return true;
}
return false;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20ae88cde502593479f10d5de11fd9ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,29 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public static class ExtVector3
{
public static float MagnitudeInDirection(Vector3 vector, Vector3 direction, bool normalizeParameters = true)
{
if(normalizeParameters) direction.Normalize();
return Vector3.Dot(vector, direction);
}
public static Vector3 Abs(this Vector3 vector)
{
return new Vector3(Mathf.Abs(vector.x), Mathf.Abs(vector.y), Mathf.Abs(vector.z));
}
public static bool IsParallel(Vector3 direction, Vector3 otherDirection, float precision = .0001f)
{
return Vector3.Cross(direction, otherDirection).sqrMagnitude < precision;
}
public static bool IsInDirection(Vector3 direction, Vector3 otherDirection)
{
return Vector3.Dot(direction, otherDirection) > 0f;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a1254460ffbab7488623cc17228d217
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,101 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public static class Geometry
{
public static float LinePlaneDistance(Vector3 linePoint, Vector3 lineVec, Vector3 planePoint, Vector3 planeNormal)
{
//calculate the distance between the linePoint and the line-plane intersection point
float dotNumerator = Vector3.Dot((planePoint - linePoint), planeNormal);
float dotDenominator = Vector3.Dot(lineVec, planeNormal);
//line and plane are not parallel
if(dotDenominator != 0f)
{
return dotNumerator / dotDenominator;
}
return 0;
}
//Note that the line is infinite, this is not a line-segment plane intersect
public static Vector3 LinePlaneIntersect(Vector3 linePoint, Vector3 lineVec, Vector3 planePoint, Vector3 planeNormal)
{
float distance = LinePlaneDistance(linePoint, lineVec, planePoint, planeNormal);
//line and plane are not parallel
if(distance != 0f)
{
return linePoint + (lineVec * distance);
}
return Vector3.zero;
}
//Returns 2 points since on line 1 there will be a closest point to line 2, and on line 2 there will be a closest point to line 1.
public static IntersectPoints ClosestPointsOnTwoLines(Vector3 point1, Vector3 point1Direction, Vector3 point2, Vector3 point2Direction)
{
IntersectPoints intersections = new IntersectPoints();
//I dont think we need to normalize
//point1Direction.Normalize();
//point2Direction.Normalize();
float a = Vector3.Dot(point1Direction, point1Direction);
float b = Vector3.Dot(point1Direction, point2Direction);
float e = Vector3.Dot(point2Direction, point2Direction);
float d = a*e - b*b;
//This is a check if parallel, howeverm since we are not normalizing the directions, it seems even if they are parallel they will not == 0
//so they will get past this point, but its seems to be alright since it seems to still give a correct point (although a point very fary away).
//Also, if they are parallel and we dont normalize, the deciding point seems randomly choses on the lines, which while is still correct,
//our ClosestPointsOnTwoLineSegments gets undesireable results when on corners. (for example when using it in our ClosestPointOnTriangleToLine).
if(d != 0f)
{
Vector3 r = point1 - point2;
float c = Vector3.Dot(point1Direction, r);
float f = Vector3.Dot(point2Direction, r);
float s = (b*f - c*e) / d;
float t = (a*f - c*b) / d;
intersections.first = point1 + point1Direction * s;
intersections.second = point2 + point2Direction * t;
}else{
//Lines are parallel, select any points next to eachother
intersections.first = point1;
intersections.second = point2 + Vector3.Project(point1 - point2, point2Direction);
}
return intersections;
}
public static IntersectPoints ClosestPointsOnSegmentToLine(Vector3 segment0, Vector3 segment1, Vector3 linePoint, Vector3 lineDirection)
{
IntersectPoints closests = ClosestPointsOnTwoLines(segment0, segment1 - segment0, linePoint, lineDirection);
closests.first = ClampToSegment(closests.first, segment0, segment1);
return closests;
}
//Assumes the point is already on the line somewhere
public static Vector3 ClampToSegment(Vector3 point, Vector3 linePoint1, Vector3 linePoint2)
{
Vector3 lineDirection = linePoint2 - linePoint1;
if(!ExtVector3.IsInDirection(point - linePoint1, lineDirection))
{
point = linePoint1;
}
else if(ExtVector3.IsInDirection(point - linePoint2, lineDirection))
{
point = linePoint2;
}
return point;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d3bdd6b810192f644b8a1c8d2a08093d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 HiddenMonk
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 26d9c02a7b696574f89d1a5ee3f30686
guid: d0c3b92d5b2dc534b941587e5bed2af7
DefaultImporter:
externalObjects: {}
userData:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a06e169499f3e0043bca18c372b3a812
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,48 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public struct AxisInfo
{
public Vector3 pivot;
public Vector3 xDirection;
public Vector3 yDirection;
public Vector3 zDirection;
public void Set(Transform target, Vector3 pivot, TransformSpace space)
{
if(space == TransformSpace.Global)
{
xDirection = Vector3.right;
yDirection = Vector3.up;
zDirection = Vector3.forward;
}
else if(space == TransformSpace.Local)
{
xDirection = target.right;
yDirection = target.up;
zDirection = target.forward;
}
this.pivot = pivot;
}
public Vector3 GetXAxisEnd(float size)
{
return pivot + (xDirection * size);
}
public Vector3 GetYAxisEnd(float size)
{
return pivot + (yDirection * size);
}
public Vector3 GetZAxisEnd(float size)
{
return pivot + (zDirection * size);
}
public Vector3 GetAxisEnd(Vector3 direction, float size)
{
return pivot + (direction * size);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0703255fec9cd45458a07800813b3487
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace RuntimeGizmos
{
public class AxisVectors
{
public List<Vector3> x = new List<Vector3>();
public List<Vector3> y = new List<Vector3>();
public List<Vector3> z = new List<Vector3>();
public List<Vector3> all = new List<Vector3>();
public void Add(AxisVectors axisVectors)
{
x.AddRange(axisVectors.x);
y.AddRange(axisVectors.y);
z.AddRange(axisVectors.z);
all.AddRange(axisVectors.all);
}
public void Clear()
{
x.Clear();
y.Clear();
z.Clear();
all.Clear();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 75383c8255c26e14bbdffbc4c4630463
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 13734b144f60b3f43bc71e1771ca85ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,113 @@
using System;
using CommandUndoRedo;
using UnityEngine;
using System.Collections.Generic;
namespace RuntimeGizmos
{
public abstract class SelectCommand : ICommand
{
protected Transform target;
protected TransformGizmo transformGizmo;
public SelectCommand(TransformGizmo transformGizmo, Transform target)
{
this.transformGizmo = transformGizmo;
this.target = target;
}
public abstract void Execute();
public abstract void UnExecute();
}
public class AddTargetCommand : SelectCommand
{
List<Transform> targetRoots = new List<Transform>();
public AddTargetCommand(TransformGizmo transformGizmo, Transform target, List<Transform> targetRoots) : base(transformGizmo, target)
{
//Since we might have had a child selected and then selected the parent, the child would have been removed from the selected,
//so we store all the targetRoots before we add so that if we undo we can properly have the children selected again.
this.targetRoots.AddRange(targetRoots);
}
public override void Execute()
{
transformGizmo.AddTarget(target, false);
}
public override void UnExecute()
{
transformGizmo.RemoveTarget(target, false);
for(int i = 0; i < targetRoots.Count; i++)
{
transformGizmo.AddTarget(targetRoots[i], false);
}
}
}
public class RemoveTargetCommand : SelectCommand
{
public RemoveTargetCommand(TransformGizmo transformGizmo, Transform target) : base(transformGizmo, target) {}
public override void Execute()
{
transformGizmo.RemoveTarget(target, false);
}
public override void UnExecute()
{
transformGizmo.AddTarget(target, false);
}
}
public class ClearTargetsCommand : SelectCommand
{
List<Transform> targetRoots = new List<Transform>();
public ClearTargetsCommand(TransformGizmo transformGizmo, List<Transform> targetRoots) : base(transformGizmo, null)
{
this.targetRoots.AddRange(targetRoots);
}
public override void Execute()
{
transformGizmo.ClearTargets(false);
}
public override void UnExecute()
{
for(int i = 0; i < targetRoots.Count; i++)
{
transformGizmo.AddTarget(targetRoots[i], false);
}
}
}
public class ClearAndAddTargetCommand : SelectCommand
{
List<Transform> targetRoots = new List<Transform>();
public ClearAndAddTargetCommand(TransformGizmo transformGizmo, Transform target, List<Transform> targetRoots) : base(transformGizmo, target)
{
this.targetRoots.AddRange(targetRoots);
}
public override void Execute()
{
transformGizmo.ClearTargets(false);
transformGizmo.AddTarget(target, false);
}
public override void UnExecute()
{
transformGizmo.RemoveTarget(target, false);
for(int i = 0; i < targetRoots.Count; i++)
{
transformGizmo.AddTarget(targetRoots[i], false);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0049ee060d2e7ed4d94301c1c6d74154
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,62 @@
using System;
using CommandUndoRedo;
using UnityEngine;
namespace RuntimeGizmos
{
public class TransformCommand : ICommand
{
TransformValues newValues;
TransformValues oldValues;
Transform transform;
TransformGizmo transformGizmo;
public TransformCommand(TransformGizmo transformGizmo, Transform transform)
{
this.transformGizmo = transformGizmo;
this.transform = transform;
oldValues = new TransformValues() {position=transform.position, rotation=transform.rotation, scale=transform.localScale};
}
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};
}
public void Execute()
{
transform.position = newValues.position;
transform.rotation = newValues.rotation;
transform.localScale = newValues.scale;
transformGizmo.SetPivotPoint();
}
public void UnExecute()
{
transform.position = oldValues.position;
transform.rotation = oldValues.rotation;
transform.localScale = oldValues.scale;
transformGizmo.SetPivotPoint();
}
struct TransformValues
{
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d257cdf8c9d53a4459c0c1187ac05feb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,18 @@
namespace RuntimeGizmos
{
public enum TransformSpace {Global, Local}
public enum TransformType {Move, Rotate, Scale /*, RectTool*/, All}
public enum TransformPivot {Pivot, Center}
public enum Axis {None, X, Y, Z, Any}
//CenterType.All is the center of the current object mesh or pivot if not mesh and all its childrens mesh or pivot if no mesh.
// CenterType.All might give different results than unity I think because unity only counts empty gameobjects a little bit, as if they have less weight.
//CenterType.Solo is the center of the current objects mesh or pivot if no mesh.
//Unity seems to use colliders first to use to find how much weight the object has or something to decide how much it effects the center,
//but for now we only look at the Renderer.bounds.center, so expect some differences between unity.
public enum CenterType {All, Solo}
//ScaleType.FromPoint acts as if you are using a parent transform as your new pivot and transforming that parent instead of the child.
//ScaleType.FromPointOffset acts as if you are scaling based on a point that is offset from the actual pivot. Its similar to unity editor scaling in Center pivot mode (though a little inaccurate if object is skewed)
public enum ScaleType {FromPoint, FromPointOffset}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf981dc491f04c440b6c6731531f2a60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public struct IntersectPoints
{
public Vector3 first;
public Vector3 second;
public IntersectPoints(Vector3 first, Vector3 second)
{
this.first = first;
this.second = second;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 160db4dc48cd871468057690b209f902
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,35 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public struct Square
{
public Vector3 bottomLeft;
public Vector3 bottomRight;
public Vector3 topLeft;
public Vector3 topRight;
public Vector3 this[int index]
{
get
{
switch (index)
{
case 0:
return this.bottomLeft;
case 1:
return this.topLeft;
case 2:
return this.topRight;
case 3:
return this.bottomRight;
case 4:
return this.bottomLeft; //so we wrap around back to start
default:
return Vector3.zero;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9bbbbd13e719be64a845006bb088471f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using System;
using UnityEngine;
namespace RuntimeGizmos
{
public class TargetInfo
{
public Vector3 centerPivotPoint;
public Vector3 previousPosition;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: af153c5bfa29c074096e5c8845ba8fb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,16 @@
{
"name": "RuntimeGizmo",
"rootNamespace": "",
"references": [
"GUID:4bfbe5f35cfda4e488c0fb232ba9c5ce"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d8ec2c44ae4c78a409a16352c7b155c8
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6362a1947d6af0a4fb85f2ed67b3caad
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6f9cb40319c2d8c4eb626565073d5d24
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
Shader "Custom/Lines"
{
SubShader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
ZWrite Off
ZTest Always
Cull Off
Fog { Mode Off }
BindChannels
{
Bind "vertex", vertex
Bind "color", color
}
}
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c657963988cda87498e6109600174edf
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
//Taken and modified from github.com/Shrimpey/Outlined-Diffuse-Shader-Fixed/blob/master/CustomOutline.shader
Shader "Custom/Outline" {
Properties {
_OutlineColor ("Outline Color", Color) = (1,.5,0,1)
_Outline ("Outline width", Range (0, 1)) = .1
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f {
float4 pos : POSITION;
float4 color : COLOR;
};
uniform float _Outline;
uniform float4 _OutlineColor;
v2f vert(appdata v) {
// just make a copy of incoming vertex data but scaled according to normal direction
v2f o;
v.vertex *= ( 1 + _Outline);
o.pos = UnityObjectToClipPos(v.vertex);
o.color = _OutlineColor;
return o;
}
ENDCG
SubShader {
Tags { "DisableBatching" = "True" }
Pass {
Name "OUTLINE"
Tags {"LightMode" = "UniversalForward" }
Cull Front
ZWrite On
ColorMask RGB
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
half4 frag(v2f i) :COLOR { return i.color; }
ENDCG
}
}
Fallback "Diffuse"
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 1d502c40f258ee247825a9863766aa22
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
preprocessorOverride: 0
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: da7bf8ee0c95a8343a31634e5937040d
timeCreated: 1532218344
guid: 1c0ad0e8e55c95c4e931911c4b943a64
timeCreated: 1476929157
licenseType: Free
MonoImporter:
serializedVersion: 2
@@ -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:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b3328dfb827db9647ac6aa97cf955b1f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
namespace CommandUndoRedo
{
public class CommandGroup : ICommand
{
List<ICommand> commands = new List<ICommand>();
public CommandGroup() {}
public CommandGroup(List<ICommand> commands)
{
this.commands.AddRange(commands);
}
public void Set(List<ICommand> commands)
{
this.commands = commands;
}
public void Add(ICommand command)
{
commands.Add(command);
}
public void Remove(ICommand command)
{
commands.Remove(command);
}
public void Clear()
{
commands.Clear();
}
public void Execute()
{
for(int i = 0; i < commands.Count; i++)
{
commands[i].Execute();
}
}
public void UnExecute()
{
for(int i = commands.Count - 1; i >= 0; i--)
{
commands[i].UnExecute();
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3810e7de3b69ac84fafcea0e0793c033
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
namespace CommandUndoRedo
{
public class DropoutStack<T> : LinkedList<T>
{
int _maxLength = int.MaxValue;
public int maxLength {get {return _maxLength;} set {SetMaxLength(value);}}
public DropoutStack() {}
public DropoutStack(int maxLength)
{
this.maxLength = maxLength;
}
public void Push(T item)
{
if(this.Count > 0 && this.Count + 1 > maxLength)
{
this.RemoveLast();
}
if(this.Count + 1 <= maxLength)
{
this.AddFirst(item);
}
}
public T Pop()
{
T item = this.First.Value;
this.RemoveFirst();
return item;
}
void SetMaxLength(int max)
{
_maxLength = max;
if(this.Count > _maxLength)
{
int leftover = this.Count - _maxLength;
for(int i = 0; i < leftover; i++)
{
this.RemoveLast();
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d2ddbd8af401c194bbcba4b5be14831b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
using System;
namespace CommandUndoRedo
{
public interface ICommand
{
void Execute();
void UnExecute();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f9cd0c213b771d84bb2ed0d65ce83561
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
namespace CommandUndoRedo
{
public class UndoRedo
{
public int maxUndoStored {get {return undoCommands.maxLength;} set {SetMaxLength(value);}}
DropoutStack<ICommand> undoCommands = new DropoutStack<ICommand>();
DropoutStack<ICommand> redoCommands = new DropoutStack<ICommand>();
public UndoRedo() {}
public UndoRedo(int maxUndoStored)
{
this.maxUndoStored = maxUndoStored;
}
public void Clear()
{
undoCommands.Clear();
redoCommands.Clear();
}
public void Undo()
{
if(undoCommands.Count > 0)
{
ICommand command = undoCommands.Pop();
command.UnExecute();
redoCommands.Push(command);
}
}
public void Redo()
{
if(redoCommands.Count > 0)
{
ICommand command = redoCommands.Pop();
command.Execute();
undoCommands.Push(command);
}
}
public void Insert(ICommand command)
{
if(maxUndoStored <= 0) return;
undoCommands.Push(command);
redoCommands.Clear();
}
public void Execute(ICommand command)
{
command.Execute();
Insert(command);
}
void SetMaxLength(int max)
{
undoCommands.maxLength = max;
redoCommands.maxLength = max;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 297f3596ca22e9244a563037bca0b4c7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,36 @@
using System;
namespace CommandUndoRedo
{
public static class UndoRedoManager
{
static UndoRedo undoRedo = new UndoRedo();
public static int maxUndoStored {get {return undoRedo.maxUndoStored;} set {undoRedo.maxUndoStored = value;}}
public static void Clear()
{
undoRedo.Clear();
}
public static void Undo()
{
undoRedo.Undo();
}
public static void Redo()
{
undoRedo.Redo();
}
public static void Insert(ICommand command)
{
undoRedo.Insert(command);
}
public static void Execute(ICommand command)
{
undoRedo.Execute(command);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89804e2ce721593439fb97818d0d5f89
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+57
View File
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SerializableBone
{
public string Name = "";
public string ParentName = "";
public List<BoneTags> Tags = new List<BoneTags>();
public SerializableTransform Transform = new SerializableTransform();
/// <summary> Reference to original bone for runtime. Not saved to file. </summary>
[NonSerialized] public Transform Bone;
public SerializableBone(){}
public SerializableBone(Transform t, bool generateTags = true, List<BoneTags> tags = null)
{
if(tags == null) tags = new List<BoneTags>();
if (generateTags)
{
if (t.name.EndsWith("_L"))
{
tags.Add(BoneTags.Left);
}
else if (t.name.EndsWith("_R"))
{
tags.Add(BoneTags.Right);
}
if(t.GetComponentInParent<DynamicBone>() != null)
{
tags.Add(BoneTags.Dynamic);
}
}
Name = t.name;
Tags = tags;
Transform = new SerializableTransform(t, Space.Self);
ParentName = t.parent == null ? "root" : t.parent.name;
Bone = t;
}
//feel free to add more. do not change order!
public enum BoneTags
{
Left,
Right,
Dynamic,
Humanoid,
Finger,
Face
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 76589de57e9a06541a4c0e05fee843e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+108
View File
@@ -0,0 +1,108 @@
using System;
using UnityEngine;
namespace SerializableTypes
{
/// <summary> Serializable version of UnityEngine.Vector3. </summary>
[Serializable]
public struct SVector3
{
public float x;
public float y;
public float z;
public SVector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public override string ToString()
=> $"[x, y, z]";
public static implicit operator Vector3(SVector3 s)
=> new Vector3(s.x, s.y, s.z);
public static implicit operator SVector3(Vector3 v)
=> new SVector3(v.x, v.y, v.z);
public static SVector3 operator +(SVector3 a, SVector3 b)
=> new SVector3(a.x + b.x, a.y + b.y, a.z + b.z);
public static SVector3 operator -(SVector3 a, SVector3 b)
=> new SVector3(a.x - b.x, a.y - b.y, a.z - b.z);
public static SVector3 operator -(SVector3 a)
=> new SVector3(-a.x, -a.y, -a.z);
public static SVector3 operator *(SVector3 a, float m)
=> new SVector3(a.x * m, a.y * m, a.z * m);
public static SVector3 operator *(float m, SVector3 a)
=> new SVector3(a.x * m, a.y * m, a.z * m);
public static SVector3 operator /(SVector3 a, float d)
=> new SVector3(a.x / d, a.y / d, a.z / d);
}
/// <summary> Serializable version of UnityEngine.Quaternion. </summary>
[Serializable]
public struct SQuaternion
{
public float x;
public float y;
public float z;
public float w;
public SQuaternion(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public override string ToString()
=> $"[{x}, {y}, {z}, {w}]";
public static implicit operator Quaternion(SQuaternion s)
=> new Quaternion(s.x, s.y, s.z, s.w);
public static implicit operator SQuaternion(Quaternion q)
=> new SQuaternion(q.x, q.y, q.z, q.w);
}
/// <summary> Serializable version of UnityEngine.Color32 without transparency. </summary>
[Serializable]
public struct SColor32
{
public byte r;
public byte g;
public byte b;
public SColor32(byte r, byte g, byte b)
{
this.r = r;
this.g = g;
this.b = b;
}
public SColor32(Color32 c)
{
r = c.r;
g = c.g;
b = c.b;
}
public override string ToString()
=> $"[{r}, {g}, {b}]";
public static implicit operator Color32(SColor32 rValue)
=> new Color32(rValue.r, rValue.g, rValue.b, a: byte.MaxValue);
public static implicit operator SColor32(Color32 rValue)
=> new SColor32(rValue.r, rValue.g, rValue.b);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1e1995c5fed47fd45991ae57801b07c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+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:
@@ -0,0 +1,69 @@
using SerializableTypes;
using UnityEngine;
[System.Serializable]
public class SerializableTransform
{
public Space Space;
public SVector3 Position;
public SVector3 Rotation;
public SVector3 Scale;
public SerializableTransform()
{
Space = Space.World;
Scale = Vector3.one;
Position = Vector3.zero;
Rotation = Vector3.zero;
}
public SerializableTransform(Transform t, Space space)
{
Space = space;
if (space == Space.World)
{
Position = t.position;
Rotation = t.eulerAngles;
Scale = t.localScale; //lossyscale is read-only, so can't be used later
}
else
{
Position = t.localPosition;
Rotation = t.localEulerAngles;
Scale = t.localScale;
}
}
public void ApplyTo(Transform t)
{
if (Space == Space.World)
{
t.position = Position;
t.eulerAngles = Rotation;
t.localScale = Scale;
}
else
{
t.localPosition = Position;
t.localEulerAngles = Rotation;
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;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f5ff55a51a723d54ea02f9089ead0ec2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: cabaf29aa96c5f44d807cc8c0e1996d7
guid: 770f9310a8e01724fb9582052237af3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
+222
View File
@@ -0,0 +1,222 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class UIPoseContainer : MonoBehaviour
{
public PoseData PoseData;
public TMPro.TMP_InputField
NameLabel,
DescriptionLabel;
public TMPro.TMP_Text
InfoLabel;
[SerializeField]
private Button
_btnSave,
_btnLoad,
_btnDelete;
public static UIPoseContainer Create(PoseData data)
{
var poseContainer = Instantiate(UmaViewerUI.Instance.PoseManager.Pfb_PoseContainer, UmaViewerUI.Instance.PoseManager.SavedPoseList.content);
poseContainer.Init(data);
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;
NameLabel.text = data.Name;
DescriptionLabel.text = data.Description;
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()
{
Name = NameLabel.text,
Date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"),
Character = container.name,
Description = DescriptionLabel.text,
ViewerVersion = Application.version,
Bones = container.SaveBones(),
Morphs = container.SaveMorphs(true)
};
var duplicateContainer = CheckIfContainerExists(poseData.Name);
if (duplicateContainer != null && 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;
if (container == null) return;
var poseData = new PoseData()
{
Name = NameLabel.text,
Date = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"),
Character = container.name,
Description = DescriptionLabel.text,
ViewerVersion = Application.version,
Bones = container.SaveBones(),
Morphs = container.SaveMorphs(true)
};
var duplicateContainer = CheckIfContainerExists(poseData.Name);
if (duplicateContainer != null && 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);
if(poseData.Name != PoseData.Name)
{
//Create new container with new data
UIPoseContainer.Create(poseData);
//Reset back to old data
Init(PoseData);
}
else
{
//Only replace the data if everything succeeded
Init(poseData);
}
}
catch (Exception e)
{
UmaViewerUI.Instance.ShowMessage(e.Message, UIMessageType.Error);
}
}
public void Load()
{
PoseManager.SetPoseModeStatic(true);
UmaContainerCharacter container = UmaViewerBuilder.Instance.CurrentUMAContainer;
if (container == null) return;
var loadOptions = PoseManager.GetLoadOptions();
container.LoadBones(PoseData, loadOptions);
if (loadOptions.Morphs)
{
container.LoadMorphs(PoseData);
}
}
public void Delete()
{
Destroy(gameObject);
string fullpath = $"{Application.dataPath}/../Poses/{PoseData.Name}.umaPose";
fullpath = Path.GetFullPath(fullpath);
if(File.Exists(fullpath))
{
File.Delete(fullpath);
}
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;
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1c176a293fb01e4886a4456e855e23f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+280 -84
View File
@@ -1,15 +1,13 @@
using Gallop;
using Gallop.Live.Cutt;
using RootMotion.Dynamics;
using RootMotion.FinalIK;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
using static SerializableBone;
public class UmaContainerCharacter : UmaContainer
{
@@ -86,6 +84,7 @@ public class UmaContainerCharacter : UmaContainer
private Collider dragCollider;
private BipedIK IK;
private PuppetMaster PuppetMaster;
private List<Transform> _humanoidBones;
public void Initialize(bool smile)
{
@@ -281,6 +280,11 @@ public class UmaContainerCharacter : UmaContainer
}
}
public void SetPuppetMasterMode(PuppetMaster.Mode mode)
{
PuppetMaster.mode = mode;
}
public void SetDynamicBoneEnable(bool isOn)
{
if (IsMini) return;
@@ -307,121 +311,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);
}
}
@@ -788,6 +791,7 @@ public class UmaContainerCharacter : UmaContainer
break;
case "Gallop/3D/Chara/ToonMayu":
m.shader = UmaAssetManager.EyebrowShader;
m.renderQueue += 1; //fix eyebrows disappearing sometimes
break;
default:
Debug.Log(m.shader.name);
@@ -1369,4 +1373,196 @@ public class UmaContainerCharacter : UmaContainer
emotionDriven.FaceEmotionKey = UmaDatabaseController.Instance.FaceTypeData;
emotionDriven.Initialize();
}
public void SetupBoneHandles()
{
if (IsLive) return;
UIHandleCharacterRoot rootHandle = UIHandleCharacterRoot.CreateAsChild(this);
var humanBones = GetHumanBones();
foreach(var bone in humanBones)
{
List<BoneTags> tags = new List<BoneTags>() { BoneTags.Humanoid };
if (bone.name.EndsWith("_L")) tags.Add(BoneTags.Left);
if (bone.name.EndsWith("_R")) tags.Add(BoneTags.Right);
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);
}
}
public List<SerializableBone> SaveBones()
{
var boneList = new List<SerializableBone>();
GatherSerializableBonesRecursive(Position, boneList, 0);
return boneList;
}
private void GatherSerializableBonesRecursive(Transform current, List<SerializableBone> bones, int depth)
{
for(int i = 0; i < current.childCount; i++)
{
GatherSerializableBonesRecursive(current.GetChild(i), bones, depth + 1);
}
//this can be optimized by keeping track if the bone is dynamic
//and generating a list of tags beforehand
//otherwise getComponentInParent() is called for every bone
var bone = new SerializableBone(current, true);
if(depth == 0)
{
//make it independent from character name
bone.ParentName = "root";
}
bones.Add(bone);
}
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.Transform.ApplyTo(bone.Bone, options);
}
//could add a 'bone not found' threshold for returning false
return true;
}
public List<Transform> GetHumanBones()
{
if(_humanoidBones == null)
{
var animator = UmaAnimator;
List<Transform> list = new List<Transform>(animator.gameObject.GetComponentsInChildren<Transform>());
_humanoidBones = new List<Transform>()
{
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")),
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.Where(b => b != null).ToList();
}
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;
}
}
+10 -4
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>();
@@ -303,6 +302,7 @@ public class UmaViewerBuilder : MonoBehaviour
umaContainer.Initialize(!UI.isTPose);
umaContainer.Position = umaContainer.transform.Find("Position");
umaContainer.SetupBoneHandles();
if (!UI.isTPose && loadMotion)
{
@@ -524,6 +524,7 @@ public class UmaViewerBuilder : MonoBehaviour
umaContainer.Initialize(!UI.isTPose);
umaContainer.Position = umaContainer.transform.Find("Position");
umaContainer.SetupBoneHandles();
if (!UI.isTPose && loadMotion)
{
@@ -636,7 +637,10 @@ public class UmaViewerBuilder : MonoBehaviour
var eyebrowRmat = matList.FirstOrDefault(a => a.gameObject.name.Equals("M_Mayu_R"));
UI.LoadFacialPanelsMini(eyemat.material, eyebrowLmat.material, eyebrowRmat.material, mouthmat.material);
if(Main.AbList.TryGetValue($"3d/motion/mini/event/body/chara/chr{id}_00/anm_min_eve_chr{id}_00_idle01_loop",out asset))
umaContainer.Position = umaContainer.transform.Find("Position");
umaContainer.SetupBoneHandles();
if (Main.AbList.TryGetValue($"3d/motion/mini/event/body/chara/chr{id}_00/anm_min_eve_chr{id}_00_idle01_loop",out asset))
{
umaContainer.LoadAnimation(asset);
}
@@ -930,6 +934,8 @@ public class UmaViewerBuilder : MonoBehaviour
public void UnloadUma()
{
PoseManager.SetPoseModeStatic(false);
if (CurrentUMAContainer != null)
{
//It seems that OnDestroy will executed after new model loaded, which cause new FacialPanels empty...
+16 -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
{
@@ -44,6 +45,8 @@ public class UmaViewerUI : MonoBehaviour
public PageManager ScenePageCtrl;
public ScrollRect MessageScrollRect;
public Text MessageText;
public PoseManager PoseManager;
public HandleManager HandleManager;
[Header("lists")]
public ScrollRect EmotionList;
@@ -60,6 +63,8 @@ public class UmaViewerUI : MonoBehaviour
public ScrollRect NormalSubSoundList;
public PageManager NormalSoundCtrl;
[Header("pose mode")]
public Transform HandlesPanel;
[Header("audio")]
public Slider AudioSlider;
@@ -158,6 +163,8 @@ public class UmaViewerUI : MonoBehaviour
UpdateDBButton.interactable = (Config.Instance.WorkMode == WorkMode.Standalone);
UmaAssetManager.OnLoadedBundleUpdate += LoadedAssetsAdd;
UmaAssetManager.OnLoadedBundleClear += LoadedAssetsClear;
PoseManager.LoadLocalPoseFiles();
}
private void OnDestroy()
@@ -592,6 +599,7 @@ public class UmaViewerUI : MonoBehaviour
public void PlayLive()
{
if (currentLive == null) return;
PoseManager.SetPoseMode(false);
var selectlist = LiveSelectList.content.GetComponentsInChildren<LiveCharacterSelect>();
if (selectlist != null)
{
@@ -694,7 +702,6 @@ public class UmaViewerUI : MonoBehaviour
list.Add(Main.AbList["3d/animator/drivenkeylocator"]);
list.Add(Main.AbList[$"3d/motion/event/body/chara/chr{achara.Id}_00/anm_eve_chr{achara.Id}_00_idle01_loop"]);
Builder.UnloadUma();
//UmaAssetManager.UnloadAllBundle(true);
UmaAssetManager.PreLoadAndRun(list , delegate {
@@ -1051,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()
@@ -1399,4 +1406,9 @@ public class UmaViewerUI : MonoBehaviour
}
}
}
public void ToggleVisible(GameObject go)
{
go.SetActive(!go.activeSelf);
}
}
-1
View File
@@ -3,7 +3,6 @@
"rootNamespace": "",
"references": [
"GUID:6055be8ebefd69e48b49212b09b47b2f",
"GUID:800597811bcc5d848b15e12807d6de45",
"GUID:d60799ab2a985554ea1a39cd38695018",
"GUID:fd1d627189c561043911a07470238b9c",
"GUID:145e2572884581c48a08acf566c1a1d6",
@@ -1,15 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Gallop
{
public class CameraEventCallback : MonoBehaviour
{
private Camera _targetCamera; // 0x18
public Action<Camera> OnPreCullCallback; // 0x20
public Action<Camera> OnPreRenderCallback; // 0x28
public Action<Camera> OnPostRenderCallback; // 0x30
}
}
@@ -1,9 +0,0 @@
using UnityEngine;
namespace Gallop
{
public class CharaTransformProcessData : ScriptableObject
{
}
}
@@ -1,16 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Gallop.Cutt.Util
{
[System.Serializable]
public class TimelineCharaPartsData
{
[SerializeField]
private string _rendererName;
[SerializeField]
private int _rendererHash;
public bool IsVisible;
}
}

Some files were not shown because too many files have changed in this diff Show More