mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2024-12-29 02:35:06 +08:00
feat: improvements to armature tracking (#665)
* opti(armature-lock): parallelize burst jobs for armature lock processing * feat: continue armature tracking when the MAMA GameObject is disabled Closes: #500 * feat: add global toggle for armature locking Closes: #484
This commit is contained in:
parent
27f0557367
commit
648c9a9608
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using nadena.dev.modular_avatar.ui;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
ApplyToCurrentAvatar();
|
ApplyToCurrentAvatar();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Modular Avatar/Manual bake avatar", true)]
|
[MenuItem(UnityMenuItems.TopMenu_ManualBakeAvatar, true, UnityMenuItems.TopMenu_ManualBakeAvatarOrder)]
|
||||||
private static bool ValidateApplyToCurrentAvatar()
|
private static bool ValidateApplyToCurrentAvatar()
|
||||||
{
|
{
|
||||||
return ndmf.AvatarProcessor.CanProcessObject(Selection.activeGameObject);
|
return ndmf.AvatarProcessor.CanProcessObject(Selection.activeGameObject);
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using nadena.dev.modular_avatar.ui;
|
||||||
using nadena.dev.ndmf.localization;
|
using nadena.dev.ndmf.localization;
|
||||||
using nadena.dev.ndmf.ui;
|
using nadena.dev.ndmf.ui;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -87,7 +88,7 @@ namespace nadena.dev.modular_avatar.core.editor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Modular Avatar/Reload localizations")]
|
[MenuItem(UnityMenuItems.TopMenu_ReloadLocalizations, false, UnityMenuItems.TopMenu_ReloadLocalizationsOrder)]
|
||||||
public static void Reload()
|
public static void Reload()
|
||||||
{
|
{
|
||||||
Localizer.ReloadLocalizations();
|
Localizer.ReloadLocalizations();
|
||||||
|
@ -1,13 +1,65 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using nadena.dev.modular_avatar.ui;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.armature_lock
|
namespace nadena.dev.modular_avatar.core.armature_lock
|
||||||
{
|
{
|
||||||
|
internal class ArmatureLockConfig
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
: UnityEditor.ScriptableSingleton<ArmatureLockConfig>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if !UNITY_EDITOR
|
||||||
|
internal static ArmatureLockConfig instance { get; } = new ArmatureLockConfig();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private bool _globalEnable = true;
|
||||||
|
|
||||||
|
internal bool GlobalEnable
|
||||||
|
{
|
||||||
|
get => _globalEnable;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _globalEnable) return;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
Undo.RecordObject(this, "Toggle Edit Mode Bone Sync");
|
||||||
|
Menu.SetChecked(UnityMenuItems.TopMenu_EditModeBoneSync, value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_globalEnable = value;
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
// Run prepare one last time to dispose of lock structures
|
||||||
|
UpdateLoopController.InvokeArmatureLockPrepare();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[InitializeOnLoadMethod]
|
||||||
|
static void Init()
|
||||||
|
{
|
||||||
|
EditorApplication.delayCall += () => {
|
||||||
|
Menu.SetChecked(UnityMenuItems.TopMenu_EditModeBoneSync, instance._globalEnable);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem(UnityMenuItems.TopMenu_EditModeBoneSync, false, UnityMenuItems.TopMenu_EditModeBoneSyncOrder)]
|
||||||
|
static void ToggleBoneSync()
|
||||||
|
{
|
||||||
|
instance.GlobalEnable = !instance.GlobalEnable;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
internal class ArmatureLockController : IDisposable
|
internal class ArmatureLockController : IDisposable
|
||||||
{
|
{
|
||||||
private static long lastMovedFrame = 0;
|
private static long lastMovedFrame = 0;
|
||||||
@ -24,6 +76,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
private readonly GetTransformsDelegate _getTransforms;
|
private readonly GetTransformsDelegate _getTransforms;
|
||||||
private IArmatureLock _lock;
|
private IArmatureLock _lock;
|
||||||
|
|
||||||
|
private bool GlobalEnable => ArmatureLockConfig.instance.GlobalEnable;
|
||||||
private bool _updateActive;
|
private bool _updateActive;
|
||||||
|
|
||||||
private bool UpdateActive
|
private bool UpdateActive
|
||||||
@ -35,11 +88,13 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
UpdateLoopController.OnArmatureLockUpdate += VoidUpdate;
|
UpdateLoopController.OnArmatureLockPrepare += UpdateLoopPrepare;
|
||||||
|
UpdateLoopController.OnArmatureLockUpdate += UpdateLoopFinish;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UpdateLoopController.OnArmatureLockUpdate -= VoidUpdate;
|
UpdateLoopController.OnArmatureLockPrepare -= UpdateLoopPrepare;
|
||||||
|
UpdateLoopController.OnArmatureLockUpdate -= UpdateLoopFinish;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateActive = value;
|
_updateActive = value;
|
||||||
@ -70,6 +125,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Enabled == value) return;
|
if (Enabled == value) return;
|
||||||
|
|
||||||
_enabled = value;
|
_enabled = value;
|
||||||
if (_enabled) UpdateActive = true;
|
if (_enabled) UpdateActive = true;
|
||||||
}
|
}
|
||||||
@ -105,24 +161,73 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
return RebuildLock() && (_lock?.IsStable() ?? false);
|
return RebuildLock() && (_lock?.IsStable() ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VoidUpdate()
|
private void VoidPrepare()
|
||||||
{
|
{
|
||||||
Update();
|
UpdateLoopPrepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLoopFinish()
|
||||||
|
{
|
||||||
|
DoFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool Update()
|
internal bool Update()
|
||||||
{
|
{
|
||||||
LockResult result;
|
UpdateLoopPrepare();
|
||||||
|
return DoFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsPrepared = false;
|
||||||
|
|
||||||
|
private void UpdateLoopPrepare()
|
||||||
|
{
|
||||||
|
if (_mama == null || !_mama.gameObject.scene.IsValid())
|
||||||
|
{
|
||||||
|
UpdateActive = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Enabled)
|
if (!Enabled)
|
||||||
{
|
{
|
||||||
UpdateActive = false;
|
UpdateActive = false;
|
||||||
|
_lock?.Dispose();
|
||||||
|
_lock = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GlobalEnable)
|
||||||
|
{
|
||||||
|
_lock?.Dispose();
|
||||||
|
_lock = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_curMode == _mode)
|
||||||
|
{
|
||||||
|
_lock?.Prepare();
|
||||||
|
IsPrepared = _lock != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DoFinish()
|
||||||
|
{
|
||||||
|
LockResult result;
|
||||||
|
|
||||||
|
if (!GlobalEnable)
|
||||||
|
{
|
||||||
_lock?.Dispose();
|
_lock?.Dispose();
|
||||||
_lock = null;
|
_lock = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var wasPrepared = IsPrepared;
|
||||||
|
IsPrepared = false;
|
||||||
|
|
||||||
|
if (!Enabled) return true;
|
||||||
|
|
||||||
if (_curMode == _mode)
|
if (_curMode == _mode)
|
||||||
{
|
{
|
||||||
|
if (!wasPrepared) _lock?.Prepare();
|
||||||
result = _lock?.Execute() ?? LockResult.Failed;
|
result = _lock?.Execute() ?? LockResult.Failed;
|
||||||
if (result == LockResult.Success)
|
if (result == LockResult.Success)
|
||||||
{
|
{
|
||||||
@ -134,6 +239,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
|
|
||||||
if (!RebuildLock()) return false;
|
if (!RebuildLock()) return false;
|
||||||
|
|
||||||
|
_lock?.Prepare();
|
||||||
result = (_lock?.Execute() ?? LockResult.Failed);
|
result = (_lock?.Execute() ?? LockResult.Failed);
|
||||||
|
|
||||||
return result != LockResult.Failed;
|
return result != LockResult.Failed;
|
||||||
|
@ -20,6 +20,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
private NativeIntPtr WroteAny;
|
private NativeIntPtr WroteAny;
|
||||||
|
|
||||||
private JobHandle LastOp;
|
private JobHandle LastOp;
|
||||||
|
private JobHandle LastPrepare;
|
||||||
|
|
||||||
public BidirectionalArmatureLock(IReadOnlyList<(Transform, Transform)> bones)
|
public BidirectionalArmatureLock(IReadOnlyList<(Transform, Transform)> bones)
|
||||||
{
|
{
|
||||||
@ -142,21 +143,20 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DoCompute(out JobHandle handle)
|
public void Prepare()
|
||||||
{
|
{
|
||||||
handle = default;
|
if (_disposed) return;
|
||||||
|
|
||||||
if (_disposed) return false;
|
|
||||||
|
|
||||||
WroteAny.Value = 0;
|
|
||||||
|
|
||||||
LastOp.Complete();
|
LastOp.Complete();
|
||||||
|
|
||||||
|
WroteAny.Value = 0;
|
||||||
|
|
||||||
var readBase = new ReadBone()
|
var readBase = new ReadBone()
|
||||||
{
|
{
|
||||||
_state = BaseBones,
|
_state = BaseBones,
|
||||||
}.Schedule(_baseBoneAccess);
|
}.Schedule(_baseBoneAccess);
|
||||||
LastOp = handle = new Compute()
|
|
||||||
|
LastOp = LastPrepare = new Compute()
|
||||||
{
|
{
|
||||||
BaseBones = BaseBones,
|
BaseBones = BaseBones,
|
||||||
MergeBones = MergeBones,
|
MergeBones = MergeBones,
|
||||||
@ -165,7 +165,12 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
ShouldWriteMerge = ShouldWriteMerge,
|
ShouldWriteMerge = ShouldWriteMerge,
|
||||||
WroteAny = WroteAny.GetParallel(),
|
WroteAny = WroteAny.GetParallel(),
|
||||||
}.Schedule(_mergeBoneAccess, readBase);
|
}.Schedule(_mergeBoneAccess, readBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckConsistency()
|
||||||
|
{
|
||||||
|
if (_disposed) return false;
|
||||||
|
|
||||||
// Check parents haven't changed
|
// Check parents haven't changed
|
||||||
for (int i = 0; i < _baseBones.Length; i++)
|
for (int i = 0; i < _baseBones.Length; i++)
|
||||||
{
|
{
|
||||||
@ -186,27 +191,27 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
|
|
||||||
public bool IsStable()
|
public bool IsStable()
|
||||||
{
|
{
|
||||||
if (!DoCompute(out var compute)) return false;
|
Prepare();
|
||||||
|
if (!CheckConsistency()) return false;
|
||||||
compute.Complete();
|
LastPrepare.Complete();
|
||||||
|
|
||||||
return WroteAny.Value == 0;
|
return WroteAny.Value == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LockResult Execute()
|
public LockResult Execute()
|
||||||
{
|
{
|
||||||
if (!DoCompute(out var compute)) return LockResult.Failed;
|
if (!CheckConsistency()) return LockResult.Failed;
|
||||||
|
|
||||||
var commitBase = new Commit()
|
var commitBase = new Commit()
|
||||||
{
|
{
|
||||||
BoneState = BaseBones,
|
BoneState = BaseBones,
|
||||||
ShouldWrite = ShouldWriteBase,
|
ShouldWrite = ShouldWriteBase,
|
||||||
}.Schedule(_baseBoneAccess, compute);
|
}.Schedule(_baseBoneAccess, LastPrepare);
|
||||||
var commitMerge = new Commit()
|
var commitMerge = new Commit()
|
||||||
{
|
{
|
||||||
BoneState = MergeBones,
|
BoneState = MergeBones,
|
||||||
ShouldWrite = ShouldWriteMerge,
|
ShouldWrite = ShouldWriteMerge,
|
||||||
}.Schedule(_mergeBoneAccess, compute);
|
}.Schedule(_mergeBoneAccess, LastPrepare);
|
||||||
|
|
||||||
commitBase.Complete();
|
commitBase.Complete();
|
||||||
commitMerge.Complete();
|
commitMerge.Complete();
|
||||||
|
@ -4,6 +4,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
{
|
{
|
||||||
internal interface IArmatureLock : IDisposable
|
internal interface IArmatureLock : IDisposable
|
||||||
{
|
{
|
||||||
|
void Prepare();
|
||||||
LockResult Execute();
|
LockResult Execute();
|
||||||
bool IsStable();
|
bool IsStable();
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ using nadena.dev.modular_avatar.JacksonDunstan.NativeCollections;
|
|||||||
using Unity.Burst;
|
using Unity.Burst;
|
||||||
using Unity.Collections;
|
using Unity.Collections;
|
||||||
using Unity.Jobs;
|
using Unity.Jobs;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Jobs;
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
#endif
|
#endif
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Jobs;
|
|
||||||
|
|
||||||
namespace nadena.dev.modular_avatar.core.armature_lock
|
namespace nadena.dev.modular_avatar.core.armature_lock
|
||||||
{
|
{
|
||||||
@ -29,7 +29,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
private TransformAccessArray _baseBonesAccessor, _mergeBonesAccessor;
|
private TransformAccessArray _baseBonesAccessor, _mergeBonesAccessor;
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private JobHandle LastOp;
|
private JobHandle LastOp, LastPrepare;
|
||||||
|
|
||||||
[BurstCompile]
|
[BurstCompile]
|
||||||
struct WriteBone : IJobParallelForTransform
|
struct WriteBone : IJobParallelForTransform
|
||||||
@ -197,13 +197,13 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
return (scale.x < epsilon || scale.y < epsilon || scale.z < epsilon);
|
return (scale.x < epsilon || scale.y < epsilon || scale.z < epsilon);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DoCompute(out JobHandle handle)
|
public void Prepare()
|
||||||
{
|
{
|
||||||
handle = default;
|
if (_disposed) return;
|
||||||
if (_disposed) return false;
|
|
||||||
|
|
||||||
LastOp.Complete();
|
LastOp.Complete();
|
||||||
|
|
||||||
|
|
||||||
_fault.Value = 0;
|
_fault.Value = 0;
|
||||||
_wroteAny.Value = 0;
|
_wroteAny.Value = 0;
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
_state = _mergeState
|
_state = _mergeState
|
||||||
}.Schedule(_mergeBonesAccessor);
|
}.Schedule(_mergeBonesAccessor);
|
||||||
var readAll = JobHandle.CombineDependencies(jobReadBase, jobReadMerged);
|
var readAll = JobHandle.CombineDependencies(jobReadBase, jobReadMerged);
|
||||||
LastOp = handle = new ComputePosition
|
LastOp = LastPrepare = new ComputePosition
|
||||||
{
|
{
|
||||||
_boneStatic = _boneStaticData,
|
_boneStatic = _boneStaticData,
|
||||||
_mergeState = _mergeState,
|
_mergeState = _mergeState,
|
||||||
@ -225,6 +225,11 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
_fault = _fault.GetParallel(),
|
_fault = _fault.GetParallel(),
|
||||||
_wroteAny = _wroteAny.GetParallel(),
|
_wroteAny = _wroteAny.GetParallel(),
|
||||||
}.Schedule(_baseBones.Length, 32, readAll);
|
}.Schedule(_baseBones.Length, 32, readAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CheckConsistency()
|
||||||
|
{
|
||||||
|
if (_disposed) return false;
|
||||||
|
|
||||||
// Validate parents while that job is running
|
// Validate parents while that job is running
|
||||||
for (int i = 0; i < _baseBones.Length; i++)
|
for (int i = 0; i < _baseBones.Length; i++)
|
||||||
@ -246,9 +251,10 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
|
|
||||||
public bool IsStable()
|
public bool IsStable()
|
||||||
{
|
{
|
||||||
if (!DoCompute(out var compute)) return false;
|
Prepare();
|
||||||
|
if (!CheckConsistency()) return false;
|
||||||
|
|
||||||
compute.Complete();
|
LastPrepare.Complete();
|
||||||
|
|
||||||
return _fault.Value == 0 && _wroteAny.Value == 0;
|
return _fault.Value == 0 && _wroteAny.Value == 0;
|
||||||
}
|
}
|
||||||
@ -259,14 +265,14 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
/// <returns>True if successful, false if cached data was invalidated and needs recreating</returns>
|
/// <returns>True if successful, false if cached data was invalidated and needs recreating</returns>
|
||||||
public LockResult Execute()
|
public LockResult Execute()
|
||||||
{
|
{
|
||||||
if (!DoCompute(out var compute)) return LockResult.Failed;
|
if (!CheckConsistency()) return LockResult.Failed;
|
||||||
|
|
||||||
var commit = new WriteBone()
|
var commit = new WriteBone()
|
||||||
{
|
{
|
||||||
_fault = _fault,
|
_fault = _fault,
|
||||||
_values = _mergeSavedState,
|
_values = _mergeSavedState,
|
||||||
_shouldWrite = _wroteAny
|
_shouldWrite = _wroteAny
|
||||||
}.Schedule(_mergeBonesAccessor, compute);
|
}.Schedule(_mergeBonesAccessor, LastPrepare);
|
||||||
|
|
||||||
commit.Complete();
|
commit.Complete();
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
{
|
{
|
||||||
internal static class UpdateLoopController
|
internal static class UpdateLoopController
|
||||||
{
|
{
|
||||||
|
internal static event Action OnArmatureLockPrepare;
|
||||||
internal static event Action OnArmatureLockUpdate;
|
internal static event Action OnArmatureLockUpdate;
|
||||||
internal static event Action OnMoveIndependentlyUpdate;
|
internal static event Action OnMoveIndependentlyUpdate;
|
||||||
|
|
||||||
@ -11,14 +12,22 @@ namespace nadena.dev.modular_avatar.core.armature_lock
|
|||||||
[UnityEditor.InitializeOnLoadMethod]
|
[UnityEditor.InitializeOnLoadMethod]
|
||||||
private static void Init()
|
private static void Init()
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
|
||||||
UnityEditor.EditorApplication.update += () =>
|
UnityEditor.EditorApplication.update += () =>
|
||||||
{
|
{
|
||||||
OnArmatureLockUpdate?.Invoke();
|
if (ArmatureLockConfig.instance.GlobalEnable)
|
||||||
|
{
|
||||||
|
OnArmatureLockPrepare?.Invoke();
|
||||||
|
OnArmatureLockUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
OnMoveIndependentlyUpdate?.Invoke();
|
OnMoveIndependentlyUpdate?.Invoke();
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
internal static void InvokeArmatureLockPrepare()
|
||||||
|
{
|
||||||
|
OnArmatureLockPrepare?.Invoke();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -74,6 +74,7 @@ namespace nadena.dev.modular_avatar.core
|
|||||||
base.OnValidate();
|
base.OnValidate();
|
||||||
MigrateLockConfig();
|
MigrateLockConfig();
|
||||||
RuntimeUtil.delayCall(SetLockMode);
|
RuntimeUtil.delayCall(SetLockMode);
|
||||||
|
Debug.Log("$$$ OnValidate");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ResetArmatureLock()
|
internal void ResetArmatureLock()
|
||||||
@ -106,7 +107,7 @@ namespace nadena.dev.modular_avatar.core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_lockController.Enabled = isActiveAndEnabled;
|
_lockController.Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MigrateLockConfig()
|
private void MigrateLockConfig()
|
||||||
@ -126,7 +127,8 @@ namespace nadena.dev.modular_avatar.core
|
|||||||
|
|
||||||
private void OnDisable()
|
private void OnDisable()
|
||||||
{
|
{
|
||||||
_lockController.Enabled = false;
|
// we use enabled instead of activeAndEnabled to ensure we track even when the GameObject is disabled
|
||||||
|
_lockController.Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnDestroy()
|
protected override void OnDestroy()
|
||||||
|
3
Runtime/UI.meta
Normal file
3
Runtime/UI.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e36cbbfd8a704421becea83cb2d1e72f
|
||||||
|
timeCreated: 1707812798
|
14
Runtime/UI/UnityMenuItems.cs
Normal file
14
Runtime/UI/UnityMenuItems.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace nadena.dev.modular_avatar.ui
|
||||||
|
{
|
||||||
|
internal class UnityMenuItems
|
||||||
|
{
|
||||||
|
internal const string TopMenu_EditModeBoneSync = "Tools/Modular Avatar/Sync Bones in Edit Mode";
|
||||||
|
internal const int TopMenu_EditModeBoneSyncOrder = 100;
|
||||||
|
|
||||||
|
internal const string TopMenu_ManualBakeAvatar = "Tools/Modular Avatar/Manual Bake Avatar";
|
||||||
|
internal const int TopMenu_ManualBakeAvatarOrder = 1000;
|
||||||
|
|
||||||
|
internal const string TopMenu_ReloadLocalizations = "Tools/Modular Avatar/Reload Localizations";
|
||||||
|
internal const int TopMenu_ReloadLocalizationsOrder = 1001;
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/UI/UnityMenuItems.cs.meta
Normal file
3
Runtime/UI/UnityMenuItems.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c5b3fcacdeb74934b0fb8554490d5d9c
|
||||||
|
timeCreated: 1707812807
|
Loading…
Reference in New Issue
Block a user