1910 changed files with 1198006 additions and 67812 deletions
@ -1,369 +0,0 @@ |
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!1102 &-8258256563073254863 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: openStop |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -7792811542948930001} |
|||
- {fileID: 3627530597684413355} |
|||
- {fileID: -2560027898811023536} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 7515460337550946210, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &-7792811542948930001 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: next |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: 8015446570950281760} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1107 &-6778641050302873508 |
|||
AnimatorStateMachine: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: Base Layer |
|||
m_ChildStates: |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 8015446570950281760} |
|||
m_Position: {x: -130, y: 500, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 1909220101572688523} |
|||
m_Position: {x: -110, y: 240, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -51858381997564467} |
|||
m_Position: {x: 230, y: 510, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -2101302564905477905} |
|||
m_Position: {x: 330, y: 380, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 4229820379494049694} |
|||
m_Position: {x: 200, y: 190, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -8258256563073254863} |
|||
m_Position: {x: 30, y: 340, z: 0} |
|||
m_ChildStateMachines: [] |
|||
m_AnyStateTransitions: [] |
|||
m_EntryTransitions: [] |
|||
m_StateMachineTransitions: {} |
|||
m_StateMachineBehaviours: [] |
|||
m_AnyStatePosition: {x: 50, y: 20, z: 0} |
|||
m_EntryPosition: {x: 50, y: 120, z: 0} |
|||
m_ExitPosition: {x: 800, y: 120, z: 0} |
|||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} |
|||
m_DefaultState: {fileID: -8258256563073254863} |
|||
--- !u!1101 &-2560027898811023536 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: close |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -2101302564905477905} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &-2101302564905477905 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: close |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 6283062061880575365, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &-677711796674791455 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: [] |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -8258256563073254863} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1101 &-370417210073110067 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: [] |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -8258256563073254863} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &-51858381997564467 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: back |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -677711796674791455} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: -1223372888097988523, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!91 &9100000 |
|||
AnimatorController: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: BookAnim |
|||
serializedVersion: 5 |
|||
m_AnimatorParameters: |
|||
- m_Name: back |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: next |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: open |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: close |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
m_AnimatorLayers: |
|||
- serializedVersion: 5 |
|||
m_Name: Base Layer |
|||
m_StateMachine: {fileID: -6778641050302873508} |
|||
m_Mask: {fileID: 0} |
|||
m_Motions: [] |
|||
m_Behaviours: [] |
|||
m_BlendingMode: 0 |
|||
m_SyncedLayerIndex: -1 |
|||
m_DefaultWeight: 0 |
|||
m_IKPass: 0 |
|||
m_SyncedLayerAffectsTiming: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
--- !u!1102 &1909220101572688523 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: open |
|||
m_Speed: 3 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 5315072357139859488, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &3627530597684413355 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: back |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -51858381997564467} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &4229820379494049694 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: New State |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 0} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1102 &8015446570950281760 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: next |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -370417210073110067} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 376750786793711421, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: c65b1bd77750abf44a1fcd05c5129e67 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,247 @@ |
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!1102 &-7950515957825162590 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: open |
|||
m_Speed: 3 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -6779006279012101952} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 5315072357139859488, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &-6779006279012101952 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: [] |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: 6239727856879991033} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1107 &-2019547273944851464 |
|||
AnimatorStateMachine: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: Base Layer |
|||
m_ChildStates: |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 6239727856879991033} |
|||
m_Position: {x: 30, y: 280, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 383259955519726504} |
|||
m_Position: {x: 310, y: 280, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -7950515957825162590} |
|||
m_Position: {x: 30, y: 200, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 8248595459056457366} |
|||
m_Position: {x: 30, y: 360, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 7437642775475494425} |
|||
m_Position: {x: -210, y: 320, z: 0} |
|||
m_ChildStateMachines: [] |
|||
m_AnyStateTransitions: [] |
|||
m_EntryTransitions: [] |
|||
m_StateMachineTransitions: {} |
|||
m_StateMachineBehaviours: [] |
|||
m_AnyStatePosition: {x: 50, y: 20, z: 0} |
|||
m_EntryPosition: {x: 50, y: 120, z: 0} |
|||
m_ExitPosition: {x: 800, y: 120, z: 0} |
|||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} |
|||
m_DefaultState: {fileID: -7950515957825162590} |
|||
--- !u!91 &9100000 |
|||
AnimatorController: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: BookAnim |
|||
serializedVersion: 5 |
|||
m_AnimatorParameters: |
|||
- m_Name: next |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 0} |
|||
m_AnimatorLayers: |
|||
- serializedVersion: 5 |
|||
m_Name: Base Layer |
|||
m_StateMachine: {fileID: -2019547273944851464} |
|||
m_Mask: {fileID: 0} |
|||
m_Motions: [] |
|||
m_Behaviours: [] |
|||
m_BlendingMode: 0 |
|||
m_SyncedLayerIndex: -1 |
|||
m_DefaultWeight: 0 |
|||
m_IKPass: 0 |
|||
m_SyncedLayerAffectsTiming: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
--- !u!1102 &383259955519726504 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: next |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 376750786793711421, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &3509212805040107398 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: next |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: 383259955519726504} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &6239727856879991033 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: openStop |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: 3509212805040107398} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 7515460337550946210, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1102 &7437642775475494425 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: back |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: -1223372888097988523, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1102 &8248595459056457366 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: close |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 6283062061880575365, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 80245aeb1e478d24cb0f50e97c3a0bc5 |
|||
NativeFormatImporter: |
|||
externalObjects: {} |
|||
mainObjectFileID: 9100000 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,53 @@ |
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!74 &7400000 |
|||
AnimationClip: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: New Animation |
|||
serializedVersion: 7 |
|||
m_Legacy: 0 |
|||
m_Compressed: 0 |
|||
m_UseHighQualityCurve: 1 |
|||
m_RotationCurves: [] |
|||
m_CompressedRotationCurves: [] |
|||
m_EulerCurves: [] |
|||
m_PositionCurves: [] |
|||
m_ScaleCurves: [] |
|||
m_FloatCurves: [] |
|||
m_PPtrCurves: [] |
|||
m_SampleRate: 60 |
|||
m_WrapMode: 0 |
|||
m_Bounds: |
|||
m_Center: {x: 0, y: 0, z: 0} |
|||
m_Extent: {x: 0, y: 0, z: 0} |
|||
m_ClipBindingConstant: |
|||
genericBindings: [] |
|||
pptrCurveMapping: [] |
|||
m_AnimationClipSettings: |
|||
serializedVersion: 2 |
|||
m_AdditiveReferencePoseClip: {fileID: 0} |
|||
m_AdditiveReferencePoseTime: 0 |
|||
m_StartTime: 0 |
|||
m_StopTime: 1 |
|||
m_OrientationOffsetY: 0 |
|||
m_Level: 0 |
|||
m_CycleOffset: 0 |
|||
m_HasAdditiveReferencePose: 0 |
|||
m_LoopTime: 0 |
|||
m_LoopBlend: 0 |
|||
m_LoopBlendOrientation: 0 |
|||
m_LoopBlendPositionY: 0 |
|||
m_LoopBlendPositionXZ: 0 |
|||
m_KeepOriginalOrientation: 0 |
|||
m_KeepOriginalPositionY: 1 |
|||
m_KeepOriginalPositionXZ: 0 |
|||
m_HeightFromFeet: 0 |
|||
m_Mirror: 0 |
|||
m_EditorCurves: [] |
|||
m_EulerEditorCurves: [] |
|||
m_HasGenericRootTransform: 0 |
|||
m_HasMotionFloatCurves: 0 |
|||
m_Events: [] |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 9e41e9e2a97379e4c9e83f183e02e800 |
|||
NativeFormatImporter: |
|||
externalObjects: {} |
|||
mainObjectFileID: 7400000 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: ff7f5a8490406ef4e9da24c3737c43b4 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,513 @@ |
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!1102 &-8258256563073254863 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: openStop |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -7792811542948930001} |
|||
- {fileID: 3627530597684413355} |
|||
- {fileID: -2560027898811023536} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 7515460337550946210, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &-7792811542948930001 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: next |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: 8015446570950281760} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1107 &-6778641050302873508 |
|||
AnimatorStateMachine: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: Base Layer |
|||
m_ChildStates: |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 8015446570950281760} |
|||
m_Position: {x: -130, y: 500, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 1909220101572688523} |
|||
m_Position: {x: -200, y: 230, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -51858381997564467} |
|||
m_Position: {x: 230, y: 510, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -2101302564905477905} |
|||
m_Position: {x: 330, y: 380, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 4229820379494049694} |
|||
m_Position: {x: 200, y: 190, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -8258256563073254863} |
|||
m_Position: {x: 20, y: 310, z: 0} |
|||
m_ChildStateMachines: [] |
|||
m_AnyStateTransitions: [] |
|||
m_EntryTransitions: [] |
|||
m_StateMachineTransitions: {} |
|||
m_StateMachineBehaviours: [] |
|||
m_AnyStatePosition: {x: 50, y: 20, z: 0} |
|||
m_EntryPosition: {x: 50, y: 120, z: 0} |
|||
m_ExitPosition: {x: 800, y: 120, z: 0} |
|||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} |
|||
m_DefaultState: {fileID: -8258256563073254863} |
|||
--- !u!1101 &-2560027898811023536 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: close |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -2101302564905477905} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &-2101302564905477905 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: close |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 6283062061880575365, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1102 &-1663489848954531827 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: New State |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -719615132450865132} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 0} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &-1143988195813381563 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: [] |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -8258256563073254863} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0.25 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 0.94174755 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 1 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1101 &-719615132450865132 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: move |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: 6778565456416125388} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 0 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1101 &-677711796674791455 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: [] |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -8258256563073254863} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1101 &-370417210073110067 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: [] |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -8258256563073254863} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &-51858381997564467 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: back |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -677711796674791455} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: -1223372888097988523, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!91 &9100000 |
|||
AnimatorController: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: BookAnim |
|||
serializedVersion: 5 |
|||
m_AnimatorParameters: |
|||
- m_Name: back |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: next |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 1 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: open |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: close |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- m_Name: move |
|||
m_Type: 9 |
|||
m_DefaultFloat: 0 |
|||
m_DefaultInt: 0 |
|||
m_DefaultBool: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
m_AnimatorLayers: |
|||
- serializedVersion: 5 |
|||
m_Name: Base Layer |
|||
m_StateMachine: {fileID: -6778641050302873508} |
|||
m_Mask: {fileID: 0} |
|||
m_Motions: [] |
|||
m_Behaviours: [] |
|||
m_BlendingMode: 0 |
|||
m_SyncedLayerIndex: -1 |
|||
m_DefaultWeight: 0 |
|||
m_IKPass: 0 |
|||
m_SyncedLayerAffectsTiming: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
- serializedVersion: 5 |
|||
m_Name: New Layer |
|||
m_StateMachine: {fileID: 1212512486479305084} |
|||
m_Mask: {fileID: 0} |
|||
m_Motions: [] |
|||
m_Behaviours: [] |
|||
m_BlendingMode: 0 |
|||
m_SyncedLayerIndex: -1 |
|||
m_DefaultWeight: 1 |
|||
m_IKPass: 0 |
|||
m_SyncedLayerAffectsTiming: 0 |
|||
m_Controller: {fileID: 9100000} |
|||
--- !u!1107 &1212512486479305084 |
|||
AnimatorStateMachine: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: New Layer |
|||
m_ChildStates: |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: -1663489848954531827} |
|||
m_Position: {x: 30, y: 240, z: 0} |
|||
- serializedVersion: 1 |
|||
m_State: {fileID: 6778565456416125388} |
|||
m_Position: {x: 30, y: 390, z: 0} |
|||
m_ChildStateMachines: [] |
|||
m_AnyStateTransitions: [] |
|||
m_EntryTransitions: [] |
|||
m_StateMachineTransitions: {} |
|||
m_StateMachineBehaviours: [] |
|||
m_AnyStatePosition: {x: 50, y: 20, z: 0} |
|||
m_EntryPosition: {x: 50, y: 120, z: 0} |
|||
m_ExitPosition: {x: 800, y: 120, z: 0} |
|||
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} |
|||
m_DefaultState: {fileID: -1663489848954531827} |
|||
--- !u!1102 &1909220101572688523 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: open |
|||
m_Speed: 3 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -1143988195813381563} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 5315072357139859488, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, |
|||
type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1101 &3627530597684413355 |
|||
AnimatorStateTransition: |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: |
|||
m_Conditions: |
|||
- m_ConditionMode: 1 |
|||
m_ConditionEvent: back |
|||
m_EventTreshold: 0 |
|||
m_DstStateMachine: {fileID: 0} |
|||
m_DstState: {fileID: -51858381997564467} |
|||
m_Solo: 0 |
|||
m_Mute: 0 |
|||
m_IsExit: 0 |
|||
serializedVersion: 3 |
|||
m_TransitionDuration: 0 |
|||
m_TransitionOffset: 0 |
|||
m_ExitTime: 1 |
|||
m_HasExitTime: 1 |
|||
m_HasFixedDuration: 0 |
|||
m_InterruptionSource: 0 |
|||
m_OrderedInterruption: 1 |
|||
m_CanTransitionToSelf: 1 |
|||
--- !u!1102 &4229820379494049694 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: New State |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 0} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1102 &6778565456416125388 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: UpMOVE |
|||
m_Speed: 2 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: [] |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 7400000, guid: 3ec038c88f54ebf498a96e2aaa37aa48, type: 2} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
--- !u!1102 &8015446570950281760 |
|||
AnimatorState: |
|||
serializedVersion: 6 |
|||
m_ObjectHideFlags: 1 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: next |
|||
m_Speed: 1 |
|||
m_CycleOffset: 0 |
|||
m_Transitions: |
|||
- {fileID: -370417210073110067} |
|||
m_StateMachineBehaviours: [] |
|||
m_Position: {x: 50, y: 50, z: 0} |
|||
m_IKOnFeet: 0 |
|||
m_WriteDefaultValues: 1 |
|||
m_Mirror: 0 |
|||
m_SpeedParameterActive: 0 |
|||
m_MirrorParameterActive: 0 |
|||
m_CycleOffsetParameterActive: 0 |
|||
m_TimeParameterActive: 0 |
|||
m_Motion: {fileID: 376750786793711421, guid: 669ffc3f53ffa7b4f94eea6ef984cf54, type: 3} |
|||
m_Tag: |
|||
m_SpeedParameter: |
|||
m_MirrorParameter: |
|||
m_CycleOffsetParameter: |
|||
m_TimeParameter: |
|||
@ -0,0 +1,177 @@ |
|||
%YAML 1.1 |
|||
%TAG !u! tag:unity3d.com,2011: |
|||
--- !u!74 &7400000 |
|||
AnimationClip: |
|||
m_ObjectHideFlags: 0 |
|||
m_CorrespondingSourceObject: {fileID: 0} |
|||
m_PrefabInstance: {fileID: 0} |
|||
m_PrefabAsset: {fileID: 0} |
|||
m_Name: UpMOVE |
|||
serializedVersion: 7 |
|||
m_Legacy: 0 |
|||
m_Compressed: 0 |
|||
m_UseHighQualityCurve: 1 |
|||
m_RotationCurves: [] |
|||
m_CompressedRotationCurves: [] |
|||
m_EulerCurves: [] |
|||
m_PositionCurves: |
|||
- curve: |
|||
serializedVersion: 2 |
|||
m_Curve: |
|||
- serializedVersion: 3 |
|||
time: 0 |
|||
value: {x: 0.98, y: 1.11, z: -0.64} |
|||
inSlope: {x: 0, y: 0, z: 0} |
|||
outSlope: {x: 0, y: 0, z: 0} |
|||
tangentMode: 0 |
|||
weightedMode: 0 |
|||
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} |
|||
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} |
|||
- serializedVersion: 3 |
|||
time: 1 |
|||
value: {x: 0.98, y: 1.32, z: -0.64} |
|||
inSlope: {x: 0, y: 0, z: 0} |
|||
outSlope: {x: 0, y: 0, z: 0} |
|||
tangentMode: 0 |
|||
weightedMode: 0 |
|||
inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} |
|||
outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} |
|||
m_PreInfinity: 2 |
|||
m_PostInfinity: 2 |
|||
m_RotationOrder: 4 |
|||
path: |
|||
m_ScaleCurves: [] |
|||
m_FloatCurves: [] |
|||
m_PPtrCurves: [] |
|||
m_SampleRate: 60 |
|||
m_WrapMode: 0 |
|||
m_Bounds: |
|||
m_Center: {x: 0, y: 0, z: 0} |
|||
m_Extent: {x: 0, y: 0, z: 0} |
|||
m_ClipBindingConstant: |
|||
genericBindings: |
|||
- serializedVersion: 2 |
|||
path: 0 |
|||
attribute: 1 |
|||
script: {fileID: 0} |
|||
typeID: 4 |
|||
customType: 0 |
|||
isPPtrCurve: 0 |
|||
isIntCurve: 0 |
|||
isSerializeReferenceCurve: 0 |
|||
pptrCurveMapping: [] |
|||
m_AnimationClipSettings: |
|||
serializedVersion: 2 |
|||
m_AdditiveReferencePoseClip: {fileID: 0} |
|||
m_AdditiveReferencePoseTime: 0 |
|||
m_StartTime: 0 |
|||
m_StopTime: 1 |
|||
m_OrientationOffsetY: 0 |
|||
m_Level: 0 |
|||
m_CycleOffset: 0 |
|||
m_HasAdditiveReferencePose: 0 |
|||
m_LoopTime: 0 |
|||
m_LoopBlend: 0 |
|||
m_LoopBlendOrientation: 0 |
|||
m_LoopBlendPositionY: 0 |
|||
m_LoopBlendPositionXZ: 0 |
|||
m_KeepOriginalOrientation: 0 |
|||
m_KeepOriginalPositionY: 1 |
|||
m_KeepOriginalPositionXZ: 0 |
|||
m_HeightFromFeet: 0 |
|||
m_Mirror: 0 |
|||
m_EditorCurves: |
|||
- serializedVersion: 2 |
|||
curve: |
|||
serializedVersion: 2 |
|||
m_Curve: |
|||
- serializedVersion: 3 |
|||
time: 0 |
|||
value: 0.98 |
|||
inSlope: 0 |
|||
outSlope: 0 |
|||
tangentMode: 136 |
|||
weightedMode: 0 |
|||
inWeight: 0.33333334 |
|||
outWeight: 0.33333334 |
|||
- serializedVersion: 3 |
|||
time: 1 |
|||
value: 0.98 |
|||
inSlope: 0 |
|||
outSlope: 0 |
|||
tangentMode: 136 |
|||
weightedMode: 0 |
|||
inWeight: 0.33333334 |
|||
outWeight: 0.33333334 |
|||
m_PreInfinity: 2 |
|||
m_PostInfinity: 2 |
|||
m_RotationOrder: 4 |
|||
attribute: m_LocalPosition.x |
|||
path: |
|||
classID: 4 |
|||
script: {fileID: 0} |
|||
flags: 0 |
|||
- serializedVersion: 2 |
|||
curve: |
|||
serializedVersion: 2 |
|||
m_Curve: |
|||
- serializedVersion: 3 |
|||
time: 0 |
|||
value: 1.11 |
|||
inSlope: 0 |
|||
outSlope: 0 |
|||
tangentMode: 136 |
|||
weightedMode: 0 |
|||
inWeight: 0.33333334 |
|||
outWeight: 0.33333334 |
|||
- serializedVersion: 3 |
|||
time: 1 |
|||
value: 1.32 |
|||
inSlope: 0 |
|||
outSlope: 0 |
|||
tangentMode: 136 |
|||
weightedMode: 0 |
|||
inWeight: 0.33333334 |
|||
outWeight: 0.33333334 |
|||
m_PreInfinity: 2 |
|||
m_PostInfinity: 2 |
|||
m_RotationOrder: 4 |
|||
attribute: m_LocalPosition.y |
|||
path: |
|||
classID: 4 |
|||
script: {fileID: 0} |
|||
flags: 0 |
|||
- serializedVersion: 2 |
|||
curve: |
|||
serializedVersion: 2 |
|||
m_Curve: |
|||
- serializedVersion: 3 |
|||
time: 0 |
|||
value: -0.64 |
|||
inSlope: 0 |
|||
outSlope: 0 |
|||
tangentMode: 136 |
|||
weightedMode: 0 |
|||
inWeight: 0.33333334 |
|||
outWeight: 0.33333334 |
|||
- serializedVersion: 3 |
|||
time: 1 |
|||
value: -0.64 |
|||
inSlope: 0 |
|||
outSlope: 0 |
|||
tangentMode: 136 |
|||
weightedMode: 0 |
|||
inWeight: 0.33333334 |
|||
outWeight: 0.33333334 |
|||
m_PreInfinity: 2 |
|||
m_PostInfinity: 2 |
|||
m_RotationOrder: 4 |
|||
attribute: m_LocalPosition.z |
|||
path: |
|||
classID: 4 |
|||
script: {fileID: 0} |
|||
flags: 0 |
|||
m_EulerEditorCurves: [] |
|||
m_HasGenericRootTransform: 1 |
|||
m_HasMotionFloatCurves: 0 |
|||
m_Events: [] |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3ec038c88f54ebf498a96e2aaa37aa48 |
|||
NativeFormatImporter: |
|||
externalObjects: {} |
|||
mainObjectFileID: 7400000 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6f00bb0fb4d211446b86a0e8d9f3aa99 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3a1139eb77b67514e9a2033189d654aa |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,31 @@ |
|||
--- |
|||
name: Bug report |
|||
about: Create a report to help improve |
|||
title: '' |
|||
labels: '' |
|||
assignees: '' |
|||
|
|||
--- |
|||
|
|||
**Describe the bug** |
|||
A clear and concise description of what the bug is. |
|||
|
|||
**To Reproduce** |
|||
Steps to reproduce the behavior: |
|||
1. Go to '...' |
|||
2. Click on '....' |
|||
3. Scroll down to '....' |
|||
4. See error |
|||
|
|||
**Expected behavior** |
|||
A clear and concise description of what you expected to happen. |
|||
|
|||
**Screenshots** |
|||
If applicable, add screenshots to help explain your problem. |
|||
|
|||
- OS: [e.g. Windows 10] |
|||
- Unity: [e.g 2019.2.6] |
|||
- Deform version: [e.g 1.0.3] |
|||
|
|||
**Additional context** |
|||
Add any other context about the problem here. |
|||
@ -0,0 +1,76 @@ |
|||
 |
|||
|
|||
[](https://unity3d.com/get-unity/download) |
|||
[](https://github.com/keenanwoodall/Deform/blob/master/LICENSE.txt) |
|||
[](https://github.com/keenanwoodall/Deform/compare) |
|||
[](https://openupm.com/packages/com.beans.deform/) |
|||
|
|||
[](https://twitter.com/intent/follow?screen_name=keenanwoodall) |
|||
[](https://discord.gg/NnX5cpr) |
|||
|
|||
A fully-featured deformer system for [Unity](https://unity3d.com/). Deform is multi-threaded with the Job System, compiled with Burst and calculations are done using the Mathematics library. |
|||
|
|||
*Also available on the [Asset Store.](https://assetstore.unity.com/packages/tools/modeling/deform-148425)* |
|||
|
|||
## Features |
|||
⚡ Lightning fast!</br> |
|||
🧶 Fully multi-threaded!</br> |
|||
⭐ 40+ deformers!</br> |
|||
💾 Meshes can be saved!</br> |
|||
🔧 Easily extendable!</br> |
|||
🌐 Works in worldspace!</br> |
|||
🎨 Custom editors and handles!</br> |
|||
|
|||
## [Documentation](https://github.com/keenanwoodall/Deform/wiki) |
|||
* [Installation](https://github.com/keenanwoodall/Deform/wiki/Installation) (Important) |
|||
* [Getting Started](https://github.com/keenanwoodall/Deform/wiki/Getting-Started) |
|||
* [Creating a Custom Deformer](https://github.com/keenanwoodall/Deform/wiki/Creating-A-Custom-Deformer) |
|||
* [Optimization Tips](https://github.com/keenanwoodall/Deform/wiki/Optimization-Tips) |
|||
|
|||
## FAQ |
|||
> Does Deform work with the new prefab system? |
|||
|
|||
Yes. Deform works seamlessly with nested prefabs and prefab variants. |
|||
|
|||
> Are skinned mesh renderers supported? |
|||
|
|||
Yes. However because of how Unity handles skinned mesh renderers; the mesh cannot be modified after its bones are animated. This means that animations to the skinned mesh renderer are applied *after* Deform modifies the mesh; which is often not the desired effect. Read more [here](https://github.com/keenanwoodall/Deform/wiki/WTF-Is-Up-Skinned-Mesh-Renderers). |
|||
|
|||
> I'm getting an error about read/write permissions. How do I fix it? |
|||
|
|||
This means you have a Deformable component on a mesh that doesn't have read/write permissions enabled. The offending Deformable component should have a "Fix It" button in the inspector that will change the import settings, but on older versions of Deform you'll have to select the offending mesh in your Project window and enable Read/Write permissions in its import settings manually. |
|||
|
|||
> Do deformers have to be on the object they are deforming? |
|||
|
|||
No. Because deformables require deformers be added manually, they can be anywhere in the scene and on any game object. |
|||
|
|||
> Can deformables share deformers? |
|||
|
|||
Yes. You can create a single deformer and add it to multiple deformables. |
|||
|
|||
> How do deformables handle instancing? |
|||
|
|||
Each deformable has it's own unique mesh. |
|||
|
|||
## Limitations |
|||
Deform runs on the CPU. While it *is* incredibly fast, you should not expect to get performance comparable to vertex shaders. Because meshes are modified on the CPU each mesh has to be unique. This means that, unless dynamically batched (which comes with its own performance costs), each mesh will require a new draw call. Deform is not meant to be used at a massive scale. If you need to deform an entire world, tons of meshes, or an incredibly high poly model use vertex shaders. |
|||
|
|||
**tldr:** Use shaders if you need speed, use Deform if you need modularity and ease-of-use. |
|||
|
|||
## Acknowledgments |
|||
* Thanks to [Thomas Ingram](https://twitter.com/vertexxyz) for going the extra-mile to help with editor scripting. |
|||
* Thanks to [Alexander Ameye](https://twitter.com/alexanderameye), [William Besnard](https://twitter.com/BillSansky), [Raphael Herdlicka](https://www.herdlicka.net/) and [David Carney](https://twitter.com/thedavidcarney) for beta testing and giving crucial feedback. |
|||
|
|||
Additional massive thanks to the following contributors for helping develop Deform into the best tool it can be:</br>[sabresaurus](https://github.com/sabresaurus), [Brullworfel](https://github.com/Brullworfel), [favoyang](https://github.com/favoyang), and [HitCache](https://github.com/HitCache) |
|||
|
|||
I love seeing creative and cool uses of this tool. If you make something you're proud of I'd be honored if you showed it to me! |
|||
|
|||
You can find me on the interwebs at these addresses:<br> |
|||
[email](mailto:keenanwoodall@gmail.com) | [twitter](https://twitter.com/keenanwoodall) | [website](http://keenanwoodall.com) |
|||
<br>Feel free to reach out about anything! |
|||
|
|||
#### If you like Deform, please consider donating! |
|||
|
|||
[](https://paypal.me/KeenanWoodall) |
|||
[](https://ko-fi.com/keenanwoodall) |
|||
[](https://keenanwoodall.itch.io/deform) |
|||
|
After Width: | Height: | Size: 643 KiB |
@ -0,0 +1,37 @@ |
|||
[Ll]ibrary/ |
|||
[Tt]emp/ |
|||
[Oo]bj/ |
|||
[Bb]uild/ |
|||
[Bb]uilds/ |
|||
Assets/AssetStoreTools* |
|||
|
|||
# Visual Studio cache directory |
|||
.vs/ |
|||
|
|||
# Autogenerated VS/MD/Consulo solution and project files |
|||
ExportedObj/ |
|||
.consulo/ |
|||
*.csproj |
|||
*.unityproj |
|||
*.sln |
|||
*.suo |
|||
*.tmp |
|||
*.user |
|||
*.userprefs |
|||
*.pidb |
|||
*.booproj |
|||
*.svd |
|||
*.pdb |
|||
*.opendb |
|||
|
|||
# Unity3D generated meta files |
|||
*.pidb.meta |
|||
*.pdb.meta |
|||
|
|||
# Unity3D Generated File On Crash Reports |
|||
sysinfo.txt |
|||
|
|||
# Builds |
|||
*.apk |
|||
*.unitypackage |
|||
*.DS_Store |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6ab568e08c3af734bb361b708ac2694b |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f629ac0587808274991790275ea8b414 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: b8e23bf4e78f9144787b0eef163a879b |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,41 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (DeformableManager)), CanEditMultipleObjects] |
|||
public class DeformableManagerEditor : Editor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Update = new GUIContent (text: "Update", tooltip: "Should the manager update?"); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Update; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Update = obj.FindProperty ("update"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
private void OnEnable () |
|||
{ |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Update, Content.Update); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 22fc03601b935444ca03c5307c6f62b7 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,443 @@ |
|||
#if UNITY_2019_2_OR_NEWER
|
|||
#define CAN_POPULATE_GAME_OBJECT_MENU
|
|||
#define CAN_USE_TYPE_CACHE
|
|||
#endif
|
|||
|
|||
using System.Linq; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using UnityEditor.IMGUI.Controls; |
|||
#if CAN_POPULATE_GAME_OBJECT_MENU
|
|||
using UnityEditor.SceneManagement; |
|||
#endif
|
|||
using Deform; |
|||
using Beans.Unity.Editor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public class CreatorWindow : EditorWindow |
|||
{ |
|||
private static List<DeformerAttribute> DeformerAttributes; |
|||
private List<DeformerAttribute> filteredDeformerAttributes; |
|||
|
|||
private static class Styles |
|||
{ |
|||
public const int MARGIN_X = 2; |
|||
public const int MARGIN_Y = 2; |
|||
|
|||
public static readonly GUIStyle Button; |
|||
|
|||
static Styles () |
|||
{ |
|||
Button = new GUIStyle (EditorStyles.miniButton); |
|||
Button.margin = new RectOffset (MARGIN_X, MARGIN_X, MARGIN_Y, MARGIN_Y); |
|||
} |
|||
} |
|||
|
|||
private static class Content |
|||
{ |
|||
public static GUIContent CreateDeformable = new GUIContent (text: "Deformable", tooltip: "Create a deformable"); |
|||
public static GUIContent CreateElasticDeformable = new GUIContent (text: "Elastic Deformable (WIP)", tooltip: "Create an elastic deformable"); |
|||
} |
|||
|
|||
[SerializeField] |
|||
private Vector2 scrollPosition; |
|||
[SerializeField] |
|||
private SearchField searchField; |
|||
[SerializeField] |
|||
private string searchQuery; |
|||
[SerializeField] |
|||
private Dictionary<Category, bool> categoryFoldouts = new Dictionary<Category, bool> |
|||
{ |
|||
{ Category.Normal, true }, |
|||
{ Category.Noise, true }, |
|||
{ Category.Mask, true }, |
|||
{ Category.Utility, true }, |
|||
{ Category.WIP, true } |
|||
}; |
|||
|
|||
[MenuItem ("Window/Deform/Creator", priority = 10000)] |
|||
[MenuItem ("Tools/Deform/Creator Window", priority = 10000)] |
|||
public static void ShowWindow () |
|||
{ |
|||
GetWindow<CreatorWindow> ("Creator", true); |
|||
} |
|||
|
|||
[UnityEditor.Callbacks.DidReloadScripts] |
|||
private static void UpdateDeformerAttributes () |
|||
{ |
|||
DeformerAttributes = GetAllDeformerAttributes ().OrderBy (x => x.Name).OrderBy (x => (int)x.Category).ToList (); |
|||
#if CAN_POPULATE_GAME_OBJECT_MENU
|
|||
SceneHierarchyHooks.addItemsToGameObjectContextMenu += PopulateGameObjectMenu; |
|||
#endif
|
|||
} |
|||
#if CAN_POPULATE_GAME_OBJECT_MENU
|
|||
private static void PopulateGameObjectMenu(GenericMenu menu, GameObject selection) |
|||
{ |
|||
menu.AddItem(new GUIContent($"Deform/{nameof(Deformable).Nicify()}"), false, AddOrCreateDeformable<Deformable>); |
|||
menu.AddItem(new GUIContent($"Deform/{nameof(ElasticDeformable).Nicify()}"), false, AddOrCreateDeformable<ElasticDeformable>); |
|||
for (int i = 0; i < DeformerAttributes.Count; i++) |
|||
{ |
|||
var current = DeformerAttributes[i]; |
|||
var path = string.Empty; |
|||
if (current.Category == Category.Normal) |
|||
path = $"Deform/Deformers/{current.Name}"; |
|||
else |
|||
path = $"Deform/Deformers/{current.Category}/{current.Name}"; |
|||
menu.AddItem(new GUIContent(path, current.Description), false, () => CreateDeformerFromAttribute (current, true)); |
|||
} |
|||
} |
|||
#endif
|
|||
|
|||
private void OnEnable () |
|||
{ |
|||
searchField = new SearchField (); |
|||
|
|||
UpdateDeformerAttributes (); |
|||
|
|||
Undo.undoRedoPerformed += Repaint; |
|||
} |
|||
|
|||
private void OnDisable () |
|||
{ |
|||
Undo.undoRedoPerformed -= Repaint; |
|||
} |
|||
|
|||
private void OnGUI () |
|||
{ |
|||
EditorGUILayout.Space (); |
|||
|
|||
if (GUILayout.Button(Content.CreateDeformable, Styles.Button)) |
|||
AddOrCreateDeformable<Deformable>(); |
|||
if (GUILayout.Button(Content.CreateElasticDeformable, Styles.Button)) |
|||
AddOrCreateDeformable<ElasticDeformable>(); |
|||
|
|||
using (new EditorGUILayout.HorizontalScope ()) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var rect = GUILayoutUtility.GetRect (1, 1, 18, 18, GUILayout.ExpandWidth (true)); |
|||
rect.width -= Styles.MARGIN_X * 2; |
|||
rect.x += Styles.MARGIN_X; |
|||
rect.y += Styles.MARGIN_Y * 2; |
|||
|
|||
var newSearchQuery = searchField.OnToolbarGUI (rect, searchQuery); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (this, "Changed Search Query"); |
|||
searchQuery = newSearchQuery; |
|||
} |
|||
} |
|||
} |
|||
|
|||
EditorGUILayout.Space (); |
|||
|
|||
using (var scroll = new EditorGUILayout.ScrollViewScope (scrollPosition)) |
|||
{ |
|||
if (DeformerAttributes == null || DeformerAttributes.Count == 0) |
|||
EditorGUILayout.LabelField ("No deformers found.", GUILayout.MinWidth (0)); |
|||
else |
|||
{ |
|||
filteredDeformerAttributes = |
|||
( |
|||
from d in DeformerAttributes |
|||
where string.IsNullOrEmpty (searchQuery) || d.Name.ToLower ().Contains (searchQuery.ToLower ()) |
|||
select d |
|||
).ToList (); |
|||
|
|||
var drawnCount = 0; |
|||
for (int i = 0; i < filteredDeformerAttributes.Count; i++) |
|||
{ |
|||
var current = filteredDeformerAttributes[i]; |
|||
|
|||
if (drawnCount == 0) |
|||
{ |
|||
var countInCategory = filteredDeformerAttributes.Count (t => t.Category == current.Category); |
|||
categoryFoldouts[current.Category] = EditorGUILayoutx.FoldoutHeader ($"{current.Category.ToString ()} ({countInCategory})", categoryFoldouts[current.Category], EditorStyles.label); |
|||
} |
|||
|
|||
if (categoryFoldouts[current.Category]) |
|||
if (GUILayout.Button (new GUIContent (current.Name, current.Description), Styles.Button)) |
|||
CreateDeformerFromAttribute (current, Event.current.modifiers != EventModifiers.Alt); |
|||
|
|||
drawnCount++; |
|||
|
|||
if (i + 1 < filteredDeformerAttributes.Count) |
|||
{ |
|||
var next = filteredDeformerAttributes[i + 1]; |
|||
if (next.Category != current.Category) |
|||
{ |
|||
var countInCategory = filteredDeformerAttributes.Count (t => t.Category == next.Category); |
|||
categoryFoldouts[next.Category] = EditorGUILayoutx.FoldoutHeader ($"{next.Category.ToString ()} ({countInCategory})", categoryFoldouts[next.Category], EditorStyles.label); |
|||
} |
|||
} |
|||
} |
|||
|
|||
EditorGUILayout.Space (); |
|||
} |
|||
scrollPosition = scroll.scrollPosition; |
|||
} |
|||
} |
|||
|
|||
private static List<Deformable> justAddedDeformablesPool = new List<Deformable>(); |
|||
public static void AddOrCreateDeformable<T> () where T : Deformable |
|||
{ |
|||
var targets = Selection.gameObjects; |
|||
|
|||
justAddedDeformablesPool.Clear(); |
|||
|
|||
// If we don't have any objects selected, create a new Deformable.
|
|||
if (targets == null || targets.Length == 0) |
|||
CreateDeformable<T> (); |
|||
else |
|||
{ |
|||
foreach (var target in Selection.gameObjects) |
|||
{ |
|||
// We can't add components to a gameobject that's part of a prefab asset
|
|||
if (!PrefabUtility.IsPartOfPrefabAsset (target)) |
|||
{ |
|||
T deformable = null; |
|||
|
|||
// Check if there's an LOD Group
|
|||
var lodGroup = target.GetComponent<LODGroup>(); |
|||
|
|||
// If an LOD Group is selected, lets add Deformables to its children
|
|||
if (lodGroup != null) |
|||
{ |
|||
if (EditorUtility.DisplayDialog |
|||
( |
|||
title: "Deformable LOD Group", |
|||
message: $"You just tried to add a {typeof(T).Name} to an {nameof(LODGroup)}. Would you like to make its childen Deformable?", |
|||
ok: "Yes", |
|||
cancel:"No" |
|||
)) |
|||
{ |
|||
foreach (Transform child in lodGroup.transform) |
|||
{ |
|||
// Check if there's already a Deformable
|
|||
deformable = child.GetComponent<T>(); |
|||
// If there isn't, we can add one
|
|||
if (deformable == null && MeshTarget.IsValid(child)) |
|||
{ |
|||
justAddedDeformablesPool.Add(Undo.AddComponent<T>(child.gameObject)); |
|||
} |
|||
} |
|||
|
|||
if (EditorUtility.DisplayDialog |
|||
( |
|||
title: "Deformable LOD Group", |
|||
message: $"A {nameof(GroupDeformer)} can help you keep deformers in sync across multiple LODs. Would you like one added automatically?", |
|||
ok: "Yes", |
|||
cancel:"No" |
|||
)) |
|||
{ |
|||
GroupDeformer group = Undo.AddComponent<GroupDeformer>(target.gameObject); |
|||
|
|||
foreach (var d in justAddedDeformablesPool) |
|||
{ |
|||
Undo.RecordObject(d, "Added deformer"); |
|||
d.AddDeformer(group); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
// Since there wasn't an LOD group, check if there's already a Deformable
|
|||
deformable = target.GetComponent<T>(); |
|||
// If there isn't, we can add one
|
|||
if (deformable == null && MeshTarget.IsValid(target)) |
|||
{ |
|||
justAddedDeformablesPool.Add(Undo.AddComponent<T>(target)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// If we never ended up adding a Deformable component, we should create new one.
|
|||
if (justAddedDeformablesPool.Count == 0) |
|||
CreateDeformable<T> (); |
|||
} |
|||
} |
|||
|
|||
private static T CreateDeformable<T> () where T : Deformable |
|||
{ |
|||
var newObject = GameObject.CreatePrimitive (PrimitiveType.Sphere); |
|||
newObject.name = $"{typeof(T).Name} Object"; |
|||
|
|||
newObject.transform.position = SceneView.lastActiveSceneView.pivot; |
|||
|
|||
var deformable = newObject.AddComponent<T> (); |
|||
deformable.ChangeMesh (DeformEditorResources.LoadAssetOfType<Mesh> ("DeformDefaultMesh")); |
|||
|
|||
newObject.GetComponent<Renderer> ().material = DeformEditorResources.LoadAssetOfType<Material> ("DeformDefaultMaterial"); |
|||
|
|||
DestroyImmediate (newObject.GetComponent<Collider> ()); |
|||
|
|||
Selection.activeGameObject = newObject; |
|||
|
|||
Undo.RegisterCreatedObjectUndo |
|||
( |
|||
newObject, |
|||
$"Created {typeof(T).Name} GameObject" |
|||
); |
|||
|
|||
return deformable; |
|||
} |
|||
|
|||
public static void CreateDeformerFromAttribute (DeformerAttribute attribute, bool autoAdd) |
|||
{ |
|||
var selectedGameObjects = Selection.gameObjects; |
|||
if (selectedGameObjects == null || selectedGameObjects.Length == 0) |
|||
{ |
|||
var newGameObject = new GameObject (attribute.Name); |
|||
|
|||
Undo.RegisterCreatedObjectUndo (newGameObject, "Created Deformer"); |
|||
|
|||
newGameObject.AddComponent (attribute.Type); |
|||
|
|||
newGameObject.transform.localRotation = Quaternion.Euler (attribute.XRotation, attribute.YRotation, attribute.ZRotation); |
|||
|
|||
Selection.activeGameObject = newGameObject; |
|||
} |
|||
else |
|||
{ |
|||
Undo.SetCurrentGroupName ("Created Deformer"); |
|||
|
|||
var newGameObject = new GameObject (attribute.Name); |
|||
Undo.RegisterCreatedObjectUndo (newGameObject, "Created Deformer"); |
|||
|
|||
EditorGUIUtility.PingObject (newGameObject); |
|||
|
|||
if (autoAdd) |
|||
{ |
|||
if (selectedGameObjects.Length == 1) |
|||
{ |
|||
if (!PrefabUtility.IsPartOfPrefabAsset (Selection.gameObjects[0])) |
|||
{ |
|||
var parent = selectedGameObjects[0].transform; |
|||
newGameObject.transform.SetParent (parent, true); |
|||
newGameObject.transform.position = parent.position; |
|||
newGameObject.transform.rotation = parent.rotation * Quaternion.Euler (attribute.XRotation, attribute.YRotation, attribute.ZRotation); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
var center = GetAverageGameObjectPosition (selectedGameObjects); |
|||
var rotation = Quaternion.Euler (attribute.XRotation, attribute.YRotation, attribute.ZRotation); |
|||
newGameObject.transform.SetPositionAndRotation (center, rotation); |
|||
} |
|||
|
|||
var newDeformer = newGameObject.AddComponent (attribute.Type) as Deformer; |
|||
|
|||
var deformables = GetComponents<Deformable> (selectedGameObjects); |
|||
var groups = GetComponents<GroupDeformer> (selectedGameObjects); |
|||
var repeaters = GetComponents<RepeaterDeformer> (selectedGameObjects); |
|||
|
|||
foreach (var deformable in deformables) |
|||
{ |
|||
if (deformable != null && !PrefabUtility.IsPartOfPrefabAsset (deformable)) |
|||
{ |
|||
Undo.RecordObject (deformable, "Added Deformer"); |
|||
deformable.DeformerElements.Add (new DeformerElement (newDeformer)); |
|||
} |
|||
} |
|||
|
|||
foreach (var group in groups) |
|||
{ |
|||
if (group != null && !PrefabUtility.IsPartOfPrefabAsset (group)) |
|||
{ |
|||
Undo.RecordObject (group, "Added Deformer"); |
|||
group.DeformerElements.Add (new DeformerElement (newDeformer)); |
|||
} |
|||
} |
|||
|
|||
foreach (var repeater in repeaters) |
|||
{ |
|||
if (repeater != null && !PrefabUtility.IsPartOfPrefabAsset (repeater)) |
|||
{ |
|||
Undo.RecordObject (repeater, "Set Deformer"); |
|||
repeater.DeformerElement.Component = newDeformer; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
newGameObject.AddComponent (attribute.Type); |
|||
|
|||
Selection.activeGameObject = newGameObject; |
|||
} |
|||
|
|||
Undo.CollapseUndoOperations (Undo.GetCurrentGroup ()); |
|||
} |
|||
} |
|||
|
|||
private static IEnumerable<T> GetComponents<T> (GameObject[] objects) where T : Component |
|||
{ |
|||
for (int i = 0; i < objects.Length; i++) |
|||
{ |
|||
var component = objects[i].GetComponent<T> (); |
|||
if (component != null) |
|||
yield return component; |
|||
} |
|||
} |
|||
|
|||
private static Vector3 GetAverageGameObjectPosition (GameObject[] gameObjects) |
|||
{ |
|||
if (gameObjects == null || gameObjects.Length == 0) |
|||
return Vector3.zero; |
|||
|
|||
var sum = Vector3.zero; |
|||
foreach (var gameObject in gameObjects) |
|||
sum += gameObject.transform.position; |
|||
|
|||
return sum / gameObjects.Length; |
|||
} |
|||
|
|||
public static IEnumerable<DeformerAttribute> GetAllDeformerAttributes() |
|||
{ |
|||
#if CAN_USE_TYPE_CACHE
|
|||
{ |
|||
var types = TypeCache.GetTypesWithAttribute<DeformerAttribute>(); |
|||
foreach (var type in types) |
|||
{ |
|||
if (type.IsSubclassOf(typeof(Deformer))) |
|||
{ |
|||
var attribute = type.GetCustomAttribute<DeformerAttribute>(false); |
|||
if (attribute != null) |
|||
yield return attribute; |
|||
} |
|||
} |
|||
} |
|||
#else
|
|||
{ |
|||
var assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); |
|||
foreach (var assembly in assemblies) |
|||
{ |
|||
IEnumerable<System.Type> types; |
|||
try |
|||
{ |
|||
types = assembly.GetTypes(); |
|||
} |
|||
catch (ReflectionTypeLoadException e) |
|||
{ |
|||
types = e.Types.Where(t => t != null); |
|||
} |
|||
|
|||
foreach (var type in types) |
|||
{ |
|||
if (type.IsSubclassOf(typeof(Deformer))) |
|||
{ |
|||
var attribute = type.GetCustomAttribute<DeformerAttribute>(false); |
|||
if (attribute != null) |
|||
yield return attribute; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
#endif
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 4285705c990c5f745a348d44391c1cc4 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,93 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public class CreditsWindow : EditorWindow |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Title = new GUIContent (text: "Credits"); |
|||
public static readonly GUIContent Twitter = new GUIContent (text: "Twitter"); |
|||
public static readonly GUIContent GitHub = new GUIContent (text: "GitHub"); |
|||
public static readonly GUIContent Website = new GUIContent (text: "Website"); |
|||
} |
|||
|
|||
private static class Styles |
|||
{ |
|||
public static readonly GUIStyle Title; |
|||
public static readonly GUIStyle CreditsText; |
|||
|
|||
static Styles () |
|||
{ |
|||
Title = new GUIStyle (EditorStyles.largeLabel); |
|||
Title.alignment = TextAnchor.MiddleCenter; |
|||
Title.fontStyle = FontStyle.Bold; |
|||
|
|||
CreditsText = new GUIStyle (EditorStyles.label); |
|||
CreditsText.wordWrap = true; |
|||
} |
|||
} |
|||
|
|||
private Vector2 scrollPosition = Vector2.zero; |
|||
|
|||
[MenuItem ("Window/Deform/Credits", priority = 10200)] |
|||
[MenuItem ("Tools/Deform/Credits", priority = 10200)] |
|||
public static void ShowWindow () |
|||
{ |
|||
GetWindow<CreditsWindow> ("Credits", true); |
|||
} |
|||
|
|||
private void OnGUI () |
|||
{ |
|||
EditorGUILayout.LabelField (Content.Title, Styles.Title, GUILayout.ExpandWidth (true)); |
|||
|
|||
EditorGUILayoutx.Splitter (); |
|||
|
|||
using (new EditorGUILayout.ScrollViewScope (scrollPosition)) |
|||
{ |
|||
EditorGUILayout.LabelField |
|||
( |
|||
"Created by Keenan Woodall.", |
|||
Styles.CreditsText |
|||
); |
|||
|
|||
EditorGUILayout.Space (); |
|||
|
|||
if (EditorGUILayoutx.LinkLabel (Content.Twitter)) |
|||
Application.OpenURL ("https://twitter.com/keenanwoodall"); |
|||
|
|||
if (EditorGUILayoutx.LinkLabel (Content.GitHub)) |
|||
Application.OpenURL ("https://github.com/keenanwoodall"); |
|||
|
|||
if (EditorGUILayoutx.LinkLabel (Content.Website)) |
|||
Application.OpenURL ("https://keenanwoodall.com"); |
|||
|
|||
EditorGUILayout.Space (); |
|||
|
|||
EditorGUILayout.LabelField |
|||
( |
|||
"Thanks to Thomas Ingram for going the extra mile with editor scripting help.", |
|||
Styles.CreditsText |
|||
); |
|||
|
|||
EditorGUILayout.Space (); |
|||
|
|||
EditorGUILayout.LabelField |
|||
( |
|||
"Thanks to Alexander Ameye, William Besnard, Raphael Herdlicka and David Carney for beta testing and providing crucial feedback.", |
|||
Styles.CreditsText |
|||
); |
|||
|
|||
EditorGUILayout.Space (); |
|||
|
|||
EditorGUILayout.LabelField |
|||
( |
|||
"Additional massive thanks to the following contributors for helping develop Deform into the best tool it can be:\nsabresaurus, Brullworfel, favoyang, and HitCache", |
|||
Styles.CreditsText |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3bd1a68bc6078e349b650922ad5da620 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d2939bdacb2a307468383cbf20b9a98f |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,134 @@ |
|||
using System; |
|||
using System.Reflection; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using UnityEditorInternal; |
|||
using Beans.Unity.Editor; |
|||
using Object = UnityEngine.Object; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
/// <summary>
|
|||
/// Draws a reorderable list of IComponentElements.
|
|||
/// </summary>
|
|||
/// <typeparam name="T">The type of component the element holds.</typeparam>
|
|||
public class ReorderableComponentElementList<T> : IDisposable where T : Component |
|||
{ |
|||
private readonly ReorderableList list; |
|||
private Editor selectedComponentInspectorEditor; |
|||
|
|||
/// <summary>
|
|||
/// Make sure your implementation of IComponentElement has a PropertyDrawer and
|
|||
/// serialized fields for for the component reference and active bool called "component" and "active".
|
|||
/// </summary>
|
|||
public ReorderableComponentElementList (SerializedObject serializedObject, SerializedProperty elements) |
|||
{ |
|||
list = new ReorderableList (serializedObject, elements); |
|||
list.elementHeight = EditorGUIUtility.singleLineHeight; |
|||
|
|||
list.onAddCallback = (list) => |
|||
{ |
|||
var property = list.serializedProperty; |
|||
|
|||
property.arraySize++; |
|||
|
|||
// Even though in the DeformerElement class, active defaults to true, serialized bools default to false.
|
|||
var lastElement = property.GetArrayElementAtIndex (property.arraySize - 1); |
|||
lastElement.FindPropertyRelative ("active").boolValue = true; |
|||
}; |
|||
|
|||
list.drawHeaderCallback = (r) => GUI.Label (r, new GUIContent ($"{typeof (T).Name}s")); |
|||
list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => |
|||
{ |
|||
try |
|||
{ |
|||
var elementProperty = list.serializedProperty.GetArrayElementAtIndex (index); |
|||
|
|||
EditorGUI.PropertyField (rect, elementProperty); |
|||
|
|||
// get the current element's component property
|
|||
var componentProperty = elementProperty.FindPropertyRelative ("component"); |
|||
|
|||
if (componentProperty == null) |
|||
{ |
|||
elementProperty.serializedObject.SetIsDifferentCacheDirty (); |
|||
elementProperty.serializedObject.Update (); |
|||
|
|||
componentProperty = elementProperty.FindPropertyRelative ("component"); |
|||
} |
|||
|
|||
// and the property's object reference
|
|||
var component = (Component)componentProperty.objectReferenceValue; |
|||
|
|||
// if the current element is selected
|
|||
if (!componentProperty.hasMultipleDifferentValues && index == list.index && component != null) |
|||
{ |
|||
// create it's editor and draw it
|
|||
Editor.CreateCachedEditor (component, null, ref selectedComponentInspectorEditor); |
|||
#if UNITY_2019_1_OR_NEWER
|
|||
SceneView.duringSceneGui -= SceneGUI; |
|||
SceneView.duringSceneGui += SceneGUI; |
|||
#else
|
|||
SceneView.onSceneGUIDelegate -= SceneGUI; |
|||
SceneView.onSceneGUIDelegate += SceneGUI; |
|||
#endif
|
|||
|
|||
var foldoutName = $"{ObjectNames.NicifyVariableName (componentProperty.objectReferenceValue.GetType ().Name)} Properties"; |
|||
using (var foldout = new EditorGUILayoutx.FoldoutContainerScope (list.serializedProperty, foldoutName, DeformEditorResources.GetStyle ("Box"), EditorStyles.foldout)) |
|||
{ |
|||
if (foldout.isOpen) |
|||
{ |
|||
selectedComponentInspectorEditor.OnInspectorGUI (); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
catch (NullReferenceException) |
|||
{ |
|||
list.serializedProperty.serializedObject.SetIsDifferentCacheDirty (); |
|||
list.serializedProperty.serializedObject.Update (); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
private void SceneGUI (SceneView sceneView) |
|||
{ |
|||
if (selectedComponentInspectorEditor == null || selectedComponentInspectorEditor.target == null) |
|||
return; |
|||
var method = selectedComponentInspectorEditor.GetType().GetMethod("OnSceneGUI", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); |
|||
if (method == null) |
|||
return; |
|||
method.Invoke (selectedComponentInspectorEditor, null); |
|||
selectedComponentInspectorEditor.Repaint (); |
|||
} |
|||
|
|||
public void DoLayoutList () |
|||
{ |
|||
try |
|||
{ |
|||
// list.DoLayoutList doesn't support indenting so list.DoList will be used with a manually indented rect.
|
|||
var rect = GUILayoutUtility.GetRect (1, list.GetHeight ()); |
|||
rect = EditorGUI.IndentedRect (rect); |
|||
list.DoList (rect); |
|||
} |
|||
// If an error is thrown, the serialized object was modified but not marked as dirty so we need to force it to sync back up with the targets.
|
|||
catch (InvalidOperationException) |
|||
{ |
|||
var so = list.serializedProperty.serializedObject; |
|||
so.SetIsDifferentCacheDirty (); |
|||
so.Update (); |
|||
} |
|||
} |
|||
|
|||
public void Dispose () |
|||
{ |
|||
#if UNITY_2019_1_OR_NEWER
|
|||
SceneView.duringSceneGui -= SceneGUI; |
|||
#else
|
|||
SceneView.onSceneGUIDelegate -= SceneGUI; |
|||
#endif
|
|||
Object.DestroyImmediate (selectedComponentInspectorEditor, true); |
|||
selectedComponentInspectorEditor = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 62b049ab207776f47af1fb42c98d5020 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,36 @@ |
|||
using Deform; |
|||
using UnityEditor; |
|||
using UnityEditor.Callbacks; |
|||
using UnityEngine; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public enum BuildStrippingMode |
|||
{ |
|||
StripDeformInScenes, |
|||
NoStripping, |
|||
}; |
|||
|
|||
public class DeformBuildPostProcessor |
|||
{ |
|||
[PostProcessScene] |
|||
public static void OnPostprocessScene() |
|||
{ |
|||
var deformables = Resources.FindObjectsOfTypeAll<Deformable>(); |
|||
foreach (var deformable in deformables) |
|||
{ |
|||
if (deformable.StripMode == StripMode.DontStrip) |
|||
continue; |
|||
|
|||
deformable.assignOriginalMeshOnDisable = false; |
|||
|
|||
var go = deformable.gameObject; |
|||
// Is it an ordinary scene object?
|
|||
if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave)) |
|||
{ |
|||
Object.DestroyImmediate(deformable); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 8c592b547d084b92a5afccad88e33274 |
|||
timeCreated: 1613922158 |
|||
@ -0,0 +1,18 @@ |
|||
{ |
|||
"name": "DeformEditor", |
|||
"references": [ |
|||
"Beans.Unity.Editor", |
|||
"Deform", |
|||
"Unity.Mathematics" |
|||
], |
|||
"optionalUnityReferences": [], |
|||
"includePlatforms": [ |
|||
"Editor" |
|||
], |
|||
"excludePlatforms": [], |
|||
"allowUnsafeCode": false, |
|||
"overrideReferences": false, |
|||
"precompiledReferences": [], |
|||
"autoReferenced": true, |
|||
"defineConstraints": [] |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 8eedebcb73101994492a80e4cc658d74 |
|||
AssemblyDefinitionImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,67 @@ |
|||
using UnityEditor; |
|||
using UnityEngine; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public static class DeformEditorGUIUtility |
|||
{ |
|||
public static class Strings |
|||
{ |
|||
public static readonly string AxisTooltip = "This is the transform that all the calculations will be relative local to. If left blank, the component's transform will be used.\n-\nAll vertices are converted to a space relative to this transform."; |
|||
public static readonly string FactorTooltip = "Strength of the effect."; |
|||
public static readonly string FalloffTooltip = "The sharpness of the effects' transition."; |
|||
public static readonly string TopTooltip = "Any vertices above this will be unaffected."; |
|||
public static readonly string BottomTooltip = "Any vertices below this will be unaffected."; |
|||
public static readonly string SmoothTooltip = "Should the strength of this effect be smoothed near the bounds?"; |
|||
} |
|||
|
|||
public static class DefaultContent |
|||
{ |
|||
public static readonly GUIContent Axis = new GUIContent |
|||
( |
|||
text: "Axis", |
|||
tooltip: Strings.AxisTooltip |
|||
); |
|||
public static readonly GUIContent Factor = new GUIContent |
|||
( |
|||
text: "Factor", |
|||
tooltip: Strings.FactorTooltip |
|||
); |
|||
public static readonly GUIContent Falloff = new GUIContent |
|||
( |
|||
text: "Falloff", |
|||
tooltip: Strings.FalloffTooltip |
|||
); |
|||
public static readonly GUIContent Top = new GUIContent |
|||
( |
|||
text: "Top", |
|||
tooltip: Strings.TopTooltip |
|||
); |
|||
public static readonly GUIContent Bottom = new GUIContent |
|||
( |
|||
text: "Bottom", |
|||
tooltip: Strings.BottomTooltip |
|||
); |
|||
public static readonly GUIContent Smooth = new GUIContent |
|||
( |
|||
text: "Smooth", |
|||
tooltip: Strings.SmoothTooltip |
|||
); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Convert a world position to a screen position to be used with GUI
|
|||
/// </summary>
|
|||
public static Vector3 WorldToGUIPoint(Camera sceneViewCamera, Vector3 worldPosition) |
|||
{ |
|||
Vector3 screenPoint = sceneViewCamera.WorldToScreenPoint(worldPosition); |
|||
|
|||
// Flip the y position so it matches the rect coordinate space
|
|||
screenPoint.y = sceneViewCamera.pixelHeight - screenPoint.y; |
|||
// Convert from pixels to points (e.g. on retina screens)
|
|||
screenPoint /= EditorGUIUtility.pixelsPerPoint; |
|||
|
|||
return screenPoint; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 23cfd6dfadf5bc64182cdd633a333399 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,122 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using System; |
|||
using System.IO; |
|||
using Object = UnityEngine.Object; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
/// <summary>
|
|||
/// A class to assist in loading editor resources.
|
|||
/// </summary>
|
|||
public static class DeformEditorResources |
|||
{ |
|||
public enum SearchFilter |
|||
{ |
|||
All, |
|||
Assets, |
|||
Packages |
|||
} |
|||
|
|||
private static GUISkin ProSkin, PersonalSkin; |
|||
|
|||
public static T LoadAssetOfType<T> (string contains = null, SearchFilter searchAssets = SearchFilter.All, Action error = null, Action success = null) where T : Object |
|||
{ |
|||
bool allowScriptAssets = typeof (T) == typeof (MonoScript); |
|||
|
|||
T t = null; |
|||
string[] assetGUIDs = AssetDatabase.FindAssets ($"t:{typeof (T).Name}", GetSearchDirectories (searchAssets)); |
|||
foreach (var assetGUID in assetGUIDs) |
|||
{ |
|||
string assetPath = AssetDatabase.GUIDToAssetPath (assetGUID); |
|||
if (string.IsNullOrEmpty (assetPath) || !allowScriptAssets && assetPath.EndsWith (".cs") || contains != null && !Path.GetFileName (assetPath).Contains (contains)) |
|||
continue; |
|||
t = AssetDatabase.LoadAssetAtPath<T> (assetPath); |
|||
break; |
|||
} |
|||
|
|||
if (t == null) |
|||
error?.Invoke (); |
|||
else |
|||
success?.Invoke (); |
|||
|
|||
return t; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates asset relative to the Assets folder.
|
|||
/// </summary>
|
|||
public static void CreateAsset (Object asset, string relativePath) |
|||
{ |
|||
EnsurePath (relativePath); |
|||
AssetDatabase.CreateAsset (asset, $"Assets/{relativePath}"); |
|||
} |
|||
|
|||
private static void EnsurePath (string relativePath) |
|||
{ |
|||
if (!AssetDatabase.IsValidFolder ($"Assets/{relativePath}")) |
|||
{ |
|||
var paths = relativePath.Split ('/'); |
|||
var workingPath = "Assets"; |
|||
for (int i = 0; i < paths.Length - 1; i++) |
|||
{ |
|||
if (!AssetDatabase.IsValidFolder ($"{workingPath}/{paths[i]}")) |
|||
AssetDatabase.CreateFolder (workingPath, paths[i]); |
|||
|
|||
workingPath += $"/{paths[i]}"; |
|||
} |
|||
AssetDatabase.Refresh (ImportAssetOptions.Default); |
|||
} |
|||
} |
|||
|
|||
private static string[] GetSearchDirectories (SearchFilter searchAssets) |
|||
{ |
|||
string[] searchDirs; |
|||
switch (searchAssets) |
|||
{ |
|||
case SearchFilter.All: |
|||
searchDirs = new[] { "Assets", "Packages" }; |
|||
break; |
|||
case SearchFilter.Assets: |
|||
searchDirs = new[] { "Assets" }; |
|||
break; |
|||
case SearchFilter.Packages: |
|||
searchDirs = new[] { "Packages" }; |
|||
break; |
|||
default: |
|||
throw new ArgumentOutOfRangeException (nameof (searchAssets), searchAssets, null); |
|||
} |
|||
|
|||
return searchDirs; |
|||
} |
|||
|
|||
public static GUISkin GetSkin () |
|||
{ |
|||
if (EditorGUIUtility.isProSkin) |
|||
{ |
|||
if (ProSkin == null) |
|||
ProSkin = LoadAssetOfType<GUISkin> (contains: "DeformProfessional"); |
|||
return ProSkin; |
|||
} |
|||
else |
|||
{ |
|||
if (PersonalSkin == null) |
|||
PersonalSkin = LoadAssetOfType<GUISkin> (contains: "DeformPersonal"); |
|||
return PersonalSkin; |
|||
} |
|||
} |
|||
|
|||
public static GUIStyle GetStyle (string name) |
|||
{ |
|||
return GetSkin ().GetStyle (name); |
|||
} |
|||
|
|||
public static Texture2D GetTexture (string name, bool appendDarkOrLightBasedOnSkin = true) |
|||
{ |
|||
if (appendDarkOrLightBasedOnSkin) |
|||
name += EditorGUIUtility.isProSkin ? "Light" : "Dark"; |
|||
|
|||
return LoadAssetOfType<Texture2D> (name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f52641e37ffbfee4bbf3640faf7cec5c |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,118 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public static class DeformEditorSettings |
|||
{ |
|||
[InitializeOnLoadMethod] |
|||
private static void EnsureSettingsAsset () |
|||
{ |
|||
if (settingsAsset == null) |
|||
settingsAsset = DeformEditorResources.LoadAssetOfType<DeformEditorSettingsAsset> (searchAssets: DeformEditorResources.SearchFilter.Assets); |
|||
if (settingsAsset == null) |
|||
{ |
|||
settingsAsset = ScriptableObject.CreateInstance<DeformEditorSettingsAsset> (); |
|||
DeformEditorResources.CreateAsset (settingsAsset, "Deform/EditorResources/DeformSettings.asset"); |
|||
} |
|||
} |
|||
|
|||
private static DeformEditorSettingsAsset settingsAsset; |
|||
public static DeformEditorSettingsAsset SettingsAsset |
|||
{ |
|||
get |
|||
{ |
|||
EnsureSettingsAsset (); |
|||
return settingsAsset; |
|||
} |
|||
} |
|||
|
|||
public static Color SolidHandleColor |
|||
{ |
|||
get => SettingsAsset.solidHandleColor; |
|||
set |
|||
{ |
|||
SettingsAsset.solidHandleColor = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
public static Color LightHandleColor |
|||
{ |
|||
get => SettingsAsset.lightHandleColor; |
|||
set |
|||
{ |
|||
SettingsAsset.lightHandleColor = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
public static Color RecordingHandleColor |
|||
{ |
|||
get => SettingsAsset.recordingHandleColor; |
|||
set |
|||
{ |
|||
SettingsAsset.recordingHandleColor = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
|
|||
public static float DottedLineSize |
|||
{ |
|||
get => SettingsAsset.dottedLineSize; |
|||
set |
|||
{ |
|||
SettingsAsset.dottedLineSize = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
public static float ScreenspaceSliderHandleCapSize |
|||
{ |
|||
get => SettingsAsset.screenspaceHandleCapSize; |
|||
set |
|||
{ |
|||
SettingsAsset.screenspaceHandleCapSize = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
public static float ScreenspaceAngleHandleSize |
|||
{ |
|||
get => SettingsAsset.screenspaceAngleHandleSize; |
|||
set |
|||
{ |
|||
SettingsAsset.screenspaceAngleHandleSize = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
public static float ScreenspaceLatticeHandleCapSize |
|||
{ |
|||
get => SettingsAsset.screenspaceLatticeCapSize; |
|||
set |
|||
{ |
|||
SettingsAsset.screenspaceLatticeCapSize = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
|
|||
public static bool ModelsReadableByDefault |
|||
{ |
|||
get => SettingsAsset.modelsReadableByDefault; |
|||
set |
|||
{ |
|||
SettingsAsset.modelsReadableByDefault = value; |
|||
EditorUtility.SetDirty (SettingsAsset); |
|||
} |
|||
} |
|||
|
|||
public static void SelectSettingsAsset () |
|||
{ |
|||
Selection.activeObject = SettingsAsset; |
|||
} |
|||
|
|||
[MenuItem ("Window/Deform/Settings", priority = 10000)] |
|||
[MenuItem ("Tools/Deform/Settings", priority = 10000)] |
|||
public static void ShowWindow () |
|||
{ |
|||
SelectSettingsAsset(); |
|||
EditorApplication.ExecuteMenuItem("Window/General/Inspector"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: a6f41df97449ac244b3fb8df502a7cae |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,20 @@ |
|||
using Deform; |
|||
using UnityEngine; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public class DeformEditorSettingsAsset : ScriptableObject |
|||
{ |
|||
[CollapsibleSection("Scene")] |
|||
[DisplayName("Solid Color")] public Color solidHandleColor = new Color (1f, 0.4f, 0f, 1f); |
|||
[DisplayName("Light Color")] public Color lightHandleColor = new Color (1f, 0.4f, 0f, 0.75f); |
|||
[DisplayName("Recording Color")] public Color recordingHandleColor = new Color (1f, 0f, 0f, 0.9f); |
|||
public float dottedLineSize = 5f; |
|||
[DisplayName("Handle Size")] public float screenspaceHandleCapSize = 0.0275f; |
|||
[DisplayName("Angle Handle Size")] public float screenspaceAngleHandleSize = 1.25f; |
|||
[DisplayName("Lattice Handle Size")] public float screenspaceLatticeCapSize = 0.035f; |
|||
|
|||
[CollapsibleSection("Importer")] |
|||
public bool modelsReadableByDefault = false; |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 84838e1060cbc4f45a2f463816b2d2fe |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,63 @@ |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
using UnityEditor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor(typeof(DeformEditorSettingsAsset))] |
|||
public class DeformEditorSettingsAssetInspector : Editor |
|||
{ |
|||
List<string> collapsedSections = new List<string>(); |
|||
|
|||
public override void OnInspectorGUI() |
|||
{ |
|||
var targetType = typeof(DeformEditorSettingsAsset); |
|||
serializedObject.UpdateIfRequiredOrScript(); |
|||
SerializedProperty iterator = serializedObject.GetIterator(); |
|||
|
|||
bool currentSectionExpanded = true; |
|||
for (bool enterChildren = true; iterator.NextVisible(enterChildren); enterChildren = false) |
|||
{ |
|||
using (new EditorGUI.DisabledScope(iterator.propertyPath == "m_Script")) |
|||
{ |
|||
var property = iterator; |
|||
FieldInfo fieldInfo = targetType.GetField(property.propertyPath, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy); |
|||
if (fieldInfo != null) |
|||
{ |
|||
var customAttributes = fieldInfo.GetCustomAttributes(); |
|||
|
|||
foreach (var customAttribute in customAttributes) |
|||
{ |
|||
if (customAttribute is CollapsibleSection collapsibleSection) |
|||
{ |
|||
bool collapsed = collapsedSections.Contains(collapsibleSection.Title); |
|||
currentSectionExpanded = !collapsed; |
|||
EditorGUI.BeginChangeCheck(); |
|||
bool newExpand = EditorGUILayoutx.FoldoutHeader(collapsibleSection.Title, !collapsed); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
if (newExpand) |
|||
{ |
|||
collapsedSections.Remove(collapsibleSection.Title); |
|||
} |
|||
else |
|||
{ |
|||
collapsedSections.Add(collapsibleSection.Title); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (currentSectionExpanded) |
|||
{ |
|||
EditorGUILayout.PropertyField(iterator, true); |
|||
} |
|||
} |
|||
} |
|||
serializedObject.ApplyModifiedProperties(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 712fd566a2714796808abe8a1ff4681d |
|||
timeCreated: 1613924572 |
|||
@ -0,0 +1,208 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
/// <summary>
|
|||
/// Assists in drawing custom handles based on a consistent style.
|
|||
/// </summary>
|
|||
public static class DeformHandles |
|||
{ |
|||
public const int DEF_CURVE_SEGMENTS = 120; |
|||
|
|||
public delegate void LineMethod (Vector3 a, Vector3 b); |
|||
public enum LineMode { Solid, Light, SolidDotted, LightDotted } |
|||
public enum CapType { Circle, Rectangle, Dot } |
|||
|
|||
private static LineMethod GetLineMethod (LineMode mode) |
|||
{ |
|||
switch (mode) |
|||
{ |
|||
default: |
|||
case LineMode.Solid: |
|||
case LineMode.Light: |
|||
return Handles.DrawLine; |
|||
case LineMode.SolidDotted: |
|||
case LineMode.LightDotted: |
|||
return (a, b) => Handles.DrawDottedLine (a, b, DeformEditorSettings.DottedLineSize); |
|||
} |
|||
} |
|||
|
|||
private static Color GetLineColor (LineMode mode) |
|||
{ |
|||
switch (mode) |
|||
{ |
|||
default: |
|||
case LineMode.Solid: |
|||
case LineMode.SolidDotted: |
|||
return DeformEditorSettings.SolidHandleColor; |
|||
case LineMode.Light: |
|||
case LineMode.LightDotted: |
|||
return DeformEditorSettings.LightHandleColor; |
|||
} |
|||
} |
|||
|
|||
public static void HandleCapFunction (int controlId, Vector3 position, Quaternion rotation, float size, EventType eventType) |
|||
{ |
|||
Handles.DotHandleCap (controlId, position, rotation, size, eventType); |
|||
} |
|||
|
|||
public static void Line (Vector3 a, Vector3 b, LineMode mode) |
|||
{ |
|||
using (new Handles.DrawingScope (GetLineColor (mode))) |
|||
GetLineMethod (mode) (a, b); |
|||
} |
|||
public static void Line (Vector3 a, Vector3 b, LineMode mode, Color color) |
|||
{ |
|||
using (new Handles.DrawingScope (color)) |
|||
GetLineMethod (mode) (a, b); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws an arc.
|
|||
/// </summary>
|
|||
public static void WireArc (Vector3 center, Vector3 normal, Vector3 from, float angle, float radius) |
|||
{ |
|||
using (new Handles.DrawingScope (DeformEditorSettings.LightHandleColor)) |
|||
Handles.DrawWireArc (center, normal, from, angle, radius); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a full circle.
|
|||
/// </summary>
|
|||
public static void Circle (Vector3 center, Vector3 normal, Vector3 from, float radius) |
|||
{ |
|||
using (new Handles.DrawingScope (DeformEditorSettings.LightHandleColor)) |
|||
Handles.DrawWireArc (center, normal, from, 360f, radius); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a handle that can be dragged along an axis.
|
|||
/// </summary>
|
|||
public static Vector3 Slider (Vector3 position, Vector3 direction) |
|||
{ |
|||
var size = HandleUtility.GetHandleSize (position) * DeformEditorSettings.ScreenspaceSliderHandleCapSize; |
|||
using (new Handles.DrawingScope (DeformEditorSettings.SolidHandleColor)) |
|||
return Handles.Slider (position, direction, size, HandleCapFunction, 0f); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a small handle that can be dragged along an axis.
|
|||
/// </summary>
|
|||
public static Vector3 MiniSlider (Vector3 position, Vector3 direction) |
|||
{ |
|||
var size = HandleUtility.GetHandleSize (position) * DeformEditorSettings.ScreenspaceSliderHandleCapSize * 0.5f; |
|||
using (new Handles.DrawingScope (DeformEditorSettings.SolidHandleColor)) |
|||
return Handles.Slider (position, direction, size, HandleCapFunction, 0f); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws a radius handle.
|
|||
/// </summary>
|
|||
public static float Radius (Quaternion rotation, Vector3 position, float radius) |
|||
{ |
|||
using (new Handles.DrawingScope (DeformEditorSettings.SolidHandleColor)) |
|||
return Handles.RadiusHandle (rotation, position, radius); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draws an animation curve in the scene, in 3D space.
|
|||
/// </summary>
|
|||
public static void Curve (AnimationCurve curve, Vector3 position, Quaternion rotation, Vector3 scale, float magnitude, float xOffset, float yOffset, int segments = DEF_CURVE_SEGMENTS) |
|||
{ |
|||
if (curve == null || curve.length == 0) |
|||
return; |
|||
|
|||
var lastPoint = Vector3.zero; |
|||
var lastPointSet = false; |
|||
|
|||
for (int i = 0; i < segments; i++) |
|||
{ |
|||
var height = curve.Evaluate (i / (float)segments); |
|||
|
|||
var point = Vector3.Lerp (Vector3.zero, Vector3.forward, i / (float)segments); |
|||
point.z -= xOffset; |
|||
point.y = (height * magnitude) + yOffset; |
|||
|
|||
var worldPoint = Matrix4x4.TRS (position, rotation, scale).MultiplyPoint3x4 (point); |
|||
//axis.localToWorldMatrix.MultiplyPoint3x4 (point);
|
|||
|
|||
if (lastPointSet) |
|||
Line (lastPoint, worldPoint, LineMode.Solid); |
|||
|
|||
lastPoint = worldPoint; |
|||
lastPointSet = true; |
|||
} |
|||
} |
|||
|
|||
public static void Curve (AnimationCurve curve, Transform axis, float magnitude, float xOffset, float yOffset, int segments = DEF_CURVE_SEGMENTS) |
|||
{ |
|||
Curve (curve, axis.position, axis.rotation, axis.lossyScale, magnitude, xOffset, yOffset, segments); |
|||
} |
|||
|
|||
public static void Bounds(Bounds bounds, Matrix4x4 matrix, LineMode mode) => Bounds(bounds, matrix, mode, GetLineColor(mode)); |
|||
public static void Bounds (Bounds bounds, Matrix4x4 matrix, LineMode mode, Color color) |
|||
{ |
|||
var leftTopFront = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 (-bounds.extents.x, bounds.extents.y, bounds.extents.z)); |
|||
var rightTopFront = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 ( bounds.extents.x, bounds.extents.y, bounds.extents.z)); |
|||
var leftBottomFront = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 (-bounds.extents.x, -bounds.extents.y, bounds.extents.z)); |
|||
var rightBottomFront = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 ( bounds.extents.x, -bounds.extents.y, bounds.extents.z)); |
|||
var leftTopBack = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 (-bounds.extents.x, bounds.extents.y, -bounds.extents.z)); |
|||
var rightTopBack = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 ( bounds.extents.x, bounds.extents.y, -bounds.extents.z)); |
|||
var leftBottomBack = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 (-bounds.extents.x, -bounds.extents.y, -bounds.extents.z)); |
|||
var rightBottomBack = matrix.MultiplyPoint3x4 (bounds.center + new Vector3 ( bounds.extents.x, -bounds.extents.y, -bounds.extents.z)); |
|||
|
|||
// Front
|
|||
Line (leftTopFront, rightTopFront, mode, color); |
|||
Line (rightTopFront, rightBottomFront, mode, color); |
|||
Line (rightBottomFront, leftBottomFront, mode, color); |
|||
Line (leftBottomFront, leftTopFront, mode, color); |
|||
// Back
|
|||
Line (leftTopBack, rightTopBack, mode, color); |
|||
Line (rightTopBack, rightBottomBack, mode, color); |
|||
Line (rightBottomBack, leftBottomBack, mode, color); |
|||
Line (leftBottomBack, leftTopBack, mode, color); |
|||
// Side
|
|||
Line (leftTopBack, leftTopFront, mode, color); |
|||
Line (rightTopBack, rightTopFront, mode, color); |
|||
Line (rightBottomBack, rightBottomFront, mode, color); |
|||
Line (leftBottomBack, leftBottomFront, mode, color); |
|||
} |
|||
|
|||
public static void TransformToolHandle (Transform target, float scale = 1f) |
|||
{ |
|||
var matrix = Matrix4x4.Scale (Vector3.one * scale); |
|||
|
|||
var newPosition = matrix.inverse.MultiplyPoint3x4 (target.position); |
|||
var newRotation = target.rotation; |
|||
var newScale = target.localScale; |
|||
|
|||
using (new Handles.DrawingScope (matrix)) |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
switch (Tools.current) |
|||
{ |
|||
default: |
|||
case Tool.Move: |
|||
if (Tools.pivotRotation == PivotRotation.Local) |
|||
newPosition = Handles.PositionHandle (matrix.inverse.MultiplyPoint3x4 (target.position), target.rotation); |
|||
else |
|||
newPosition = Handles.PositionHandle (matrix.inverse.MultiplyPoint3x4 (target.position), Quaternion.identity); |
|||
break; |
|||
case Tool.Rotate: |
|||
newRotation = Handles.RotationHandle(target.rotation, matrix.inverse.MultiplyPoint3x4 (target.position)); |
|||
break; |
|||
case Tool.Scale: |
|||
newScale = Handles.ScaleHandle (target.localScale, matrix.inverse.MultiplyPoint3x4 (target.position), target.rotation, HandleUtility.GetHandleSize (target.position)); |
|||
break; |
|||
} |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (target, "Changed Transform"); |
|||
target.SetPositionAndRotation (matrix.MultiplyPoint3x4 (newPosition), newRotation); |
|||
target.localScale = newScale; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: a618223751393864db9bdf7bea9bc2ce |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,25 @@ |
|||
using UnityEngine; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public static class DeformHandlesUtility |
|||
{ |
|||
/// <summary>
|
|||
/// Returns the distance between two points along a primary transform axis.
|
|||
/// </summary>
|
|||
public static float DistanceAlongAxis (Transform transform, Vector3 a, Vector3 b, Axis axis) |
|||
{ |
|||
var delta = (Quaternion.Inverse (transform.rotation) * (b - a)); |
|||
switch (axis) |
|||
{ |
|||
default: |
|||
return delta.x; |
|||
case Axis.Y: |
|||
return delta.y; |
|||
case Axis.Z: |
|||
return delta.z; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 13ebe39dcdce65d458379b1d82e36ddc |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,16 @@ |
|||
using UnityEditor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public class DeformModelPostProcessor : AssetPostprocessor |
|||
{ |
|||
private void OnPreprocessModel() |
|||
{ |
|||
if (DeformEditorSettings.ModelsReadableByDefault && assetImporter is ModelImporter m) |
|||
{ |
|||
if (m.importSettingsMissing) |
|||
m.isReadable = true; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: e6a742a56a27f2d4da0c0b7f05536b4a |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,68 @@ |
|||
using System.Reflection; |
|||
using UnityEditor; |
|||
using UnityEngine; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
/// <summary>
|
|||
/// Provides helper methods for custom editor tools when dealing with Unity's built in object selection systems
|
|||
/// </summary>
|
|||
public static class DeformUnityObjectSelection |
|||
{ |
|||
/// <summary>
|
|||
/// Mimics Unity's built in selection marquee
|
|||
/// </summary>
|
|||
public static void DrawUnityStyleMarquee(Rect marqueeRect) |
|||
{ |
|||
Handles.BeginGUI(); |
|||
|
|||
Rect innerMarquee = new Rect(marqueeRect.position, marqueeRect.size * Vector2.one); |
|||
// These colours roughly match Unity's built in marquee
|
|||
var innerColor = new Color32(148, 184, 237, (byte) (0.33f * 255)); |
|||
var borderColor = new Color(1, 1, 1, 0.67f); |
|||
|
|||
GUI.DrawTexture(innerMarquee, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 1, innerColor, Vector4.zero, Vector4.zero); |
|||
GUI.DrawTexture(marqueeRect, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 1, borderColor, Vector4.one, Vector4.zero); |
|||
|
|||
Handles.EndGUI(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Has the user activated the built in Select All command?
|
|||
/// </summary>
|
|||
public static bool SelectAllPressed => Event.current.type == EventType.ExecuteCommand && Event.current.commandName == "SelectAll"; |
|||
|
|||
/// <summary>
|
|||
/// Prevent Unity's scene view selection system responding to mouse inputs (e.g. clicks and marquee mouse drags)
|
|||
/// </summary>
|
|||
public static int DisableSceneViewObjectSelection() |
|||
{ |
|||
var defaultControl = GUIUtility.GetControlID(FocusType.Passive); |
|||
if (Event.current.type == EventType.Layout) |
|||
HandleUtility.AddDefaultControl(defaultControl); |
|||
return defaultControl; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Unity's built in mouse up selection relies on RectSelection thinking it is the correct control in the
|
|||
/// MouseDown, in some cases we may override that for our own purposes but later want to use the MouseUp
|
|||
/// selection after all
|
|||
/// </summary>
|
|||
public static void AttemptMouseUpObjectSelection() |
|||
{ |
|||
if (Event.current.type != EventType.MouseUp) |
|||
{ |
|||
Debug.LogError("MouseUp selection should only be attempted from the MouseUp event"); |
|||
} |
|||
|
|||
var rectSelection = typeof(SceneView).GetField("m_RectSelection", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(SceneView.currentDrawingSceneView); |
|||
|
|||
// Make sure we have the correct control "hot" that RectSelection is expecting
|
|||
int rectSelectionID = (int) typeof(Editor).Assembly.GetType("UnityEditor.RectSelection").GetField("s_RectSelectionID", BindingFlags.NonPublic | BindingFlags.Static).GetValue(rectSelection); |
|||
|
|||
GUIUtility.hotControl = rectSelectionID; |
|||
|
|||
typeof(Editor).Assembly.GetType("UnityEditor.RectSelection").GetMethod("OnGUI").Invoke(rectSelection, null); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d0d51f534bf242d6bbaa39e929a52cf5 |
|||
timeCreated: 1613253086 |
|||
@ -0,0 +1,124 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
public static class MenuItemActions |
|||
{ |
|||
[MenuItem ("Tools/Deform/Actions/Clean All Deformables", priority = 10100)] |
|||
public static void CleanAllDeformables () |
|||
{ |
|||
var deformables = GameObject.FindObjectsOfType<Deformable> (); |
|||
|
|||
Undo.RecordObjects (deformables, "Cleaned All Deformables"); |
|||
foreach (var deformable in deformables) |
|||
deformable.DeformerElements.RemoveAll (t => t.Component == null); |
|||
|
|||
var groupDeformers = GameObject.FindObjectsOfType<GroupDeformer> (); |
|||
|
|||
Undo.RecordObjects (groupDeformers, "Cleaned All Deformables"); |
|||
foreach (var groupDeformer in groupDeformers) |
|||
groupDeformer.DeformerElements.RemoveAll (t => t.Component == null); |
|||
|
|||
EditorUtility.DisplayDialog ("Cleaned All Deformables", $"{deformables.Length + groupDeformers.Length} found and cleaned.", "OK"); |
|||
} |
|||
|
|||
private static void StripDeformable(Deformable deformable) |
|||
{ |
|||
Undo.RecordObject (deformable, "Changed Assign Original Mesh On Disable"); |
|||
// Make sure the meshes are up to date before stripping (we don't want it being culled when stripped stopping preventing the correct mesh being baked out)
|
|||
deformable.ForceImmediateUpdate(); |
|||
deformable.assignOriginalMeshOnDisable = false; |
|||
Undo.DestroyObjectImmediate (deformable); |
|||
} |
|||
|
|||
[MenuItem ("Tools/Deform/Actions/Strip All Deformables", priority = 10101)] |
|||
public static void StripAllDeformablesFromMeshes () |
|||
{ |
|||
var deformables = GameObject.FindObjectsOfType<Deformable> (); |
|||
Undo.SetCurrentGroupName ("Stripped All Deformables"); |
|||
foreach (var deformable in deformables) |
|||
{ |
|||
StripDeformable(deformable); |
|||
} |
|||
|
|||
EditorUtility.DisplayDialog ("Stripped All Deformables", $"{deformables.Length} found and stripped.", "OK"); |
|||
} |
|||
|
|||
[MenuItem ("Tools/Deform/Actions/Strip Selected Deformables", priority = 10102)] |
|||
public static void StripSelectedDeformablesFromMeshes () |
|||
{ |
|||
var selections = Selection.gameObjects; |
|||
Undo.SetCurrentGroupName ("Stripped Selected Deformables"); |
|||
foreach (var selection in selections) |
|||
{ |
|||
var deformable = selection.GetComponent<Deformable> (); |
|||
if (deformable != null) |
|||
{ |
|||
StripDeformable(deformable); |
|||
} |
|||
} |
|||
} |
|||
[MenuItem ("Tools/Deform/Actions/Strip Selected Deformables", validate = true)] |
|||
private static bool CanStripDeformableFromMesh () |
|||
{ |
|||
var selections = Selection.gameObjects; |
|||
foreach (var selection in selections) |
|||
if (selection.GetComponent<Deformable> () != null) |
|||
return true; |
|||
return false; |
|||
} |
|||
|
|||
[MenuItem ("Tools/Deform/Actions/Make Immediate Children Deformable", priority = 10103)] |
|||
public static void MakeImmediateChildrenDeformables () |
|||
{ |
|||
var newSelection = new HashSet<GameObject> (); |
|||
|
|||
var selections = Selection.gameObjects; |
|||
Undo.SetCurrentGroupName ("Made Immediate Children Deformable"); |
|||
foreach (var selection in selections) |
|||
{ |
|||
foreach (Transform child in selection.transform) |
|||
{ |
|||
if (child.GetComponent<Deformable> ()) |
|||
continue; |
|||
if (MeshTarget.IsValid (child.gameObject)) |
|||
newSelection.Add (Undo.AddComponent<Deformable> (child.gameObject).gameObject); |
|||
} |
|||
} |
|||
|
|||
Selection.objects = newSelection.ToArray (); |
|||
} |
|||
|
|||
[MenuItem ("Tools/Deform/Actions/Make All Children Deformable", priority = 10104)] |
|||
public static void MakeAllChildrenDeformables () |
|||
{ |
|||
var newSelection = new HashSet<GameObject> (); |
|||
|
|||
var selections = Selection.gameObjects; |
|||
Undo.SetCurrentGroupName ("Made All Children Deformable"); |
|||
foreach (var selection in selections) |
|||
{ |
|||
var allChildren = selection.transform.GetComponentsInChildren<Transform>(); |
|||
foreach (Transform child in allChildren) |
|||
{ |
|||
if (child.GetComponent<Deformable> ()) |
|||
continue; |
|||
if (MeshTarget.IsValid (child.gameObject)) |
|||
newSelection.Add (Undo.AddComponent<Deformable> (child.gameObject).gameObject); |
|||
} |
|||
} |
|||
|
|||
Selection.objects = newSelection.ToArray (); |
|||
} |
|||
|
|||
[MenuItem ("Tools/Deform/Report Bug", priority = 10203)] |
|||
public static void ReportBug () |
|||
{ |
|||
Application.OpenURL ("https://github.com/keenanwoodall/Deform/issues/new"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 1f19a8e85e05eef488f714947b932d17 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 5067e182e58efac4c85676f2ae9e0e0b |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: b1d28bc6dc1df144f9da2141b27fdf54 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,66 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
/// <summary>
|
|||
/// Handles creating vertex caches in the Editor.
|
|||
/// </summary>
|
|||
public static class VertexCacheCreator |
|||
{ |
|||
/// <summary>
|
|||
/// Returns true if a mesh asset or GameObject is selected that a vertex cache can be created from.
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[MenuItem ("Assets/Create/Deform/Vertex Cache", true, 10000)] |
|||
private static bool CanValidateVertexCache () |
|||
{ |
|||
var selections = Selection.gameObjects; |
|||
|
|||
foreach (var selection in selections) |
|||
{ |
|||
var meshFilters = selection.GetComponentsInChildren<MeshFilter> (); |
|||
if (meshFilters != null && meshFilters.Length > 0) |
|||
return true; |
|||
|
|||
var skinnedMeshRenderers = selection.GetComponentsInChildren<SkinnedMeshRenderer> (); |
|||
if (skinnedMeshRenderers != null && skinnedMeshRenderers.Length > 0) |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a vertex cache based on the currently selected mesh asset or gameobject.
|
|||
/// </summary>
|
|||
[MenuItem ("Assets/Create/Deform/Vertex Cache")] |
|||
public static void CreateVertexCache () |
|||
{ |
|||
var selections = Selection.gameObjects; |
|||
|
|||
foreach (var selection in selections) |
|||
{ |
|||
var meshFilters = selection.GetComponentsInChildren<MeshFilter> (); |
|||
var skinnedMeshRenderers = selection.GetComponentsInChildren<SkinnedMeshRenderer> (); |
|||
|
|||
foreach (var mf in meshFilters) |
|||
{ |
|||
var cache = ScriptableObject.CreateInstance<VertexCache> (); |
|||
cache.Initialize (mf.sharedMesh); |
|||
|
|||
AssetDatabase.CreateAsset (cache, $"Assets/{mf.name}.asset"); |
|||
} |
|||
|
|||
foreach (var smr in skinnedMeshRenderers) |
|||
{ |
|||
var cache = ScriptableObject.CreateInstance<VertexCache> (); |
|||
cache.Initialize (smr.sharedMesh); |
|||
|
|||
AssetDatabase.CreateAsset (cache, $"Assets/{smr.name}.asset"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: ce30d4e52d83cf847839eaa3e9306b66 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,24 @@ |
|||
using System.Linq; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (VertexCache))] |
|||
[CanEditMultipleObjects] |
|||
public class VertexCacheEditor : Editor |
|||
{ |
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
var firstVertexCache = target as VertexCache; |
|||
|
|||
var targetsHaveDifferentVertexCount = targets.Any (t => ((VertexCache)t).Data.Vertices.Length != firstVertexCache.Data.Vertices.Length); |
|||
|
|||
EditorGUI.showMixedValue = targetsHaveDifferentVertexCount; |
|||
EditorGUILayout.LabelField ($"Vertex Count: {firstVertexCache.Data.Vertices.Length}"); |
|||
EditorGUI.showMixedValue = false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d1917b9cad20a82458917dfb09d51f08 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,382 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor(typeof(Deformable), editorForChildClasses: true), CanEditMultipleObjects] |
|||
public class DeformableEditor : Editor |
|||
{ |
|||
private static class Styles |
|||
{ |
|||
public static readonly GUIStyle WrappedLabel; |
|||
|
|||
static Styles() |
|||
{ |
|||
WrappedLabel = new GUIStyle(EditorStyles.miniLabel); |
|||
WrappedLabel.wordWrap = true; |
|||
} |
|||
} |
|||
|
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent UpdateMode = new GUIContent(text: "Update Mode", tooltip: "Auto: Gets updated by a manager.\nPause: Never updated or reset.\nStop: Mesh is reverted to it's undeformed state until mode is switched.\nCustom: Allows updates, but not from a Deformable Manager."); |
|||
public static readonly GUIContent CullingMode = new GUIContent(text: "Culling Mode", tooltip: "Always Update: Update everything regardless of renderer visibility.\n\nDon't Update: Do not update unless renderer is visible. When the deformers aren't recalculated, bounds cannot be updated which may result in animated deformables not reappearing on screen."); |
|||
public static readonly GUIContent StripMode = new GUIContent(text: "Strip Mode", tooltip: "Strip:\nThis deformable will only exist in edit mode.\n\nDon't Strip:\nThis deformable will continue at runtime."); |
|||
public static readonly GUIContent NormalsRecalculation = new GUIContent(text: "Normals", tooltip: "Auto: Normals are auto calculated after the mesh is deformed; overwriting any changes made by deformers.\nNone: Normals aren't modified by the Deformable."); |
|||
public static readonly GUIContent BoundsRecalculation = new GUIContent(text: "Bounds", tooltip: "Auto: Bounds are recalculated for any deformers that need it, and at the end after all the deformers finish.\nNever: Bounds are never recalculated.\nOnce At The End: Deformers that needs updated bounds are ignored and bounds are only recalculated at the end."); |
|||
public static readonly GUIContent ColliderRecalculation = new GUIContent(text: "Collider", tooltip: "Auto: Collider's mesh is updated when the rendered mesh is updated.\nNone: Collider's mesh isn't updated."); |
|||
public static readonly GUIContent MeshCollider = new GUIContent(text: "Mesh Collider", tooltip: "The Mesh Collider to sync with the deformed mesh. To improve performance, try turning off different cooking options on the Mesh Collider (Especially 'Cook For Faster Simulation')."); |
|||
public static readonly GUIContent CustomBounds = new GUIContent(text: "Custom Bounds"); |
|||
public static readonly GUIContent ApplyBounds = new GUIContent(text: "Apply Bounds", tooltip: "Applies the currently recorded bounds."); |
|||
|
|||
public static readonly string ReadWriteNotEnableAlert = "Read/Write permissions must be enabled on the target mesh."; |
|||
public static readonly string StaticBatchingAlert = "Deformable will be stripped at runtime when static batching is enabled."; |
|||
public static readonly string FixReadWriteNotEnabled = "Fix It!"; |
|||
|
|||
public static readonly GUIContent[] UtilityToolbar = |
|||
{ |
|||
new GUIContent (text: "Clear", tooltip: "Remove all deformers from the deformer list."), |
|||
new GUIContent (text: "Clean", tooltip: "Remove all null deformers from the deformer list."), |
|||
new GUIContent (text: "Save Obj", tooltip: "Save the current mesh as a .obj file in the project. (Doesn't support vertex colors)"), |
|||
new GUIContent (text: "Save Asset", tooltip: "Save the current mesh as a mesh asset file in the project.") |
|||
}; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty UpdateMode; |
|||
public SerializedProperty CullingMode; |
|||
public SerializedProperty StripMode; |
|||
public SerializedProperty NormalsRecalculation; |
|||
public SerializedProperty BoundsRecalculation; |
|||
public SerializedProperty ColliderRecalculation; |
|||
public SerializedProperty MeshCollider; |
|||
public SerializedProperty CustomBounds; |
|||
|
|||
public Properties(SerializedObject obj) |
|||
{ |
|||
UpdateMode = obj.FindProperty("updateMode"); |
|||
CullingMode = obj.FindProperty("cullingMode"); |
|||
StripMode = obj.FindProperty("stripMode"); |
|||
NormalsRecalculation = obj.FindProperty("normalsRecalculation"); |
|||
BoundsRecalculation = obj.FindProperty("boundsRecalculation"); |
|||
ColliderRecalculation = obj.FindProperty("colliderRecalculation"); |
|||
MeshCollider = obj.FindProperty("meshCollider"); |
|||
CustomBounds = obj.FindProperty("customBounds"); |
|||
} |
|||
} |
|||
|
|||
protected Action overrideCullingModeGUI; |
|||
protected Action overrideStripModeGUI; |
|||
|
|||
private Properties properties; |
|||
private ReorderableComponentElementList<Deformer> deformerList; |
|||
|
|||
private static bool foldoutDebug; |
|||
private GUIContent record; |
|||
private GUIStyle redBox; |
|||
private bool recording; |
|||
|
|||
protected virtual void OnEnable() |
|||
{ |
|||
record = new GUIContent(DeformEditorResources.GetTexture("Record", false), "Record current bounds"); |
|||
properties = new Properties(serializedObject); |
|||
|
|||
deformerList = new ReorderableComponentElementList<Deformer>(serializedObject, serializedObject.FindProperty("deformerElements")); |
|||
} |
|||
|
|||
protected virtual void OnDisable() |
|||
{ |
|||
deformerList.Dispose(); |
|||
} |
|||
|
|||
public override void OnInspectorGUI() |
|||
{ |
|||
serializedObject.UpdateIfRequiredOrScript(); |
|||
|
|||
DrawMainSettings(); |
|||
EditorGUILayout.Space(); |
|||
DrawDeformersList(); |
|||
EditorGUILayout.Space(); |
|||
DrawUtilityToolbar(); |
|||
EditorGUILayout.Space(); |
|||
DrawDebugInfo(); |
|||
DrawHelpBoxes(); |
|||
|
|||
if (serializedObject.ApplyModifiedProperties()) |
|||
EditorApplication.QueuePlayerLoopUpdate(); |
|||
} |
|||
|
|||
protected virtual void DrawMainSettings() |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope()) |
|||
{ |
|||
EditorGUILayout.PropertyField(properties.UpdateMode, Content.UpdateMode); |
|||
if (check.changed) |
|||
{ |
|||
serializedObject.ApplyModifiedProperties(); |
|||
foreach (var t in targets) |
|||
((Deformable)t).UpdateMode = (UpdateMode)properties.UpdateMode.enumValueIndex; |
|||
} |
|||
} |
|||
|
|||
if (overrideCullingModeGUI != null) |
|||
overrideCullingModeGUI.Invoke(); |
|||
else |
|||
EditorGUILayout.PropertyField(properties.CullingMode, Content.CullingMode); |
|||
|
|||
if (overrideStripModeGUI != null) |
|||
overrideStripModeGUI.Invoke(); |
|||
else |
|||
{ |
|||
var batchingStatic = targets.Select(t => ((Deformable)t).gameObject).Any(go => |
|||
GameObjectUtility.AreStaticEditorFlagsSet(go, StaticEditorFlags.BatchingStatic)); |
|||
if (!batchingStatic) |
|||
{ |
|||
using (new EditorGUI.DisabledScope(Application.isPlaying)) |
|||
EditorGUILayout.PropertyField(properties.StripMode, Content.StripMode); |
|||
} |
|||
else |
|||
using (new EditorGUI.DisabledScope(true)) |
|||
{ |
|||
EditorGUILayout.EnumPopup(Content.StripMode, StripMode.Strip); |
|||
EditorGUILayout.HelpBox(new GUIContent(Content.StaticBatchingAlert)); |
|||
} |
|||
} |
|||
|
|||
EditorGUILayout.PropertyField(properties.NormalsRecalculation, Content.NormalsRecalculation); |
|||
EditorGUILayout.PropertyField(properties.BoundsRecalculation, Content.BoundsRecalculation); |
|||
|
|||
if (properties.BoundsRecalculation.hasMultipleDifferentValues || (BoundsRecalculation)properties.BoundsRecalculation.enumValueIndex == BoundsRecalculation.Custom) |
|||
{ |
|||
if (target is Deformable deformable) |
|||
{ |
|||
var originalBackgroundColor = GUI.backgroundColor; |
|||
|
|||
var mesh = deformable.GetMesh(); |
|||
using (new EditorGUI.IndentLevelScope()) |
|||
using (new EditorGUILayout.HorizontalScope()) |
|||
{ |
|||
if (recording) |
|||
{ |
|||
GUI.backgroundColor = Color.red; |
|||
mesh.RecalculateBounds(); |
|||
var bounds = deformable.GetMesh().bounds; |
|||
EditorGUILayout.BoundsField(properties.CustomBounds.displayName, bounds); |
|||
GUI.backgroundColor = originalBackgroundColor; |
|||
} |
|||
else |
|||
{ |
|||
EditorGUILayout.PropertyField(properties.CustomBounds, Content.CustomBounds); |
|||
} |
|||
|
|||
var buttonStyle = ((GUIStyle) "button"); |
|||
|
|||
var boundsLabelSize = EditorStyles.label.CalcSize(Content.CustomBounds); |
|||
var recordRect = GUILayoutUtility.GetLastRect(); |
|||
recordRect.xMin += boundsLabelSize.x + 6; |
|||
recordRect = EditorGUI.IndentedRect(recordRect); |
|||
var recordSize = buttonStyle.CalcSize(record); |
|||
recordRect.width = recordSize.x; |
|||
recordRect.height = recordSize.y; |
|||
|
|||
var wasRecording = recording; |
|||
if (recording = GUI.Toggle(recordRect, recording, record, buttonStyle)) |
|||
{ |
|||
var applyRect = recordRect; |
|||
var applySize = buttonStyle.CalcSize(Content.ApplyBounds); |
|||
applyRect.width = applySize.x; |
|||
applyRect.height = applySize.y; |
|||
applyRect.position += Vector2.right * (recordRect.width + 6); |
|||
|
|||
if (GUI.Button(applyRect, Content.ApplyBounds)) |
|||
{ |
|||
Undo.RecordObjects(targets, "Apply Recorded Bounds"); |
|||
recording = false; |
|||
foreach (var t in targets) |
|||
{ |
|||
if (!(t is Deformable d)) continue; |
|||
var m = d.GetMesh(); |
|||
m.RecalculateBounds(); |
|||
d.CustomBounds = m.bounds; |
|||
} |
|||
} |
|||
} |
|||
|
|||
GUI.backgroundColor = originalBackgroundColor; |
|||
|
|||
if (wasRecording != recording) |
|||
SceneView.RepaintAll(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
EditorGUILayout.PropertyField(properties.ColliderRecalculation, Content.ColliderRecalculation); |
|||
if (properties.ColliderRecalculation.hasMultipleDifferentValues || (ColliderRecalculation)properties.ColliderRecalculation.enumValueIndex == ColliderRecalculation.Auto) |
|||
{ |
|||
using (new EditorGUI.IndentLevelScope()) |
|||
EditorGUILayout.PropertyField(properties.MeshCollider, Content.MeshCollider); |
|||
} |
|||
} |
|||
|
|||
protected virtual void DrawDeformersList() |
|||
{ |
|||
deformerList.DoLayoutList(); |
|||
|
|||
var newDeformers = EditorGUILayoutx.DragAndDropArea<Deformer>(); |
|||
if (newDeformers != null && newDeformers.Count > 0) |
|||
{ |
|||
Undo.RecordObjects(targets, "Added Deformers"); |
|||
foreach (var t in targets) |
|||
{ |
|||
var elements = ((Deformable)t).DeformerElements; |
|||
foreach (var newDeformer in newDeformers) |
|||
elements.Add(new DeformerElement(newDeformer)); |
|||
} |
|||
|
|||
// I'd like to give a massive thanks and credit to Thomas Ingram for taking time out of his day to
|
|||
// solve an abomination of a bug and find this fix. He truly is an editor scripting legend.
|
|||
// Changing fields directly with multiple objects selected doesn't dirty the serialized object for some reason.
|
|||
// To force it to be dirty you have to call this method.
|
|||
serializedObject.SetIsDifferentCacheDirty(); |
|||
serializedObject.Update(); |
|||
} |
|||
} |
|||
|
|||
protected virtual void DrawUtilityToolbar() |
|||
{ |
|||
using (new EditorGUILayout.HorizontalScope()) |
|||
{ |
|||
var selectedIndex = GUILayout.Toolbar(-1, Content.UtilityToolbar, EditorStyles.miniButton, GUILayout.MinWidth(0)); |
|||
switch (selectedIndex) |
|||
{ |
|||
default: |
|||
throw new System.ArgumentException($"No valid action for toolbar index {selectedIndex}."); |
|||
case -1: |
|||
break; |
|||
case 0: |
|||
Undo.RecordObjects(targets, "Cleared Deformers"); |
|||
foreach (var t in targets) |
|||
((Deformable)t).DeformerElements.Clear(); |
|||
break; |
|||
case 1: |
|||
Undo.RecordObjects(targets, "Cleaned Deformers"); |
|||
foreach (var t in targets) |
|||
((Deformable)t).DeformerElements.RemoveAll(d => d.Component == null); |
|||
break; |
|||
case 2: |
|||
foreach (var t in targets) |
|||
{ |
|||
var deformable = t as Deformable; |
|||
|
|||
// C:/...<ProjectName>/Assets/
|
|||
var projectPath = Application.dataPath + "/"; |
|||
var assetPath = EditorUtility.SaveFilePanelInProject("Save Obj", $"{deformable.name}.obj", "obj", ""); |
|||
if (string.IsNullOrEmpty(assetPath)) |
|||
break; |
|||
var fileName = assetPath; |
|||
// Now that we have a unique asset path we can remove the "Assets/" and ".obj" to get the unique name.
|
|||
// It's pretty gross, but it works and this code doesn't need to be performant.
|
|||
fileName = fileName.Remove(0, 7); |
|||
fileName = fileName.Remove(fileName.Length - 4, 4); |
|||
|
|||
ObjExporter.SaveMesh(deformable.GetMesh(), deformable.GetRenderer(), projectPath, fileName); |
|||
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); |
|||
} |
|||
break; |
|||
case 3: |
|||
foreach (var t in targets) |
|||
{ |
|||
var deformable = t as Deformable; |
|||
|
|||
var assetPath = EditorUtility.SaveFilePanelInProject("Save Mesh Asset", $"{deformable.name}.asset", "asset", ""); |
|||
if (string.IsNullOrEmpty(assetPath)) |
|||
break; |
|||
|
|||
AssetDatabase.CreateAsset(Instantiate(deformable.GetMesh()), assetPath); |
|||
AssetDatabase.SaveAssets(); |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected virtual void DrawDebugInfo() |
|||
{ |
|||
if (foldoutDebug = EditorGUILayoutx.FoldoutHeader("Debug Info", foldoutDebug)) |
|||
{ |
|||
var vertexCount = 0; |
|||
var modifiedData = DataFlags.None; |
|||
var bounds = (target as Deformable).GetCurrentMesh().bounds; |
|||
foreach (var t in targets) |
|||
{ |
|||
var deformable = t as Deformable; |
|||
var mesh = deformable.GetMesh(); |
|||
|
|||
if (mesh != null) |
|||
vertexCount += deformable.GetMesh().vertexCount; |
|||
modifiedData |= deformable.ModifiedDataFlags; |
|||
} |
|||
|
|||
EditorGUILayout.LabelField($"Vertex Count: {vertexCount}", Styles.WrappedLabel); |
|||
EditorGUILayout.LabelField($"Modified Data: {modifiedData.ToString()}", Styles.WrappedLabel); |
|||
EditorGUILayout.LabelField($"Bounds: {bounds.ToString()}", Styles.WrappedLabel); |
|||
} |
|||
} |
|||
|
|||
protected virtual void DrawHelpBoxes() |
|||
{ |
|||
foreach (var t in targets) |
|||
{ |
|||
var deformable = t as Deformable; |
|||
|
|||
var originalMesh = deformable.GetOriginalMesh(); |
|||
if (originalMesh != null && !originalMesh.isReadable) |
|||
{ |
|||
using (new EditorGUILayout.HorizontalScope()) |
|||
{ |
|||
EditorGUILayout.HelpBox(Content.ReadWriteNotEnableAlert, MessageType.Error); |
|||
if (GUILayout.Button(Content.FixReadWriteNotEnabled, GUILayout.Width(50f), GUILayout.Height(EditorGUIUtility.singleLineHeight * 2f + EditorGUIUtility.standardVerticalSpacing))) |
|||
{ |
|||
if (AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(originalMesh)) is ModelImporter importer) |
|||
{ |
|||
importer.isReadable = true; |
|||
importer.SaveAndReimport(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected virtual void OnSceneGUI() |
|||
{ |
|||
if (!(target is Deformable deformable)) |
|||
return; |
|||
if (recording) |
|||
{ |
|||
deformable.GetCurrentMesh().RecalculateBounds(); |
|||
DeformHandles.Bounds(deformable.GetCurrentMesh().bounds, deformable.transform.localToWorldMatrix, DeformHandles.LineMode.SolidDotted, DeformEditorSettings.RecordingHandleColor); |
|||
} |
|||
else if (foldoutDebug || deformable.BoundsRecalculation == BoundsRecalculation.Custom) |
|||
{ |
|||
DeformHandles.Bounds(deformable.GetCurrentMesh().bounds, deformable.transform.localToWorldMatrix, DeformHandles.LineMode.LightDotted); |
|||
} |
|||
} |
|||
|
|||
[MenuItem("CONTEXT/Deformable/Strip")] |
|||
private static void Strip(MenuCommand command) |
|||
{ |
|||
var deformable = (Deformable)command.context; |
|||
|
|||
Undo.SetCurrentGroupName("Strip Selected Deformables"); |
|||
Undo.RecordObject(deformable, "Changed Assign Original Mesh On Disable"); |
|||
deformable.assignOriginalMeshOnDisable = false; |
|||
Undo.DestroyObjectImmediate(deformable); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: ea27e5d942c6b434a8195f27a7913f07 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,44 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (Deformer), false), CanEditMultipleObjects] |
|||
public class DeformerEditor : Editor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Update = new GUIContent (text: "Update"); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Update; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Update = obj.FindProperty ("update"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected virtual void OnEnable () |
|||
{ |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Update, Content.Update); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public virtual void OnSceneGUI () { } |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3654d68a8756a0c49acf1b696d66bb97 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 259b58c482bab884f93dd0627d16beea |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,140 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using UnityEditor.IMGUI.Controls; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (BendDeformer)), CanEditMultipleObjects] |
|||
public class BendDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Angle = new GUIContent (text: "Angle", tooltip: "How many degrees the mesh should be bent by the time it reaches the top bounds."); |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Top = new GUIContent (text: "Top", tooltip: "Any vertices above this will have been fully bent."); |
|||
public static readonly GUIContent Bottom = new GUIContent (text: "Bottom", tooltip: "Any vertices below this will be fully unbent."); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Angle; |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Mode; |
|||
public SerializedProperty Top; |
|||
public SerializedProperty TopMode; |
|||
public SerializedProperty Bottom; |
|||
public SerializedProperty BottomMode; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Angle = obj.FindProperty ("angle"); |
|||
Factor = obj.FindProperty ("factor"); |
|||
Top = obj.FindProperty ("top"); |
|||
TopMode = obj.FindProperty ("topMode"); |
|||
Bottom = obj.FindProperty ("bottom"); |
|||
BottomMode = obj.FindProperty ("bottomMode"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
private readonly ArcHandle angleHandle = new ArcHandle (); |
|||
private readonly VerticalBoundsHandle boundsHandle = new VerticalBoundsHandle (); |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
|
|||
properties = new Properties (serializedObject); |
|||
|
|||
boundsHandle.HandleCapFunction = DeformHandles.HandleCapFunction; |
|||
boundsHandle.DrawGuidelineCallback = (a, b) => DeformHandles.Line (a, b, DeformHandles.LineMode.LightDotted); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Angle, Content.Angle); |
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
|
|||
using (new EditorGUILayout.HorizontalScope()) |
|||
{ |
|||
EditorGUILayoutx.MinField(properties.Top, properties.Bottom.floatValue, Content.Top); |
|||
EditorGUILayout.PropertyField(properties.TopMode, GUIContent.none, GUILayout.Width(75)); |
|||
} |
|||
using (new EditorGUILayout.HorizontalScope()) |
|||
{ |
|||
EditorGUILayoutx.MaxField(properties.Bottom, properties.Top.floatValue, Content.Bottom); |
|||
EditorGUILayout.PropertyField(properties.BottomMode, GUIContent.none, GUILayout.Width(75)); |
|||
} |
|||
|
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var bend = target as BendDeformer; |
|||
|
|||
DrawAngleHandle (bend); |
|||
|
|||
boundsHandle.HandleColor = DeformEditorSettings.SolidHandleColor; |
|||
boundsHandle.ScreenspaceHandleSize = DeformEditorSettings.ScreenspaceSliderHandleCapSize; |
|||
if (boundsHandle.DrawHandle (bend.Top, bend.Bottom, bend.Axis, Vector3.up)) |
|||
{ |
|||
Undo.RecordObject (bend, "Changed Bounds"); |
|||
bend.Top = boundsHandle.Top; |
|||
bend.Bottom = boundsHandle.Bottom; |
|||
} |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawAngleHandle (BendDeformer bend) |
|||
{ |
|||
var handleRotation = bend.Axis.rotation * Quaternion.Euler (-90, 0f, 0f); |
|||
// There's some weird issue where if you pass the normal lossyScale, the handle's scale on the y axis is changed when the transform's z axis is changed.
|
|||
// My simple solution is to swap the y and z.
|
|||
var handleScale = new Vector3 |
|||
( |
|||
x: bend.Axis.lossyScale.x, |
|||
y: bend.Axis.lossyScale.z, |
|||
z: bend.Axis.lossyScale.y |
|||
); |
|||
|
|||
var matrix = Matrix4x4.TRS (bend.Axis.position + bend.Axis.up * bend.Bottom * bend.Axis.lossyScale.y, handleRotation, handleScale); |
|||
|
|||
var radiusDistanceOffset = HandleUtility.GetHandleSize (bend.Axis.position + bend.Axis.up * bend.Top) * DeformEditorSettings.ScreenspaceSliderHandleCapSize * 2f; |
|||
|
|||
angleHandle.angle = bend.Angle; |
|||
angleHandle.radius = (bend.Top - bend.Bottom) + radiusDistanceOffset; |
|||
angleHandle.fillColor = Color.clear; |
|||
|
|||
using (new Handles.DrawingScope (DeformEditorSettings.SolidHandleColor, matrix)) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
angleHandle.DrawHandle (); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (bend, "Changed Angle"); |
|||
bend.Angle = angleHandle.angle; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 42b020e8b4018f248bb26e6fa52afc46 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,62 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
using Beans.Unity.Editor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (BlendDeformer)), CanEditMultipleObjects] |
|||
public class BlendDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Cache = new GUIContent (text: "Cache", tooltip: "The vertex cache to blend towards. It must have the same vertex count as the deformable."); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Cache; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Cache = obj.FindProperty ("cache"); |
|||
} |
|||
} |
|||
|
|||
Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
UnityEditor.EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
|
|||
using (var check = new UnityEditor.EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
UnityEditor.EditorGUILayout.ObjectField (properties.Cache, Content.Cache); |
|||
if (check.changed) |
|||
{ |
|||
// need to apply properties early if the cache was changed so that cache's value change occurs before Initialize()
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
foreach (var t in targets) |
|||
((BlendDeformer)t).Initialize (); |
|||
} |
|||
} |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 11512545e091ff142bd5b986d85278ef |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,141 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using UnityEditor.IMGUI.Controls; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (BoundedBendDeformer)), CanEditMultipleObjects] |
|||
public class BoundedBendDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Angle = new GUIContent (text: "Angle", tooltip: "How many degrees the mesh should be bent by the time it reaches the top bounds."); |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Mode = new GUIContent (text: "Mode", tooltip: "Unlimited: Entire mesh is bent.\nLimited: Mesh is only bent between bounds."); |
|||
public static readonly GUIContent Bounds = new GUIContent (text: "Bounds", tooltip: "Any vertices outside this will be fully unbent."); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Angle; |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Mode; |
|||
public SerializedProperty Bounds; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Angle = obj.FindProperty ("angle"); |
|||
Factor = obj.FindProperty ("factor"); |
|||
Mode = obj.FindProperty ("mode"); |
|||
Bounds = obj.FindProperty ("bounds"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
private ArcHandle angleHandle = new ArcHandle (); |
|||
//private readonly VerticalBoundsHandle boundsHandle = new VerticalBoundsHandle ();
|
|||
private BoxBoundsHandle boxHandle = new BoxBoundsHandle(); |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
|
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Angle, Content.Angle); |
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.Mode, Content.Mode); |
|||
|
|||
using (new EditorGUI.IndentLevelScope ()) |
|||
{ |
|||
EditorGUILayout.PropertyField(properties.Bounds, Content.Bounds); |
|||
} |
|||
|
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorGUILayoutx.WIPAlert(); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var bend = target as BoundedBendDeformer; |
|||
|
|||
DrawAngleHandle (bend); |
|||
|
|||
boxHandle.handleColor = DeformEditorSettings.SolidHandleColor; |
|||
boxHandle.wireframeColor = DeformEditorSettings.LightHandleColor; |
|||
boxHandle.center = bend.Bounds.center; |
|||
boxHandle.size = bend.Bounds.size; |
|||
|
|||
using (new Handles.DrawingScope(Matrix4x4.TRS(bend.Axis.position, bend.Axis.rotation, bend.Axis.lossyScale))) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope()) |
|||
{ |
|||
boxHandle.DrawHandle(); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject(bend, "Changed Bounds"); |
|||
bend.Bounds = new Bounds(boxHandle.center, boxHandle.size); |
|||
SceneView.RepaintAll(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawAngleHandle (BoundedBendDeformer bend) |
|||
{ |
|||
|
|||
var handleRotation = bend.Axis.rotation * Quaternion.Euler (-90, 0f, 0f); |
|||
// There's some weird issue where if you pass the normal lossyScale, the handle's scale on the y axis is changed when the transform's z axis is changed.
|
|||
// My simple solution is to swap the y and z.
|
|||
var handleScale = new Vector3 |
|||
( |
|||
x: bend.Axis.lossyScale.x, |
|||
y: bend.Axis.lossyScale.z, |
|||
z: bend.Axis.lossyScale.y |
|||
); |
|||
|
|||
var matrix = Matrix4x4.TRS (bend.Axis.position + bend.Axis.up * bend.Bounds.min.y * bend.Axis.lossyScale.y, handleRotation, handleScale); |
|||
|
|||
var radiusDistanceOffset = HandleUtility.GetHandleSize (bend.Axis.position + bend.Axis.up * bend.Bounds.max.y) * DeformEditorSettings.ScreenspaceSliderHandleCapSize * 2f; |
|||
|
|||
angleHandle.angle = bend.Angle; |
|||
angleHandle.radius = (bend.Bounds.max.y - bend.Bounds.min.y) + radiusDistanceOffset; |
|||
angleHandle.fillColor = Color.clear; |
|||
|
|||
using (new Handles.DrawingScope (DeformEditorSettings.SolidHandleColor, matrix)) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
angleHandle.DrawHandle (); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (bend, "Changed Angle"); |
|||
bend.Angle = angleHandle.angle; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 4562d8782226229409063ab4eed40058 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,109 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (BulgeDeformer)), CanEditMultipleObjects] |
|||
public class BulgeDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Top = DeformEditorGUIUtility.DefaultContent.Top; |
|||
public static readonly GUIContent Bottom = DeformEditorGUIUtility.DefaultContent.Bottom; |
|||
public static readonly GUIContent Smooth = DeformEditorGUIUtility.DefaultContent.Smooth; |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Top; |
|||
public SerializedProperty Bottom; |
|||
public SerializedProperty Smooth; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Top = obj.FindProperty ("top"); |
|||
Bottom = obj.FindProperty ("bottom"); |
|||
Smooth = obj.FindProperty ("smooth"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
private VerticalBoundsHandle boundsHandle = new VerticalBoundsHandle (); |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
|
|||
properties = new Properties (serializedObject); |
|||
|
|||
boundsHandle.HandleCapFunction = DeformHandles.HandleCapFunction; |
|||
boundsHandle.DrawGuidelineCallback = (a, b) => DeformHandles.Line (a, b, DeformHandles.LineMode.LightDotted); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayoutx.MinField (properties.Top, properties.Bottom.floatValue, Content.Top); |
|||
EditorGUILayoutx.MaxField (properties.Bottom, properties.Top.floatValue, Content.Bottom); |
|||
EditorGUILayout.PropertyField (properties.Smooth, Content.Smooth); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var bulge = target as BulgeDeformer; |
|||
|
|||
DrawFactorHandle (bulge); |
|||
|
|||
boundsHandle.HandleColor = DeformEditorSettings.SolidHandleColor; |
|||
boundsHandle.ScreenspaceHandleSize = DeformEditorSettings.ScreenspaceSliderHandleCapSize; |
|||
if (boundsHandle.DrawHandle (bulge.Top, bulge.Bottom, bulge.Axis, Vector3.forward)) |
|||
{ |
|||
Undo.RecordObject (bulge, "Changed Bounds"); |
|||
bulge.Top = boundsHandle.Top; |
|||
bulge.Bottom = boundsHandle.Bottom; |
|||
} |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawFactorHandle (BulgeDeformer bulge) |
|||
{ |
|||
var direction = bulge.Axis.up; |
|||
|
|||
var center = bulge.Axis.position + (bulge.Axis.forward * ((bulge.Top + bulge.Bottom) * 0.5f)); |
|||
var worldPosition = center + direction * ((bulge.Factor + 1f) * 0.5f); |
|||
|
|||
DeformHandles.Line (center, worldPosition, DeformHandles.LineMode.LightDotted); |
|||
|
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var newWorldPosition = DeformHandles.Slider (worldPosition, direction); |
|||
if (check.changed) |
|||
{ |
|||
var newFactor = DeformHandlesUtility.DistanceAlongAxis (bulge.Axis, bulge.Axis.position, newWorldPosition, Axis.Y) * 2f - 1f; |
|||
Undo.RecordObject (bulge, "Changed Factor"); |
|||
bulge.Factor = newFactor; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 946b50fe2453b234f874645e88a269d7 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,102 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using UnityEditor.IMGUI.Controls; |
|||
using Deform; |
|||
using Beans.Unity.Editor; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (CubifyDeformer)), CanEditMultipleObjects] |
|||
public class CubifyDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Width = new GUIContent (text: "Width", tooltip: "The width of the cube."); |
|||
public static readonly GUIContent Height = new GUIContent (text: "Height", tooltip: "The height of the cube."); |
|||
public static readonly GUIContent Length = new GUIContent (text: "Length", tooltip: "The length of the cube."); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Width; |
|||
public SerializedProperty Height; |
|||
public SerializedProperty Length; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Width = obj.FindProperty ("width"); |
|||
Height = obj.FindProperty ("height"); |
|||
Length = obj.FindProperty ("length"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
private BoxBoundsHandle boundsHandle = new BoxBoundsHandle (); |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.Width, Content.Width); |
|||
EditorGUILayout.PropertyField (properties.Height, Content.Height); |
|||
EditorGUILayout.PropertyField (properties.Length, Content.Length); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorGUILayoutx.WIPAlert (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var cubify = target as CubifyDeformer; |
|||
|
|||
DrawBoundsHandle (cubify); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawBoundsHandle (CubifyDeformer cubify) |
|||
{ |
|||
boundsHandle.handleColor = DeformEditorSettings.SolidHandleColor; |
|||
boundsHandle.wireframeColor = DeformEditorSettings.LightHandleColor; |
|||
boundsHandle.center = Vector3.zero; |
|||
boundsHandle.size = new Vector3 (cubify.Width, cubify.Height, cubify.Length); |
|||
|
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (cubify.Axis.position, cubify.Axis.rotation, cubify.Axis.lossyScale))) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
boundsHandle.DrawHandle (); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (cubify, "Changed Size"); |
|||
cubify.Width = boundsHandle.size.x; |
|||
cubify.Height = boundsHandle.size.y; |
|||
cubify.Length = boundsHandle.size.z; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3ee5282b793ce644199c8b7635a9e888 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,70 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (CurveDisplaceDeformer)), CanEditMultipleObjects] |
|||
public class CurveDisplaceDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Offset = new GUIContent (text: "Offset"); |
|||
public static readonly GUIContent Curve = new GUIContent (text: "Curve"); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Offset; |
|||
public SerializedProperty Curve; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Offset = obj.FindProperty ("offset"); |
|||
Curve = obj.FindProperty ("curve"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
|
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.Offset, Content.Offset); |
|||
EditorGUILayout.PropertyField (properties.Curve, Content.Curve); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var curveDisplace = target as CurveDisplaceDeformer; |
|||
|
|||
if (curveDisplace.Curve == null || curveDisplace.Curve.length < 1) |
|||
return; |
|||
DeformHandles.Curve (curveDisplace.Curve, curveDisplace.Axis, curveDisplace.Factor, curveDisplace.Offset, 0f); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 854dbd972d4677246927ca411c9301f1 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,72 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (CurveScaleDeformer)), CanEditMultipleObjects] |
|||
public class CurveScaleDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Bias = new GUIContent (text: "Bias"); |
|||
public static readonly GUIContent Offset = new GUIContent (text: "Offset"); |
|||
public static readonly GUIContent Curve = new GUIContent (text: "Curve"); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Bias; |
|||
public SerializedProperty Offset; |
|||
public SerializedProperty Curve; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Bias = obj.FindProperty ("bias"); |
|||
Offset = obj.FindProperty ("offset"); |
|||
Curve = obj.FindProperty ("curve"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.Bias, Content.Bias); |
|||
EditorGUILayout.PropertyField (properties.Offset, Content.Offset); |
|||
EditorGUILayout.PropertyField (properties.Curve, Content.Curve); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var curveScale = target as CurveScaleDeformer; |
|||
|
|||
var handleScale = new Vector3 (1f, 1f, curveScale.Axis.lossyScale.z); |
|||
DeformHandles.Curve (curveScale.Curve, curveScale.Axis.position, curveScale.Axis.rotation, handleScale, curveScale.Factor * 0.5f, curveScale.Offset, curveScale.Bias * 0.5f); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 20c761f71d931364793c4a2fa75566c7 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,120 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (CylindrifyDeformer)), CanEditMultipleObjects] |
|||
public class CylindrifyDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Radius = new GUIContent (text: "Radius", tooltip: "The cylinder radius."); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Radius; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Radius = obj.FindProperty ("radius"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.Radius, Content.Radius); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
if (target == null) |
|||
return; |
|||
|
|||
var cylindrify = target as CylindrifyDeformer; |
|||
|
|||
DrawRadiusHandle (cylindrify); |
|||
DrawFactorHandle (cylindrify); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawFactorHandle (CylindrifyDeformer cylindrify) |
|||
{ |
|||
if (cylindrify.Radius == 0f) |
|||
return; |
|||
|
|||
var position = Vector3.up * cylindrify.Factor * cylindrify.Radius; |
|||
|
|||
var axis = cylindrify.Axis; |
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (axis.position, axis.rotation, axis.lossyScale))) |
|||
{ |
|||
DeformHandles.Line (position, Vector3.zero, DeformHandles.LineMode.Light); |
|||
DeformHandles.Line (position, Vector3.up * cylindrify.Radius, DeformHandles.LineMode.LightDotted); |
|||
|
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var newWorldPosition = DeformHandles.Slider (position, Vector3.up); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (cylindrify, "Changed Radius"); |
|||
cylindrify.Factor = newWorldPosition.y; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void DrawRadiusHandle (CylindrifyDeformer cylindrify) |
|||
{ |
|||
var position = Vector3.up * cylindrify.Radius; |
|||
|
|||
var axis = cylindrify.Axis; |
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (axis.position, axis.rotation, axis.lossyScale))) |
|||
{ |
|||
var size = HandleUtility.GetHandleSize (position) * DeformEditorSettings.ScreenspaceSliderHandleCapSize; |
|||
|
|||
DeformHandles.Circle (Vector3.zero, Vector3.forward, Vector3.up, cylindrify.Radius); |
|||
|
|||
DeformHandles.Line (position + Vector3.forward * size, position + Vector3.forward * size * 5f, DeformHandles.LineMode.Light); |
|||
DeformHandles.Line (position - Vector3.forward * size, position - Vector3.forward * size * 5f, DeformHandles.LineMode.Light); |
|||
|
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var newWorldPosition = DeformHandles.Slider (position, Vector3.up); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (cylindrify, "Changed Radius"); |
|||
cylindrify.Radius = cylindrify.Axis.position.y; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 458db85642e33fe488853d3393b4a919 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,50 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (InflateDeformer)), CanEditMultipleObjects] |
|||
public class InflateDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent UseUpdatedNormals = new GUIContent (text: "Use Updated Normals", tooltip: "When true, the normals will be recalculated before the vertices are inflated. This is an expensive operation and will result in a split where adjacent triangles don't share vertices."); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty UseUpdatedNormals; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
UseUpdatedNormals = obj.FindProperty ("useUpdatedNormals"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.UseUpdatedNormals, Content.UseUpdatedNormals); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: aef144dabdb2f9b4cb1571fcd6cbcfb1 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,71 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (LatheDisplaceDeformer)), CanEditMultipleObjects] |
|||
public class LatheDisplaceDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Bias = new GUIContent (text: "Bias"); |
|||
public static readonly GUIContent Offset = new GUIContent (text: "Offset"); |
|||
public static readonly GUIContent Curve = new GUIContent (text: "Curve"); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Bias; |
|||
public SerializedProperty Offset; |
|||
public SerializedProperty Curve; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Bias = obj.FindProperty ("bias"); |
|||
Offset = obj.FindProperty ("offset"); |
|||
Curve = obj.FindProperty ("curve"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayout.PropertyField (properties.Bias, Content.Bias); |
|||
EditorGUILayout.PropertyField (properties.Offset, Content.Offset); |
|||
EditorGUILayout.PropertyField (properties.Curve, Content.Curve); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var lathe = target as LatheDisplaceDeformer; |
|||
|
|||
DeformHandles.Curve (lathe.Curve, lathe.Axis, lathe.Factor * 0.5f, lathe.Offset, lathe.Bias * 0.5f); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 95a0f8b3c2326a44391c0a318983fc3c |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,582 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform; |
|||
using Unity.Mathematics; |
|||
using UnityEngine.Rendering; |
|||
using static Unity.Mathematics.math; |
|||
using float3 = Unity.Mathematics.float3; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor(typeof(LatticeDeformer))] |
|||
public class LatticeDeformerEditor : DeformerEditor |
|||
{ |
|||
private Vector3Int newResolution; |
|||
|
|||
private float3 handleScale = Vector3.one; |
|||
private Tool activeTool = Tool.None; |
|||
|
|||
enum MouseDragState |
|||
{ |
|||
NotActive, |
|||
Eligible, |
|||
InProgress |
|||
} |
|||
|
|||
private MouseDragState mouseDragState = MouseDragState.NotActive; |
|||
private Vector2 mouseDownPosition; |
|||
private int previousSelectionCount = 0; |
|||
|
|||
// Positions of selected points before a rotate or scale begins
|
|||
private List<float3> selectedOriginalPositions = new List<float3>(); |
|||
|
|||
// Positions and resolution before a resize
|
|||
private float3[] cachedResizePositions = new float3[0]; |
|||
private Vector3Int cachedResizeResolution; |
|||
|
|||
[SerializeField] private List<int> selectedIndices = new List<int>(); |
|||
|
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Resolution = new GUIContent(text: "Resolution", tooltip: "Per axis control point counts, the higher the resolution the more splits"); |
|||
public static readonly GUIContent Mode = new GUIContent(text: "Mode", tooltip: "Mode by which vertices are positioned between control points"); |
|||
public static readonly GUIContent StopEditing = new GUIContent(text: "Stop Editing Control Points", tooltip: "Restore normal transform tools\n\nShortcut: Escape"); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Resolution; |
|||
public SerializedProperty Mode; |
|||
|
|||
public Properties(SerializedObject obj) |
|||
{ |
|||
Resolution = obj.FindProperty("resolution"); |
|||
Mode = obj.FindProperty("mode"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable() |
|||
{ |
|||
base.OnEnable(); |
|||
|
|||
properties = new Properties(serializedObject); |
|||
|
|||
LatticeDeformer latticeDeformer = ((LatticeDeformer) target); |
|||
newResolution = latticeDeformer.Resolution; |
|||
CacheResizePositionsFromChange(); |
|||
|
|||
Undo.undoRedoPerformed += UndoRedoPerformed; |
|||
} |
|||
|
|||
private void UndoRedoPerformed() |
|||
{ |
|||
LatticeDeformer latticeDeformer = ((LatticeDeformer) target); |
|||
newResolution = latticeDeformer.Resolution; |
|||
CacheResizePositionsFromChange(); |
|||
} |
|||
|
|||
public override void OnInspectorGUI() |
|||
{ |
|||
base.OnInspectorGUI(); |
|||
|
|||
LatticeDeformer latticeDeformer = ((LatticeDeformer) target); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript(); |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
|
|||
EditorGUILayout.PropertyField(properties.Mode); |
|||
newResolution = EditorGUILayout.Vector3IntField(Content.Resolution, newResolution); |
|||
// Make sure we have at least two control points per axis
|
|||
newResolution = Vector3Int.Max(newResolution, new Vector3Int(2, 2, 2)); |
|||
// Don't let the lattice resolution get ridiculously high
|
|||
newResolution = Vector3Int.Min(newResolution, new Vector3Int(32, 32, 32)); |
|||
|
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
Undo.RecordObject(target, "Update Lattice"); |
|||
latticeDeformer.GenerateControlPoints(newResolution, cachedResizePositions, cachedResizeResolution); |
|||
selectedIndices.Clear(); |
|||
} |
|||
|
|||
if (GUILayout.Button("Reset Lattice Points")) |
|||
{ |
|||
Undo.RecordObject(target, "Reset Lattice Points"); |
|||
latticeDeformer.GenerateControlPoints(newResolution); |
|||
selectedIndices.Clear(); |
|||
|
|||
CacheResizePositionsFromChange(); |
|||
} |
|||
|
|||
if (latticeDeformer.CanAutoFitBounds) |
|||
{ |
|||
if (GUILayout.Button("Auto-Fit Bounds")) |
|||
{ |
|||
Undo.RecordObject(latticeDeformer.transform, "Auto-Fit Bounds"); |
|||
latticeDeformer.FitBoundsToParentDeformable(); |
|||
} |
|||
} |
|||
|
|||
serializedObject.ApplyModifiedProperties(); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate(); |
|||
} |
|||
|
|||
public override void OnSceneGUI() |
|||
{ |
|||
base.OnSceneGUI(); |
|||
|
|||
LatticeDeformer lattice = target as LatticeDeformer; |
|||
Transform transform = lattice.transform; |
|||
float3[] controlPoints = lattice.ControlPoints; |
|||
Event e = Event.current; |
|||
|
|||
using (new Handles.DrawingScope(transform.localToWorldMatrix)) |
|||
{ |
|||
var cachedZTest = Handles.zTest; |
|||
|
|||
// Change the depth testing to only show handles in front of solid objects (i.e. typical depth testing)
|
|||
Handles.zTest = CompareFunction.LessEqual; |
|||
DrawLattice(lattice, DeformHandles.LineMode.Solid); |
|||
// Change the depth testing to only show handles *behind* solid objects
|
|||
Handles.zTest = CompareFunction.Greater; |
|||
DrawLattice(lattice, DeformHandles.LineMode.Light); |
|||
|
|||
// Restore the original z test value now we're done with our drawing
|
|||
Handles.zTest = cachedZTest; |
|||
|
|||
var resolution = lattice.Resolution; |
|||
for (int z = 0; z < resolution.z; z++) |
|||
{ |
|||
for (int y = 0; y < resolution.y; y++) |
|||
{ |
|||
for (int x = 0; x < resolution.x; x++) |
|||
{ |
|||
var controlPointHandleID = GUIUtility.GetControlID("LatticeDeformerControlPoint".GetHashCode(), FocusType.Passive); |
|||
var activeColor = DeformEditorSettings.SolidHandleColor; |
|||
var controlPointIndex = lattice.GetIndex(x, y, z); |
|||
|
|||
if (GUIUtility.hotControl == controlPointHandleID || selectedIndices.Contains(controlPointIndex)) |
|||
{ |
|||
activeColor = Handles.selectedColor; |
|||
} |
|||
else if (HandleUtility.nearestControl == controlPointHandleID) |
|||
{ |
|||
activeColor = Handles.preselectionColor; |
|||
} |
|||
|
|||
if (e.type == EventType.MouseDown && HandleUtility.nearestControl == controlPointHandleID && e.button == 0 && MouseActionAllowed) |
|||
{ |
|||
BeginSelectionChangeRegion(); |
|||
GUIUtility.hotControl = controlPointHandleID; |
|||
GUIUtility.keyboardControl = controlPointHandleID; |
|||
e.Use(); |
|||
|
|||
bool modifierKeyPressed = e.control || e.shift || e.command; |
|||
|
|||
if (modifierKeyPressed && selectedIndices.Contains(controlPointIndex)) |
|||
{ |
|||
// Pressed a modifier key so toggle the selection
|
|||
selectedIndices.Remove(controlPointIndex); |
|||
} |
|||
else |
|||
{ |
|||
if (!modifierKeyPressed) |
|||
{ |
|||
selectedIndices.Clear(); |
|||
} |
|||
|
|||
if (!selectedIndices.Contains(controlPointIndex)) |
|||
{ |
|||
selectedIndices.Add(controlPointIndex); |
|||
} |
|||
} |
|||
|
|||
EndSelectionChangeRegion(); |
|||
} |
|||
|
|||
if (Tools.current != Tool.None && selectedIndices.Count != 0) |
|||
{ |
|||
// If the user changes tool, change our internal mode to match but disable the corresponding Unity tool
|
|||
// (e.g. they hit W key or press on the Rotate Tool button on the top left toolbar)
|
|||
activeTool = Tools.current; |
|||
Tools.current = Tool.None; |
|||
} |
|||
|
|||
using (new Handles.DrawingScope(activeColor)) |
|||
{ |
|||
var position = controlPoints[controlPointIndex]; |
|||
var size = HandleUtility.GetHandleSize(position) * DeformEditorSettings.ScreenspaceLatticeHandleCapSize; |
|||
|
|||
Handles.DotHandleCap( |
|||
controlPointHandleID, |
|||
position, |
|||
Quaternion.identity, |
|||
size, |
|||
e.type); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
var defaultControl = DeformUnityObjectSelection.DisableSceneViewObjectSelection(); |
|||
|
|||
if (selectedIndices.Count != 0) |
|||
{ |
|||
var currentPivotPosition = float3.zero; |
|||
|
|||
if (Tools.pivotMode == PivotMode.Center) |
|||
{ |
|||
// Get the average position
|
|||
foreach (var index in selectedIndices) |
|||
{ |
|||
currentPivotPosition += controlPoints[index]; |
|||
} |
|||
|
|||
currentPivotPosition /= selectedIndices.Count; |
|||
} |
|||
else |
|||
{ |
|||
// Match the scene view behaviour that Pivot mode uses the last selected object as pivot
|
|||
currentPivotPosition = controlPoints[selectedIndices.Last()]; |
|||
} |
|||
|
|||
float3 handlePosition = transform.TransformPoint(currentPivotPosition); |
|||
|
|||
if (e.type == EventType.MouseDown) |
|||
{ |
|||
// Potentially started interacting with a handle so reset everything
|
|||
handleScale = Vector3.one; |
|||
// Make sure we cache the positions just before the interaction changes them
|
|||
CacheOriginalPositions(); |
|||
} |
|||
|
|||
var originalPivotPosition = float3.zero; |
|||
|
|||
if (Tools.pivotMode == PivotMode.Center) |
|||
{ |
|||
// Get the average position
|
|||
foreach (var originalPosition in selectedOriginalPositions) |
|||
{ |
|||
originalPivotPosition += originalPosition; |
|||
} |
|||
|
|||
originalPivotPosition /= selectedIndices.Count; |
|||
} |
|||
else |
|||
{ |
|||
// Match the scene view behaviour that Pivot mode uses the last selected object as pivot
|
|||
originalPivotPosition = selectedOriginalPositions.LastOrDefault(); |
|||
} |
|||
|
|||
var handleRotation = transform.rotation; |
|||
if (Tools.pivotRotation == PivotRotation.Global) |
|||
{ |
|||
handleRotation = Quaternion.identity; |
|||
} |
|||
|
|||
if (activeTool == Tool.Move) |
|||
{ |
|||
EditorGUI.BeginChangeCheck(); |
|||
float3 newPosition = Handles.PositionHandle(handlePosition, handleRotation); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
Undo.RecordObject(target, "Update Lattice"); |
|||
|
|||
var delta = newPosition - handlePosition; |
|||
delta = transform.InverseTransformVector(delta); |
|||
foreach (var selectedIndex in selectedIndices) |
|||
{ |
|||
controlPoints[selectedIndex] += delta; |
|||
} |
|||
|
|||
CacheResizePositionsFromChange(); |
|||
} |
|||
} |
|||
else if (activeTool == Tool.Rotate) |
|||
{ |
|||
EditorGUI.BeginChangeCheck(); |
|||
quaternion newRotation = Handles.RotationHandle(handleRotation, handlePosition); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
Undo.RecordObject(target, "Update Lattice"); |
|||
|
|||
for (var index = 0; index < selectedIndices.Count; index++) |
|||
{ |
|||
if (Tools.pivotRotation == PivotRotation.Global) |
|||
{ |
|||
controlPoints[selectedIndices[index]] = originalPivotPosition + (float3) transform.InverseTransformDirection(mul(newRotation, transform.TransformDirection(selectedOriginalPositions[index] - originalPivotPosition))); |
|||
} |
|||
else |
|||
{ |
|||
controlPoints[selectedIndices[index]] = originalPivotPosition + mul(mul(inverse(handleRotation), newRotation), (selectedOriginalPositions[index] - originalPivotPosition)); |
|||
} |
|||
} |
|||
|
|||
CacheResizePositionsFromChange(); |
|||
} |
|||
} |
|||
else if (activeTool == Tool.Scale) |
|||
{ |
|||
var size = HandleUtility.GetHandleSize(handlePosition); |
|||
EditorGUI.BeginChangeCheck(); |
|||
handleScale = Handles.ScaleHandle(handleScale, handlePosition, handleRotation, size); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
Undo.RecordObject(target, "Update Lattice"); |
|||
|
|||
for (var index = 0; index < selectedIndices.Count; index++) |
|||
{ |
|||
if (Tools.pivotRotation == PivotRotation.Global) |
|||
{ |
|||
controlPoints[selectedIndices[index]] = originalPivotPosition + (float3) transform.InverseTransformDirection(handleScale * transform.TransformDirection(selectedOriginalPositions[index] - originalPivotPosition)); |
|||
} |
|||
else |
|||
{ |
|||
controlPoints[selectedIndices[index]] = originalPivotPosition + handleScale * (selectedOriginalPositions[index] - originalPivotPosition); |
|||
} |
|||
} |
|||
|
|||
CacheResizePositionsFromChange(); |
|||
} |
|||
} |
|||
|
|||
Handles.BeginGUI(); |
|||
if (GUI.Button(new Rect((EditorGUIUtility.currentViewWidth - 200) / 2, SceneView.currentDrawingSceneView.position.height - 60, 200, 30), Content.StopEditing)) |
|||
{ |
|||
DeselectAll(); |
|||
} |
|||
|
|||
Handles.EndGUI(); |
|||
} |
|||
|
|||
if (e.button == 0) // Left Mouse Button
|
|||
{ |
|||
if (e.type == EventType.MouseDown && HandleUtility.nearestControl == defaultControl && MouseActionAllowed) |
|||
{ |
|||
mouseDownPosition = e.mousePosition; |
|||
mouseDragState = MouseDragState.Eligible; |
|||
} |
|||
else if (e.type == EventType.MouseDrag && mouseDragState == MouseDragState.Eligible) |
|||
{ |
|||
mouseDragState = MouseDragState.InProgress; |
|||
SceneView.currentDrawingSceneView.Repaint(); |
|||
} |
|||
else if (GUIUtility.hotControl == 0 && |
|||
(e.type == EventType.MouseUp |
|||
|| (mouseDragState == MouseDragState.InProgress && e.rawType == EventType.MouseUp))) // Have they released the mouse outside the scene view while doing marquee select?
|
|||
{ |
|||
if (mouseDragState == MouseDragState.InProgress) |
|||
{ |
|||
var mouseUpPosition = e.mousePosition; |
|||
|
|||
Rect marqueeRect = Rect.MinMaxRect(Mathf.Min(mouseDownPosition.x, mouseUpPosition.x), |
|||
Mathf.Min(mouseDownPosition.y, mouseUpPosition.y), |
|||
Mathf.Max(mouseDownPosition.x, mouseUpPosition.x), |
|||
Mathf.Max(mouseDownPosition.y, mouseUpPosition.y)); |
|||
|
|||
BeginSelectionChangeRegion(); |
|||
|
|||
if (!e.shift && !e.control && !e.command) |
|||
{ |
|||
selectedIndices.Clear(); |
|||
} |
|||
|
|||
for (var index = 0; index < controlPoints.Length; index++) |
|||
{ |
|||
Camera camera = SceneView.currentDrawingSceneView.camera; |
|||
var screenPoint = DeformEditorGUIUtility.WorldToGUIPoint(camera, transform.TransformPoint(controlPoints[index])); |
|||
|
|||
if (screenPoint.z < 0) |
|||
{ |
|||
// Don't consider points that are behind the camera
|
|||
continue; |
|||
} |
|||
|
|||
if (marqueeRect.Contains(screenPoint)) |
|||
{ |
|||
if (e.control || e.command) // Remove selection
|
|||
{ |
|||
selectedIndices.Remove(index); |
|||
} |
|||
else |
|||
{ |
|||
selectedIndices.Add(index); |
|||
} |
|||
} |
|||
} |
|||
|
|||
EndSelectionChangeRegion(); |
|||
} |
|||
else |
|||
{ |
|||
if (selectedIndices.Count == 0) // This shouldn't be called if you have any points selected (we want to allow you to deselect the points)
|
|||
{ |
|||
DeformUnityObjectSelection.AttemptMouseUpObjectSelection(); |
|||
} |
|||
else |
|||
{ |
|||
DeselectAll(); |
|||
} |
|||
} |
|||
|
|||
mouseDragState = MouseDragState.NotActive; |
|||
} |
|||
} |
|||
|
|||
if (e.type == EventType.Repaint && mouseDragState == MouseDragState.InProgress) |
|||
{ |
|||
var mouseUpPosition = e.mousePosition; |
|||
|
|||
Rect marqueeRect = Rect.MinMaxRect(Mathf.Min(mouseDownPosition.x, mouseUpPosition.x), |
|||
Mathf.Min(mouseDownPosition.y, mouseUpPosition.y), |
|||
Mathf.Max(mouseDownPosition.x, mouseUpPosition.x), |
|||
Mathf.Max(mouseDownPosition.y, mouseUpPosition.y)); |
|||
DeformUnityObjectSelection.DrawUnityStyleMarquee(marqueeRect); |
|||
SceneView.RepaintAll(); |
|||
} |
|||
|
|||
// If the lattice is visible, override Unity's built-in Select All so that it selects all control points
|
|||
if (DeformUnityObjectSelection.SelectAllPressed) |
|||
{ |
|||
BeginSelectionChangeRegion(); |
|||
selectedIndices.Clear(); |
|||
var resolution = lattice.Resolution; |
|||
for (int z = 0; z < resolution.z; z++) |
|||
{ |
|||
for (int y = 0; y < resolution.y; y++) |
|||
{ |
|||
for (int x = 0; x < resolution.x; x++) |
|||
{ |
|||
var controlPointIndex = lattice.GetIndex(x, y, z); |
|||
selectedIndices.Add(controlPointIndex); |
|||
} |
|||
} |
|||
} |
|||
|
|||
EndSelectionChangeRegion(); |
|||
|
|||
e.Use(); |
|||
} |
|||
|
|||
if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Escape) |
|||
{ |
|||
DeselectAll(); |
|||
} |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate(); |
|||
} |
|||
|
|||
private void DeselectAll() |
|||
{ |
|||
BeginSelectionChangeRegion(); |
|||
selectedIndices.Clear(); |
|||
EndSelectionChangeRegion(); |
|||
} |
|||
|
|||
private void BeginSelectionChangeRegion() |
|||
{ |
|||
Undo.RecordObject(this, "Selection Change"); |
|||
previousSelectionCount = selectedIndices.Count; |
|||
} |
|||
|
|||
private void EndSelectionChangeRegion() |
|||
{ |
|||
if (selectedIndices.Count != previousSelectionCount) |
|||
{ |
|||
if (selectedIndices.Count != 0 && previousSelectionCount == 0 && Tools.current == Tool.None) // Is this our first selection?
|
|||
{ |
|||
// Make sure when we start selecting control points we actually have a useful tool equipped
|
|||
activeTool = Tool.Move; |
|||
} |
|||
else if (selectedIndices.Count == 0 && previousSelectionCount != 0) |
|||
{ |
|||
// If we have deselected we should probably restore the active tool from before
|
|||
Tools.current = activeTool; |
|||
} |
|||
|
|||
// Selected positions have changed so make sure we're up to date
|
|||
CacheOriginalPositions(); |
|||
|
|||
// Different UI elements may be visible depending on selection count, so redraw when it changes
|
|||
Repaint(); |
|||
} |
|||
} |
|||
|
|||
private void CacheOriginalPositions() |
|||
{ |
|||
// Cache the selected control point positions before the interaction, so that all handle
|
|||
// transformations are done using the original values rather than compounding error each frame
|
|||
var latticeDeformer = (target as LatticeDeformer); |
|||
float3[] controlPoints = latticeDeformer.ControlPoints; |
|||
selectedOriginalPositions.Clear(); |
|||
foreach (int selectedIndex in selectedIndices) |
|||
{ |
|||
selectedOriginalPositions.Add(controlPoints[selectedIndex]); |
|||
} |
|||
} |
|||
|
|||
private void CacheResizePositionsFromChange() |
|||
{ |
|||
var latticeDeformer = (target as LatticeDeformer); |
|||
float3[] controlPoints = latticeDeformer.ControlPoints; |
|||
cachedResizePositions = new float3[controlPoints.Length]; |
|||
controlPoints.CopyTo(cachedResizePositions, 0); |
|||
|
|||
cachedResizeResolution = latticeDeformer.Resolution; |
|||
} |
|||
|
|||
private static bool MouseActionAllowed |
|||
{ |
|||
get |
|||
{ |
|||
if (Event.current.alt) return false; |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
|
|||
private void DrawLattice(LatticeDeformer lattice, DeformHandles.LineMode lineMode) |
|||
{ |
|||
var resolution = lattice.Resolution; |
|||
var controlPoints = lattice.ControlPoints; |
|||
for (int z = 0; z < resolution.z - 1; z++) |
|||
{ |
|||
for (int y = 0; y < resolution.y - 1; y++) |
|||
{ |
|||
for (int x = 0; x < resolution.x - 1; x++) |
|||
{ |
|||
int index000 = lattice.GetIndex(x, y, z); |
|||
int index100 = lattice.GetIndex(x + 1, y, z); |
|||
int index010 = lattice.GetIndex(x, y + 1, z); |
|||
int index110 = lattice.GetIndex(x + 1, y + 1, z); |
|||
int index001 = lattice.GetIndex(x, y, z + 1); |
|||
int index101 = lattice.GetIndex(x + 1, y, z + 1); |
|||
int index011 = lattice.GetIndex(x, y + 1, z + 1); |
|||
int index111 = lattice.GetIndex(x + 1, y + 1, z + 1); |
|||
|
|||
DeformHandles.Line(controlPoints[index000], controlPoints[index100], lineMode); |
|||
DeformHandles.Line(controlPoints[index010], controlPoints[index110], lineMode); |
|||
DeformHandles.Line(controlPoints[index001], controlPoints[index101], lineMode); |
|||
DeformHandles.Line(controlPoints[index011], controlPoints[index111], lineMode); |
|||
|
|||
DeformHandles.Line(controlPoints[index000], controlPoints[index010], lineMode); |
|||
DeformHandles.Line(controlPoints[index100], controlPoints[index110], lineMode); |
|||
DeformHandles.Line(controlPoints[index001], controlPoints[index011], lineMode); |
|||
DeformHandles.Line(controlPoints[index101], controlPoints[index111], lineMode); |
|||
|
|||
DeformHandles.Line(controlPoints[index000], controlPoints[index001], lineMode); |
|||
DeformHandles.Line(controlPoints[index100], controlPoints[index101], lineMode); |
|||
DeformHandles.Line(controlPoints[index010], controlPoints[index011], lineMode); |
|||
DeformHandles.Line(controlPoints[index110], controlPoints[index111], lineMode); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
fileFormatVersion: 2 |
|||
guid: b77dcb044ea84a9f9407ca0f2b9a15a3 |
|||
timeCreated: 1611788559 |
|||
@ -0,0 +1,55 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (MagnetDeformer)), CanEditMultipleObjects] |
|||
public class MagnetDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Falloff = new GUIContent (text: "Falloff", tooltip: "The sharpness of the effect's transition."); |
|||
public static readonly GUIContent Center = new GUIContent (text: "Center", tooltip:DeformEditorGUIUtility.Strings.AxisTooltip); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Falloff; |
|||
public SerializedProperty Center; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Falloff = obj.FindProperty ("falloff"); |
|||
Center = obj.FindProperty ("center"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.PropertyField (properties.Factor, Content.Factor); |
|||
EditorGUILayoutx.MinField (properties.Falloff, 0f, Content.Falloff); |
|||
EditorGUILayout.PropertyField (properties.Center, Content.Center); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f365de2e47265484199408d9917665b5 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: fd89931157130e44882090cb6e512eae |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,8 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d964228ca463c664cafab531da60a547 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,165 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Deform.Masking; |
|||
using UnityEditor.IMGUI.Controls; |
|||
|
|||
namespace DeformEditor.Masking |
|||
{ |
|||
[CustomEditor (typeof (BoxMask)), CanEditMultipleObjects] |
|||
public class BoxMaskEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent InnerBounds = new GUIContent (text: "Inner Bounds"); |
|||
public static readonly GUIContent OuterBounds = new GUIContent (text: "Outer Bounds"); |
|||
public static readonly GUIContent Invert = new GUIContent (text: "Invert"); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty InnerBounds; |
|||
public SerializedProperty OuterBounds; |
|||
public SerializedProperty Invert; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
InnerBounds = obj.FindProperty ("innerBounds"); |
|||
OuterBounds = obj.FindProperty ("outerBounds"); |
|||
Invert = obj.FindProperty ("invert"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
private readonly BoxBoundsHandle boxHandle = new BoxBoundsHandle (); |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
|
|||
EditorGUILayout.PropertyField (properties.InnerBounds, Content.InnerBounds); |
|||
var innerBounds = properties.InnerBounds.boundsValue; |
|||
var outerBounds = properties.OuterBounds.boundsValue; |
|||
|
|||
innerBounds = EnforcePositiveExtents (innerBounds); |
|||
|
|||
innerBounds.min = new Vector3 (Mathf.Max (innerBounds.min.x, outerBounds.min.x), Mathf.Max (innerBounds.min.y, outerBounds.min.y), Mathf.Max (innerBounds.min.z, outerBounds.min.z)); |
|||
innerBounds.max = new Vector3 (Mathf.Min (innerBounds.max.x, outerBounds.max.x), Mathf.Min (innerBounds.max.y, outerBounds.max.y), Mathf.Min (innerBounds.max.z, outerBounds.max.z)); |
|||
|
|||
EditorGUILayout.PropertyField (properties.OuterBounds, Content.OuterBounds); |
|||
outerBounds = properties.OuterBounds.boundsValue; |
|||
outerBounds.min = new Vector3 (Mathf.Min (innerBounds.min.x, outerBounds.min.x), Mathf.Min (innerBounds.min.y, outerBounds.min.y), Mathf.Min (innerBounds.min.z, outerBounds.min.z)); |
|||
outerBounds.max = new Vector3 (Mathf.Max (innerBounds.max.x, outerBounds.max.x), Mathf.Max (innerBounds.max.y, outerBounds.max.y), Mathf.Max (innerBounds.max.z, outerBounds.max.z)); |
|||
|
|||
properties.InnerBounds.boundsValue = innerBounds; |
|||
properties.OuterBounds.boundsValue = outerBounds; |
|||
|
|||
EditorGUILayout.PropertyField (properties.Invert, Content.Invert); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var boxMask = target as BoxMask; |
|||
|
|||
DrawInnerBoundsHandle (boxMask); |
|||
|
|||
var innerBounds = boxMask.InnerBounds; |
|||
var outerBounds = boxMask.OuterBounds; |
|||
|
|||
innerBounds = EnforcePositiveExtents (innerBounds); |
|||
|
|||
innerBounds.min = new Vector3 (Mathf.Max (innerBounds.min.x, outerBounds.min.x), Mathf.Max (innerBounds.min.y, outerBounds.min.y), Mathf.Max (innerBounds.min.z, outerBounds.min.z)); |
|||
innerBounds.max = new Vector3 (Mathf.Min (innerBounds.max.x, outerBounds.max.x), Mathf.Min (innerBounds.max.y, outerBounds.max.y), Mathf.Min (innerBounds.max.z, outerBounds.max.z)); |
|||
|
|||
DrawOuterBoundsHandle (boxMask); |
|||
|
|||
outerBounds = boxMask.OuterBounds; |
|||
|
|||
outerBounds.min = new Vector3 (Mathf.Min (innerBounds.min.x, outerBounds.min.x), Mathf.Min (innerBounds.min.y, outerBounds.min.y), Mathf.Min (innerBounds.min.z, outerBounds.min.z)); |
|||
outerBounds.max = new Vector3 (Mathf.Max (innerBounds.max.x, outerBounds.max.x), Mathf.Max (innerBounds.max.y, outerBounds.max.y), Mathf.Max (innerBounds.max.z, outerBounds.max.z)); |
|||
|
|||
boxMask.InnerBounds = innerBounds; |
|||
boxMask.OuterBounds = outerBounds; |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawInnerBoundsHandle (BoxMask boxMask) |
|||
{ |
|||
boxHandle.handleColor = DeformEditorSettings.SolidHandleColor; |
|||
boxHandle.wireframeColor = DeformEditorSettings.LightHandleColor; |
|||
boxHandle.center = boxMask.InnerBounds.center; |
|||
boxHandle.size = boxMask.InnerBounds.size; |
|||
|
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (boxMask.Axis.position, boxMask.Axis.rotation, boxMask.Axis.lossyScale))) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
boxHandle.DrawHandle (); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (boxMask, "Changed Size"); |
|||
boxMask.InnerBounds = new Bounds (boxHandle.center, boxHandle.size); |
|||
boxMask.OuterBounds.Encapsulate (boxMask.InnerBounds); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
private void DrawOuterBoundsHandle (BoxMask boxMask) |
|||
{ |
|||
boxHandle.handleColor = DeformEditorSettings.SolidHandleColor; |
|||
boxHandle.wireframeColor = DeformEditorSettings.LightHandleColor; |
|||
boxHandle.center = boxMask.OuterBounds.center; |
|||
boxHandle.size = boxMask.OuterBounds.size; |
|||
|
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (boxMask.Axis.position, boxMask.Axis.rotation, boxMask.Axis.lossyScale))) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
boxHandle.DrawHandle (); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (boxMask, "Changed Size"); |
|||
boxMask.OuterBounds = new Bounds (boxHandle.center, boxHandle.size); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private Bounds EnforcePositiveExtents (Bounds bounds) |
|||
{ |
|||
var extents = bounds.extents; |
|||
|
|||
extents.x = Mathf.Max (0f, extents.x); |
|||
extents.y = Mathf.Max (0f, extents.y); |
|||
extents.z = Mathf.Max (0f, extents.z); |
|||
|
|||
bounds.extents = extents; |
|||
|
|||
return bounds; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 07641f8e2fa04264883561cf714676b9 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,107 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform.Masking; |
|||
|
|||
namespace DeformEditor.Masking |
|||
{ |
|||
[CustomEditor (typeof (SphereMask)), CanEditMultipleObjects] |
|||
public class SphereMaskEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent InnerRadius = new GUIContent (text: "Inner Radius"); |
|||
public static readonly GUIContent OuterRadius = new GUIContent (text: "Outer Radius"); |
|||
public static readonly GUIContent Invert = new GUIContent (text: "Invert"); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty InnerRadius; |
|||
public SerializedProperty OuterRadius; |
|||
public SerializedProperty Invert; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
InnerRadius = obj.FindProperty ("innerRadius"); |
|||
OuterRadius = obj.FindProperty ("outerRadius"); |
|||
Invert = obj.FindProperty ("invert"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
EditorGUILayoutx.MaxField (properties.InnerRadius, properties.OuterRadius.floatValue, Content.InnerRadius); |
|||
EditorGUILayoutx.MinField (properties.OuterRadius, properties.InnerRadius.floatValue, Content.OuterRadius); |
|||
EditorGUILayout.PropertyField (properties.Invert, Content.Invert); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var sphereMask = target as SphereMask; |
|||
|
|||
DrawOuterRadiusHandle (sphereMask); |
|||
DrawInnerRadiusHandle (sphereMask); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawInnerRadiusHandle (SphereMask sphereMask) |
|||
{ |
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (sphereMask.Axis.position, sphereMask.Axis.rotation, sphereMask.Axis.lossyScale))) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var newRadius = DeformHandles.Radius (Quaternion.identity, Vector3.zero, sphereMask.InnerRadius * 0.5f); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (sphereMask, "Changed Radius"); |
|||
sphereMask.InnerRadius = newRadius * 2f; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void DrawOuterRadiusHandle (SphereMask sphereMask) |
|||
{ |
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (sphereMask.Axis.position, sphereMask.Axis.rotation, sphereMask.Axis.lossyScale))) |
|||
{ |
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var newRadius = DeformHandles.Radius (Quaternion.identity, Vector3.zero, sphereMask.OuterRadius * 0.5f); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (sphereMask, "Changed Radius"); |
|||
sphereMask.OuterRadius = newRadius * 2f; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 4e91177af36100140b5b9aa283e38403 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,59 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform.Masking; |
|||
|
|||
namespace DeformEditor.Masking |
|||
{ |
|||
[CustomEditor (typeof (VertexColorMask)), CanEditMultipleObjects] |
|||
public class VertexColorMaskEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Falloff = DeformEditorGUIUtility.DefaultContent.Falloff; |
|||
public static readonly GUIContent Invert = new GUIContent (text: "Invert"); |
|||
public static readonly GUIContent Channel = new GUIContent (text: "Channel"); |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Falloff; |
|||
public SerializedProperty Invert; |
|||
public SerializedProperty Channel; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Falloff = obj.FindProperty ("falloff"); |
|||
Invert = obj.FindProperty ("invert"); |
|||
Channel = obj.FindProperty ("channel"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
EditorGUILayoutx.MinField (properties.Falloff, 0f, Content.Falloff); |
|||
EditorGUILayout.PropertyField (properties.Invert, Content.Invert); |
|||
EditorGUILayout.PropertyField (properties.Channel, Content.Channel); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: de9725ecc0cd4994abba096f58f0d9fa |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,59 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform.Masking; |
|||
|
|||
namespace DeformEditor.Masking |
|||
{ |
|||
[CustomEditor (typeof (VerticalGradientMask)), CanEditMultipleObjects] |
|||
public class VerticalGradientMaskEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Falloff = DeformEditorGUIUtility.DefaultContent.Falloff; |
|||
public static readonly GUIContent Invert = new GUIContent (text: "Invert"); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Falloff; |
|||
public SerializedProperty Invert; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Falloff = obj.FindProperty ("falloff"); |
|||
Invert = obj.FindProperty ("invert"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
properties = new Properties (serializedObject); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
EditorGUILayoutx.MinField (properties.Falloff, 0f, Content.Falloff); |
|||
EditorGUILayout.PropertyField (properties.Invert, Content.Invert); |
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: e107b5e56e2a15e4ebb14971bbb13b06 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,162 @@ |
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
using Beans.Unity.Editor; |
|||
using Deform; |
|||
|
|||
namespace DeformEditor |
|||
{ |
|||
[CustomEditor (typeof (MeltDeformer)), CanEditMultipleObjects] |
|||
public class MeltDeformerEditor : DeformerEditor |
|||
{ |
|||
private static class Content |
|||
{ |
|||
public static readonly GUIContent Factor = DeformEditorGUIUtility.DefaultContent.Factor; |
|||
public static readonly GUIContent Falloff = DeformEditorGUIUtility.DefaultContent.Falloff; |
|||
public static readonly GUIContent Radius = new GUIContent (text: "Radius", tooltip: "How far the vertices spread as they approach the bottom."); |
|||
public static readonly GUIContent UseNormals = new GUIContent (text: "Use Normals", tooltip: "When true the vertices will spread along the normals' xy plane (relative to the melt axis) which can look better, but can result in a split mesh if you have unsmoothed vertices."); |
|||
public static readonly GUIContent ClampAtBottom = new GUIContent (text: "Clamp At Bottom", tooltip: "When true, vertices won't be allowed below the bottom limit."); |
|||
public static readonly GUIContent Top = DeformEditorGUIUtility.DefaultContent.Top; |
|||
public static readonly GUIContent Bottom = new GUIContent (text: "Bottom", tooltip: "Any vertices below this will have the full effect."); |
|||
public static readonly GUIContent Noise = new GUIContent (text: "Noise"); |
|||
public static readonly GUIContent Vertical = new GUIContent (text: "Vertical"); |
|||
public static readonly GUIContent VerticalFrequency = new GUIContent (text: "Frequency", tooltip: "The frequency of the vertical noise. Lower values result in a smoother mesh."); |
|||
public static readonly GUIContent VerticalMagnitude = new GUIContent (text: "Magnitude", tooltip: "The strength of the vertical noise."); |
|||
public static readonly GUIContent Radial = new GUIContent (text: "Radial"); |
|||
public static readonly GUIContent RadialFrequency = new GUIContent (text: "Frequency", tooltip: "The frequency of the radial noise. Lower values result in a smoother mesh."); |
|||
public static readonly GUIContent RadialMagnitude = new GUIContent (text: "Magnitude", tooltip: "The strength of the radial noise."); |
|||
public static readonly GUIContent Axis = DeformEditorGUIUtility.DefaultContent.Axis; |
|||
} |
|||
|
|||
private class Properties |
|||
{ |
|||
public SerializedProperty Factor; |
|||
public SerializedProperty Falloff; |
|||
public SerializedProperty Radius; |
|||
public SerializedProperty UseNormals; |
|||
public SerializedProperty ClampAtBottom; |
|||
public SerializedProperty Top; |
|||
public SerializedProperty Bottom; |
|||
public SerializedProperty VerticalFrequency; |
|||
public SerializedProperty VerticalMagnitude; |
|||
public SerializedProperty RadialFrequency; |
|||
public SerializedProperty RadialMagnitude; |
|||
public SerializedProperty Axis; |
|||
|
|||
public Properties (SerializedObject obj) |
|||
{ |
|||
Factor = obj.FindProperty ("factor"); |
|||
Falloff = obj.FindProperty ("falloff"); |
|||
Radius = obj.FindProperty ("radius"); |
|||
UseNormals = obj.FindProperty ("useNormals"); |
|||
ClampAtBottom = obj.FindProperty ("clampAtBottom"); |
|||
Top = obj.FindProperty ("top"); |
|||
Bottom = obj.FindProperty ("bottom"); |
|||
VerticalFrequency = obj.FindProperty ("verticalFrequency"); |
|||
VerticalMagnitude = obj.FindProperty ("verticalMagnitude"); |
|||
RadialFrequency = obj.FindProperty ("radialFrequency"); |
|||
RadialMagnitude = obj.FindProperty ("radialMagnitude"); |
|||
Axis = obj.FindProperty ("axis"); |
|||
} |
|||
} |
|||
|
|||
private Properties properties; |
|||
private readonly VerticalBoundsHandle boundsHandle = new VerticalBoundsHandle (); |
|||
|
|||
protected override void OnEnable () |
|||
{ |
|||
base.OnEnable (); |
|||
|
|||
properties = new Properties (serializedObject); |
|||
|
|||
boundsHandle.HandleCapFunction = DeformHandles.HandleCapFunction; |
|||
boundsHandle.DrawGuidelineCallback = (a, b) => DeformHandles.Line (a, b, DeformHandles.LineMode.LightDotted); |
|||
} |
|||
|
|||
public override void OnInspectorGUI () |
|||
{ |
|||
base.OnInspectorGUI (); |
|||
|
|||
serializedObject.UpdateIfRequiredOrScript (); |
|||
|
|||
EditorGUILayout.Slider (properties.Factor, 0f, 1f, Content.Factor); |
|||
EditorGUILayoutx.MinField (properties.Falloff, 0f); |
|||
EditorGUILayout.PropertyField (properties.Radius, Content.Radius); |
|||
EditorGUILayout.PropertyField (properties.UseNormals, Content.UseNormals); |
|||
EditorGUILayout.PropertyField (properties.ClampAtBottom, Content.ClampAtBottom); |
|||
EditorGUILayoutx.MinField (properties.Top, properties.Bottom.floatValue, Content.Top); |
|||
EditorGUILayoutx.MaxField (properties.Bottom, properties.Top.floatValue, Content.Bottom); |
|||
|
|||
EditorGUILayout.LabelField (Content.Noise); |
|||
using (new EditorGUI.IndentLevelScope ()) |
|||
{ |
|||
EditorGUILayout.LabelField (Content.Vertical); |
|||
|
|||
using (new EditorGUI.IndentLevelScope ()) |
|||
{ |
|||
EditorGUILayout.PropertyField (properties.VerticalFrequency, Content.VerticalFrequency); |
|||
EditorGUILayout.PropertyField (properties.VerticalMagnitude, Content.VerticalMagnitude); |
|||
} |
|||
|
|||
EditorGUILayout.LabelField (Content.Radial); |
|||
|
|||
using (new EditorGUI.IndentLevelScope ()) |
|||
{ |
|||
EditorGUILayout.PropertyField (properties.RadialFrequency, Content.RadialFrequency); |
|||
EditorGUILayout.PropertyField (properties.RadialMagnitude, Content.RadialMagnitude); |
|||
} |
|||
} |
|||
|
|||
EditorGUILayout.PropertyField (properties.Axis, Content.Axis); |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
|
|||
EditorGUILayoutx.WIPAlert (); |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
public override void OnSceneGUI () |
|||
{ |
|||
base.OnSceneGUI (); |
|||
|
|||
var melt = target as MeltDeformer; |
|||
|
|||
DrawRadiusHandle (melt); |
|||
|
|||
boundsHandle.HandleColor = DeformEditorSettings.SolidHandleColor; |
|||
boundsHandle.ScreenspaceHandleSize = DeformEditorSettings.ScreenspaceSliderHandleCapSize; |
|||
if (boundsHandle.DrawHandle (melt.Top, melt.Bottom, melt.Axis, Vector3.forward)) |
|||
{ |
|||
Undo.RecordObject (melt, "Changed Bounds"); |
|||
melt.Top = boundsHandle.Top; |
|||
melt.Bottom = boundsHandle.Bottom; |
|||
} |
|||
|
|||
EditorApplication.QueuePlayerLoopUpdate (); |
|||
} |
|||
|
|||
private void DrawRadiusHandle (MeltDeformer melt) |
|||
{ |
|||
var scaledRadius = melt.Radius; |
|||
|
|||
var bottomPosition = Vector3.forward * melt.Bottom; |
|||
|
|||
using (new Handles.DrawingScope (Matrix4x4.TRS (melt.Axis.position, melt.Axis.rotation, melt.Axis.lossyScale))) |
|||
{ |
|||
DeformHandles.Circle (bottomPosition, Vector3.forward, Vector3.right, scaledRadius); |
|||
|
|||
var radiusWorldPosition = (Vector3.forward * melt.Bottom) + Vector3.up * scaledRadius; |
|||
|
|||
using (var check = new EditorGUI.ChangeCheckScope ()) |
|||
{ |
|||
var newRadiusWorldPosition = DeformHandles.Slider (radiusWorldPosition, Vector3.up); |
|||
if (check.changed) |
|||
{ |
|||
Undo.RecordObject (melt, "Changed Radius"); |
|||
melt.Radius = newRadiusWorldPosition.y; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 601f0ed525cf9b340a5ec6e1d7538755 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue