mirror of
https://github.com/originalnicodr/CinematicUnityExplorer.git
synced 2025-07-18 17:38:01 +08:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
48fec535fd | |||
5e9abd33b4 | |||
6ebf19dfa0 | |||
cc34a50e21 | |||
954b6f4f1c | |||
b785f76ba3 | |||
d2d22de66c | |||
af2ad057fb | |||
ca726e0ae7 | |||
a02460be33 | |||
30b9e6e387 | |||
58f477ed0d | |||
fd672615be | |||
f8886700d9 | |||
dae6930b43 | |||
d9ebe5819c | |||
171ee3f0d8 | |||
448ab66f5b | |||
b090f68732 | |||
13dcef668f |
@ -204,10 +204,14 @@ Allows you to manually play characters and NPC animations in a scene. This shoul
|
||||
|
||||
Favorite animations so they appear first on the dropdown list by clicking on the star button with the animation selected.
|
||||
|
||||
The Animator Panel also allows you to freeze all characters in a scene all at once, alongside giving you control over which characters should ignore the master toggler. That way you can make the playable character avoid getting frozen, or avoid un-freezing NPCs or enemies that already have the animations you want them to have.
|
||||
The Animator Panel also allows you to freeze all characters in a scene all at once, alongside giving you control over which characters should ignore the master toggler. Each animator also comes with a toggle to be able to hide a character meshes from a scene.
|
||||
|
||||
Alongside all of this, you can also open each character game object by clicking on their names, so you can move, rotate, scale them around, disable them, or further edit their properties and child objects.
|
||||
|
||||
### Bones Panel
|
||||
|
||||
For each animator, you can also spawn a Bones Panel. This panel will list all of the character's bones and meshes, and provide easy-to-access toggles to disable them and sliders to move them around, allowing you to pose a character to your liking.
|
||||
|
||||
## Misc Panel
|
||||
- HUD toggle.
|
||||
- Force high LODs toggle. This means that the highest models possible will be forced on all meshes.
|
||||
|
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "com.originalnicodr.cinematicunityexplorer",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"displayName": "CinematicUnityExplorer",
|
||||
"description": "UnityExplorer fork focused on providing tools for creating marketing material for Unity games.",
|
||||
"unity": "2017.1",
|
||||
|
@ -21,13 +21,16 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
public Toggle IgnoreMasterToggle;
|
||||
public Toggle AnimatorToggle;
|
||||
public Toggle MeshToggle;
|
||||
public ButtonRef inspectButton;
|
||||
ButtonRef playButton;
|
||||
public Dropdown animatorDropdown;
|
||||
ButtonRef favAnimation;
|
||||
Slider animationTimeline;
|
||||
ButtonRef playButton;
|
||||
ButtonRef openBonesPanelButton;
|
||||
|
||||
// ICell
|
||||
public float DefaultHeight => 25f;
|
||||
public float DefaultHeight => 30f;
|
||||
public GameObject UIRoot { get; set; }
|
||||
public RectTransform Rect { get; set; }
|
||||
|
||||
@ -64,7 +67,7 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
|
||||
private void PlayButton_OnClick(){
|
||||
animatorPlayer.PlayOverridingAnimation();
|
||||
animatorPlayer.PlayOverridingAnimation(0);
|
||||
// Needed for the new animation to play for some reason
|
||||
EnableAnimation(false);
|
||||
EnableAnimation(true);
|
||||
@ -72,31 +75,36 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
public virtual GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
GameObject AnimatorToggleObj = UIFactory.CreateToggle(parent, $"AnimatorToggle", out AnimatorToggle, out Text animatorToggleText);
|
||||
UIFactory.SetLayoutElement(AnimatorToggleObj, minHeight: 25);
|
||||
AnimatorToggle.isOn = animatorPlayer != null && animatorPlayer.animator.speed == 1;
|
||||
AnimatorToggle.onValueChanged.AddListener(EnableAnimation);
|
||||
UIRoot = UIFactory.CreateUIObject("AnimatorCell", parent);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(UIRoot, false, false, true, true, 4, childAlignment: TextAnchor.MiddleLeft);
|
||||
UIFactory.SetLayoutElement(UIRoot, minHeight: 25, flexibleWidth: 9999);
|
||||
|
||||
UIRoot = AnimatorToggleObj;
|
||||
UIRoot.SetActive(false);
|
||||
GameObject MeshToggleObj = UIFactory.CreateToggle(UIRoot, "MeshToggle", out MeshToggle, out Text MeshToggleText);
|
||||
UIFactory.SetLayoutElement(MeshToggleObj, minHeight: 30);
|
||||
MeshToggle.onValueChanged.AddListener(EnableMesh);
|
||||
|
||||
Rect = UIRoot.GetComponent<RectTransform>();
|
||||
Rect.anchorMin = new Vector2(0, 1);
|
||||
Rect.anchorMax = new Vector2(0, 1);
|
||||
Rect.pivot = new Vector2(0.5f, 1);
|
||||
Rect.sizeDelta = new Vector2(25, 25);
|
||||
Rect.sizeDelta = new Vector2(30, 30);
|
||||
|
||||
UIFactory.SetLayoutElement(UIRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 25, flexibleHeight: 0);
|
||||
UIFactory.SetLayoutElement(UIRoot, minWidth: 100, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0);
|
||||
|
||||
inspectButton = UIFactory.CreateButton(UIRoot, "InspectButton", "");
|
||||
UIFactory.SetLayoutElement(inspectButton.GameObject, minWidth: 200, minHeight: 25);
|
||||
inspectButton.OnClick += () => InspectorManager.Inspect(animatorPlayer.animator.gameObject);
|
||||
|
||||
GameObject AnimatorToggleObj = UIFactory.CreateToggle(UIRoot, "AnimatorToggle", out AnimatorToggle, out Text animatorToggleText);
|
||||
UIFactory.SetLayoutElement(AnimatorToggleObj, minHeight: 30);
|
||||
AnimatorToggle.isOn = animatorPlayer != null && animatorPlayer.animator.speed == 1;
|
||||
AnimatorToggle.onValueChanged.AddListener(EnableAnimation);
|
||||
|
||||
ButtonRef resetAnimation = UIFactory.CreateButton(UIRoot, "Reset Animation", "Reset");
|
||||
UIFactory.SetLayoutElement(resetAnimation.GameObject, minWidth: 50, minHeight: 25);
|
||||
resetAnimation.OnClick += ResetAnimation;
|
||||
|
||||
GameObject ignoresMasterTogglerObj = UIFactory.CreateToggle(UIRoot, $"AnimatorIgnoreMasterToggle", out IgnoreMasterToggle, out Text ignoreMasterToggleText);
|
||||
GameObject ignoresMasterTogglerObj = UIFactory.CreateToggle(UIRoot, "AnimatorIgnoreMasterToggle", out IgnoreMasterToggle, out Text ignoreMasterToggleText);
|
||||
UIFactory.SetLayoutElement(ignoresMasterTogglerObj, minHeight: 25, minWidth: 155);
|
||||
IgnoreMasterToggle.isOn = false;
|
||||
IgnoreMasterToggle.onValueChanged.AddListener(IgnoreMasterToggle_Clicked);
|
||||
@ -112,7 +120,7 @@ namespace UnityExplorer.UI.Panels
|
||||
favAnimation.ButtonText.text = animatorPlayer.IsAnimationFaved(animatorPlayer.overridingAnimation) ? "★" : "☆";
|
||||
};
|
||||
|
||||
GameObject overridingAnimationObj = UIFactory.CreateDropdown(UIRoot, $"Animations_Dropdown", out animatorDropdown, null, 14, (idx) => {
|
||||
GameObject overridingAnimationObj = UIFactory.CreateDropdown(UIRoot, "Animations_Dropdown", out animatorDropdown, null, 14, (idx) => {
|
||||
if (animatorPlayer.animator.wrappedObject == null)
|
||||
return;
|
||||
animatorPlayer.overridingAnimation = idx < animatorDropdown.options.Count ? animatorPlayer.animations.Find(a => a.name == animatorDropdown.options[idx].text) : animatorPlayer.overridingAnimation;
|
||||
@ -151,10 +159,24 @@ namespace UnityExplorer.UI.Panels
|
||||
//UpdateDropdownOptions();
|
||||
};
|
||||
|
||||
GameObject animationTimelineObj = UIFactory.CreateSlider(UIRoot, "AnimationTimelineSlider", out animationTimeline);
|
||||
UIFactory.SetLayoutElement(animationTimelineObj, minHeight: 25, minWidth: 200, flexibleHeight: 0);
|
||||
animationTimeline.minValue = 0;
|
||||
animationTimeline.maxValue = 1;
|
||||
animationTimeline.onValueChanged.AddListener((float val) => {
|
||||
animatorPlayer.PlayOverridingAnimation(val);
|
||||
AnimatorToggle.isOn = false;
|
||||
});
|
||||
|
||||
playButton = UIFactory.CreateButton(UIRoot, "PlayButton", "Play", new Color(0.2f, 0.26f, 0.2f));
|
||||
UIFactory.SetLayoutElement(playButton.Component.gameObject, minHeight: 25, minWidth: 90);
|
||||
playButton.OnClick += PlayButton_OnClick;
|
||||
|
||||
openBonesPanelButton = UIFactory.CreateButton(UIRoot, "OpenBonesPanelButton", "Open Bones Panel");
|
||||
UIFactory.SetLayoutElement(openBonesPanelButton.Component.gameObject, minWidth: 150, minHeight: 25, flexibleWidth: 0, flexibleHeight: 0);
|
||||
|
||||
openBonesPanelButton.OnClick += () => { animatorPlayer.OpenBonesPanel(); };
|
||||
|
||||
return UIRoot;
|
||||
}
|
||||
|
||||
@ -170,5 +192,9 @@ namespace UnityExplorer.UI.Panels
|
||||
if (animatorPlayer.animator.wrappedObject != null)
|
||||
animatorPlayer.animator.speed = value ? 1 : 0;
|
||||
}
|
||||
|
||||
internal void EnableMesh(bool value){
|
||||
animatorPlayer.SetMeshesEnabled(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,11 @@ namespace UnityExplorer.UI.Panels
|
||||
public List<IAnimationClip> animations = new List<IAnimationClip>();
|
||||
public bool shouldIgnoreMasterToggle = false;
|
||||
|
||||
BonesManager bonesManager;
|
||||
private List<Transform> bones = new List<Transform>();
|
||||
private List<SkinnedMeshRenderer> skinnedMeshes = new();
|
||||
private List<MeshRenderer> extraMeshes = new();
|
||||
|
||||
public IAnimationClip overridingAnimation;
|
||||
private IAnimationClip lastCurrentAnimation;
|
||||
private IRuntimeAnimatorController originalAnimatorController;
|
||||
@ -42,6 +47,9 @@ namespace UnityExplorer.UI.Panels
|
||||
this.overridingAnimation = lastCurrentAnimation != null ? lastCurrentAnimation : (animations.Count > 0 ? animations[0] : null);
|
||||
|
||||
this.favAnimations = new List<IAnimationClip>();
|
||||
|
||||
this.skinnedMeshes.AddRange(this.animator.wrappedObject.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(false));
|
||||
this.extraMeshes.AddRange(this.animator.wrappedObject.gameObject.GetComponentsInChildren<MeshRenderer>(false));
|
||||
}
|
||||
|
||||
// Include the animations being played in other layers
|
||||
@ -54,6 +62,7 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
|
||||
public void ResetAnimation(){
|
||||
if (bonesManager != null) bonesManager.turnOffAnimatorToggle.isOn = true;
|
||||
// Let the game change animations again
|
||||
animator.StopPlayback();
|
||||
if (originalAnimatorController != null && animator.wrappedObject != null){
|
||||
@ -65,7 +74,7 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayOverridingAnimation(){
|
||||
public void PlayOverridingAnimation(float normalizedTime){
|
||||
ResetAnimation();
|
||||
if (animatorOverrideController == null){
|
||||
animatorOverrideController = new IAnimatorOverrideController();
|
||||
@ -84,7 +93,7 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
IAnimationClip currentAnimation = animator.GetCurrentAnimatorClipInfo(0)[0].clip;
|
||||
animatorOverrideController[currentAnimation] = overridingAnimation;
|
||||
animator.Play(currentAnimation.name);
|
||||
animator.Play(currentAnimation.name, normalizedTime);
|
||||
|
||||
lastCurrentAnimation = currentAnimation;
|
||||
}
|
||||
@ -115,6 +124,35 @@ namespace UnityExplorer.UI.Panels
|
||||
animator.enabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Transform> GetMeshes(){
|
||||
List<Transform> meshes = new List<Transform>();
|
||||
|
||||
foreach (SkinnedMeshRenderer skinnedMesh in skinnedMeshes) {
|
||||
meshes.AddRange(skinnedMesh.bones);
|
||||
}
|
||||
meshes.AddRange(extraMeshes.Select(m => m.transform));
|
||||
|
||||
return meshes.GroupBy(b => b.name).Select(b => b.First()).ToList().OrderBy(b => b.name).ToList();
|
||||
}
|
||||
|
||||
public void OpenBonesPanel(){
|
||||
if (skinnedMeshes.Count == 0 && extraMeshes.Count == 0) return;
|
||||
if (bonesManager == null){
|
||||
bonesManager = new BonesManager(UIManager.GetPanel<UnityExplorer.UI.Panels.AnimatorPanel>(UIManager.Panels.AnimatorPanel).Owner, GetMeshes(), animator);
|
||||
}
|
||||
bonesManager.SetActive(true);
|
||||
}
|
||||
|
||||
public void SetMeshesEnabled(bool value){
|
||||
foreach (SkinnedMeshRenderer skinnedMesh in skinnedMeshes) {
|
||||
skinnedMesh.TryCast<Renderer>().enabled = value;
|
||||
}
|
||||
|
||||
foreach (MeshRenderer meshRenderer in extraMeshes) {
|
||||
meshRenderer.gameObject.SetActive(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IAnimator
|
||||
@ -209,9 +247,9 @@ namespace UnityExplorer.UI.Panels
|
||||
}
|
||||
}
|
||||
|
||||
public void Play(string animatorClip){
|
||||
public void Play(string animatorClip, float normalizedTime){
|
||||
MethodInfo play = realType.GetMethod("Play", new Type[] {typeof(string), typeof(int), typeof(float)});
|
||||
play.Invoke(_animator.TryCast(), new object[] {animatorClip, -1, 0f});
|
||||
play.Invoke(_animator.TryCast(), new object[] {animatorClip, -1, normalizedTime});
|
||||
}
|
||||
|
||||
public float speed
|
||||
|
342
src/Cinematic/Cells/BonesCell.cs
Normal file
342
src/Cinematic/Cells/BonesCell.cs
Normal file
@ -0,0 +1,342 @@
|
||||
using UnityExplorer.UI.Widgets;
|
||||
using UniverseLib.Input;
|
||||
using UniverseLib.UI;
|
||||
using UniverseLib.UI.Models;
|
||||
using UniverseLib.UI.Widgets.ScrollView;
|
||||
|
||||
namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
public class BonesCell : ICell
|
||||
{
|
||||
public Transform bone;
|
||||
public TransformControls transformControls;
|
||||
|
||||
ComponentControl positionControl;
|
||||
ComponentControl rotationControl;
|
||||
ComponentControl scaleControl;
|
||||
public AxisComponentControl CurrentSlidingAxisControl { get; set; }
|
||||
public BonesManager Owner;
|
||||
private ButtonRef inspectButton;
|
||||
|
||||
// ICell
|
||||
public float DefaultHeight => 25f;
|
||||
public GameObject UIRoot { get; set; }
|
||||
public RectTransform Rect { get; set; }
|
||||
|
||||
public bool Enabled => UIRoot.activeSelf;
|
||||
public void Enable() => UIRoot.SetActive(true);
|
||||
public void Disable() => UIRoot.SetActive(false);
|
||||
|
||||
public void SetBone(Transform bone, BonesManager bonesManager){
|
||||
this.bone = bone;
|
||||
inspectButton.ButtonText.text = bone.name;
|
||||
Owner = bonesManager;
|
||||
}
|
||||
|
||||
public virtual GameObject CreateContent(GameObject parent)
|
||||
{
|
||||
UIRoot = UIFactory.CreateUIObject("BoneCell", parent, new Vector2(25, 25));
|
||||
Rect = UIRoot.GetComponent<RectTransform>();
|
||||
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(UIRoot, false, false, true, true, 3);
|
||||
UIFactory.SetLayoutElement(UIRoot, minHeight: 25, minWidth: 50, flexibleWidth: 9999);
|
||||
|
||||
GameObject header = UIFactory.CreateUIObject("BoneHeader", UIRoot);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(header, false, false, true, true, 4, childAlignment: TextAnchor.MiddleLeft);
|
||||
UIFactory.SetLayoutElement(header, minHeight: 25, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
|
||||
GameObject MeshToggleObj = UIFactory.CreateToggle(header, "MeshToggle", out Toggle MeshToggle, out Text MeshToggleText);
|
||||
UIFactory.SetLayoutElement(MeshToggleObj, minHeight: 30);
|
||||
MeshToggle.onValueChanged.AddListener(SetBoneEnabled);
|
||||
|
||||
inspectButton = UIFactory.CreateButton(header, "InspectButton", "");
|
||||
UIFactory.SetLayoutElement(inspectButton.GameObject, minWidth: 150, minHeight: 25);
|
||||
inspectButton.OnClick += () => InspectorManager.Inspect(bone.gameObject);
|
||||
|
||||
GameObject headerButtons = UIFactory.CreateUIObject("BoneHeader", header);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(headerButtons, false, false, true, true, 4, childAlignment: TextAnchor.MiddleRight);
|
||||
UIFactory.SetLayoutElement(headerButtons, minHeight: 25, flexibleWidth: 9999, flexibleHeight: 800);
|
||||
|
||||
ButtonRef restoreBoneStateButton = UIFactory.CreateButton(headerButtons, "RestoreBoneState", "Restore State");
|
||||
UIFactory.SetLayoutElement(restoreBoneStateButton.GameObject, minWidth: 125, minHeight: 25);
|
||||
restoreBoneStateButton.OnClick += RestoreBoneState;
|
||||
|
||||
positionControl = ComponentControl.Create(this, UIRoot, "Local Position", TransformType.LocalPosition, 0.01f);
|
||||
rotationControl = ComponentControl.Create(this, UIRoot, "Rotation", TransformType.Rotation, 10f);
|
||||
scaleControl = ComponentControl.Create(this, UIRoot, "Scale", TransformType.Scale, 0.1f);
|
||||
|
||||
return UIRoot;
|
||||
}
|
||||
|
||||
private void RestoreBoneState(){
|
||||
Owner.RestoreBoneState(bone.name);
|
||||
}
|
||||
|
||||
private void SetBoneEnabled(bool value){
|
||||
bone.gameObject.SetActive(value);
|
||||
}
|
||||
|
||||
// TransformControls-like functions
|
||||
public void UpdateTransformControlValues(bool force){
|
||||
positionControl.Update(force);
|
||||
rotationControl.Update(force);
|
||||
scaleControl.Update(force);
|
||||
}
|
||||
|
||||
public void UpdateVectorSlider()
|
||||
{
|
||||
AxisComponentControl control = CurrentSlidingAxisControl;
|
||||
|
||||
if (control == null)
|
||||
return;
|
||||
|
||||
if (!IInputManager.GetMouseButton(0))
|
||||
{
|
||||
control.slider.value = 0f;
|
||||
control = null;
|
||||
return;
|
||||
}
|
||||
|
||||
AxisControlOperation(control.slider.value, control.parent, control.axis);
|
||||
|
||||
if (Owner.turnOffAnimatorToggle.isOn) Owner.turnOffAnimatorToggle.isOn = false;
|
||||
}
|
||||
|
||||
public void AxisControlOperation(float value, ComponentControl parent, int axis)
|
||||
{
|
||||
Transform transform = bone;
|
||||
|
||||
Vector3 vector = parent.Type switch
|
||||
{
|
||||
TransformType.Position => transform.position,
|
||||
TransformType.LocalPosition => transform.localPosition,
|
||||
TransformType.Rotation => transform.localEulerAngles,
|
||||
TransformType.Scale => transform.localScale,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
// apply vector value change
|
||||
switch (axis)
|
||||
{
|
||||
case 0:
|
||||
vector.x += value; break;
|
||||
case 1:
|
||||
vector.y += value; break;
|
||||
case 2:
|
||||
vector.z += value; break;
|
||||
}
|
||||
|
||||
// set vector back to transform
|
||||
switch (parent.Type)
|
||||
{
|
||||
case TransformType.Position:
|
||||
transform.position = vector; break;
|
||||
case TransformType.LocalPosition:
|
||||
transform.localPosition = vector; break;
|
||||
case TransformType.Rotation:
|
||||
transform.localEulerAngles = vector; break;
|
||||
case TransformType.Scale:
|
||||
transform.localScale = vector; break;
|
||||
}
|
||||
|
||||
UpdateTransformControlValues(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Duplication of Vector3Control class
|
||||
public class ComponentControl
|
||||
{
|
||||
public BonesCell Owner { get; }
|
||||
public Transform Transform => Owner.bone;
|
||||
public TransformType Type { get; }
|
||||
|
||||
public InputFieldRef MainInput { get; }
|
||||
|
||||
public AxisComponentControl[] axisComponentControl { get; } = new AxisComponentControl[3];
|
||||
|
||||
public InputFieldRef IncrementInput { get; set; }
|
||||
public float Increment { get; set; } = 0.1f;
|
||||
|
||||
Vector3 lastValue;
|
||||
|
||||
Vector3 CurrentValue => Type switch
|
||||
{
|
||||
TransformType.Position => Transform.position,
|
||||
TransformType.LocalPosition => Transform.localPosition,
|
||||
TransformType.Rotation => Transform.localEulerAngles,
|
||||
TransformType.Scale => Transform.localScale,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
public ComponentControl(BonesCell cell, TransformType type, InputFieldRef input)
|
||||
{
|
||||
this.Owner = cell;
|
||||
this.Type = type;
|
||||
this.MainInput = input;
|
||||
}
|
||||
|
||||
public void Update(bool force)
|
||||
{
|
||||
// Probably not needed
|
||||
if (Transform == null) return;
|
||||
|
||||
Vector3 currValue = CurrentValue;
|
||||
if (force || (!MainInput.Component.isFocused && !lastValue.Equals(currValue)))
|
||||
{
|
||||
MainInput.Text = ParseUtility.ToStringForInput<Vector3>(currValue);
|
||||
lastValue = currValue;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTransformInputEndEdit(TransformType type, string input)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TransformType.Position:
|
||||
{
|
||||
if (ParseUtility.TryParse(input, out Vector3 val, out _))
|
||||
Transform.position = val;
|
||||
}
|
||||
break;
|
||||
case TransformType.LocalPosition:
|
||||
{
|
||||
if (ParseUtility.TryParse(input, out Vector3 val, out _))
|
||||
Transform.localPosition = val;
|
||||
}
|
||||
break;
|
||||
case TransformType.Rotation:
|
||||
{
|
||||
if (ParseUtility.TryParse(input, out Vector3 val, out _))
|
||||
Transform.localEulerAngles = val;
|
||||
}
|
||||
break;
|
||||
case TransformType.Scale:
|
||||
{
|
||||
if (ParseUtility.TryParse(input, out Vector3 val, out _))
|
||||
Transform.localScale = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Owner.UpdateTransformControlValues(true);
|
||||
if (Owner.Owner.turnOffAnimatorToggle.isOn) Owner.Owner.turnOffAnimatorToggle.isOn = false;
|
||||
}
|
||||
|
||||
void IncrementInput_OnEndEdit(string value)
|
||||
{
|
||||
if (!ParseUtility.TryParse(value, out float increment, out _))
|
||||
IncrementInput.Text = ParseUtility.ToStringForInput<float>(Increment);
|
||||
else
|
||||
{
|
||||
Increment = increment;
|
||||
foreach (AxisComponentControl slider in axisComponentControl)
|
||||
{
|
||||
slider.slider.minValue = -increment;
|
||||
slider.slider.maxValue = increment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ComponentControl Create(BonesCell cell, GameObject transformGroup, string title, TransformType type, float increment)
|
||||
{
|
||||
GameObject rowObj = UIFactory.CreateUIObject($"Row_{title}", transformGroup);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(rowObj, false, false, true, true, 5, 0, 0, 0, 0, default);
|
||||
UIFactory.SetLayoutElement(rowObj, minHeight: 25, flexibleWidth: 9999);
|
||||
|
||||
Text titleLabel = UIFactory.CreateLabel(rowObj, "PositionLabel", title, TextAnchor.MiddleRight, Color.grey);
|
||||
UIFactory.SetLayoutElement(titleLabel.gameObject, minHeight: 25, minWidth: 110);
|
||||
|
||||
InputFieldRef inputField = UIFactory.CreateInputField(rowObj, "InputField", "...");
|
||||
UIFactory.SetLayoutElement(inputField.Component.gameObject, minHeight: 25, minWidth: 100, flexibleWidth: 999);
|
||||
|
||||
ComponentControl control = new(cell, type, inputField);
|
||||
|
||||
inputField.Component.GetOnEndEdit().AddListener((string value) => { control.OnTransformInputEndEdit(type, value); });
|
||||
control.Increment = increment;
|
||||
|
||||
control.axisComponentControl[0] = AxisComponentControl.Create(rowObj, "X", 0, control);
|
||||
control.axisComponentControl[1] = AxisComponentControl.Create(rowObj, "Y", 1, control);
|
||||
control.axisComponentControl[2] = AxisComponentControl.Create(rowObj, "Z", 2, control);
|
||||
|
||||
control.IncrementInput = UIFactory.CreateInputField(rowObj, "IncrementInput", "...");
|
||||
control.IncrementInput.Text = increment.ToString();
|
||||
UIFactory.SetLayoutElement(control.IncrementInput.GameObject, minWidth: 30, flexibleWidth: 0, minHeight: 25);
|
||||
control.IncrementInput.Component.GetOnEndEdit().AddListener(control.IncrementInput_OnEndEdit);
|
||||
|
||||
if (type == TransformType.Scale){
|
||||
GameObject extraRowObj = UIFactory.CreateUIObject("Row_UniformScale", transformGroup);
|
||||
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(extraRowObj, false, false, true, true, 5, 0, 0, 0, 0, default);
|
||||
UIFactory.SetLayoutElement(extraRowObj, minHeight: 25, flexibleWidth: 9999);
|
||||
|
||||
Text uniformScaleTitleLabel = UIFactory.CreateLabel(extraRowObj, "UniformScaleLabel", "Uniform Scale:", TextAnchor.MiddleRight, Color.grey);
|
||||
UIFactory.SetLayoutElement(uniformScaleTitleLabel.gameObject, minHeight: 25, minWidth: 110);
|
||||
|
||||
GameObject uniformScaleControlObj = UIFactory.CreateSlider(extraRowObj, "UniformScaleSlider", out Slider uniformScaleControl);
|
||||
UIFactory.SetLayoutElement(uniformScaleControlObj, minHeight: 25, minWidth: 200, flexibleHeight: 0);
|
||||
uniformScaleControl.minValue = 0.0001f;
|
||||
uniformScaleControl.maxValue = 10;
|
||||
uniformScaleControl.value = 1;
|
||||
uniformScaleControl.onValueChanged.AddListener((float val) => { cell.bone.localScale = new Vector3(val, val, val); });
|
||||
}
|
||||
|
||||
return control;
|
||||
}
|
||||
}
|
||||
|
||||
// // Duplication of AxisControl class
|
||||
public class AxisComponentControl
|
||||
{
|
||||
public readonly ComponentControl parent;
|
||||
|
||||
public readonly int axis;
|
||||
public readonly Slider slider;
|
||||
|
||||
public AxisComponentControl(int axis, Slider slider, ComponentControl parentControl)
|
||||
{
|
||||
this.parent = parentControl;
|
||||
this.axis = axis;
|
||||
this.slider = slider;
|
||||
}
|
||||
|
||||
void OnVectorSliderChanged(float value)
|
||||
{
|
||||
parent.Owner.CurrentSlidingAxisControl = value == 0f ? null : this;
|
||||
}
|
||||
|
||||
void OnVectorMinusClicked()
|
||||
{
|
||||
parent.Owner.AxisControlOperation(-this.parent.Increment, this.parent, this.axis);
|
||||
}
|
||||
|
||||
void OnVectorPlusClicked()
|
||||
{
|
||||
parent.Owner.AxisControlOperation(this.parent.Increment, this.parent, this.axis);
|
||||
}
|
||||
|
||||
public static AxisComponentControl Create(GameObject parent, string title, int axis, ComponentControl owner)
|
||||
{
|
||||
Text label = UIFactory.CreateLabel(parent, $"Label_{title}", $"{title}:", TextAnchor.MiddleRight, Color.grey);
|
||||
UIFactory.SetLayoutElement(label.gameObject, minHeight: 25, minWidth: 30);
|
||||
|
||||
GameObject sliderObj = UIFactory.CreateSlider(parent, $"Slider_{title}", out Slider slider);
|
||||
UIFactory.SetLayoutElement(sliderObj, minHeight: 25, minWidth: 75, flexibleWidth: 0);
|
||||
slider.m_FillImage.color = Color.clear;
|
||||
|
||||
slider.minValue = -owner.Increment;
|
||||
slider.maxValue = owner.Increment;
|
||||
|
||||
AxisComponentControl sliderControl = new(axis, slider, owner);
|
||||
|
||||
slider.onValueChanged.AddListener(sliderControl.OnVectorSliderChanged);
|
||||
|
||||
ButtonRef minusButton = UIFactory.CreateButton(parent, "MinusIncrementButton", "-");
|
||||
UIFactory.SetLayoutElement(minusButton.GameObject, minWidth: 20, flexibleWidth: 0, minHeight: 25);
|
||||
minusButton.OnClick += sliderControl.OnVectorMinusClicked;
|
||||
|
||||
ButtonRef plusButton = UIFactory.CreateButton(parent, "PlusIncrementButton", "+");
|
||||
UIFactory.SetLayoutElement(plusButton.GameObject, minWidth: 20, flexibleWidth: 0, minHeight: 25);
|
||||
plusButton.OnClick += sliderControl.OnVectorPlusClicked;
|
||||
|
||||
return sliderControl;
|
||||
}
|
||||
}
|
||||
}
|
@ -29,6 +29,9 @@ namespace CinematicUnityExplorer.Cinematic
|
||||
// Store the initial position when a session start in IGCSDof.
|
||||
Mono.CSharp.Tuple<Vector3, Quaternion> position = null;
|
||||
|
||||
// When we end a session, we need to make sure to go back to the position when the session ends.
|
||||
private Mono.CSharp.Tuple<Vector3, Quaternion> endSessionPosition = null;
|
||||
|
||||
private readonly bool isValid = false;
|
||||
private bool _isActive = false;
|
||||
public bool IsActive => isValid && _isActive;
|
||||
@ -42,21 +45,21 @@ namespace CinematicUnityExplorer.Cinematic
|
||||
private readonly Queue<StepCommand> commands = new();
|
||||
|
||||
private IntPtr CameraStatus = IntPtr.Zero;
|
||||
// In order to avoid allocations on every Update call, we create this buffer to allocate once
|
||||
// and copy from here the CameraStatus (because Marshal.Copy requires a buffer, urgh).
|
||||
private readonly byte[] CameraStatusBuffer = new byte[] { 0x0 };
|
||||
|
||||
public void UpdateFreecamStatus(bool enabled)
|
||||
{
|
||||
if (CameraStatus == IntPtr.Zero) return;
|
||||
|
||||
CameraStatusBuffer[0] = enabled ? (byte)0x1 : (byte)0x0;
|
||||
Marshal.Copy(CameraStatusBuffer, 0, CameraStatus, 1);
|
||||
|
||||
Marshal.WriteByte(CameraStatus, enabled ? (byte)0x1 : (byte)0x0);
|
||||
}
|
||||
|
||||
public void ExecuteCameraCommand(Camera cam)
|
||||
{
|
||||
var transform = cam.transform;
|
||||
|
||||
// Check whether we should go back to the original position despite being active or not
|
||||
this.ShouldMoveToOriginalPosition(transform);
|
||||
|
||||
if (!_isActive || position == null)
|
||||
{
|
||||
position = new(transform.position, transform.rotation);
|
||||
@ -89,8 +92,23 @@ namespace CinematicUnityExplorer.Cinematic
|
||||
_isActive = true;
|
||||
}
|
||||
|
||||
// At the EndSession, since we have a queue system, we have to have a special check when the session ends and
|
||||
// then move the camera back to the original position, because the queue gets cleaned as soon as the session
|
||||
// ends.
|
||||
public void ShouldMoveToOriginalPosition(Transform transform)
|
||||
{
|
||||
if (!isValid) return;
|
||||
if (endSessionPosition == null) return;
|
||||
|
||||
transform.position = endSessionPosition.Item1;
|
||||
transform.rotation = endSessionPosition.Item2;
|
||||
|
||||
endSessionPosition = null;
|
||||
}
|
||||
|
||||
private void EndSession()
|
||||
{
|
||||
endSessionPosition = position;
|
||||
position = null;
|
||||
_isActive = false;
|
||||
|
||||
|
@ -29,6 +29,7 @@ namespace UnityExplorer.Config
|
||||
public static ConfigElement<string> CSConsole_Assembly_Blacklist;
|
||||
public static ConfigElement<string> Reflection_Signature_Blacklist;
|
||||
public static ConfigElement<bool> Reflection_Hide_NativeInfoPtrs;
|
||||
public static ConfigElement<bool> Auto_Scale_UI;
|
||||
|
||||
public static ConfigElement<bool> Default_Gameplay_Freecam;
|
||||
public static ConfigElement<KeyCode> Pause;
|
||||
@ -180,6 +181,10 @@ namespace UnityExplorer.Config
|
||||
"For example, this will hide 'Class.NativeFieldInfoPtr_value' for the field 'Class.value'.",
|
||||
false);
|
||||
|
||||
Auto_Scale_UI = new("Make the mod UI automatically scale with resolution",
|
||||
"Especially useful when running games in high resolutions and you are having a hard time reading the mods menu (requires restart).",
|
||||
true);
|
||||
|
||||
Default_Gameplay_Freecam = new("Default Gameplay Freecam",
|
||||
"Turn this on if you want the default gameplay freecam toggle on the Freecam panel to be on on startup.",
|
||||
false);
|
||||
|
@ -20,7 +20,7 @@ namespace UnityExplorer
|
||||
public static class ExplorerCore
|
||||
{
|
||||
public const string NAME = "CinematicUnityExplorer";
|
||||
public const string VERSION = "1.1.0";
|
||||
public const string VERSION = "1.2.0";
|
||||
public const string AUTHOR = "originalnicodr, Sinai, yukieiji";
|
||||
public const string GUID = "com.originalnicodr.cinematicunityexplorer";
|
||||
|
||||
@ -80,7 +80,7 @@ namespace UnityExplorer
|
||||
|
||||
KeypressListener.Setup();
|
||||
|
||||
MakeUEUIScale();
|
||||
if (ConfigManager.Auto_Scale_UI.Value) MakeUEUIScale();
|
||||
}
|
||||
|
||||
internal static void Update()
|
||||
|
@ -23,14 +23,15 @@ namespace UnityExplorer.UI.Panels
|
||||
|
||||
public override string Name => "Animator";
|
||||
public override UIManager.Panels PanelType => UIManager.Panels.AnimatorPanel;
|
||||
public override int MinWidth => 900;
|
||||
public override int MinWidth => 1300;
|
||||
public override int MinHeight => 200;
|
||||
public override Vector2 DefaultAnchorMin => new(0.4f, 0.4f);
|
||||
public override Vector2 DefaultAnchorMax => new(0.6f, 0.6f);
|
||||
public override bool NavButtonWanted => true;
|
||||
public override bool ShouldSaveActiveState => true;
|
||||
|
||||
Toggle masterAnimatorToggle = new Toggle();
|
||||
Toggle masterAnimatorToggle;
|
||||
Toggle masterMeshToggle;
|
||||
|
||||
private static ScrollPool<AnimatorCell> animatorScrollPool;
|
||||
internal List<AnimatorPlayer> animators = new List<AnimatorPlayer>();
|
||||
@ -47,8 +48,6 @@ namespace UnityExplorer.UI.Panels
|
||||
animatorScrollPool.Initialize(this);
|
||||
DoneScrollPoolInit = true;
|
||||
}
|
||||
|
||||
animatorScrollPool.Refresh(true, false);
|
||||
}
|
||||
|
||||
private void FindAllAnimators(){
|
||||
@ -68,8 +67,16 @@ namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
if (animators[i].animator.wrappedObject != null){
|
||||
int newAnimatorsIndex = newAnimators.FindIndex(a => a.animator.wrappedObject == animators[i].animator.wrappedObject);
|
||||
if (newAnimatorsIndex != -1)
|
||||
if (newAnimatorsIndex != -1) {
|
||||
// If refreshing the animator gives us new animations, add them to the already existing ones.
|
||||
// Might break stuff.
|
||||
foreach (IAnimationClip animationClip in newAnimators[newAnimatorsIndex].animations) {
|
||||
// TODO: Refactor AnimatorPlayer.animations from List<IAnimationClip> to HashSet<IAnimationClip> to avoid checking this
|
||||
if (!animators[i].animations.Contains(animationClip))
|
||||
animators[i].animations.Add(animationClip);
|
||||
}
|
||||
newAnimators[newAnimatorsIndex] = animators[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
animators = newAnimators;
|
||||
@ -99,6 +106,19 @@ namespace UnityExplorer.UI.Panels
|
||||
animatorScrollPool.Refresh(true, false);
|
||||
}
|
||||
|
||||
public void MasterToggleMeshes(bool enable){
|
||||
// Load animators for the first time if there are not any
|
||||
if (animators.Count == 0) FindAllAnimators();
|
||||
|
||||
foreach (AnimatorPlayer animatorPlayer in animators){
|
||||
if (!animatorPlayer.shouldIgnoreMasterToggle){
|
||||
animatorPlayer.SetMeshesEnabled(enable);
|
||||
}
|
||||
}
|
||||
|
||||
animatorScrollPool.Refresh(true, false);
|
||||
}
|
||||
|
||||
public void HotkeyToggleAnimators(){
|
||||
masterAnimatorToggle.isOn = !masterAnimatorToggle.isOn;
|
||||
}
|
||||
@ -110,25 +130,37 @@ namespace UnityExplorer.UI.Panels
|
||||
GameObject firstGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "MainOptions", false, false, true, true, 3,
|
||||
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
|
||||
UIFactory.SetLayoutElement(firstGroup, minHeight: 25, flexibleWidth: 9999);
|
||||
//UIElements.Add(horiGroup);
|
||||
|
||||
ButtonRef updateAnimators = UIFactory.CreateButton(firstGroup, "RefreshAnimators", "Refresh Animators");
|
||||
UIFactory.SetLayoutElement(updateAnimators.GameObject, minWidth: 150, minHeight: 25);
|
||||
updateAnimators.OnClick += FindAllAnimators;
|
||||
GameObject headerSpace1 = UIFactory.CreateUIObject("HeaderSpace1", firstGroup);
|
||||
UIFactory.SetLayoutElement(headerSpace1, minWidth: 0, flexibleWidth: 0);
|
||||
|
||||
GameObject meshObj = UIFactory.CreateToggle(firstGroup, "Master Mesh Toggle", out masterMeshToggle, out Text masterMeshText);
|
||||
UIFactory.SetLayoutElement(meshObj, minHeight: 25, minWidth: 230);
|
||||
masterMeshToggle.onValueChanged.AddListener(value => MasterToggleMeshes(value));
|
||||
masterMeshText.text = "Master Mesh Toggler";
|
||||
|
||||
GameObject animatorObj = UIFactory.CreateToggle(firstGroup, "Master Animation Toggle", out masterAnimatorToggle, out Text masterAnimatorText);
|
||||
UIFactory.SetLayoutElement(animatorObj, minHeight: 25);
|
||||
masterAnimatorToggle.onValueChanged.AddListener(value => MasterToggleAnimators(value));
|
||||
masterAnimatorText.text = "Master Animator Toggler";
|
||||
|
||||
GameObject headerSpace2 = UIFactory.CreateUIObject("HeaderSpace2", firstGroup);
|
||||
UIFactory.SetLayoutElement(headerSpace2, minWidth: 10, flexibleWidth: 0);
|
||||
|
||||
ButtonRef resetAnimators = UIFactory.CreateButton(firstGroup, "ResetAnimators", "Reset Animators");
|
||||
UIFactory.SetLayoutElement(resetAnimators.GameObject, minWidth: 150, minHeight: 25);
|
||||
resetAnimators.OnClick += ResetAllAnimators;
|
||||
|
||||
GameObject animatorObj = UIFactory.CreateToggle(firstGroup, $"Master Animation Toggle", out masterAnimatorToggle, out Text masterAnimatorText);
|
||||
UIFactory.SetLayoutElement(animatorObj, minHeight: 25);
|
||||
masterAnimatorToggle.isOn = true;
|
||||
masterAnimatorToggle.onValueChanged.AddListener(value => MasterToggleAnimators(value));
|
||||
masterAnimatorText.text = "Master Toggler";
|
||||
GameObject secondGroup = UIFactory.CreateHorizontalGroup(firstGroup, "HeaderRight", false, false, true, true, 3,
|
||||
default, new Color(1, 1, 1, 0), TextAnchor.MiddleRight);
|
||||
UIFactory.SetLayoutElement(secondGroup, minHeight: 25, flexibleWidth: 9999);
|
||||
|
||||
GameObject secondGroup = UIFactory.CreateHorizontalGroup(ContentRoot, "MainOptions", false, false, true, true, 3,
|
||||
default, new Color(1, 1, 1, 0), TextAnchor.MiddleLeft);
|
||||
UIFactory.SetLayoutElement(firstGroup, minHeight: 25, flexibleWidth: 9999);
|
||||
ButtonRef updateAnimators = UIFactory.CreateButton(secondGroup, "RefreshAnimators", "Refresh Animators");
|
||||
UIFactory.SetLayoutElement(updateAnimators.GameObject, minWidth: 150, minHeight: 25);
|
||||
updateAnimators.OnClick += FindAllAnimators;
|
||||
|
||||
GameObject headerSpaceRight = UIFactory.CreateUIObject("HeaderSpaceRight", firstGroup);
|
||||
UIFactory.SetLayoutElement(headerSpaceRight, minWidth: 25, flexibleWidth: 0);
|
||||
|
||||
animatorScrollPool = UIFactory.CreateScrollPool<AnimatorCell>(ContentRoot, "AnimatorsList", out GameObject scrollObj,
|
||||
out GameObject scrollContent, new Color(0.03f, 0.03f, 0.03f));
|
||||
|
135
src/UI/Panels/BonesPanel.cs
Normal file
135
src/UI/Panels/BonesPanel.cs
Normal file
@ -0,0 +1,135 @@
|
||||
using UniverseLib.UI;
|
||||
using UniverseLib.UI.Panels;
|
||||
using UniverseLib.UI.Widgets.ScrollView;
|
||||
|
||||
namespace UnityExplorer.UI.Panels
|
||||
{
|
||||
public class BonesManager : PanelBase, ICellPoolDataSource<BonesCell>
|
||||
{
|
||||
public override string Name => $"Bones Manager";
|
||||
public override int MinWidth => 1000;
|
||||
public override int MinHeight => 400;
|
||||
public override Vector2 DefaultAnchorMin => Vector2.zero;
|
||||
public override Vector2 DefaultAnchorMax => Vector2.zero;
|
||||
public Toggle turnOffAnimatorToggle;
|
||||
|
||||
private IAnimator animator;
|
||||
private Text skeletonName;
|
||||
private List<Transform> bones = new List<Transform>();
|
||||
private Dictionary<string, CachedBonesTransform> bonesOriginalState = new();
|
||||
|
||||
private ScrollPool<BonesCell> boneScrollPool;
|
||||
public int ItemCount => bones.Count;
|
||||
private bool DoneScrollPoolInit;
|
||||
|
||||
public BonesManager(UIBase owner, List<Transform> bones, IAnimator animator) : base(owner)
|
||||
{
|
||||
this.bones = bones;
|
||||
this.animator = animator;
|
||||
skeletonName.text = $"Skeleton: {animator?.name}";
|
||||
}
|
||||
|
||||
public override void SetActive(bool active)
|
||||
{
|
||||
base.SetActive(active);
|
||||
|
||||
if (active && !DoneScrollPoolInit)
|
||||
{
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(this.Rect);
|
||||
boneScrollPool.Initialize(this);
|
||||
DoneScrollPoolInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ConstructPanelContent()
|
||||
{
|
||||
skeletonName = UIFactory.CreateLabel(ContentRoot, $"SkeletonName", "");
|
||||
UIFactory.SetLayoutElement(skeletonName.gameObject, minWidth: 100, minHeight: 25);
|
||||
skeletonName.fontSize = 16;
|
||||
|
||||
GameObject turnOffAnimatorToggleObj = UIFactory.CreateToggle(ContentRoot, "Animator toggle", out turnOffAnimatorToggle, out Text turnOffAnimatorToggleText);
|
||||
UIFactory.SetLayoutElement(turnOffAnimatorToggleObj, minHeight: 25, flexibleWidth: 9999);
|
||||
turnOffAnimatorToggle.onValueChanged.AddListener(OnTurnOffAnimatorToggle);
|
||||
turnOffAnimatorToggleText.text = "Toggle animator (needs to be off to move bones)";
|
||||
|
||||
boneScrollPool = UIFactory.CreateScrollPool<BonesCell>(ContentRoot, "BonesList", out GameObject scrollObj,
|
||||
out GameObject scrollContent, new Color(0.06f, 0.06f, 0.06f));
|
||||
UIFactory.SetLayoutElement(scrollObj, flexibleWidth: 9999, flexibleHeight: 9999);
|
||||
}
|
||||
|
||||
private void OnTurnOffAnimatorToggle(bool value)
|
||||
{
|
||||
if (value){
|
||||
// Restore meshes manually in case some are not part of a skeleton and won't get restored automatically.
|
||||
// Besides, this restores the scale, which the animator doesn't.
|
||||
foreach (Transform bone in bones){
|
||||
CachedBonesTransform CachedBonesTransform = bonesOriginalState[bone.name];
|
||||
bone.localPosition = CachedBonesTransform.position;
|
||||
bone.localEulerAngles = CachedBonesTransform.angles;
|
||||
bone.localScale = CachedBonesTransform.scale;
|
||||
// We assume these were on before. If not we should save its state beforehand.
|
||||
bone.gameObject.SetActive(true);
|
||||
}
|
||||
} else {
|
||||
bonesOriginalState.Clear();
|
||||
foreach (Transform bone in bones){
|
||||
bonesOriginalState[bone.name] = new CachedBonesTransform(bone.localPosition, bone.localEulerAngles, bone.localScale);
|
||||
}
|
||||
}
|
||||
animator.enabled = value;
|
||||
}
|
||||
|
||||
public void RestoreBoneState(string boneName)
|
||||
{
|
||||
foreach (Transform bone in bones){
|
||||
if (bone.name == boneName){
|
||||
CachedBonesTransform CachedBonesTransform = bonesOriginalState[boneName];
|
||||
bone.localPosition = CachedBonesTransform.position;
|
||||
bone.localEulerAngles = CachedBonesTransform.angles;
|
||||
bone.localScale = CachedBonesTransform.scale;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCell(BonesCell cell, int index)
|
||||
{
|
||||
if (index >= bones.Count)
|
||||
{
|
||||
cell.Disable();
|
||||
return;
|
||||
}
|
||||
|
||||
Transform bone = bones[index];
|
||||
cell.SetBone(bone, this);
|
||||
cell.UpdateTransformControlValues(true);
|
||||
}
|
||||
|
||||
public void OnCellBorrowed(BonesCell cell) {
|
||||
cell.UpdateVectorSlider();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
foreach(BonesCell boneCell in boneScrollPool.CellPool) {
|
||||
boneCell.UpdateVectorSlider();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CachedBonesTransform
|
||||
{
|
||||
public CachedBonesTransform(Vector3 position, Vector3 angles, Vector3 scale)
|
||||
{
|
||||
this.position = position;
|
||||
this.angles = angles;
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public readonly Vector3 position;
|
||||
public readonly Vector3 angles;
|
||||
public readonly Vector3 scale;
|
||||
}
|
||||
}
|
@ -241,7 +241,8 @@ namespace UnityExplorer.UI.Panels
|
||||
IEnumerable<Behaviour> comps = ourCamera.GetComponentsInChildren<Behaviour>();
|
||||
foreach (Behaviour comp in comps)
|
||||
{
|
||||
if (comp.GetActualType().ToString() == "Cinemachine.CinemachineBrain"){
|
||||
string comp_type = comp.GetActualType().ToString();
|
||||
if (comp_type == "Cinemachine.CinemachineBrain" || comp_type == "Il2CppCinemachine.CinemachineBrain"){
|
||||
comp.enabled = enable;
|
||||
disabledCinemachine = !enable;
|
||||
break;
|
||||
@ -685,7 +686,6 @@ namespace UnityExplorer.UI.Panels
|
||||
FreeCamPanel.EndFreecam();
|
||||
return;
|
||||
}
|
||||
|
||||
Transform transform = FreeCamPanel.ourCamera.transform;
|
||||
|
||||
if (!FreeCamPanel.blockFreecamMovementToggle.isOn && !FreeCamPanel.cameraPathMover.playingPath && FreeCamPanel.connector?.IsActive != true) {
|
||||
|
@ -74,13 +74,26 @@ namespace UnityExplorer.UI.Widgets
|
||||
{
|
||||
if (float.TryParse(val, out float f))
|
||||
{
|
||||
if (f < slider.minValue || f > slider.maxValue){
|
||||
if (f < slider.minValue){
|
||||
ExplorerCore.LogWarning("Error, new time scale value outside of margins.");
|
||||
timeInput.Text = desiredTime.ToString("0.00");
|
||||
return;
|
||||
}
|
||||
|
||||
slider.value = f; // Will update the desiredTime value and extra things
|
||||
// Allow registering timescale values above the slider max value
|
||||
if (f >= slider.maxValue) {
|
||||
// Move the slider to the right
|
||||
slider.value = slider.maxValue;
|
||||
|
||||
desiredTime = f;
|
||||
pause = false;
|
||||
previousDesiredTime = desiredTime;
|
||||
}
|
||||
else {
|
||||
slider.value = f; // Will update the desiredTime value and extra things
|
||||
}
|
||||
|
||||
timeInput.Text = f.ToString("0.00");
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user