diff --git a/.vs/RimWorld-Animation-Studio/v16/.suo b/.vs/RimWorld-Animation-Studio/v16/.suo index 9f4e74d2..4407ca6c 100644 Binary files a/.vs/RimWorld-Animation-Studio/v16/.suo and b/.vs/RimWorld-Animation-Studio/v16/.suo differ diff --git a/Assembly-CSharp.csproj b/Assembly-CSharp.csproj index a77c91d6..df8f7e6f 100644 --- a/Assembly-CSharp.csproj +++ b/Assembly-CSharp.csproj @@ -67,34 +67,32 @@ - - - - - + - - - - - - - + + + + + + + + + - - - - - - + + - + + + + + @@ -112,14 +110,18 @@ - - - - - - + + + + + + + + + + @@ -127,17 +129,14 @@ - - - - + @@ -146,7 +145,7 @@ - + diff --git a/Assembly-CSharp.csproj.user b/Assembly-CSharp.csproj.user new file mode 100644 index 00000000..c10e84ba --- /dev/null +++ b/Assembly-CSharp.csproj.user @@ -0,0 +1,6 @@ + + + + ProjectFiles + + \ No newline at end of file diff --git a/Assets/Resources/Prefabs/StageCard.prefab b/Assets/Resources/Prefabs/StageCard.prefab index 29cd9b08..ebaafd48 100644 --- a/Assets/Resources/Prefabs/StageCard.prefab +++ b/Assets/Resources/Prefabs/StageCard.prefab @@ -647,6 +647,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 20b2be62d5fdc4b4992cede005ec2aee, type: 3} m_Name: m_EditorClassIdentifier: + stageName: {fileID: 1575336727571200468} + stageNameField: {fileID: 8975510041719035916} + banner: {fileID: 8402660926707036654} --- !u!1 &5467517697077698744 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scenes/MainScene.unity b/Assets/Scenes/MainScene.unity index 0f405934..d98b2448 100644 --- a/Assets/Scenes/MainScene.unity +++ b/Assets/Scenes/MainScene.unity @@ -155,14 +155,14 @@ RectTransform: - {fileID: 1882610407} - {fileID: 1128954052} - {fileID: 1124030520} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 12 + m_Father: {fileID: 1216651060} + m_RootOrder: 8 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 10, y: -370} + m_AnchoredPosition: {x: 10, y: -150} m_SizeDelta: {x: 120, y: 30} - m_Pivot: {x: 0, y: 0.5} + m_Pivot: {x: 0, y: 1} --- !u!114 &11575767 MonoBehaviour: m_ObjectHideFlags: 0 @@ -170,11 +170,14 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 11575765} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 0ba5b69d448f9434ca7d74d4022f3dcd, type: 3} m_Name: m_EditorClassIdentifier: + dropdown: {fileID: 0} + label: {fileID: 0} + hashcode: -1 --- !u!114 &11575768 MonoBehaviour: m_ObjectHideFlags: 0 @@ -225,18 +228,7 @@ MonoBehaviour: m_Options: [] m_OnValueChanged: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 11575767} - m_MethodName: UpdateActorRace - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] m_AlphaFadeSpeed: 0.15 --- !u!114 &11575769 MonoBehaviour: @@ -718,14 +710,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 1 + m_Father: {fileID: 657181759} + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 1, y: -150} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 30} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!114 &47347462 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1095,6 +1087,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &70380477 GameObject: m_ObjectHideFlags: 0 @@ -1443,6 +1437,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &82705930 GameObject: m_ObjectHideFlags: 0 @@ -4305,18 +4301,7 @@ MonoBehaviour: m_CharacterLimit: 0 m_OnEndEdit: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 2130812670} - m_MethodName: UpdateAnimationDef - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] m_OnValueChanged: m_PersistentCalls: m_Calls: [] @@ -5911,6 +5896,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &365075582 GameObject: m_ObjectHideFlags: 0 @@ -6314,14 +6301,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 316478197} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 14 + m_Father: {fileID: 1216651060} + m_RootOrder: 10 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -95, y: -370} + m_AnchoredPosition: {x: -97, y: -150} m_SizeDelta: {x: 60, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!114 &375594582 MonoBehaviour: m_ObjectHideFlags: 0 @@ -6388,7 +6375,7 @@ MonoBehaviour: m_OnEndEdit: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 3804747680621674853} + - m_Target: {fileID: 0} m_MethodName: OnValueChanged m_Mode: 1 m_Arguments: @@ -7140,6 +7127,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &418498614 MonoBehaviour: m_ObjectHideFlags: 0 @@ -7378,6 +7367,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &429161116 GameObject: m_ObjectHideFlags: 0 @@ -9647,14 +9638,13 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: isAnimating: 0 - stageTick: 1 stageTimelineSlider: {fileID: 1289465655} stageLoopDropdown: {fileID: 429161118} cyclesNormalField: {fileID: 74082975} cyclesFastField: {fileID: 1463915054} animationClipTimeField: {fileID: 760297267} animationClipLengthField: {fileID: 1676585155} - actorCard: {fileID: 3804747680621674853} + actorCard: {fileID: 0} animationTimelines: {fileID: 1100016168} actorBodies: {fileID: 1828035561} stretchKeyframesToggle: {fileID: 462332576} @@ -10389,7 +10379,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.5} m_AnchorMax: {x: 1, y: 0.5} - m_AnchoredPosition: {x: 0, y: 84.99498} + m_AnchoredPosition: {x: 0, y: 84.999985} m_SizeDelta: {x: 0, y: 5} m_Pivot: {x: 0, y: 1} --- !u!114 &542629604 @@ -11389,6 +11379,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &591894604 GameObject: m_ObjectHideFlags: 0 @@ -12798,6 +12790,44 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 28} m_Pivot: {x: 0.5, y: 1} +--- !u!1 &657181758 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 657181759} + m_Layer: 5 + m_Name: ActorControls + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &657181759 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 657181758} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 47347461} + - {fileID: 899286715} + - {fileID: 1136677497} + m_Father: {fileID: 935483303140078260} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 310, y: 65.97644} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &658284331 GameObject: m_ObjectHideFlags: 0 @@ -13145,6 +13175,8 @@ MonoBehaviour: delay: 0.3 offset: {x: -5, y: -15} flipX: 1 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &681903175 MonoBehaviour: m_ObjectHideFlags: 0 @@ -13846,6 +13878,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &721371349 GameObject: m_ObjectHideFlags: 0 @@ -13903,6 +13937,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &721371352 MonoBehaviour: m_ObjectHideFlags: 0 @@ -14319,6 +14355,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &728306590 GameObject: m_ObjectHideFlags: 0 @@ -14967,6 +15005,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &782222915 GameObject: m_ObjectHideFlags: 0 @@ -15671,6 +15711,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &841981644 GameObject: m_ObjectHideFlags: 0 @@ -16027,6 +16069,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &859476423 GameObject: m_ObjectHideFlags: 0 @@ -16239,6 +16283,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &865383681 MonoBehaviour: m_ObjectHideFlags: 0 @@ -17020,12 +17066,12 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 395375412} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 2 + m_Father: {fileID: 657181759} + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 11, y: -165} + m_AnchoredPosition: {x: 10, y: -30} m_SizeDelta: {x: 145, y: 30} m_Pivot: {x: 0, y: 1} --- !u!114 &899286716 @@ -17071,7 +17117,7 @@ MonoBehaviour: m_OnClick: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 531246358} + - m_Target: {fileID: 1335076905} m_MethodName: AddActor m_Mode: 1 m_Arguments: @@ -17601,8 +17647,8 @@ RectTransform: m_Father: {fileID: 971413406} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0.13577896} - m_AnchorMax: {x: 1, y: 1} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0.99997056} m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 20, y: 20} m_Pivot: {x: 0.5, y: 0.5} @@ -18174,6 +18220,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &971413405 GameObject: m_ObjectHideFlags: 0 @@ -18642,14 +18690,14 @@ RectTransform: - {fileID: 1151323893} - {fileID: 225041961} - {fileID: 593007063} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 9 + m_Father: {fileID: 1216651060} + m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -9, y: -275} + m_AnchoredPosition: {x: -10, y: -60} m_SizeDelta: {x: 120, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!114 &1001419736 MonoBehaviour: m_ObjectHideFlags: 0 @@ -18710,18 +18758,7 @@ MonoBehaviour: m_Image: {fileID: 0} m_OnValueChanged: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 3804747680621674853} - m_MethodName: OnActorLayerChange - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] m_AlphaFadeSpeed: 0.15 --- !u!114 &1001419737 MonoBehaviour: @@ -18789,14 +18826,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 11 + m_Father: {fileID: 1216651060} + m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -340} + m_AnchoredPosition: {x: 0, y: -120} m_SizeDelta: {x: 0, y: 30} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!114 &1012383902 MonoBehaviour: m_ObjectHideFlags: 0 @@ -20396,12 +20433,12 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 1321044693} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 3 + m_Father: {fileID: 657181759} + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -9, y: -165} + m_AnchoredPosition: {x: -10, y: -30} m_SizeDelta: {x: 145, y: 30} m_Pivot: {x: 1, y: 1} --- !u!114 &1136677498 @@ -20447,7 +20484,7 @@ MonoBehaviour: m_OnClick: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 531246358} + - m_Target: {fileID: 1335076905} m_MethodName: RemoveActor m_Mode: 1 m_Arguments: @@ -20937,6 +20974,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &1151323892 GameObject: m_ObjectHideFlags: 0 @@ -21261,8 +21300,8 @@ MonoBehaviour: m_TargetGraphic: {fileID: 922060210} m_HandleRect: {fileID: 922060209} m_Direction: 2 - m_Value: 1 - m_Size: 0.86422104 + m_Value: 0 + m_Size: 0.99997056 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: @@ -21886,14 +21925,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 4 + m_Father: {fileID: 1216651060} + m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 1, y: -215} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 30} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!114 &1169056256 MonoBehaviour: m_ObjectHideFlags: 0 @@ -22212,14 +22251,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 13 + m_Father: {fileID: 1216651060} + m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -150, y: -370} + m_AnchoredPosition: {x: -152, y: -150} m_SizeDelta: {x: 19.951263, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!114 &1179892062 MonoBehaviour: m_ObjectHideFlags: 0 @@ -22353,6 +22392,7 @@ GameObject: - component: {fileID: 1185311444} - component: {fileID: 1185311443} - component: {fileID: 1185311447} + - component: {fileID: 1185311448} m_Layer: 5 m_Name: TooltipMessage m_TagString: Untagged @@ -22477,6 +22517,18 @@ Canvas: m_SortingLayerID: 0 m_SortingOrder: 10000 m_TargetDisplay: 0 +--- !u!114 &1185311448 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1185311441} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ec8ec1002bf0dda4aa55bfb75b152066, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!1 &1190554010 GameObject: m_ObjectHideFlags: 0 @@ -22700,6 +22752,81 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1208864190} m_CullTransparentMesh: 0 +--- !u!1 &1216651059 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1216651060} + - component: {fileID: 1216651061} + m_Layer: 5 + m_Name: ActorCard + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1216651060 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1216651059} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1169056255} + - {fileID: 4300837137793644386} + - {fileID: 4070467796814498374} + - {fileID: 6085830301866471447} + - {fileID: 1470937577} + - {fileID: 1001419735} + - {fileID: 935483303288600285} + - {fileID: 1012383901} + - {fileID: 11575766} + - {fileID: 1179892061} + - {fileID: 375594581} + - {fileID: 2081541321} + - {fileID: 1293104866} + - {fileID: 935483304393195702} + - {fileID: 935483303887120943} + - {fileID: 935483302917639724} + - {fileID: 935483304332071718} + - {fileID: 935483303345155101} + - {fileID: 935483304128418023} + m_Father: {fileID: 935483303140078260} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 310, y: 275.7104} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1216651061 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1216651059} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9731614c7527b624492dd33f9b006fcb, type: 3} + m_Name: + m_EditorClassIdentifier: + initiatorToggle: {fileID: 935483303288600284} + selectActorLayerDropdown: {fileID: 1001419736} + bodyTypeDropdown: {fileID: 935483303887120942} + bodyOffsetXField: {fileID: 935483304332071713} + bodyOffsetZField: {fileID: 935483304128418022} + raceDropdown: {fileID: 11575768} + raceOffsetXField: {fileID: 375594583} + raceOffsetZField: {fileID: 1293104868} --- !u!1 &1224297432 GameObject: m_ObjectHideFlags: 0 @@ -23294,6 +23421,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &1231435416 GameObject: m_ObjectHideFlags: 0 @@ -24191,14 +24320,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 1475781912} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 16 + m_Father: {fileID: 1216651060} + m_RootOrder: 12 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -10, y: -370} + m_AnchoredPosition: {x: -12, y: -150} m_SizeDelta: {x: 58.349854, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!114 &1293104867 MonoBehaviour: m_ObjectHideFlags: 0 @@ -24265,7 +24394,7 @@ MonoBehaviour: m_OnEndEdit: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 3804747680621674853} + - m_Target: {fileID: 0} m_MethodName: OnValueChanged m_Mode: 1 m_Arguments: @@ -25091,7 +25220,6 @@ GameObject: - component: {fileID: 1335076902} - component: {fileID: 1335076901} - component: {fileID: 1335076900} - - component: {fileID: 1335076904} - component: {fileID: 1335076905} m_Layer: 5 m_Name: Workspace @@ -25184,20 +25312,6 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0, y: 0} ---- !u!114 &1335076904 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1335076899} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: bf0f782b7c407bf4896b633d509f5568, type: 3} - m_Name: - m_EditorClassIdentifier: - workspaceHistory: [] - maxHistoryDepth: 100 --- !u!114 &1335076905 MonoBehaviour: m_ObjectHideFlags: 0 @@ -26417,6 +26531,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &1385913472 MonoBehaviour: m_ObjectHideFlags: 0 @@ -26754,18 +26870,7 @@ MonoBehaviour: m_CharacterLimit: 0 m_OnEndEdit: m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 2130812670} - m_MethodName: UpdateAnimationDef - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 + m_Calls: [] m_OnValueChanged: m_PersistentCalls: m_Calls: [] @@ -28472,18 +28577,18 @@ RectTransform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1470937576} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 8 + m_Father: {fileID: 1216651060} + m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -142, y: -275.5} + m_AnchoredPosition: {x: -141, y: -63} m_SizeDelta: {x: 24, y: 24} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!114 &1470937578 MonoBehaviour: m_ObjectHideFlags: 0 @@ -28538,6 +28643,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &1471661200 GameObject: m_ObjectHideFlags: 0 @@ -28777,6 +28884,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &1475489072 GameObject: m_ObjectHideFlags: 0 @@ -30630,6 +30739,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0ba5b69d448f9434ca7d74d4022f3dcd, type: 3} m_Name: m_EditorClassIdentifier: + dropdown: {fileID: 0} + label: {fileID: 0} + hashcode: -1 --- !u!114 &1567848591 MonoBehaviour: m_ObjectHideFlags: 0 @@ -30991,6 +31103,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!224 &1588340713 stripped RectTransform: m_CorrespondingSourceObject: {fileID: 5546566853072149881, guid: 3d766602dcd74d14cb57739e80baea2d, @@ -32430,6 +32544,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!1 &1688913595 GameObject: m_ObjectHideFlags: 0 @@ -35808,6 +35924,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &1885877281 MonoBehaviour: m_ObjectHideFlags: 0 @@ -36578,6 +36696,8 @@ MonoBehaviour: delay: 0.3 offset: {x: 5, y: -15} flipX: 0 + tooltip: {fileID: 0} + tooltipText: {fileID: 0} --- !u!114 &1901778600 MonoBehaviour: m_ObjectHideFlags: 0 @@ -38810,14 +38930,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 15 + m_Father: {fileID: 1216651060} + m_RootOrder: 11 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -65, y: -370} + m_AnchoredPosition: {x: -67, y: -150} m_SizeDelta: {x: 17.537262, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!114 &2081541322 MonoBehaviour: m_ObjectHideFlags: 0 @@ -39559,9 +39679,9 @@ RectTransform: m_Father: {fileID: 935483303140078260} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0.5, y: 1} - m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: 0, y: -69.7} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 310, y: 133.99207} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &2130812670 @@ -40086,14 +40206,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 19 + m_Father: {fileID: 1216651060} + m_RootOrder: 15 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -150, y: -435} + m_AnchoredPosition: {x: -152.35016, y: -215} m_SizeDelta: {x: 19.951263, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!1 &935483302917639725 GameObject: m_ObjectHideFlags: 0 @@ -40287,28 +40407,8 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 2130812669} - - {fileID: 47347461} - - {fileID: 899286715} - - {fileID: 1136677497} - - {fileID: 1169056255} - - {fileID: 4300837137793644386} - - {fileID: 4070467796814498374} - - {fileID: 6085830301866471447} - - {fileID: 1470937577} - - {fileID: 1001419735} - - {fileID: 935483303288600285} - - {fileID: 1012383901} - - {fileID: 11575766} - - {fileID: 1179892061} - - {fileID: 375594581} - - {fileID: 2081541321} - - {fileID: 1293104866} - - {fileID: 935483304393195702} - - {fileID: 935483303887120943} - - {fileID: 935483302917639724} - - {fileID: 935483304332071718} - - {fileID: 935483303345155101} - - {fileID: 935483304128418023} + - {fileID: 657181759} + - {fileID: 1216651060} m_Father: {fileID: 531246357} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -40328,14 +40428,14 @@ GameObject: - component: {fileID: 935483303140078260} - component: {fileID: 935483303140078262} - component: {fileID: 935483303140078263} - - component: {fileID: 3804747680621674853} + - component: {fileID: 935483303140078264} m_Layer: 5 m_Name: AnimDefAndActorCard m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!222 &935483303140078262 CanvasRenderer: m_ObjectHideFlags: 0 @@ -40373,6 +40473,31 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!114 &935483303140078264 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 935483303140078261} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_Spacing: 0 + m_ChildForceExpandWidth: 0 + m_ChildForceExpandHeight: 0 + m_ChildControlWidth: 0 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 --- !u!1 &935483303288600274 GameObject: m_ObjectHideFlags: 0 @@ -40436,7 +40561,7 @@ MonoBehaviour: onValueChanged: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 3804747680621674853} + - m_Target: {fileID: 0} m_MethodName: OnValueChanged m_Mode: 1 m_Arguments: @@ -40461,14 +40586,14 @@ RectTransform: m_Children: - {fileID: 935483304659652922} - {fileID: 935483304589176913} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 10 + m_Father: {fileID: 1216651060} + m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 1} - m_AnchoredPosition: {x: -69, y: -305} + m_AnchoredPosition: {x: -69, y: -95.5} m_SizeDelta: {x: 150, y: 20} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!222 &935483303314225216 CanvasRenderer: m_ObjectHideFlags: 0 @@ -40609,14 +40734,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 21 + m_Father: {fileID: 1216651060} + m_RootOrder: 17 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -65, y: -435} + m_AnchoredPosition: {x: -67.35016, y: -215} m_SizeDelta: {x: 17.537262, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!222 &935483303345155103 CanvasRenderer: m_ObjectHideFlags: 0 @@ -40923,7 +41048,7 @@ MonoBehaviour: m_OnValueChanged: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 3804747680621674853} + - m_Target: {fileID: 0} m_MethodName: OnBodyTypeChanged m_Mode: 1 m_Arguments: @@ -40949,14 +41074,14 @@ RectTransform: - {fileID: 935483303916118577} - {fileID: 935483304684194972} - {fileID: 935483303425689024} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 18 + m_Father: {fileID: 1216651060} + m_RootOrder: 14 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 10, y: -435} + m_AnchoredPosition: {x: 10, y: -215} m_SizeDelta: {x: 120, y: 30} - m_Pivot: {x: 0, y: 0.5} + m_Pivot: {x: 0, y: 1} --- !u!114 &935483303909693488 MonoBehaviour: m_ObjectHideFlags: 0 @@ -41282,7 +41407,7 @@ MonoBehaviour: m_OnEndEdit: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 3804747680621674853} + - m_Target: {fileID: 0} m_MethodName: OnValueChanged m_Mode: 1 m_Arguments: @@ -41316,14 +41441,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 935483302828269144} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 22 + m_Father: {fileID: 1216651060} + m_RootOrder: 18 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -8.3498535, y: -435} + m_AnchoredPosition: {x: -10.7, y: -215} m_SizeDelta: {x: 60, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!1 &935483304221730466 GameObject: m_ObjectHideFlags: 0 @@ -41442,7 +41567,7 @@ MonoBehaviour: m_OnEndEdit: m_PersistentCalls: m_Calls: - - m_Target: {fileID: 3804747680621674853} + - m_Target: {fileID: 0} m_MethodName: OnValueChanged m_Mode: 1 m_Arguments: @@ -41484,14 +41609,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 935483304430676515} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 20 + m_Father: {fileID: 1216651060} + m_RootOrder: 16 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -94, y: -435} + m_AnchoredPosition: {x: -96.35016, y: -215} m_SizeDelta: {x: 60, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!1 &935483304332071719 GameObject: m_ObjectHideFlags: 0 @@ -41651,14 +41776,14 @@ RectTransform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 935483303140078260} - m_RootOrder: 17 + m_Father: {fileID: 1216651060} + m_RootOrder: 13 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 1.7409973, y: -405} + m_AnchoredPosition: {x: 0, y: -185} m_SizeDelta: {x: 0, y: 30} - m_Pivot: {x: 0.5, y: 0.5} + m_Pivot: {x: 0.5, y: 1} --- !u!1 &935483304393195703 GameObject: m_ObjectHideFlags: 0 @@ -42558,25 +42683,6 @@ MonoBehaviour: m_StringArgument: m_BoolArgument: 0 m_CallState: 2 ---- !u!114 &3804747680621674853 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 935483303140078261} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 9731614c7527b624492dd33f9b006fcb, type: 3} - m_Name: - m_EditorClassIdentifier: - bodyTypeDropdown: {fileID: 935483303887120942} - bodyOffsetXField: {fileID: 935483304332071713} - bodyOffsetZField: {fileID: 935483304128418022} - raceOffsetXField: {fileID: 375594583} - raceOffsetZField: {fileID: 1293104868} - initiatorToggle: {fileID: 935483303288600284} - selectActorLayerDropdown: {fileID: 1001419736} --- !u!224 &4070467796814498374 RectTransform: m_ObjectHideFlags: 0 @@ -42589,14 +42695,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 5155145354840193887} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 6 + m_Father: {fileID: 1216651060} + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: -9, y: -245} + m_AnchoredPosition: {x: -9, y: -30} m_SizeDelta: {x: 145, y: 30} - m_Pivot: {x: 1, y: 0.5} + m_Pivot: {x: 1, y: 1} --- !u!222 &4220699018471944123 CanvasRenderer: m_ObjectHideFlags: 0 @@ -42636,14 +42742,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 1453461556519350520} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 5 + m_Father: {fileID: 1216651060} + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 11, y: -245} + m_AnchoredPosition: {x: 10, y: -30} m_SizeDelta: {x: 145, y: 30} - m_Pivot: {x: 0, y: 0.5} + m_Pivot: {x: 0, y: 1} --- !u!1 &4446261852394827046 GameObject: m_ObjectHideFlags: 0 @@ -42918,14 +43024,14 @@ RectTransform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - {fileID: 7357923201829463118} - m_Father: {fileID: 935483303140078260} - m_RootOrder: 7 + m_Father: {fileID: 1216651060} + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 11, y: -275} + m_AnchoredPosition: {x: 10, y: -60} m_SizeDelta: {x: 145, y: 30} - m_Pivot: {x: 0, y: 0.5} + m_Pivot: {x: 0, y: 1} --- !u!222 &6164565606941102640 CanvasRenderer: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/AnimationComponents/AnimationClips.meta b/Assets/Scripts/1_To_update.meta similarity index 77% rename from Assets/Scripts/AnimationComponents/AnimationClips.meta rename to Assets/Scripts/1_To_update.meta index c8f155f2..b2a4c8e9 100644 --- a/Assets/Scripts/AnimationComponents/AnimationClips.meta +++ b/Assets/Scripts/1_To_update.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 20033872660014f4295d8ac40800a707 +guid: ff71352a02fb53440a35dbeabb9ebc87 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Scripts/AnimationComponents/Actor.cs b/Assets/Scripts/AnimationComponents/Actor.cs index cd4eaaf6..af479d7c 100644 --- a/Assets/Scripts/AnimationComponents/Actor.cs +++ b/Assets/Scripts/AnimationComponents/Actor.cs @@ -8,80 +8,143 @@ namespace RimWorldAnimationStudio { public class Actor { - [XmlArray("defNames"), XmlArrayItem("li")] public List defNames = new List(); - [XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List bodyDefTypes = new List(); - [XmlArray("requiredGender"), XmlArrayItem("li")] public List requiredGender = new List(); - [XmlArray("requiredGenitals"), XmlArrayItem("li")] public List requiredGenitals = new List(); - [XmlArray("raceOffsets"), XmlArrayItem("li")] public List raceOffsets = new List(); - [XmlArray("blacklistedRaces"), XmlArrayItem("li")] public List blacklistedRaces = new List(); + // Data to/from animationDef + [XmlArray("defNames"), XmlArrayItem("li")] public List defNames; + [XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List bodyDefTypes; + [XmlArray("requiredGenitals"), XmlArrayItem("li")] public List requiredGenitals; + [XmlArray("raceOffsets"), XmlArrayItem("li")] public List raceOffsets; [XmlArray("tags"), XmlArrayItem("li")] public List tags; + public BodyTypeOffset bodyTypeOffset; + public bool? initiator = false; + public bool? controlGenitalAngle; + public bool? isFucking; + public bool? isFucked; - [XmlIgnore] public ActorGender gender; - [XmlIgnore] private AlienRaceDef alienRaceDef; - - public BodyTypeOffset bodyTypeOffset = new BodyTypeOffset(); - public bool initiator = false; - public bool controlGenitalAngle; - public bool isFucking; - public bool isFucked; - - [XmlIgnore] public string bodyType = "Male"; - + // Data serialization control public bool ShouldSerializedefNames() { return defNames.NotNullOrEmpty(); } public bool ShouldSerializebodyDefTypes() { return bodyDefTypes.NotNullOrEmpty(); } - public bool ShouldSerializerequiredGender() { return requiredGender.NotNullOrEmpty(); } public bool ShouldSerializerequiredGenitals() { return requiredGenitals.NotNullOrEmpty(); } public bool ShouldSerializeraceOffsets() { return raceOffsets.NotNullOrEmpty(); } - public bool ShouldSerializeblacklistedRaces() { return blacklistedRaces.NotNullOrEmpty(); } public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); } - public bool ShouldSerializeinitiator() { return initiator; } - public bool ShouldSerializecontrolGenitalAngle() { return controlGenitalAngle; } - public bool ShouldSerializeisFucking() { return isFucking; } - public bool ShouldSerializeisFucked() { return isFucked; } + public bool ShouldSerializebodyTypeOffset() { return bodyTypeOffset?.AllOffsetsEmpty() == false; } + public bool ShouldSerializeinitiator() { return initiator == true; } + public bool ShouldSerializecontrolGenitalAngle() { return controlGenitalAngle == true; } + public bool ShouldSerializeisFucking() { return isFucking == true; } + public bool ShouldSerializeisFucked() { return isFucked == true; } - public AlienRaceDef GetAlienRaceDef() - { - if (alienRaceDef == null) - { alienRaceDef = AlienRaceDefs.GetNamed("Human"); } - - return alienRaceDef; + // Data helper functions + [XmlIgnore] public List DefNames + { + get { return defNames.NullOrEmpty() ? defNames = new List() : defNames; } + set { defNames = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); } } - public void SetAlienRaceDef(string alienRaceDefName) - { - AlienRaceDef alienRaceDef = AlienRaceDefs.GetNamed(alienRaceDefName); - - if (alienRaceDef != null) - { this.alienRaceDef = alienRaceDef; } + [XmlIgnore] public List BodyDefTypes + { + get { return bodyDefTypes.NullOrEmpty() ? bodyDefTypes = new List() : bodyDefTypes; } + set { bodyDefTypes = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); } } - public Vector3 GetAlienRaceOffset() - { - if (alienRaceDef == null) - { alienRaceDef = AlienRaceDefs.GetNamed("Human"); } + [XmlIgnore] public List RequiredGenitals + { + get { return requiredGenitals.NullOrEmpty() ? requiredGenitals = new List() : requiredGenitals; } + set { requiredGenitals = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); } + } - AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName); + [XmlIgnore] public List RaceOffsets { + get { return raceOffsets.NullOrEmpty() ? raceOffsets = new List() : raceOffsets; } + set { raceOffsets = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); } + } + + [XmlIgnore] public List Tags + { + get { return tags.NullOrEmpty() ? tags = new List() : tags; } + set { tags = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); } + } + + [XmlIgnore] public BodyTypeOffset BodyTypeOffset + { + get { return bodyTypeOffset == null ? bodyTypeOffset = new BodyTypeOffset() : bodyTypeOffset; } + set { bodyTypeOffset = value; EventsManager.OnActorChanged(this); } + } + + [XmlIgnore] public bool Initiator + { + get { return initiator == true; } + set { if (value) { initiator = true; } else initiator = null; EventsManager.OnActorChanged(this); } + } + + [XmlIgnore] public bool ControlGenitalAngle + { + get { return controlGenitalAngle == true; } + set { if (value) { controlGenitalAngle = true; } else controlGenitalAngle = null; EventsManager.OnActorChanged(this); } + } + + [XmlIgnore] public bool IsFucking + { + get { return isFucking == true; } + set { if (value) { isFucking = true; } else isFucking = null; EventsManager.OnActorChanged(this); } + } + + [XmlIgnore] public bool IsFucked + { + get { return isFucked == true; } + set { if (value) { isFucked = true; } else isFucked = null; EventsManager.OnActorChanged(this); } + } + + // Local data + [XmlIgnore] public string bodyType = "Male"; + [XmlIgnore] private PawnRaceDef pawnRaceDef; + + // Methods + public PawnRaceDef GetPawnRaceDef() + { + if (pawnRaceDef == null) + { pawnRaceDef = PawnRaceDefs.GetNamed("Human"); } + + return pawnRaceDef; + } + + public void SetPawnRaceDef(string pawnRaceDefName) + { + PawnRaceDef pawnRaceDef = PawnRaceDefs.GetNamed(pawnRaceDefName); + + if (pawnRaceDef != null) + { + this.pawnRaceDef = pawnRaceDef; + EventsManager.OnActorChanged(this); + } + } + + public Vector3 GetPawnRaceOffset() + { + if (pawnRaceDef == null) + { pawnRaceDef = PawnRaceDefs.GetNamed("Human"); } + + PawnRaceOffset raceOffset = RaceOffsets.FirstOrDefault(x => x.defName == pawnRaceDef.defName); if (raceOffset == null) { - raceOffset = new AlienRaceOffset(alienRaceDef.defName); - raceOffsets.Add(raceOffset); + raceOffset = new PawnRaceOffset(pawnRaceDef.defName); + RaceOffsets.Add(raceOffset); } return raceOffset.GetOffset(); } - public void SetAlienRaceOffset(Vector2 offset) + public void SetPawnRaceOffset(Vector2 offset) { - if (alienRaceDef == null) + if (pawnRaceDef == null) { return; } - AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName); + PawnRaceOffset raceOffset = RaceOffsets.FirstOrDefault(x => x.defName == pawnRaceDef.defName); if (raceOffset == null) { - raceOffset = new AlienRaceOffset(alienRaceDef.defName); - raceOffsets.Add(raceOffset); + raceOffset = new PawnRaceOffset(pawnRaceDef.defName); + RaceOffsets.Add(raceOffset); + + EventsManager.OnActorChanged(this); } raceOffset.SetOffset(offset); @@ -89,46 +152,25 @@ namespace RimWorldAnimationStudio public Vector3 GetFinalTransformOffset() { - Vector3 offset = GetAlienRaceOffset() + (GetAlienRaceDef().isHumanoid ? bodyTypeOffset.GetOffset(bodyType) : new Vector3()); + Vector3 offset = GetPawnRaceOffset() + (GetPawnRaceDef().isHumanoid ? BodyTypeOffset.GetOffset(bodyType) : new Vector3()); return new Vector3(offset.x, offset.z, offset.y); } - public void ValidateData() - { - bodyDefTypes = bodyDefTypes.Intersect(Tags.bodyDefTypes.Concat(CustomTags.bodyDefTypes))?.ToList(); - requiredGenitals = requiredGenitals.Intersect(Tags.bodyParts.Concat(CustomTags.bodyParts))?.ToList(); - raceOffsets = raceOffsets.Except(raceOffsets.Where(x => x.OffsetIsZero()))?.ToList(); - } - - public bool MakeNew() - { - if (Workspace.animationDef == null) - { Debug.LogWarning("Cannot make new actor - there is no AnimationDef"); return false; } - - Workspace.animationDef.actors.Add(this); - Workspace.actorID = Workspace.animationDef.actors.Count - 1; - - foreach (AnimationStage stage in Workspace.animationDef.animationStages) - { - PawnAnimationClip clip = new PawnAnimationClip(); - - if (clip.MakeNew()) - { - stage.animationClips.Add(clip); - stage.Initialize(); - stage.OnPostLoad(); - } - } - - return true; - } - public int GetActorID() { if (Workspace.animationDef == null) return -1; - - return Workspace.animationDef.actors.IndexOf(this); + return Workspace.animationDef.Actors.IndexOf(this); } + + // Pre-save / post-load + public void OnPreSave() + { + BodyDefTypes = BodyDefTypes.Intersect(DefaultTags.bodyDefTypes.Concat(CustomTags.bodyDefTypes))?.ToList(); + RequiredGenitals = RequiredGenitals.Intersect(DefaultTags.bodyParts.Concat(CustomTags.bodyParts))?.ToList(); + RaceOffsets = RaceOffsets.Except(RaceOffsets.Where(x => x.OffsetIsZero()))?.ToList(); + } + + public void OnPostLoad() { } } } diff --git a/Assets/Scripts/AnimationComponents/Actor.cs.meta b/Assets/Scripts/AnimationComponents/Actor.cs.meta index 4848df55..8aac977c 100644 --- a/Assets/Scripts/AnimationComponents/Actor.cs.meta +++ b/Assets/Scripts/AnimationComponents/Actor.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ca7cd67490c5773499bff5c06907bdf7 +guid: 63a9fd7a0256e9849bc2bc07403528e8 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/ActorAddon.cs b/Assets/Scripts/AnimationComponents/ActorAddon.cs index 9d3103b7..94a4189a 100644 --- a/Assets/Scripts/AnimationComponents/ActorAddon.cs +++ b/Assets/Scripts/AnimationComponents/ActorAddon.cs @@ -4,28 +4,69 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; +using UnityEngine; namespace RimWorldAnimationStudio { public class ActorAddon { + // Data to/from animationDef public string addonName; - public int anchoringActor; + public int? anchoringActor; public string anchorName; public string layer = "Pawn"; - public float scale; - public bool render; + public float? scale; + public bool? render; + // Data helper functions + [XmlIgnore] public string AddonName + { + get { return addonName; } + set { addonName = value; } + } + + [XmlIgnore] public int AnchoringActor + { + get { return anchoringActor.HasValue ? anchoringActor.Value : 0; } + set { anchoringActor = value; EventsManager.OnActorAddonChanged(this); } + } + + [XmlIgnore] public string AnchorName + { + get { return anchorName; } + set { anchorName = value; EventsManager.OnActorAddonChanged(this); } + } + + [XmlIgnore] public string Layer + { + get { return layer; } + set { layer = value; EventsManager.OnActorAddonChanged(this); } + } + + [XmlIgnore] public float Scale + { + get { return scale.HasValue ? scale.Value : 0f; } + set { scale = value; EventsManager.OnActorAddonChanged(this); } + } + + [XmlIgnore] public bool Render + { + get { return render == true; } + set { render = value; EventsManager.OnActorAddonChanged(this); } + } + + // Simple curves [XmlIgnore] public SimpleCurve PosX = new SimpleCurve(); [XmlIgnore] public SimpleCurve PosZ = new SimpleCurve(); [XmlIgnore] public SimpleCurve Rotation = new SimpleCurve(); + // Constructors public ActorAddon() { } public ActorAddon(string addonName, float scale = 1f) { - this.addonName = addonName; - this.scale = scale; + this.AddonName = addonName; + this.Scale = scale; } } } diff --git a/Assets/Scripts/AnimationComponents/ActorAddon.cs.meta b/Assets/Scripts/AnimationComponents/ActorAddon.cs.meta index 4d517736..5eda85a2 100644 --- a/Assets/Scripts/AnimationComponents/ActorAddon.cs.meta +++ b/Assets/Scripts/AnimationComponents/ActorAddon.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f4d87003a570d5241affe4170ae91045 +guid: 3759e796f4f62b044b9a652e746d79a1 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/AddonKeyFrame.cs b/Assets/Scripts/AnimationComponents/AddonKeyFrame.cs new file mode 100644 index 00000000..0a0f2fa0 --- /dev/null +++ b/Assets/Scripts/AnimationComponents/AddonKeyFrame.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Xml; +using System.Xml.Serialization; +using UnityEngine; + +namespace RimWorldAnimationStudio +{ + public class AddonKeyframe + { + // Data to/from animationDef + public string addonName; + public float? posX; + public float? posZ; + public float? rotation; + + // Data helper functions + [XmlIgnore] public string AddonName + { + get { return addonName; } + set { addonName = value; } + } + + [XmlIgnore] public float PosX + { + get { return posX.HasValue ? posX.Value : 0f; } + set { posX = value; EventsManager.OnAddonKeyframeChanged(this); } + } + + [XmlIgnore] public float PosZ + { + get { return posZ.HasValue ? posZ.Value : 0f; } + set { posZ = value; EventsManager.OnAddonKeyframeChanged(this); } + } + + [XmlIgnore] public float Rotation + { + get { return rotation.HasValue ? rotation.Value : 0f; } + set { rotation = value; EventsManager.OnAddonKeyframeChanged(this); } + } + + // Constructors + public AddonKeyframe() { } + + public AddonKeyframe(string addonName) + { + this.AddonName = addonName; + } + } +} diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/AddonKeyFrame.cs.meta b/Assets/Scripts/AnimationComponents/AddonKeyFrame.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/KeyFrames/AddonKeyFrame.cs.meta rename to Assets/Scripts/AnimationComponents/AddonKeyFrame.cs.meta index 2c365526..ad200690 100644 --- a/Assets/Scripts/AnimationComponents/KeyFrames/AddonKeyFrame.cs.meta +++ b/Assets/Scripts/AnimationComponents/AddonKeyFrame.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 60509e7cd8e74e6419c5c93304440a17 +guid: 339d47b209f50f545a84a8e8c7948ae1 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/AnimationClips/AnimationClip.cs b/Assets/Scripts/AnimationComponents/AnimationClips/AnimationClip.cs deleted file mode 100644 index 9f26d4fb..00000000 --- a/Assets/Scripts/AnimationComponents/AnimationClips/AnimationClip.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using System.Xml; -using System.Xml.Serialization; - -namespace RimWorldAnimationStudio -{ - public abstract class AnimationClip - { - public string layer = "Pawn"; - public List tags; - - public virtual int duration { get { return 0; } } - - public abstract void BuildSimpleCurves(); - - public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); } - - public virtual void ValidateData() { } - } -} diff --git a/Assets/Scripts/AnimationComponents/AnimationClips/PawnAnimationClip.cs b/Assets/Scripts/AnimationComponents/AnimationClips/PawnAnimationClip.cs deleted file mode 100644 index 69229d55..00000000 --- a/Assets/Scripts/AnimationComponents/AnimationClips/PawnAnimationClip.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; -using System.Xml.Serialization; -using UnityEngine; - -namespace RimWorldAnimationStudio -{ - public class PawnAnimationClip : AnimationClip - { - [XmlArray("addons"), XmlArrayItem("li")] public List _addons = new List(); - [XmlIgnore] public List addons = new List(); - - [XmlAttribute("Class")] public string className = "Rimworld_Animations.PawnAnimationClip"; - [XmlArray("keyframes"), XmlArrayItem("li")] public List keyframes = new List(); - - [XmlIgnore] public Dictionary quiver = new Dictionary(); - [XmlIgnore] public SimpleCurve GenitalAngle = new SimpleCurve(); - [XmlIgnore] public SimpleCurve BodyAngle = new SimpleCurve(); - [XmlIgnore] public SimpleCurve HeadAngle = new SimpleCurve(); - [XmlIgnore] public SimpleCurve HeadBob = new SimpleCurve(); - [XmlIgnore] public SimpleCurve BodyOffsetX = new SimpleCurve(); - [XmlIgnore] public SimpleCurve BodyOffsetZ = new SimpleCurve(); - [XmlIgnore] public SimpleCurve HeadFacing = new SimpleCurve(); - [XmlIgnore] public SimpleCurve BodyFacing = new SimpleCurve(); - - public override int duration { get { return keyframes.Max(x => x.atTick.Value); } } - - public override void BuildSimpleCurves() - { - BodyAngle.Clear(); - HeadAngle.Clear(); - BodyOffsetX.Clear(); - BodyOffsetZ.Clear(); - HeadFacing.Clear(); - BodyFacing.Clear(); - HeadBob.Clear(); - GenitalAngle.Clear(); - - foreach (ActorAddon addon in addons) - { - addon.PosX.Clear(); - addon.PosZ.Clear(); - addon.Rotation.Clear(); - } - - int keyframePosition = 0; - int duration = 0; - - keyframes[keyframes.Count - 1].tickDuration = 1; - - foreach (PawnKeyframe frame in keyframes) - { duration += frame.tickDuration; } - - for (int i = 0; i < keyframes.Count; i++) - { - PawnKeyframe keyframe = keyframes[i]; - - if (keyframe.atTick.HasValue) - { - if (keyframe.HasValidKeyframeID() == false) - { keyframe.GenerateKeyframeID(Workspace.animationDef.animationStages[Workspace.stageID].animationClips.IndexOf(this)); } - - BodyAngle.Add((float)keyframe.atTick / (float)duration, keyframe.bodyAngle, true); - HeadAngle.Add((float)keyframe.atTick / (float)duration, keyframe.headAngle, true); - BodyOffsetX.Add((float)keyframe.atTick / (float)duration, keyframe.bodyOffsetX, true); - BodyOffsetZ.Add((float)keyframe.atTick / (float)duration, keyframe.bodyOffsetZ, true); - HeadFacing.Add((float)keyframe.atTick / (float)duration, keyframe.headFacing, true); - BodyFacing.Add((float)keyframe.atTick / (float)duration, keyframe.bodyFacing, true); - HeadBob.Add((float)keyframe.atTick / (float)duration, keyframe.headBob, true); - GenitalAngle.Add((float)keyframe.atTick / (float)duration, keyframe.genitalAngle, true); - - foreach (ActorAddon addon in addons) - { - if (keyframe.addonKeyframes.Any(x => x.addonName == addon.addonName) == false) - { keyframe.addonKeyframes.Add(new AddonKeyframe(addon.addonName)); } - - addon.PosX.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.addonName).posX, true); - addon.PosZ.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.addonName).posZ, true); - addon.Rotation.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.addonName).rotation, true); - } - - if (i + 1 < keyframes.Count) - { keyframes[i].tickDuration = keyframes[i + 1].atTick.Value - keyframes[i].atTick.Value; } - } - - else - { - BodyAngle.Add((float)keyframePosition / (float)duration, keyframe.bodyAngle, true); - HeadAngle.Add((float)keyframePosition / (float)duration, keyframe.headAngle, true); - BodyOffsetX.Add((float)keyframePosition / (float)duration, keyframe.bodyOffsetX, true); - BodyOffsetZ.Add((float)keyframePosition / (float)duration, keyframe.bodyOffsetZ, true); - HeadFacing.Add((float)keyframePosition / (float)duration, keyframe.headFacing, true); - BodyFacing.Add((float)keyframePosition / (float)duration, keyframe.bodyFacing, true); - HeadBob.Add((float)keyframePosition / (float)duration, keyframe.headBob, true); - GenitalAngle.Add((float)keyframePosition / (float)duration, keyframe.genitalAngle, true); - - foreach (ActorAddon addon in addons) - { - if (keyframe.addonKeyframes.Any(x => x.addonName == addon.addonName) == false) - { keyframe.addonKeyframes.Add(new AddonKeyframe(addon.addonName)); } - - addon.PosX.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.addonName).posX, true); - addon.PosZ.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.addonName).posZ, true); - addon.Rotation.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.addonName).rotation, true); - } - - if (keyframe.tickDuration != 1 && keyframe.quiver.HasValue) - { - quiver.Add(keyframePosition, true); - quiver.Add(keyframePosition + keyframe.tickDuration - 1, false); - } - - keyframe.atTick = keyframePosition + Constants.minTick; - keyframePosition += keyframe.tickDuration; - } - } - } - - public void AddActorAddon(string addonName, float scale = 1f) - { - if (addons.Any(x => x.addonName == addonName) == false) - { - addons.Add(new ActorAddon(addonName, scale)); - } - - foreach (PawnKeyframe keyframe in keyframes) - { - if (keyframe.addonKeyframes.Any(x => x.addonName == addonName) == false) - { keyframe.addonKeyframes.Add(new AddonKeyframe(addonName)); } - } - } - - public void ShowOrHideActorAddon(string addonName, bool flag) - { - ActorAddon addon = GetActorAddon(addonName); - - if (addon != null) - { addon.render = flag; } - } - - public bool IsActorAddonVisible(string addonName) - { - ActorAddon addon = GetActorAddon(addonName); - - if (addon != null) - { return addon.render; } - - return false; - } - - public ActorAddon GetActorAddon(string addonName) - { - return addons.FirstOrDefault(x => x.addonName == addonName); - } - - public override void ValidateData() - { - _addons.Clear(); - - foreach (ActorAddon addon in addons) - { - Debug.Log(addon.anchorName); - - if (addon.render) - { - _addons.Add(addon); - } - } - } - - public int GetOwningActorID() - { - if (Workspace.animationDef == null) return -1; - - return Workspace.animationDef.animationStages[Workspace.stageID].animationClips.IndexOf(this); - } - - public bool MakeNew(int actorID = -1) - { - PawnKeyframe lastkeyframe = null; - - if (actorID >= 0) - { lastkeyframe = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID]?.keyframes?.Last(); } - - if (lastkeyframe != null) - { - PawnKeyframe keyframeA = lastkeyframe.Copy(); - keyframeA.atTick = null; - keyframeA.tickDuration = Constants.defaultAnimationClipLength - 1; - keyframeA.GenerateKeyframeID(actorID); - keyframes.Add(keyframeA); - - PawnKeyframe keyframeB = lastkeyframe.Copy(); - keyframeB.atTick = null; - keyframeB.tickDuration = 1; - keyframeB.GenerateKeyframeID(actorID); - keyframes.Add(keyframeB); - } - - else - { - PawnKeyframe keyframeA = new PawnKeyframe(); - keyframeA.tickDuration = Constants.defaultAnimationClipLength - 1; - keyframes.Add(keyframeA); - - PawnKeyframe keyframeB = new PawnKeyframe(); - keyframes.Add(keyframeB); - } - - BuildSimpleCurves(); - return true; - } - - public void OnPostLoad() - { - addons = _addons.Copy(); - - foreach (PawnKeyframe keyframe in keyframes) - { - keyframe.OnPostLoad(); - } - - AddActorAddon("left hand", 0.667f); - AddActorAddon("right hand", 0.667f); - AddActorAddon("dildo"); - } - } -} diff --git a/Assets/Scripts/AnimationComponents/AnimationClips/ThingAnimationClip.cs b/Assets/Scripts/AnimationComponents/AnimationClips/ThingAnimationClip.cs deleted file mode 100644 index 486c8be8..00000000 --- a/Assets/Scripts/AnimationComponents/AnimationClips/ThingAnimationClip.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Xml; -using System.Xml.Serialization; - -namespace RimWorldAnimationStudio -{ - public class ThingAnimationClip : AnimationClip - { - [XmlAttribute("Class")] public string className = "Rimworld_Animations.ThingAnimationClip"; - [XmlArray("keyframes"), XmlArrayItem("li")] public List keyframes = new List(); - - [XmlIgnore] public SimpleCurve PositionX = new SimpleCurve(); - [XmlIgnore] public SimpleCurve PositionZ = new SimpleCurve(); - [XmlIgnore] public SimpleCurve Rotation = new SimpleCurve(); - - public override int duration { get { return keyframes.Max(x => x.atTick.Value); } } - - public override void BuildSimpleCurves() - { - int duration = 0; - - //getting the length of the whole clip - foreach (ThingKeyframe frame in keyframes) - { - duration += frame.tickDuration; - } - - //guarantees loops don't get cut off mid-anim - //this.duration = duration; - - int keyframePosition = 0; - foreach (ThingKeyframe frame in keyframes) - { - if (frame.atTick.HasValue) - { - PositionX.Add((float)frame.atTick / (float)duration, frame.positionX, true); - PositionZ.Add((float)frame.atTick / (float)duration, frame.positionZ, true); - Rotation.Add((float)frame.atTick / (float)duration, frame.rotation, true); - } - - else - { - PositionX.Add((float)keyframePosition / (float)duration, frame.positionX, true); - PositionZ.Add((float)keyframePosition / (float)duration, frame.positionZ, true); - Rotation.Add((float)keyframePosition / (float)duration, frame.rotation, true); - - keyframePosition += frame.tickDuration; - } - } - } - } -} diff --git a/Assets/Scripts/AnimationComponents/AnimationDef.cs b/Assets/Scripts/AnimationComponents/AnimationDef.cs index fa44c7c5..8ecd4677 100644 --- a/Assets/Scripts/AnimationComponents/AnimationDef.cs +++ b/Assets/Scripts/AnimationComponents/AnimationDef.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Xml; using System.Xml.Serialization; @@ -8,33 +9,163 @@ namespace RimWorldAnimationStudio { public class AnimationDef { - public string defName = "Undefined"; - public string label = "Undefined"; + // Data to/from animationDef + public string defName; + public string label; public bool sounds = true; + [XmlArray("sexTypes"), XmlArrayItem("li")] public List sexTypes; + [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List interactionDefTypes; + [XmlArray("actors"), XmlArrayItem("li")] public List actors; + [XmlArray("animationStages"), XmlArrayItem("li")] public List animationStages; - [XmlArray("sexTypes"), XmlArrayItem("li")] public List sexTypes = new List(); - [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List interactionDefTypes = new List(); - [XmlArray("actors"), XmlArrayItem("li")] public List actors = new List(); - [XmlArray("animationStages"), XmlArrayItem("li")] public List animationStages = new List(); - - [XmlIgnore] public int animationTimeTicks { get { return animationStages.Sum(x => x.playTimeTicks); } } - [XmlIgnore] public int animationTimeTicksQuick { get { return animationStages.Sum(x => x.playTimeTicksQuick); } } - + // Data serialization control public bool ShouldSerializesexTypes() { return sexTypes.NotNullOrEmpty(); } public bool ShouldSerializeinteractionDefTypes() { return interactionDefTypes.NotNullOrEmpty(); } public bool ShouldSerializeactors() { return actors.NotNullOrEmpty(); } public bool ShouldSerializeanimationStages() { return animationStages.NotNullOrEmpty(); } + // Data helper functions + [XmlIgnore] public string DefName + { + get { return defName != null && defName != "" ? defName : "newAnimation"; } + set { defName = value; EventsManager.OnAnimationDefChanged(); } + } + + [XmlIgnore] public string Label + { + get { return label != null && label != "" ? label : "newAnimation"; } + set { label = value; EventsManager.OnAnimationDefChanged(); } + } + + [XmlIgnore] public List SexTypes + { + get { return sexTypes.NullOrEmpty() ? sexTypes = new List() : sexTypes; } + set { sexTypes = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); } + } + + [XmlIgnore] public List InteractionDefTypes + { + get { return interactionDefTypes.NullOrEmpty() ? interactionDefTypes = new List() : interactionDefTypes; } + set { interactionDefTypes = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); } + } + + [XmlIgnore] public List Actors + { + get { return actors.NullOrEmpty() ? actors = new List() : actors; } + set { actors = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); } + } + + [XmlIgnore] public List AnimationStages + { + get { if (animationStages.NullOrEmpty()){ animationStages = new List(); } return animationStages; } + set { animationStages = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); } + } + + // Local data + [XmlIgnore] public int animationTimeTicks { get { return AnimationStages.Sum(x => x.PlayTimeTicks); } } + [XmlIgnore] public int animationTimeTicksQuick { get { return AnimationStages.Sum(x => x.PlayTimeTicksQuick); } } + + // Methods public void Initialize() { - foreach (AnimationStage stage in animationStages) + foreach (AnimationStage stage in AnimationStages) { stage.Initialize(); } } - public void ValidateData() + public void AddActor() { - sexTypes = sexTypes.Intersect(Tags.sexTypes.Concat(CustomTags.sexTypes))?.ToList(); - interactionDefTypes = interactionDefTypes.Intersect(Tags.interactionDefTypes.Concat(CustomTags.interactionDefTypes))?.ToList(); + if (Workspace.animationDef.Actors.Count >= 8) + { + Debug.LogWarning("Cannot add actor - the animation can only contain a maximum of eight actors."); + return; + } + + Actor actor = new Actor(); + Actors.Add(actor); + + Workspace.ActorID = Workspace.animationDef.Actors.Count - 1; + + foreach (AnimationStage stage in Workspace.animationDef.AnimationStages) + { stage.AddAnimationClip(Workspace.ActorID); } + + EventsManager.OnActorCountChanged(); + Workspace.RecordEvent("Actor addition"); } + + public void RemoveActor() + { + if (Workspace.animationDef.Actors.Count == 1) + { + Debug.LogWarning("Cannot delete actor - the animation must contain at least one actor."); + return; + } + + foreach (AnimationStage stage in Workspace.animationDef.AnimationStages) + { stage.AnimationClips.RemoveAt(Workspace.ActorID); } + + Workspace.animationDef.Actors.RemoveAt(Workspace.ActorID); + Workspace.ActorID--; + + EventsManager.OnActorCountChanged(); + Workspace.RecordEvent("Actor deletion"); + } + + public void AddAnimationStage() + { + AnimationStage stage = new AnimationStage(); + AnimationStages.Add(stage); + + foreach (Actor actor in Workspace.animationDef.Actors) + { stage.AddAnimationClip(actor.GetActorID()); } + + Initialize(); + + Workspace.RecordEvent("Stage addition"); + } + + public void CloneAnimationStage() + { + AnimationStage stage = Workspace.GetCurrentAnimationStage().Copy(); + stage.StageName += " (Clone)"; + stage.Initialize(); + + Workspace.animationDef.AnimationStages.Insert(Workspace.StageID + 1, stage); + Workspace.RecordEvent("Stage clone"); + } + + public void MoveAnimationStage(int startIndex, int delta) + { + if (startIndex + delta < 0 || startIndex + delta >= AnimationStages.Count) return; + + AnimationStage stage = AnimationStages[startIndex]; + AnimationStages[startIndex] = Workspace.animationDef.AnimationStages[startIndex + delta]; + AnimationStages[startIndex + delta] = stage; + + Workspace.StageID = startIndex + delta; + Workspace.RecordEvent("Stage move"); + } + + public void RemoveAnimationStage() + { + if (Workspace.animationDef.AnimationStages.Count == 1) + { + Debug.LogWarning("Cannot delete animation stage - the animation must contain at least one animation stage."); + return; + } + + AnimationStages.RemoveAt(Workspace.StageID); + + Workspace.StageID--; + Workspace.RecordEvent("Stage deletion"); + } + + // Pre-save / post-load + public void OnPreSave() + { + SexTypes = SexTypes.Intersect(DefaultTags.sexTypes.Concat(CustomTags.sexTypes))?.ToList(); + InteractionDefTypes = InteractionDefTypes.Intersect(DefaultTags.interactionDefTypes.Concat(CustomTags.interactionDefTypes))?.ToList(); + } + + public void OnPostLoad() { } } } diff --git a/Assets/Scripts/AnimationComponents/AnimationDef.cs.meta b/Assets/Scripts/AnimationComponents/AnimationDef.cs.meta index 8c99f55f..a45270f7 100644 --- a/Assets/Scripts/AnimationComponents/AnimationDef.cs.meta +++ b/Assets/Scripts/AnimationComponents/AnimationDef.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 9cca833a1987a2749aa6e4d640d32266 +guid: 37ec1f5f150928e42bda942fe97046b9 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/AnimationStage.cs b/Assets/Scripts/AnimationComponents/AnimationStage.cs index 4a26b21f..3b966185 100644 --- a/Assets/Scripts/AnimationComponents/AnimationStage.cs +++ b/Assets/Scripts/AnimationComponents/AnimationStage.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Xml; using System.Xml.Serialization; @@ -8,68 +9,145 @@ namespace RimWorldAnimationStudio { public class AnimationStage { - public string stageName = "NewStage"; - public int stageIndex = 0; - public int playTimeTicks = 0; - public int playTimeTicksQuick = 0; - public bool isLooping = false; + // Data to/from animationDef + [SerializeField] private string stageName; + [SerializeField] private int? playTimeTicks; + [SerializeField] private int? playTimeTicksQuick; + [SerializeField] private bool? isLooping; + [SerializeField, XmlArray("animationClips"), XmlArrayItem("li")] public List animationClips; - [XmlArray("animationClips"), XmlArrayItem("li")] public List animationClips = new List(); + // Data serialization control + public bool ShouldSerializeanimationClips() { return animationClips.NotNullOrEmpty(); } + + // Data helper functions + [XmlIgnore] public string StageName + { + get { return stageName != null && stageName != "" ? stageName : "NewStage"; } + set { stageName = value; EventsManager.OnAnimationStageChanged(this); } + } + + [XmlIgnore] public int PlayTimeTicks + { + get { return playTimeTicks.HasValue ? playTimeTicks.Value : 0; } + set { playTimeTicks = value; EventsManager.OnAnimationStageChanged(this); } + } + + [XmlIgnore] public int PlayTimeTicksQuick + { + get { return playTimeTicksQuick.HasValue ? playTimeTicksQuick.Value : 0; } + set { playTimeTicksQuick = value; EventsManager.OnAnimationStageChanged(this); } + } + + [XmlIgnore] public bool IsLooping + { + get { return isLooping == true; } + set { isLooping = value; EventsManager.OnAnimationStageChanged(this); } + } + + [XmlIgnore] public List AnimationClips + { + get { return animationClips.NullOrEmpty() ? animationClips = new List() : animationClips; } + set { animationClips = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationStageChanged(this); } + } + + // Local data [XmlIgnore] public int stageWindowSize = -1; + // Methods public void Initialize() { - foreach (PawnAnimationClip clip in animationClips) + foreach (PawnAnimationClip clip in AnimationClips) { clip.BuildSimpleCurves(); - // Select playTimeTicks as longest playtime of all the animations - if (clip.duration > playTimeTicks) - { playTimeTicks = clip.duration; } + if (clip.duration > PlayTimeTicks) + { PlayTimeTicks = clip.duration; } } - } - public void ValidateData() - { - // Sort keyframes by atTick - foreach (PawnAnimationClip clip in animationClips) - { clip.keyframes = clip.keyframes.OrderBy(x => x.atTick).ToList(); } + PlayTimeTicksQuick = PlayTimeTicks; } public int GetStageID() { if (Workspace.animationDef == null) return -1; - return Workspace.animationDef.animationStages.IndexOf(this); + return Workspace.animationDef.AnimationStages.IndexOf(this); } - public bool MakeNew() + public void StretchStageWindow(int newStageWindowSize) { - if (Workspace.animationDef == null) - { Debug.LogWarning("Cannot make new animation stage - there is no AnimationDef"); return false; } + float scale = (float)newStageWindowSize / Workspace.StageWindowSize; - Workspace.animationDef.animationStages.Add(this); - - foreach (Actor actor in Workspace.animationDef.actors) + foreach (PawnAnimationClip clip in Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips) { - PawnAnimationClip clip = new PawnAnimationClip(); + foreach (PawnKeyframe keyframe in clip.Keyframes) + { + keyframe.TickDuration = Mathf.RoundToInt(keyframe.TickDuration * scale); + keyframe.atTick = null; + } - if (clip.MakeNew(actor.GetActorID())) - { animationClips.Add(clip); } + clip.BuildSimpleCurves(); + } + } + + public void ResizeStageWindow(int newStageWindowSize) + { + Workspace.GetCurrentAnimationStage().stageWindowSize = newStageWindowSize; + Workspace.GetCurrentAnimationStage().PlayTimeTicks = newStageWindowSize * Workspace.stageLoopsNormal; + Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick = newStageWindowSize * Workspace.stageLoopsQuick; + } + + public void AddAnimationClip(int actorID = -1) + { + PawnAnimationClip clip = new PawnAnimationClip(); + PawnKeyframe lastkeyframe = null; + + if (actorID >= 0) + { lastkeyframe = Workspace.GetPawnAnimationClip(actorID)?.Keyframes?.Last(); } + + if (lastkeyframe != null) + { + PawnKeyframe keyframeA = lastkeyframe.Copy(); + keyframeA.atTick = null; + keyframeA.TickDuration = Constants.defaultAnimationClipLength - 1; + keyframeA.GenerateKeyframeID(actorID); + + clip.Keyframes.Add(keyframeA); + + PawnKeyframe keyframeB = lastkeyframe.Copy(); + keyframeB.atTick = null; + keyframeB.TickDuration = 1; + keyframeB.GenerateKeyframeID(actorID); + + clip.Keyframes.Add(keyframeB); } - Initialize(); - playTimeTicksQuick = playTimeTicks; + else + { + PawnKeyframe keyframeA = new PawnKeyframe(); + keyframeA.TickDuration = Constants.defaultAnimationClipLength - 1; - return true; + clip.Keyframes.Add(keyframeA); + + PawnKeyframe keyframeB = new PawnKeyframe(); + + clip.Keyframes.Add(keyframeB); + } + + clip.BuildSimpleCurves(); + } + + // Pre-save / post-load + public void OnPreSave() + { + foreach (PawnAnimationClip clip in AnimationClips) + { clip.Keyframes = clip.Keyframes.OrderBy(x => x.atTick).ToList(); } } public void OnPostLoad() { - foreach (PawnAnimationClip clip in animationClips) - { - clip.OnPostLoad(); - } + foreach (PawnAnimationClip clip in AnimationClips) + { clip.OnPostLoad(); } } } } diff --git a/Assets/Scripts/AnimationComponents/AnimationStage.cs.meta b/Assets/Scripts/AnimationComponents/AnimationStage.cs.meta index d46dd410..49ce46f5 100644 --- a/Assets/Scripts/AnimationComponents/AnimationStage.cs.meta +++ b/Assets/Scripts/AnimationComponents/AnimationStage.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4d62c568c0ad7ea4ba7ddd3b9aa6d0e9 +guid: 9270822a570a06f41afa00e169af500c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs b/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs index fd4a85ee..63b99162 100644 --- a/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs +++ b/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs @@ -1,6 +1,5 @@ using System.Reflection; using UnityEngine; -//using Microsoft.Toolkit.Uwp.UI; namespace RimWorldAnimationStudio { @@ -12,6 +11,11 @@ namespace RimWorldAnimationStudio public string Hulk; public string Fat; + public bool AllOffsetsEmpty() + { + return string.IsNullOrEmpty(Male) && string.IsNullOrEmpty(Female) && string.IsNullOrEmpty(Thin) && string.IsNullOrEmpty(Hulk) && string.IsNullOrEmpty(Fat); + } + public void SetOffset(string bodyType, Vector2 bodyOffset) { FieldInfo bodyTypeOffsetInfo = typeof(BodyTypeOffset).GetField(bodyType); diff --git a/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs.meta b/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs.meta index 2d9148a4..1b883413 100644 --- a/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs.meta +++ b/Assets/Scripts/AnimationComponents/BodyTypeOffset.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 6db04cc11995126429fb12578d6620d7 +guid: 1dfd90f8aa6d0e04086e2b4983d42ab6 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/Defs.cs.meta b/Assets/Scripts/AnimationComponents/Defs.cs.meta deleted file mode 100644 index 9839c338..00000000 --- a/Assets/Scripts/AnimationComponents/Defs.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 92804390faa29b945818e67cf808b49c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/AddonKeyFrame.cs b/Assets/Scripts/AnimationComponents/KeyFrames/AddonKeyFrame.cs deleted file mode 100644 index 7f695fd1..00000000 --- a/Assets/Scripts/AnimationComponents/KeyFrames/AddonKeyFrame.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using System.Xml; -using System.Xml.Serialization; - -namespace RimWorldAnimationStudio -{ - public class AddonKeyframe - { - public string addonName; - public float posX; - public float posZ; - public float rotation; - - public AddonKeyframe() { } - - public AddonKeyframe(string addonName) - { - this.addonName = addonName; - } - } -} diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/Keyframe.cs b/Assets/Scripts/AnimationComponents/KeyFrames/Keyframe.cs deleted file mode 100644 index a9a01908..00000000 --- a/Assets/Scripts/AnimationComponents/KeyFrames/Keyframe.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Xml; -using System.Xml.Serialization; - -namespace RimWorldAnimationStudio -{ - public class Keyframe - { - [XmlIgnore] public int? atTick; - - public int tickDuration = 1; - public string soundEffect; - public List tags = new List(); - - public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); } - - public virtual void ValidateData() { } - } -} diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/Keyframe.cs.meta b/Assets/Scripts/AnimationComponents/KeyFrames/Keyframe.cs.meta deleted file mode 100644 index 905dbc98..00000000 --- a/Assets/Scripts/AnimationComponents/KeyFrames/Keyframe.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c909440fcfe86c14c9e363377896367c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/PawnKeyframe.cs b/Assets/Scripts/AnimationComponents/KeyFrames/PawnKeyframe.cs deleted file mode 100644 index 25bd15d7..00000000 --- a/Assets/Scripts/AnimationComponents/KeyFrames/PawnKeyframe.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; -using System.Xml.Serialization; -using UnityEngine; -using UnityEngine.UI; - -namespace RimWorldAnimationStudio -{ - public class PawnKeyframe : Keyframe - { - public float bodyAngle; - public float headAngle; - public float headBob; - public float bodyOffsetX; - public float bodyOffsetZ; - public float headFacing = 2; - public float bodyFacing = 2; - - public float genitalAngle; - public bool? quiver; - - [XmlArray("addonKeyframes"), XmlArrayItem("li")] public List _addonKeyframes = new List(); - - [XmlIgnore] public List addonKeyframes = new List(); - [XmlIgnore] public int keyframeID; - [XmlIgnore] public int actorID = -1; - - public bool ShouldSerializegenitalAngle() { return genitalAngle != 0; } - public bool ShouldSerializequiver() { return quiver != null; } - - public override void ValidateData() - { - soundEffect = Tags.soundDefs.Concat(CustomTags.soundDefs).Contains(soundEffect) ? soundEffect : null; - - _addonKeyframes.Clear(); - - foreach (AddonKeyframe addonKeyframe in addonKeyframes) - { - ActorAddon addon = Workspace.Instance.GetAnimationClipThatOwnsKeyframe(keyframeID, out int clipID).GetActorAddon(addonKeyframe.addonName); - - if (addon.render) - { _addonKeyframes.Add(addonKeyframe.Copy()); } - } - } - - public void OnPostLoad() - { - addonKeyframes.Clear(); - - foreach (AddonKeyframe addonKeyframe in _addonKeyframes) - { - addonKeyframes.Add(addonKeyframe.Copy()); - } - } - - public void GenerateKeyframeID(int actorID) - { - this.actorID = actorID; - int _keyframeID = UnityEngine.Random.Range(100000, 1000000); - - if (Workspace.animationDef.animationStages.Any(x => x.animationClips.Any(y => y.keyframes.Any(z => z.keyframeID == _keyframeID)))) - { - GenerateKeyframeID(actorID); - return; - } - - keyframeID = _keyframeID; - } - - public bool HasValidKeyframeID() - { return keyframeID >= 100000 && keyframeID < 1000000; } - - public KeyframeSlider GetKeyframeSlider() - { - return Selectable.allSelectablesArray.FirstOrDefault(x => x.GetComponent()?.keyframeID == keyframeID)?.GetComponent< KeyframeSlider>(); - } - - public AddonKeyframe GetAddonKeyframe(string addonName) - { - return addonKeyframes.FirstOrDefault(x => x.addonName == addonName); - } - } -} diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/ThingKeyFrame.cs b/Assets/Scripts/AnimationComponents/KeyFrames/ThingKeyFrame.cs deleted file mode 100644 index 98d0ea7f..00000000 --- a/Assets/Scripts/AnimationComponents/KeyFrames/ThingKeyFrame.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using System.Xml; -using System.Xml.Serialization; - -namespace RimWorldAnimationStudio -{ - public class ThingKeyframe : Keyframe - { - public float positionX; - public float positionZ; - public float rotation; - } -} diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/ThingKeyFrame.cs.meta b/Assets/Scripts/AnimationComponents/KeyFrames/ThingKeyFrame.cs.meta deleted file mode 100644 index 57266d86..00000000 --- a/Assets/Scripts/AnimationComponents/KeyFrames/ThingKeyFrame.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 48d6c7ac273c73b498a8bf4c33fda2fc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Scripts/AnimationComponents/PawnAnimationClip.cs b/Assets/Scripts/AnimationComponents/PawnAnimationClip.cs new file mode 100644 index 00000000..629dee64 --- /dev/null +++ b/Assets/Scripts/AnimationComponents/PawnAnimationClip.cs @@ -0,0 +1,390 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; +using System.Xml.Serialization; +using UnityEngine; + +namespace RimWorldAnimationStudio +{ + public class PawnAnimationClip + { + // Data to/from animationDef + public string layer = "Pawn"; + [XmlArray("addons"), XmlArrayItem("li")] public List addons; + [XmlAttribute("Class")] public string className = "Rimworld_Animations.PawnAnimationClip"; + [XmlArray("keyframes"), XmlArrayItem("li")] public List keyframes; + [XmlArray("tags"), XmlArrayItem("li")] public List tags; + + // Data serialization control + public bool ShouldSerializeaddons() { return addons.Where(x => x.Render)?.Any() == true; } + public bool ShouldSerializekeyframes() { return keyframes.NotNullOrEmpty(); } + public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); } + + // Data helper functions + [XmlIgnore] public string Layer + { + get { return layer; } + set { layer = value; EventsManager.OnPawnAnimationClipChanged(this); } + } + + [XmlIgnore] public List Addons + { + get { return addons.NullOrEmpty() ? addons = new List() : addons; } + set { addons = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnAnimationClipChanged(this); } + } + + [XmlIgnore] public List Keyframes + { + get { return keyframes.NullOrEmpty() ? keyframes = new List() : keyframes; } + set { keyframes = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnAnimationClipChanged(this); } + } + + [XmlIgnore] + public List Tags + { + get { return tags.NullOrEmpty() ? tags = new List() : tags; } + set { tags = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnAnimationClipChanged(this); } + } + + // Local data + [XmlIgnore] public int duration { get { return Keyframes.Max(x => x.atTick.Value); } } + + [XmlIgnore] public SimpleCurve GenitalAngle = new SimpleCurve(); + [XmlIgnore] public SimpleCurve BodyAngle = new SimpleCurve(); + [XmlIgnore] public SimpleCurve HeadAngle = new SimpleCurve(); + [XmlIgnore] public SimpleCurve HeadBob = new SimpleCurve(); + [XmlIgnore] public SimpleCurve BodyOffsetX = new SimpleCurve(); + [XmlIgnore] public SimpleCurve BodyOffsetZ = new SimpleCurve(); + [XmlIgnore] public SimpleCurve HeadFacing = new SimpleCurve(); + [XmlIgnore] public SimpleCurve BodyFacing = new SimpleCurve(); + + // Methods + public void BuildSimpleCurves() + { + // Clear simple curve data + BodyAngle.Clear(); + HeadAngle.Clear(); + BodyOffsetX.Clear(); + BodyOffsetZ.Clear(); + HeadFacing.Clear(); + BodyFacing.Clear(); + HeadBob.Clear(); + GenitalAngle.Clear(); + + foreach (ActorAddon addon in Addons) + { + addon.PosX.Clear(); + addon.PosZ.Clear(); + addon.Rotation.Clear(); + } + + // Start + int keyframePosition = 0; + int duration = 0; + + Keyframes[Keyframes.Count - 1].TickDuration = 1; + + foreach (PawnKeyframe frame in Keyframes) + { duration += frame.TickDuration; } + + for (int i = 0; i < Keyframes.Count; i++) + { + PawnKeyframe keyframe = Keyframes[i]; + + if (keyframe.atTick.HasValue) + { + if (keyframe.HasValidKeyframeID() == false) + { keyframe.GenerateKeyframeID(Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips.IndexOf(this)); } + + BodyAngle.Add((float)keyframe.atTick / (float)duration, keyframe.BodyAngle, true); + HeadAngle.Add((float)keyframe.atTick / (float)duration, keyframe.HeadAngle, true); + BodyOffsetX.Add((float)keyframe.atTick / (float)duration, keyframe.BodyOffsetX, true); + BodyOffsetZ.Add((float)keyframe.atTick / (float)duration, keyframe.BodyOffsetZ, true); + HeadFacing.Add((float)keyframe.atTick / (float)duration, keyframe.HeadFacing, true); + BodyFacing.Add((float)keyframe.atTick / (float)duration, keyframe.BodyFacing, true); + HeadBob.Add((float)keyframe.atTick / (float)duration, keyframe.HeadBob, true); + GenitalAngle.Add((float)keyframe.atTick / (float)duration, keyframe.GenitalAngle, true); + + foreach (ActorAddon addon in Addons) + { + if (keyframe.AddonKeyframes.Any(x => x.AddonName == addon.AddonName) == false) + { keyframe.AddonKeyframes.Add(new AddonKeyframe(addon.AddonName)); } + + addon.PosX.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosX, true); + addon.PosZ.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosZ, true); + addon.Rotation.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).Rotation, true); + } + + if (i + 1 < Keyframes.Count) + { Keyframes[i].TickDuration = Keyframes[i + 1].atTick.Value - Keyframes[i].atTick.Value; } + } + + else + { + BodyAngle.Add((float)keyframePosition / (float)duration, keyframe.BodyAngle, true); + HeadAngle.Add((float)keyframePosition / (float)duration, keyframe.HeadAngle, true); + BodyOffsetX.Add((float)keyframePosition / (float)duration, keyframe.BodyOffsetX, true); + BodyOffsetZ.Add((float)keyframePosition / (float)duration, keyframe.BodyOffsetZ, true); + HeadFacing.Add((float)keyframePosition / (float)duration, keyframe.HeadFacing, true); + BodyFacing.Add((float)keyframePosition / (float)duration, keyframe.BodyFacing, true); + HeadBob.Add((float)keyframePosition / (float)duration, keyframe.HeadBob, true); + GenitalAngle.Add((float)keyframePosition / (float)duration, keyframe.GenitalAngle, true); + + foreach (ActorAddon addon in Addons) + { + if (keyframe.AddonKeyframes.Any(x => x.AddonName == addon.AddonName) == false) + { keyframe.AddonKeyframes.Add(new AddonKeyframe(addon.AddonName)); } + + addon.PosX.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosX, true); + addon.PosZ.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosZ, true); + addon.Rotation.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).Rotation, true); + } + + keyframe.atTick = keyframePosition + Constants.minTick; + keyframePosition += keyframe.TickDuration; + } + } + } + + public void AddActorAddon(string addonName, float scale = 1f) + { + if (Addons.Any(x => x.AddonName == addonName) == false) + { + Addons.Add(new ActorAddon(addonName, scale)); + } + + foreach (PawnKeyframe keyframe in Keyframes) + { + if (keyframe.AddonKeyframes.Any(x => x.AddonName == addonName) == false) + { keyframe.AddonKeyframes.Add(new AddonKeyframe(addonName)); } + } + } + + public void ShowOrHideActorAddon(string addonName, bool flag) + { + ActorAddon addon = GetActorAddon(addonName); + + if (addon != null) + { addon.Render = flag; } + } + + public bool IsActorAddonVisible(string addonName) + { + ActorAddon addon = GetActorAddon(addonName); + + if (addon != null) + { return addon.Render; } + + return false; + } + + public ActorAddon GetActorAddon(string addonName) + { + return Addons.FirstOrDefault(x => x.AddonName == addonName); + } + + public int GetOwningActorID() + { + if (Workspace.animationDef == null) return -1; + + return Workspace.GetCurrentAnimationStage().AnimationClips.IndexOf(this); + } + + public void AddPawnKeyframe() + { + PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip(); + List keyframes = clip?.Keyframes; + + if (clip == null || keyframes == null) + { Debug.LogWarning("Cannot add pawn keyframe - the AnimationDef is invalid"); return; } + + if (keyframes.FirstOrDefault(x => x.atTick == Workspace.StageTick) != null) + { Debug.LogWarning("Cannot add pawn keyframe - a keyframe already exists at this tick"); return; } + + float clipPercent = (float)(Workspace.StageTick % clip.duration) / clip.duration; + + PawnKeyframe keyframe = new PawnKeyframe(); + keyframe.BodyAngle = clip.BodyAngle.Evaluate(clipPercent); + keyframe.HeadAngle = clip.HeadAngle.Evaluate(clipPercent); + keyframe.HeadBob = clip.HeadBob.Evaluate(clipPercent); + keyframe.BodyOffsetX = clip.BodyOffsetX.Evaluate(clipPercent); + keyframe.BodyOffsetZ = clip.BodyOffsetZ.Evaluate(clipPercent); + keyframe.HeadFacing = (int)clip.HeadFacing.Evaluate(clipPercent); + keyframe.BodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent); + keyframe.GenitalAngle = clip.GenitalAngle.Evaluate(clipPercent); + + keyframe.atTick = Workspace.StageTick; + + PawnKeyframe nextKeyframe = keyframes.FirstOrDefault(x => x.atTick > Workspace.StageTick); + + if (nextKeyframe != null) + { keyframes.Insert(keyframes.IndexOf(nextKeyframe), keyframe); } + + else + { keyframes.Add(keyframe); } + + clip.BuildSimpleCurves(); + + Workspace.RecordEvent("Keyframe addition"); + } + + public void ClonePawnKeyframe() + { + List keyframesToClone = Workspace.GetPawnKeyframesByID(Workspace.keyframeID); + + foreach (PawnKeyframe keyframe in keyframesToClone) + { + PawnAnimationClip clip = Workspace.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID, out int clipID); + + if (clip == null) + { Debug.LogWarning("Cannot clone pawn keyframe - no clip owns this keyframe"); continue; } + + if (clip.Keyframes.FirstOrDefault(x => x.atTick == Workspace.StageTick) != null) + { Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; } + + PawnKeyframe cloneFrame = keyframe.Copy(); + cloneFrame.GenerateKeyframeID(clipID); + cloneFrame.atTick = Workspace.StageTick; + + PawnKeyframe nextKeyframe = clip.Keyframes.FirstOrDefault(x => x.atTick > Workspace.StageTick); + + if (nextKeyframe != null) + { clip.Keyframes.Insert(clip.Keyframes.IndexOf(nextKeyframe), cloneFrame); } + + else + { clip.Keyframes.Add(cloneFrame); } + + clip.BuildSimpleCurves(); + } + + Workspace.RecordEvent("Keyframe clone"); + } + + public void CopyPawnKeyframes() + { + Workspace.copiedKeyframes.Clear(); + + List keyframesToClone = Workspace.GetPawnKeyframesByID(Workspace.keyframeID); + + foreach (PawnKeyframe keyframe in keyframesToClone) + { Workspace.copiedKeyframes.Add(keyframe.Copy()); } + } + + public void PastePawnKeyframes() + { + int originalWindowSize = Workspace.StageWindowSize; + + List actorsInvolved = Workspace.copiedKeyframes.Select(x => x.actorID)?.ToList(); + actorsInvolved = actorsInvolved?.Distinct()?.ToList(); + + if (actorsInvolved.NullOrEmpty()) { Debug.Log("Cannot paste keyframes - there were no copied keyframes to paste"); return; } + if (actorsInvolved.Count > 1 && actorsInvolved.Contains(Workspace.ActorID) == false) { Debug.Log("Cannot paste keyframes - keyframes copied across multiple timelines can only be pasted back into these source timelines"); return; } + + int earliestTick = actorsInvolved.Count == 1 ? Workspace.GetEarliestAtTickInCopiedKeyframes(actorsInvolved[0]) : Workspace.GetEarliestAtTickInCopiedKeyframes(Workspace.ActorID); + if (earliestTick < 1) { Debug.Log("Unknown error occured during keyframe paste operation"); return; } + + foreach (PawnKeyframe copiedKeyframe in Workspace.copiedKeyframes) + { + int tickToPasteAt = Workspace.StageTick + (copiedKeyframe.atTick.Value - earliestTick); + + if (tickToPasteAt < 1) continue; + if (tickToPasteAt > Workspace.StageWindowSize) + { + if (Workspace.stretchKeyframes) + { Workspace.GetCurrentAnimationStage().ResizeStageWindow(tickToPasteAt); } + + else continue; + } + + int targetActorID = actorsInvolved.Count == 1 ? Workspace.ActorID : copiedKeyframe.actorID; + + if (Workspace.DoesPawnKeyframeExistAtTick(Workspace.StageID, targetActorID, tickToPasteAt)) + { + PawnKeyframe oldKeyframe = Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[targetActorID].Keyframes.First(x => x.atTick == tickToPasteAt); + RemovePawnKeyframe(targetActorID, oldKeyframe.keyframeID, true); + } + + PawnKeyframe clonedKeyframe = copiedKeyframe.Copy(); + clonedKeyframe.GenerateKeyframeID(targetActorID); + clonedKeyframe.atTick = tickToPasteAt; + + PawnAnimationClip clip = Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[targetActorID]; + PawnKeyframe nextKeyframe = clip.Keyframes.FirstOrDefault(x => x.atTick > tickToPasteAt); + + if (nextKeyframe != null) + { clip.Keyframes.Insert(clip.Keyframes.IndexOf(nextKeyframe), clonedKeyframe); } + + else + { clip.Keyframes.Add(clonedKeyframe); } + + clip.BuildSimpleCurves(); + } + + if (originalWindowSize != Workspace.StageWindowSize) + { + Workspace.GetCurrentAnimationStage().StretchStageWindow(originalWindowSize); + Workspace.GetCurrentAnimationStage().ResizeStageWindow(originalWindowSize); + } + + Workspace.RecordEvent("Keyframe pasted"); + } + + public void RemovePawnKeyframe() + { + foreach (int keyframeID in Workspace.keyframeID) + { + if (Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID, out int clipID) != null) + { RemovePawnKeyframe(clipID, keyframeID); } + } + } + + public void RemovePawnKeyframe(int actorID, int keyframeID, bool force = false) + { + PawnKeyframe keyframe = Workspace.GetPawnKeyframe(actorID, keyframeID); + PawnAnimationClip clip = Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[actorID]; + + if (keyframe == null || clip == null) return; + + if (keyframe.atTick == Constants.minTick && force == false) + { Debug.LogWarning("Cannot delete key frame - the first key frame of an animation clip cannot be deleted"); return; } + + if (clip.Keyframes.Count <= 2 && force == false) + { Debug.LogWarning("Cannot delete key frame - an animation clip must have two or more keyframes"); return; } + + clip.Keyframes.Remove(keyframe); + clip.BuildSimpleCurves(); + + Workspace.RecordEvent("Keyframe deletion"); + } + + public float GetStageTickPercentage() + { + return (float)(Workspace.StageTick % duration) / duration; + } + + // Pre-save / post-load + public void OnPreSave() + { + foreach (ActorAddon addon in Addons) + { + if (addon.Render) + { addons.Add(addon); } + } + } + + public void OnPostLoad() + { + Addons = addons.Copy(); + + foreach (PawnKeyframe keyframe in Keyframes) + { + keyframe.OnPostLoad(); + } + + AddActorAddon("left hand", 0.667f); + AddActorAddon("right hand", 0.667f); + AddActorAddon("dildo"); + } + } +} diff --git a/Assets/Scripts/AnimationComponents/AnimationClips/PawnAnimationClip.cs.meta b/Assets/Scripts/AnimationComponents/PawnAnimationClip.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/AnimationClips/PawnAnimationClip.cs.meta rename to Assets/Scripts/AnimationComponents/PawnAnimationClip.cs.meta index c587e583..cdd63f55 100644 --- a/Assets/Scripts/AnimationComponents/AnimationClips/PawnAnimationClip.cs.meta +++ b/Assets/Scripts/AnimationComponents/PawnAnimationClip.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: b7f2dc95148378445919ef3ed8705c5d +guid: bd5a477338567fb4cbb26b913a52ca65 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/PawnKeyframe.cs b/Assets/Scripts/AnimationComponents/PawnKeyframe.cs new file mode 100644 index 00000000..67775372 --- /dev/null +++ b/Assets/Scripts/AnimationComponents/PawnKeyframe.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml; +using System.Xml.Serialization; +using UnityEngine; +using UnityEngine.UI; + +namespace RimWorldAnimationStudio +{ + public class PawnKeyframe + { + // Data to/from animationDef + public float? bodyAngle; + public float? headAngle; + public float? headBob; + public float? bodyOffsetX; + public float? bodyOffsetZ; + public int? headFacing; + public int? bodyFacing; + public float? genitalAngle; + public bool? quiver; + public int? tickDuration; + public string soundEffect; + public List tags; + [XmlArray("addonKeyframes"), XmlArrayItem("li")] public List addonKeyframes; + + // Data serialization control + public bool ShouldSerializebodyAngle() { return bodyAngle.HasValue && bodyAngle.Value != 0f; } + public bool ShouldSerializeheadAngle() { return headAngle.HasValue && headAngle.Value != 0f; } + public bool ShouldSerializeheadBob() { return headBob.HasValue && headBob.Value != 0f; } + public bool ShouldSerializebodyOffsetX() { return bodyOffsetX.HasValue && bodyOffsetX.Value != 0f; } + public bool ShouldSerializebodyOffsetZ() { return bodyOffsetZ.HasValue && bodyOffsetZ.Value != 0f; } + public bool ShouldSerializegenitalAngle() { return genitalAngle.HasValue && genitalAngle.Value != 0f; } + public bool ShouldSerializequiver() { return quiver == true; } + public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); } + public bool ShouldSerializeaddonKeyframes() { return addonKeyframes.NotNullOrEmpty(); } + + // Data helper functions + [XmlIgnore] public float BodyAngle + { + get { return bodyAngle.HasValue ? bodyAngle.Value : 0f; } + set { bodyAngle = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public float HeadAngle + { + get { return headAngle.HasValue ? headAngle.Value : (float)(headAngle = 0f); } + set { headAngle = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public float HeadBob + { + get { return headBob.HasValue ? headBob.Value : (float)(headBob = 0f); } + set { headBob = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public float BodyOffsetX + { + get { return bodyOffsetX.HasValue ? bodyOffsetX.Value : (float)(bodyOffsetX = 0f); } + set { bodyOffsetX = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public float BodyOffsetZ + { + get { return bodyOffsetZ.HasValue ? bodyOffsetZ.Value : (float)(bodyOffsetZ = 0f); } + set { bodyOffsetZ = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public int HeadFacing + { + get { return headFacing.HasValue ? headFacing.Value : (int)(headFacing = 2); } + set { headFacing = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public int BodyFacing + { + get { return bodyFacing.HasValue ? bodyFacing.Value : (int)(bodyFacing = 2); } + set { bodyFacing = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public float GenitalAngle + { + get { return genitalAngle.HasValue ? genitalAngle.Value : (float)(genitalAngle = 0f); } + set { genitalAngle = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public bool Quiver + { + get { return quiver == true; } + set { quiver = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public int TickDuration + { + get { return tickDuration.HasValue ? tickDuration.Value : (int)(tickDuration = 0); } + set { tickDuration = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public string SoundEffect + { + get { return soundEffect; } + set { soundEffect = value; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public List Tags + { + get { return tags.NullOrEmpty() ? tags = new List() : tags; } + set { tags = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnKeyframeChanged(this); } + } + + [XmlIgnore] public List AddonKeyframes + { + get { return addonKeyframes.NullOrEmpty() ? addonKeyframes = new List() : addonKeyframes; } + set { addonKeyframes = value.NotNullOrEmpty()? value : null; EventsManager.OnPawnKeyframeChanged(this); } + } + + // Local data + [XmlIgnore] public int keyframeID; + [XmlIgnore] public int actorID = -1; + [XmlIgnore] public int? atTick; + + // Methods + public void GenerateKeyframeID(int actorID) + { + this.actorID = actorID; + int _keyframeID = UnityEngine.Random.Range(100000, 1000000); + + if (Workspace.animationDef.AnimationStages.Any(x => x.AnimationClips.Any(y => y.Keyframes.Any(z => z.keyframeID == _keyframeID)))) + { + GenerateKeyframeID(actorID); + return; + } + + keyframeID = _keyframeID; + } + + public bool HasValidKeyframeID() + { return keyframeID >= 100000 && keyframeID < 1000000; } + + public KeyframeSlider GetKeyframeSlider() + { + return Selectable.allSelectablesArray.FirstOrDefault(x => x.GetComponent()?.keyframeID == keyframeID)?.GetComponent< KeyframeSlider>(); + } + + public AddonKeyframe GetAddonKeyframe(string addonName) + { + return AddonKeyframes.FirstOrDefault(x => x.AddonName == addonName); + } + + // Pre-save / post-load + public void OnPreSave() + { + SoundEffect = DefaultTags.soundDefs.Concat(CustomTags.soundDefs).Contains(SoundEffect) ? SoundEffect : null; + + addonKeyframes.Clear(); + + foreach (AddonKeyframe addonKeyframe in AddonKeyframes) + { + ActorAddon addon = Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID, out int clipID).GetActorAddon(addonKeyframe.AddonName); + + if (addon.Render) + { addonKeyframes.Add(addonKeyframe.Copy()); } + } + } + + public void OnPostLoad() + { + AddonKeyframes.Clear(); + + foreach (AddonKeyframe addonKeyframe in addonKeyframes) + { + AddonKeyframes.Add(addonKeyframe.Copy()); + } + } + } +} diff --git a/Assets/Scripts/AnimationComponents/KeyFrames/PawnKeyframe.cs.meta b/Assets/Scripts/AnimationComponents/PawnKeyframe.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/KeyFrames/PawnKeyframe.cs.meta rename to Assets/Scripts/AnimationComponents/PawnKeyframe.cs.meta index 1b4d03bb..7b554405 100644 --- a/Assets/Scripts/AnimationComponents/KeyFrames/PawnKeyframe.cs.meta +++ b/Assets/Scripts/AnimationComponents/PawnKeyframe.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: fe4a7d5f472a25945bac2d1892a4e2fa +guid: c8ced38490f6b174984453dc3336a543 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/AlienRaceDef.cs b/Assets/Scripts/AnimationComponents/PawnRaceDef.cs similarity index 97% rename from Assets/Scripts/AnimationComponents/AlienRaceDef.cs rename to Assets/Scripts/AnimationComponents/PawnRaceDef.cs index 4030d92a..2a25bf3b 100644 --- a/Assets/Scripts/AnimationComponents/AlienRaceDef.cs +++ b/Assets/Scripts/AnimationComponents/PawnRaceDef.cs @@ -9,8 +9,9 @@ using UnityEngine; namespace RimWorldAnimationStudio { [Serializable] - public class AlienRaceDef + public class PawnRaceDef { + // Local data public string defName; public bool isHumanoid = true; public float scale = 1f; @@ -18,13 +19,15 @@ namespace RimWorldAnimationStudio public List bodyTypeGraphics = new List(); public MultiDirectionalGraphic headGraphics = new MultiDirectionalGraphic(); - public AlienRaceDef() { } + // Constructors + public PawnRaceDef() { } - public AlienRaceDef(string defName) + public PawnRaceDef(string defName) { this.defName = defName; } + // Methods public Sprite GetHeadGraphic(CardinalDirection facing) { if (HasValidHeadGraphicPath(facing) == false) diff --git a/Assets/Scripts/AnimationComponents/AnimationClips/ThingAnimationClip.cs.meta b/Assets/Scripts/AnimationComponents/PawnRaceDef.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/AnimationClips/ThingAnimationClip.cs.meta rename to Assets/Scripts/AnimationComponents/PawnRaceDef.cs.meta index b12b97bf..047067d0 100644 --- a/Assets/Scripts/AnimationComponents/AnimationClips/ThingAnimationClip.cs.meta +++ b/Assets/Scripts/AnimationComponents/PawnRaceDef.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c4a44c0d3b9937c48b2ae8501126227e +guid: 187aef38ea296184b93265071536969c MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AnimationComponents/AlienRaceOffset.cs b/Assets/Scripts/AnimationComponents/PawnRaceOffset.cs similarity index 85% rename from Assets/Scripts/AnimationComponents/AlienRaceOffset.cs rename to Assets/Scripts/AnimationComponents/PawnRaceOffset.cs index 7b1e2356..8e9c84be 100644 --- a/Assets/Scripts/AnimationComponents/AlienRaceOffset.cs +++ b/Assets/Scripts/AnimationComponents/PawnRaceOffset.cs @@ -5,21 +5,25 @@ using UnityEngine; namespace RimWorldAnimationStudio { [Serializable] - public class AlienRaceOffset + public class PawnRaceOffset { + // Local data public string defName = "Human"; public string offset = "(0, 0)"; + // SHoulda serialize public bool ShouldSerializedefName() { return OffsetIsZero() == false; } public bool ShouldSerializeoffset() { return OffsetIsZero() == false; } - public AlienRaceOffset() { } + // Constructors + public PawnRaceOffset() { } - public AlienRaceOffset(string defName) + public PawnRaceOffset(string defName) { this.defName = defName; } + // Methods public void SetOffset(Vector2 raceOffset) { offset = "(" + raceOffset.x + ", " + raceOffset.y + ")"; diff --git a/Assets/Scripts/AnimationComponents/AlienRaceDef.cs.meta b/Assets/Scripts/AnimationComponents/PawnRaceOffset.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/AlienRaceDef.cs.meta rename to Assets/Scripts/AnimationComponents/PawnRaceOffset.cs.meta index 9c11ddbe..b2fea88a 100644 --- a/Assets/Scripts/AnimationComponents/AlienRaceDef.cs.meta +++ b/Assets/Scripts/AnimationComponents/PawnRaceOffset.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5b8a2db320a85494c882518c143b73f7 +guid: 24eafaf092974414ca90bfd4a8d2e4ba MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Math/Constants.meta b/Assets/Scripts/Data.meta similarity index 100% rename from Assets/Scripts/Math/Constants.meta rename to Assets/Scripts/Data.meta diff --git a/Assets/Scripts/Data/Constants.cs b/Assets/Scripts/Data/Constants.cs new file mode 100644 index 00000000..1a24cdb0 --- /dev/null +++ b/Assets/Scripts/Data/Constants.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Serialization; +using UnityEngine; + +namespace RimWorldAnimationStudio +{ + public static class Constants + { + // Project data + public static string currentVersion = "0.0.0"; + public static string projectHome = "https://gitgud.io/AbstractConcept/rimworld-animation-studio"; + public static string projectWiki = "https://gitgud.io/AbstractConcept/rimworld-animation-studio/-/wikis/home"; + + // Actions + public static float actionRepeatSpeed = 0.250f; + + // Animation defaults + public static int defaultAnimationClipLength = 600; + public static int minTick = 1; + public static int minAnimationClipLength = 5; + public static int maxAnimationClipLength = 9999; + + // Colors used + public static Color ColorWhite = new Color(1f, 1f, 1f); + public static Color ColorGreen = new Color(0f, 1f, 0f); + public static Color ColorGoldYellow = new Color(1f, 0.85f, 0f); + public static Color ColorDarkGold = new Color(0.75f, 0.64f, 0f); + public static Color ColorLightGrey = new Color(0.9f, 0.9f, 0.9f); + public static Color ColorMidGrey = new Color(0.75f, 0.75f, 0.75f); + public static Color ColorGrey = new Color(0.5f, 0.5f, 0.5f); + public static Color ColorDarkGrey = new Color(0.2f, 0.2f, 0.2f); + public static Color ColorPink = new Color(1.0f, 0.5f, 0.5f); + public static Color ColorOrange = new Color(1.0f, 0.7f, 0.0f); + public static Color ColorRichOrange = new Color(1.0f, 0.4f, 0.1f); + public static Color ColorCyan = new Color(0.0f, 1.0f, 1.0f); + public static Color ColorPurple = new Color(0.85f, 0.0f, 1.0f); + public static Color ColorGhost = new Color(0.5f, 0f, 0f, 0.5f); + public static Color ColorRed = new Color(0.9f, 0f, 0f); + } +} diff --git a/Assets/Scripts/Math/Constants/Constants.cs.meta b/Assets/Scripts/Data/Constants.cs.meta similarity index 100% rename from Assets/Scripts/Math/Constants/Constants.cs.meta rename to Assets/Scripts/Data/Constants.cs.meta diff --git a/Assets/Scripts/Math/Constants/Constants.cs b/Assets/Scripts/Data/DefaultTags.cs similarity index 58% rename from Assets/Scripts/Math/Constants/Constants.cs rename to Assets/Scripts/Data/DefaultTags.cs index c8e2e005..fc85e6be 100644 --- a/Assets/Scripts/Math/Constants/Constants.cs +++ b/Assets/Scripts/Data/DefaultTags.cs @@ -1,43 +1,15 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using System.Text; +using System.Threading.Tasks; using System.Xml.Serialization; -using UnityEngine; namespace RimWorldAnimationStudio { - public static class Constants + public static class DefaultTags { - public static string currentVersion = "0.0.0"; - public static string projectHome = "https://gitgud.io/AbstractConcept/rimworld-animation-studio"; - public static string projectWiki = "https://gitgud.io/AbstractConcept/rimworld-animation-studio/-/wikis/home"; - - public static float actionRepeatSpeed = 0.250f; - - public static int defaultAnimationClipLength = 600; - public static int minTick = 1; - public static int minAnimationClipLength = 5; - public static int maxAnimationClipLength = 9999; - - public static Color ColorWhite = new Color(1f, 1f, 1f); - public static Color ColorGreen = new Color(0f, 1f, 0f); - public static Color ColorGoldYellow = new Color(1f, 0.85f, 0f); - public static Color ColorDarkGold = new Color(0.75f, 0.64f, 0f); - public static Color ColorLightGrey = new Color(0.9f, 0.9f, 0.9f); - public static Color ColorMidGrey = new Color(0.75f, 0.75f, 0.75f); - public static Color ColorGrey = new Color(0.5f, 0.5f, 0.5f); - public static Color ColorDarkGrey = new Color(0.2f, 0.2f, 0.2f); - public static Color ColorPink = new Color(1.0f, 0.5f, 0.5f); - public static Color ColorOrange = new Color(1.0f, 0.7f, 0.0f); - public static Color ColorRichOrange = new Color(1.0f, 0.4f, 0.1f); - public static Color ColorCyan = new Color(0.0f, 1.0f, 1.0f); - public static Color ColorPurple = new Color(0.85f, 0.0f, 1.0f); - public static Color ColorGhost = new Color(0.5f, 0f, 0f, 0.5f); - public static Color ColorRed = new Color(0.9f, 0f, 0f); - } - - public static class Tags - { - public static List defNames = new List() { "Human", "Wolf_Timber", "Horse"}; + public static List defNames = new List() { "Human", "Wolf_Timber", "Horse" }; public static List bodyParts = new List() { "Penis", "Vagina", "Anus", "Breasts", "Mouth" }; public static List bodyDefTypes = new List() { "Human", "Bird", "BeetleLike", "BeetleLikeWithClaw", "MechanicalCentipede", "MechanicalTermite", "Lancer", "Pikeman", "Monkey", "QuadrupedAnimalWithClawsTailAndJowl", "QuadrupedAnimalWithHooves", "QuadrupedAnimalWithHoovesAndHorn", "QuadrupedAnimalWithHoovesAndHump", "QuadrupedAnimalWithHoovesAndTusks", "QuadrupedAnimalWithHoovesTusksAndTrunk", "QuadrupedAnimalWithPaws", "QuadrupedAnimalWithPawsAndTail", "Scyther", "Snake", "TurtleLike" }; public static List sexTypes = new List() { "None", "Vaginal", "Anal", "Oral", "Masturbation", "DoublePenetration", "Boobjob", "Handjob", "Footjob", "Fingering", "Scissoring", "MutualMasturbation", "Fisting", "MechImplant", "Rimming", "Fellatio", "Cunnilingus", "Sixtynine" }; @@ -65,53 +37,8 @@ namespace RimWorldAnimationStudio [XmlArray("bodyParts"), XmlArrayItem("li")] public List bodyParts = new List(); [XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List bodyDefTypes = new List(); [XmlArray("sexTypes"), XmlArrayItem("li")] public List sexTypes = new List(); - [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List interactionDefTypes = new List(); + [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List interactionDefTypes = new List(); [XmlArray("soundDefs"), XmlArrayItem("li")] public List soundDefs = new List(); [XmlArray("bodyTypes"), XmlArrayItem("li")] public static List bodyTypes = new List(); } - - public static class AlienRaceDefs - { - public static List allDefs = new List(); - - public static AlienRaceDef GetNamed(string alienRaceDef) - { - return allDefs.FirstOrDefault(x => x.defName == alienRaceDef); - } - - public static void AddDef(AlienRaceDef alienRaceDef) - { - if (allDefs.Any(x => x.defName == alienRaceDef.defName)) return; - - allDefs.Add(alienRaceDef); - } - - public static void OnLoad() - { - List allTags = Tags.bodyTypes.Concat(CustomTags.bodyTypes).ToList(); - allTags.Add("None"); - - List facings = new List() { CardinalDirection.North, CardinalDirection.East, CardinalDirection.South }; - string path; - - foreach (AlienRaceDef alienRaceDef in allDefs) - { - foreach (CardinalDirection facing in facings) - { - foreach (string bodyType in allTags) - { - path = alienRaceDef.GetBodyTypeGraphicPath(facing, bodyType); - - if (path != null && path != "") - { alienRaceDef.SetBodyTypeGraphicPath(path, facing, bodyType); } - } - - path = alienRaceDef.GetHeadGraphicPath(facing); - - if (path != null && path != "") - { alienRaceDef.SetHeadGraphicPath(path, facing); } - } - } - } - } } diff --git a/Assets/Scripts/AnimationComponents/AnimationClips/AnimationClip.cs.meta b/Assets/Scripts/Data/DefaultTags.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/AnimationClips/AnimationClip.cs.meta rename to Assets/Scripts/Data/DefaultTags.cs.meta index 11fd14d8..e5b4d31d 100644 --- a/Assets/Scripts/AnimationComponents/AnimationClips/AnimationClip.cs.meta +++ b/Assets/Scripts/Data/DefaultTags.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: aeb406e171f70f14f88980439239ca59 +guid: d2a4f1a7ea83f0544a350664fba7fc49 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/Math/Constants/Enums.cs b/Assets/Scripts/Data/Enums.cs similarity index 100% rename from Assets/Scripts/Math/Constants/Enums.cs rename to Assets/Scripts/Data/Enums.cs diff --git a/Assets/Scripts/Math/Constants/Enums.cs.meta b/Assets/Scripts/Data/Enums.cs.meta similarity index 100% rename from Assets/Scripts/Math/Constants/Enums.cs.meta rename to Assets/Scripts/Data/Enums.cs.meta diff --git a/Assets/Scripts/AnimationComponents/KeyFrames.meta b/Assets/Scripts/DefParents.meta similarity index 77% rename from Assets/Scripts/AnimationComponents/KeyFrames.meta rename to Assets/Scripts/DefParents.meta index b611c385..00fcefdf 100644 --- a/Assets/Scripts/AnimationComponents/KeyFrames.meta +++ b/Assets/Scripts/DefParents.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d3f1c8d8d1b51a147b17f5510eebb2cf +guid: c9a9e093aedeac24687d421f33a98e94 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Scripts/AnimationComponents/Defs.cs b/Assets/Scripts/DefParents/AnimationDefs.cs similarity index 63% rename from Assets/Scripts/AnimationComponents/Defs.cs rename to Assets/Scripts/DefParents/AnimationDefs.cs index 9290f8b8..11fc56a3 100644 --- a/Assets/Scripts/AnimationComponents/Defs.cs +++ b/Assets/Scripts/DefParents/AnimationDefs.cs @@ -1,11 +1,14 @@ -using System.Collections.Generic; -using System.Xml; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using System.Xml.Serialization; namespace RimWorldAnimationStudio { [XmlRoot("Defs", IsNullable = false)] - public class Defs + public class AnimationDefs { [XmlElement("Rimworld_Animations.AnimationDef")] public List animationDefs = new List(); diff --git a/Assets/Scripts/AnimationComponents/AlienRaceOffset.cs.meta b/Assets/Scripts/DefParents/AnimationDefs.cs.meta similarity index 83% rename from Assets/Scripts/AnimationComponents/AlienRaceOffset.cs.meta rename to Assets/Scripts/DefParents/AnimationDefs.cs.meta index 4bc87d8a..d44cb738 100644 --- a/Assets/Scripts/AnimationComponents/AlienRaceOffset.cs.meta +++ b/Assets/Scripts/DefParents/AnimationDefs.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a3449cf2dd7e0444bbc5a7b654cf10c5 +guid: 6e65e28553800cf489ca2b0bc7e37408 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/DefParents/PawnRaceDefs.cs b/Assets/Scripts/DefParents/PawnRaceDefs.cs new file mode 100644 index 00000000..674ca3b7 --- /dev/null +++ b/Assets/Scripts/DefParents/PawnRaceDefs.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RimWorldAnimationStudio +{ + public static class PawnRaceDefs + { + public static List allDefs = new List(); + + public static PawnRaceDef GetNamed(string pawnRaceDef) + { + return allDefs.FirstOrDefault(x => x.defName == pawnRaceDef); + } + + public static void AddDef(PawnRaceDef pawnRaceDef) + { + if (allDefs.Any(x => x.defName == pawnRaceDef.defName)) return; + + allDefs.Add(pawnRaceDef); + } + + public static void OnLoad() + { + List allTags = DefaultTags.bodyTypes.Concat(CustomTags.bodyTypes).ToList(); + allTags.Add("None"); + + List facings = new List() { CardinalDirection.North, CardinalDirection.East, CardinalDirection.South }; + string path; + + foreach (PawnRaceDef pawnRaceDef in allDefs) + { + foreach (CardinalDirection facing in facings) + { + foreach (string bodyType in allTags) + { + path = pawnRaceDef.GetBodyTypeGraphicPath(facing, bodyType); + + if (string.IsNullOrEmpty(path) == false) + { pawnRaceDef.SetBodyTypeGraphicPath(path, facing, bodyType); } + } + + path = pawnRaceDef.GetHeadGraphicPath(facing); + + if (string.IsNullOrEmpty(path) == false) + { pawnRaceDef.SetHeadGraphicPath(path, facing); } + } + } + } + } +} diff --git a/Assets/Scripts/DefParents/PawnRaceDefs.cs.meta b/Assets/Scripts/DefParents/PawnRaceDefs.cs.meta new file mode 100644 index 00000000..43eeef9f --- /dev/null +++ b/Assets/Scripts/DefParents/PawnRaceDefs.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 53e7f97b4bb5a3441884e4795d7e9391 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GUI/ActorCard.cs b/Assets/Scripts/GUI/ActorCard.cs deleted file mode 100644 index e8d428f2..00000000 --- a/Assets/Scripts/GUI/ActorCard.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEngine.UI; - -namespace RimWorldAnimationStudio -{ - public class ActorCard : MonoBehaviour - { - //public Dropdown genderDropdown; - public Dropdown bodyTypeDropdown; - public InputField bodyOffsetXField; - public InputField bodyOffsetZField; - public InputField raceOffsetXField; - public InputField raceOffsetZField; - public Toggle initiatorToggle; - public Dropdown selectActorLayerDropdown; - - public void Initialize() - { - Actor actor = Workspace.animationDef.actors[Workspace.actorID]; - string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text; - bodyType = bodyType == null || bodyType == "" ? "Male" : bodyType; - - initiatorToggle.isOn = actor.initiator; - bodyOffsetXField.text = actor.bodyTypeOffset.GetOffset(bodyType).x.ToString(); - bodyOffsetZField.text = actor.bodyTypeOffset.GetOffset(bodyType).z.ToString(); - } - - public void OnBodyTypeChanged() - { - if (Workspace.animationDef == null) return; - - Actor actor = Workspace.animationDef.actors[Workspace.actorID]; - - string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text; - bodyType = bodyType == null || bodyType == "" ? "Male" : bodyType; - - Workspace.animationDef.actors[Workspace.actorID].bodyType = bodyType; - - bodyOffsetXField.text = actor.bodyTypeOffset.GetOffset(bodyType).x.ToString(); - bodyOffsetZField.text = actor.bodyTypeOffset.GetOffset(bodyType).z.ToString(); - } - - public void OnValueChanged() - { - if (Workspace.animationDef == null) return; - - Actor actor = Workspace.animationDef.actors[Workspace.actorID]; - - string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text; - bodyType = bodyType == null || bodyType == "" ? "Male" : bodyType; - - float.TryParse(bodyOffsetXField.text, out float x); - float.TryParse(bodyOffsetZField.text, out float z); - actor.bodyTypeOffset.SetOffset(bodyType, new Vector2(x, z)); - - actor.initiator = initiatorToggle.isOn; - - //switch (genderDropdown.value) - //{ - // case 0: actor.requiredGender = new List() { "Female" }; break; - // case 2: actor.requiredGender = new List() { "Male" }; break; - // default: actor.requiredGender = null; break; - //} - - float.TryParse(raceOffsetXField.text, out x); - float.TryParse(raceOffsetZField.text, out z); - actor.SetAlienRaceOffset(new Vector2(x, z)); - - Workspace.Instance.RecordEvent("Actor body offset data"); - } - - public void OnActorLayerChange() - { - PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip(); - - if (clip == null) return; - clip.layer = selectActorLayerDropdown.captionText.text; - - Workspace.Instance.RecordEvent("Actor render layer " + clip.layer); - } - - public void Update() - { - if (Workspace.animationDef == null) return; - - if (Workspace.actorID >= AnimationController.Instance.actorBodies.GetComponentsInChildren().Count()) - { Debug.Log("Waiting for actors to initialize..."); return; } - - Actor actor = Workspace.animationDef.actors[Workspace.actorID]; - ActorBody actorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren()[Workspace.actorID]; - PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip(); - - string bodyType = actor.bodyType; - bodyType = bodyType == null || bodyType == "" ? "Male" : bodyType; - - bodyTypeDropdown.value = bodyTypeDropdown.options.IndexOf(bodyTypeDropdown.options.First(x => x.text == bodyType)); - - if (bodyOffsetXField.isFocused == false) - { bodyOffsetXField.text = actor.bodyTypeOffset.GetOffset(bodyType).x.ToString(); } - - if (bodyOffsetZField.isFocused == false) - { bodyOffsetZField.text = actor.bodyTypeOffset.GetOffset(bodyType).z.ToString(); } - - bodyTypeDropdown.interactable = actor.GetAlienRaceDef().isHumanoid; - bodyOffsetXField.interactable = actor.GetAlienRaceDef().isHumanoid; - bodyOffsetZField.interactable = actor.GetAlienRaceDef().isHumanoid; - - if (raceOffsetXField.isFocused == false) - { raceOffsetXField.text = actor.GetAlienRaceOffset().x.ToString(); } - - if (raceOffsetZField.isFocused == false) - { raceOffsetZField.text = actor.GetAlienRaceOffset().z.ToString(); } - - initiatorToggle.isOn = actor.initiator; - - //if (actor.requiredGender.NotNullOrEmpty() && actor.requiredGender.Contains("Female")) - //{ genderDropdown.SetValueWithoutNotify(0); } - - //else if (actor.requiredGender.NotNullOrEmpty() && actor.requiredGender.Contains("Male")) - //{ genderDropdown.SetValueWithoutNotify(2); } - - //else - //{ genderDropdown.SetValueWithoutNotify(1); } - - for (int i = 0; i < selectActorLayerDropdown.options.Count; i++) - { - if (selectActorLayerDropdown.options[i].text == clip.layer) - { selectActorLayerDropdown.SetValueWithoutNotify(i); } - } - } - } -} diff --git a/Assets/Scripts/GUI/Actors.meta b/Assets/Scripts/GUI/Actors.meta new file mode 100644 index 00000000..a01a24d0 --- /dev/null +++ b/Assets/Scripts/GUI/Actors.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f3c96477ef8cc42468ea6a39764a2e81 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GUI/ActorBody.cs b/Assets/Scripts/GUI/Actors/ActorBody.cs similarity index 67% rename from Assets/Scripts/GUI/ActorBody.cs rename to Assets/Scripts/GUI/Actors/ActorBody.cs index 50c45693..1eb6558e 100644 --- a/Assets/Scripts/GUI/ActorBody.cs +++ b/Assets/Scripts/GUI/Actors/ActorBody.cs @@ -26,20 +26,17 @@ namespace RimWorldAnimationStudio public void Update() { - if (Workspace.actorID == actorID && Workspace.selectedBodyPart == null) + if (Workspace.ActorID == actorID && Workspace.selectedBodyPart == null) { bodyRenderer.color = Constants.ColorGreen; } else { bodyRenderer.color = Constants.ColorWhite; } - foreach (ActorAddon addon in Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID].addons) + foreach (ActorAddon addon in Workspace.GetCurrentAnimationStage().AnimationClips[actorID].Addons) { - ActorBodyPart bodyPart = GetComponentsInChildren(true).FirstOrDefault(x => x.addonName == addon.addonName); - bodyPart?.gameObject?.SetActive(addon.render); + ActorBodyPart bodyPart = GetComponentsInChildren(true).FirstOrDefault(x => x.addonName == addon.AddonName); + bodyPart?.gameObject?.SetActive(addon.Render); } - - //headRenderer.gameObject.SetActive(Workspace.animationDef.actors[actorID].GetAlienRaceDef().isHumanoid); - //appendageRenderer.gameObject.SetActive(Workspace.animationDef.actors[actorID].requiredGenitals.Any(x => x == "Penis") || Workspace.animationDef.actors[actorID].isFucking); } public void OnPointerClick(PointerEventData eventData) @@ -54,7 +51,7 @@ namespace RimWorldAnimationStudio { Activate(); - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); if (keyframe == null) { Debug.LogWarning("Cannot alter actor - no keyframe data available"); return; } @@ -66,14 +63,14 @@ namespace RimWorldAnimationStudio if (Workspace.actorManipulationMode == ActorManipulationMode.Pan) { - keyframe.bodyOffsetX = mousePosition.x - delta.x - Workspace.animationDef.actors[actorID].GetFinalTransformOffset().x; - keyframe.bodyOffsetZ = mousePosition.y - delta.y - Workspace.animationDef.actors[actorID].GetFinalTransformOffset().y; + keyframe.BodyOffsetX = mousePosition.x - delta.x - Workspace.animationDef.Actors[actorID].GetFinalTransformOffset().x; + keyframe.BodyOffsetZ = mousePosition.y - delta.y - Workspace.animationDef.Actors[actorID].GetFinalTransformOffset().y; } else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate) { float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position); - keyframe.bodyAngle = angle; + keyframe.BodyAngle = angle; } else if (Workspace.actorManipulationMode == ActorManipulationMode.Face) @@ -82,22 +79,22 @@ namespace RimWorldAnimationStudio int facing = -Mathf.RoundToInt(angle / 90f ); facing = facing < 0 ? facing + 4 : facing; - keyframe.bodyFacing = facing; + keyframe.BodyFacing = facing; } - PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID); + PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID); clip.BuildSimpleCurves(); } public void OnEndDrag(PointerEventData eventData) { - Workspace.Instance.RecordEvent("Actor position / orientation"); + Workspace.RecordEvent("Actor position / orientation"); delta = Vector3.zero; } public void Activate() { - Workspace.actorID = actorID; + Workspace.ActorID = actorID; Workspace.selectedBodyPart = null; } } diff --git a/Assets/Scripts/GUI/ActorBody.cs.meta b/Assets/Scripts/GUI/Actors/ActorBody.cs.meta similarity index 100% rename from Assets/Scripts/GUI/ActorBody.cs.meta rename to Assets/Scripts/GUI/Actors/ActorBody.cs.meta diff --git a/Assets/Scripts/GUI/ActorBodyPart.cs b/Assets/Scripts/GUI/Actors/ActorBodyPart.cs similarity index 78% rename from Assets/Scripts/GUI/ActorBodyPart.cs rename to Assets/Scripts/GUI/Actors/ActorBodyPart.cs index 78ebb299..11b57d55 100644 --- a/Assets/Scripts/GUI/ActorBodyPart.cs +++ b/Assets/Scripts/GUI/Actors/ActorBodyPart.cs @@ -16,9 +16,14 @@ namespace RimWorldAnimationStudio private Vector3 delta = new Vector3(); + public void Start() + { + //Workspace.onActorChanged.AddListener(delegate { }); + } + public void Update() { - if ((Workspace.actorID == parent.actorID && Workspace.selectedBodyPart == null) || Workspace.selectedBodyPart == this) + if ((Workspace.ActorID == parent.actorID && Workspace.selectedBodyPart == null) || Workspace.selectedBodyPart == this) { bodyPartRenderer.color = Constants.ColorGreen; } else @@ -37,7 +42,7 @@ namespace RimWorldAnimationStudio { Activate(); - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); if (keyframe == null) { Debug.LogWarning("Cannot alter actor - no keyframe data available"); return; } @@ -50,19 +55,19 @@ namespace RimWorldAnimationStudio if (addonName != null && addonName != "") { AddonKeyframe addonKeyframe = keyframe.GetAddonKeyframe(addonName); - ActorAddon addon = Workspace.Instance.GetCurrentPawnAnimationClip().GetActorAddon(addonName); + ActorAddon addon = Workspace.GetCurrentPawnAnimationClip().GetActorAddon(addonName); if (Workspace.actorManipulationMode == ActorManipulationMode.Pan) { Vector3 anchor; - ActorBody anchoringActorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren()?.FirstOrDefault(x => x.actorID == addon.anchoringActor); + ActorBody anchoringActorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor); Vector3 bodyPos = new Vector3(anchoringActorBody.transform.position.x, anchoringActorBody.transform.position.y, 0); - AlienRaceDef alienRaceDef = Workspace.animationDef.actors[addon.anchoringActor].GetAlienRaceDef(); - Actor anchoringActor = Workspace.animationDef.actors[addon.anchoringActor]; - int bodyFacing = (int)Workspace.animationDef.animationStages[Workspace.stageID].animationClips[addon.anchoringActor].BodyFacing.Evaluate((float)AnimationController.Instance.stageTick / Workspace.StageWindowSize); + PawnRaceDef pawnRaceDef = Workspace.animationDef.Actors[addon.AnchoringActor].GetPawnRaceDef(); + Actor anchoringActor = Workspace.animationDef.Actors[addon.AnchoringActor]; + int bodyFacing = (int)Workspace.GetCurrentAnimationStage().AnimationClips[addon.AnchoringActor].BodyFacing.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize); - switch (addon.anchorName) + switch (addon.AnchorName) { case "torso": anchor = bodyPos; break; case "head": anchor = new Vector3(anchoringActorBody.transform.Find("ActorHead").position.x, anchoringActorBody.transform.Find("ActorHead").position.y, 0); break; @@ -74,8 +79,8 @@ namespace RimWorldAnimationStudio transform.position = new Vector3(mousePosition.x, mousePosition.y, 0f); - addonKeyframe.posX = transform.position.x - anchor.x; - addonKeyframe.posZ = transform.position.y - anchor.y; + addonKeyframe.PosX = transform.position.x - anchor.x; + addonKeyframe.PosZ = transform.position.y - anchor.y; ActorKeyframeCard.Instance.transform.GetComponentsInChildren()?.FirstOrDefault(x => x.addonName == addonName)?.OnKeyframeValueChanged(); } @@ -83,7 +88,7 @@ namespace RimWorldAnimationStudio else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate) { float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position); - addonKeyframe.rotation = angle; + addonKeyframe.Rotation = angle; } else if (Workspace.actorManipulationMode == ActorManipulationMode.Face) @@ -106,13 +111,13 @@ namespace RimWorldAnimationStudio Vector3 localPosB = transform.localPosition; transform.localPosition = localPosA; - keyframe.headBob += localPosB.y - localPosA.y; + keyframe.HeadBob += localPosB.y - localPosA.y; } else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate) { float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position); - keyframe.headAngle = angle; + keyframe.HeadAngle = angle; } else if (Workspace.actorManipulationMode == ActorManipulationMode.Face) @@ -121,7 +126,7 @@ namespace RimWorldAnimationStudio int facing = -Mathf.RoundToInt(angle / 90f); facing = facing < 0 ? facing + 4 : facing; - keyframe.headFacing = facing; + keyframe.HeadFacing = facing; } } @@ -130,25 +135,25 @@ namespace RimWorldAnimationStudio if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate) { float angle = -Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position); - keyframe.genitalAngle = angle; + keyframe.GenitalAngle = angle; - Workspace.animationDef.actors[Workspace.actorID].controlGenitalAngle = Workspace.animationDef.animationStages.Any(x => x.animationClips[Workspace.actorID].keyframes.Any(y => y.genitalAngle != 0)); + Workspace.GetCurrentActor().ControlGenitalAngle = Workspace.animationDef.AnimationStages.Any(x => x.AnimationClips[Workspace.ActorID].Keyframes.Any(y => y.GenitalAngle != 0)); } } - PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(parent.actorID); + PawnAnimationClip clip = Workspace.GetPawnAnimationClip(parent.actorID); clip.BuildSimpleCurves(); } public void OnEndDrag(PointerEventData eventData) { - Workspace.Instance.RecordEvent("Actor position / orientation"); + Workspace.RecordEvent("Actor position / orientation"); delta = Vector3.zero; } public void Activate() { - Workspace.actorID = parent.actorID; + Workspace.ActorID = parent.actorID; Workspace.selectedBodyPart = this; } } diff --git a/Assets/Scripts/GUI/ActorBodyPart.cs.meta b/Assets/Scripts/GUI/Actors/ActorBodyPart.cs.meta similarity index 100% rename from Assets/Scripts/GUI/ActorBodyPart.cs.meta rename to Assets/Scripts/GUI/Actors/ActorBodyPart.cs.meta diff --git a/Assets/Scripts/GUI/AddSoundDefButton.cs b/Assets/Scripts/GUI/AddSoundDefButton.cs index cb263f42..8911a2cb 100644 --- a/Assets/Scripts/GUI/AddSoundDefButton.cs +++ b/Assets/Scripts/GUI/AddSoundDefButton.cs @@ -16,10 +16,10 @@ namespace RimWorldAnimationStudio void Update() { - PawnKeyframe keyframe = Workspace.Instance.GetCurrentOrPreviousKeyframe(Workspace.actorID); + PawnKeyframe keyframe = Workspace.GetCurrentOrPreviousKeyframe(Workspace.ActorID); if (keyframe != null) - { text.text = keyframe.soundEffect == null || keyframe.soundEffect == "" ? "None" : keyframe.soundEffect; } + { text.text = keyframe.SoundEffect == null || keyframe.SoundEffect == "" ? "None" : keyframe.SoundEffect; } else { text.text = "None"; } diff --git a/Assets/Scripts/GUI/AnimationDefCard.cs b/Assets/Scripts/GUI/AnimationDefCard.cs deleted file mode 100644 index 018a2adb..00000000 --- a/Assets/Scripts/GUI/AnimationDefCard.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using UnityEngine.UI; - -namespace RimWorldAnimationStudio -{ - public class AnimationDefCard : MonoBehaviour - { - public InputField defNameField; - public InputField labelField; - //public Toggle playSoundsToggle; - - public void Update() - { - if (Workspace.animationDef == null) return; - - if (defNameField.isFocused == false) - { defNameField.text = Workspace.animationDef.defName; } - - if (labelField.isFocused == false) - { labelField.text = Workspace.animationDef.label; } - - //playSoundsToggle.isOn = Workspace.animationDef.sounds; - } - - public void UpdateAnimationDef() - { - Workspace.animationDef.defName = defNameField.text; - Workspace.animationDef.label = labelField.text; - //Workspace.animationDef.sounds = playSoundsToggle.isOn; - - Workspace.Instance.MakeHistoricRecord("AnimationDef update"); - } - } -} diff --git a/Assets/Scripts/GUI/AnimationTimeline.cs b/Assets/Scripts/GUI/AnimationTimeline.cs index 815244e4..b5724802 100644 --- a/Assets/Scripts/GUI/AnimationTimeline.cs +++ b/Assets/Scripts/GUI/AnimationTimeline.cs @@ -21,13 +21,13 @@ namespace RimWorldAnimationStudio anchorTransform = transform.parent; this.actorID = actorID; - PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID); + PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID); clip.BuildSimpleCurves(); foreach (KeyframeSlider slider in GetComponentsInChildren()) { RemovePawnKeyFrame(slider.keyframeID);} - foreach (PawnKeyframe keyframe in clip.keyframes) + foreach (PawnKeyframe keyframe in clip.Keyframes) { AddPawnKeyFrame(keyframe.keyframeID); } /*int keyframeCount = clip.keyframes.Count; @@ -66,7 +66,7 @@ namespace RimWorldAnimationStudio public void Update() { - if (Workspace.actorID == actorID) + if (Workspace.ActorID == actorID) { GetComponent().color = Constants.ColorGoldYellow; } else @@ -91,27 +91,27 @@ namespace RimWorldAnimationStudio public bool MoveAnimationTimeline(int startIndex, int delta) { - if (startIndex + delta < 0 || startIndex + delta >= Workspace.animationDef.animationStages[Workspace.stageID].animationClips.Count) + if (startIndex + delta < 0 || startIndex + delta >= Workspace.GetCurrentAnimationStage().AnimationClips.Count) { Debug.Log("Cannot move animation timeline - movement would exceed bounds"); return false; } - Actor actor = Workspace.animationDef.actors[startIndex]; - Workspace.animationDef.actors[startIndex] = Workspace.animationDef.actors[startIndex + delta]; - Workspace.animationDef.actors[startIndex + delta] = actor; + Actor actor = Workspace.animationDef.Actors[startIndex]; + Workspace.animationDef.Actors[startIndex] = Workspace.animationDef.Actors[startIndex + delta]; + Workspace.animationDef.Actors[startIndex + delta] = actor; - PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(startIndex); - Workspace.animationDef.animationStages[Workspace.stageID].animationClips[startIndex] = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[startIndex + delta]; - Workspace.animationDef.animationStages[Workspace.stageID].animationClips[startIndex + delta] = clip; + PawnAnimationClip clip = Workspace.GetPawnAnimationClip(startIndex); + Workspace.GetCurrentAnimationStage().AnimationClips[startIndex] = Workspace.GetCurrentAnimationStage().AnimationClips[startIndex + delta]; + Workspace.GetCurrentAnimationStage().AnimationClips[startIndex + delta] = clip; - Workspace.actorID = startIndex + delta; + Workspace.ActorID = startIndex + delta; - Workspace.Instance.RecordEvent("Timeline move"); + Workspace.RecordEvent("Timeline move"); return true; } public void OnPointerClick(PointerEventData eventData) { - Workspace.actorID = actorID; + Workspace.ActorID = actorID; Workspace.keyframeID.Clear(); } } diff --git a/Assets/Scripts/GUI/Cards.meta b/Assets/Scripts/GUI/Cards.meta new file mode 100644 index 00000000..ea5d142e --- /dev/null +++ b/Assets/Scripts/GUI/Cards.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c026d569e32726d4eb8821db713d0aac +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/GUI/ActorAddonCard.cs b/Assets/Scripts/GUI/Cards/ActorAddonCard.cs similarity index 61% rename from Assets/Scripts/GUI/ActorAddonCard.cs rename to Assets/Scripts/GUI/Cards/ActorAddonCard.cs index 86de0c02..84110297 100644 --- a/Assets/Scripts/GUI/ActorAddonCard.cs +++ b/Assets/Scripts/GUI/Cards/ActorAddonCard.cs @@ -27,25 +27,25 @@ namespace RimWorldAnimationStudio public void OnFieldValueChanged() { if (Workspace.animationDef == null) return; - PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip(); - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip(); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); - keyframe.GetAddonKeyframe(addonName).posX = float.Parse(xOffsetField.text); - keyframe.GetAddonKeyframe(addonName).posZ = float.Parse(zOffsetField.text); - keyframe.GetAddonKeyframe(addonName).rotation = float.Parse(rotationField.text); + keyframe.GetAddonKeyframe(addonName).PosX = float.Parse(xOffsetField.text); + keyframe.GetAddonKeyframe(addonName).PosZ = float.Parse(zOffsetField.text); + keyframe.GetAddonKeyframe(addonName).Rotation = float.Parse(rotationField.text); clip.BuildSimpleCurves(); - Workspace.Instance.RecordEvent("Actor addon position / orientation"); + Workspace.RecordEvent("Actor addon position / orientation"); } public void OnKeyframeValueChanged() { if (Workspace.animationDef == null) return; - PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip(); + PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip(); - xOffsetField.SetTextWithoutNotify(clip.GetActorAddon(addonName).PosX.Evaluate((float)AnimationController.Instance.stageTick / Workspace.StageWindowSize).ToString()); - zOffsetField.SetTextWithoutNotify(clip.GetActorAddon(addonName).PosZ.Evaluate((float)AnimationController.Instance.stageTick / Workspace.StageWindowSize).ToString()); - rotationField.SetTextWithoutNotify(clip.GetActorAddon(addonName).Rotation.Evaluate((float)AnimationController.Instance.stageTick / Workspace.StageWindowSize).ToString()); + xOffsetField.SetTextWithoutNotify(clip.GetActorAddon(addonName).PosX.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize).ToString()); + zOffsetField.SetTextWithoutNotify(clip.GetActorAddon(addonName).PosZ.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize).ToString()); + rotationField.SetTextWithoutNotify(clip.GetActorAddon(addonName).Rotation.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize).ToString()); } } } diff --git a/Assets/Scripts/GUI/ActorAddonCard.cs.meta b/Assets/Scripts/GUI/Cards/ActorAddonCard.cs.meta similarity index 100% rename from Assets/Scripts/GUI/ActorAddonCard.cs.meta rename to Assets/Scripts/GUI/Cards/ActorAddonCard.cs.meta diff --git a/Assets/Scripts/GUI/Cards/ActorCard.cs b/Assets/Scripts/GUI/Cards/ActorCard.cs new file mode 100644 index 00000000..211b9219 --- /dev/null +++ b/Assets/Scripts/GUI/Cards/ActorCard.cs @@ -0,0 +1,124 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.UI; + +namespace RimWorldAnimationStudio +{ + public class ActorCard : MonoBehaviour + { + public Toggle initiatorToggle; + public Dropdown selectActorLayerDropdown; + public Dropdown bodyTypeDropdown; + public InputField bodyOffsetXField; + public InputField bodyOffsetZField; + public Dropdown raceDropdown; + public InputField raceOffsetXField; + public InputField raceOffsetZField; + + private Actor actor { get { return Workspace.GetCurrentActor(); } } + private PawnAnimationClip clip { get { return Workspace.GetCurrentPawnAnimationClip(); } } + + public void Awake() + { + UpdateRaceDropdown(); + } + + public void Start() + { + // General events + EventsManager.onAnimationDefChanged.AddListener(delegate { UpdateGUI(); }); + EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); }); + EventsManager.onDefNamesChanged.AddListener(delegate { UpdateRaceDropdown(); }); + + // Local events + initiatorToggle.onValueChanged.AddListener(delegate { + actor.initiator = initiatorToggle.isOn; + Workspace.RecordEvent("Change in actor sex initiator status "); + }); + + selectActorLayerDropdown.onValueChanged.AddListener(delegate { + clip.Layer = selectActorLayerDropdown.options[selectActorLayerDropdown.value].text; + Workspace.RecordEvent("Change in actor render layer"); + }); + + bodyTypeDropdown.onValueChanged.AddListener(delegate { OnDropdownChanged(); }); + bodyOffsetXField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); }); + bodyOffsetZField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); }); + + raceDropdown.onValueChanged.AddListener(delegate { OnDropdownChanged(); }); + raceOffsetXField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); }); + raceOffsetZField.onEndEdit.AddListener(delegate { OnInputFieldChanged(); }); + + // Initialize + UpdateGUI(); + } + + public void OnInputFieldChanged() + { + string bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text; + bodyType = string.IsNullOrEmpty(bodyType) ? "Male" : bodyType; + + float.TryParse(bodyOffsetXField.text, out float x); + float.TryParse(bodyOffsetZField.text, out float z); + actor.BodyTypeOffset.SetOffset(bodyType, new Vector2(x, z)); + + float.TryParse(raceOffsetXField.text, out x); + float.TryParse(raceOffsetZField.text, out z); + actor.SetPawnRaceOffset(new Vector2(x, z)); + + Workspace.RecordEvent("Actor offset"); + } + + public void OnDropdownChanged() + { + actor.bodyType = bodyTypeDropdown.options[bodyTypeDropdown.value].text; + + if (raceDropdown.options[raceDropdown.value].text != actor.GetPawnRaceDef().defName) + { Workspace.selectedBodyPart = null; } + + actor.SetPawnRaceDef(raceDropdown.options[raceDropdown.value].text); + + Workspace.RecordEvent("Actor body type/race change"); + + UpdateGUI(); + } + + public void UpdateRaceDropdown() + { + raceDropdown.ClearOptions(); + int index = raceDropdown.value; + + IEnumerable optionsList = DefaultTags.defNames.Concat(CustomTags.defNames); + foreach (string defName in optionsList) + { raceDropdown.options.Add(new Dropdown.OptionData(defName)); } + + raceDropdown.value = Mathf.Clamp(index, 0, raceDropdown.options.Count - 1); + } + + public void UpdateGUI() + { + initiatorToggle.isOn = actor.Initiator; + + string layer = clip.Layer; + selectActorLayerDropdown.SetValueWithoutNotify(selectActorLayerDropdown.options.FindIndex(x => x.text == layer)); + + string bodyType = actor.bodyType; + bodyTypeDropdown.SetValueWithoutNotify(bodyTypeDropdown.options.FindIndex(x => x.text == bodyType)); + + bodyOffsetXField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.BodyTypeOffset.GetOffset(bodyType).x.ToString())); + bodyOffsetZField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.BodyTypeOffset.GetOffset(bodyType).z.ToString())); + + bodyTypeDropdown.interactable = actor.GetPawnRaceDef().isHumanoid; + bodyOffsetXField.interactable = actor.GetPawnRaceDef().isHumanoid; + bodyOffsetZField.interactable = actor.GetPawnRaceDef().isHumanoid; + + string race = actor.GetPawnRaceDef().defName; + raceDropdown.SetValueWithoutNotify(raceDropdown.options.FindIndex(x => x.text == race)); + + raceOffsetXField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.GetPawnRaceOffset().x.ToString())); + raceOffsetZField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.GetPawnRaceOffset().z.ToString())); + } + } +} diff --git a/Assets/Scripts/GUI/ActorCard.cs.meta b/Assets/Scripts/GUI/Cards/ActorCard.cs.meta similarity index 100% rename from Assets/Scripts/GUI/ActorCard.cs.meta rename to Assets/Scripts/GUI/Cards/ActorCard.cs.meta diff --git a/Assets/Scripts/GUI/ActorKeyframeCard.cs b/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs similarity index 56% rename from Assets/Scripts/GUI/ActorKeyframeCard.cs rename to Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs index ca3f3c08..98ff43f3 100644 --- a/Assets/Scripts/GUI/ActorKeyframeCard.cs +++ b/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs @@ -30,18 +30,18 @@ namespace RimWorldAnimationStudio public void OnValueChanged() { - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); - keyframe.bodyOffsetX = float.Parse(positionXField.text); - keyframe.bodyOffsetZ = float.Parse(positionZField.text); - keyframe.bodyAngle = float.Parse(rotationField.text); - keyframe.headBob = float.Parse(headBobField.text); - keyframe.headAngle = float.Parse(headRotationField.text); - keyframe.genitalAngle = float.Parse(appendageRotationField.text); + keyframe.BodyOffsetX = float.Parse(positionXField.text); + keyframe.BodyOffsetZ = float.Parse(positionZField.text); + keyframe.BodyAngle = float.Parse(rotationField.text); + keyframe.HeadBob = float.Parse(headBobField.text); + keyframe.HeadAngle = float.Parse(headRotationField.text); + keyframe.GenitalAngle = float.Parse(appendageRotationField.text); - Workspace.animationDef.actors[Workspace.actorID].controlGenitalAngle = keyframe.genitalAngle != 0; - Workspace.Instance.GetPawnAnimationClip(Workspace.actorID).BuildSimpleCurves(); - Workspace.Instance.RecordEvent("Actor position / orientation"); + Workspace.animationDef.Actors[Workspace.ActorID].ControlGenitalAngle = keyframe.GenitalAngle != 0; + Workspace.GetPawnAnimationClip(Workspace.ActorID).BuildSimpleCurves(); + Workspace.RecordEvent("Actor position / orientation"); } public void AdjustActor(Vector2 deltaOffset) @@ -59,50 +59,50 @@ namespace RimWorldAnimationStudio public void MoveActor(Vector2 deltaOffset) { - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); if (Workspace.selectedBodyPart == null) { - keyframe.bodyOffsetX += deltaOffset.x; - keyframe.bodyOffsetZ += deltaOffset.y; + keyframe.BodyOffsetX += deltaOffset.x; + keyframe.BodyOffsetZ += deltaOffset.y; } else if (Workspace.selectedBodyPart.isHead) - { keyframe.headBob += deltaOffset.y; } + { keyframe.HeadBob += deltaOffset.y; } - Workspace.Instance.GetCurrentPawnAnimationClip().BuildSimpleCurves(); - Workspace.Instance.RecordEvent("Actor position / orientation"); + Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves(); + Workspace.RecordEvent("Actor position / orientation"); } public void RotateActor(float deltaAngle) { - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); if (Workspace.selectedBodyPart == null) - { keyframe.bodyAngle += deltaAngle; } + { keyframe.BodyAngle += deltaAngle; } else if (Workspace.selectedBodyPart.isHead) - { keyframe.headAngle += deltaAngle; } + { keyframe.HeadAngle += deltaAngle; } else - { keyframe.genitalAngle -= deltaAngle; } + { keyframe.GenitalAngle -= deltaAngle; } - Workspace.Instance.GetCurrentPawnAnimationClip().BuildSimpleCurves(); - Workspace.Instance.RecordEvent("Actor position / orientation"); + Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves(); + Workspace.RecordEvent("Actor position / orientation"); } public void FaceActor(int facing) { - PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true); + PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true); if (Workspace.selectedBodyPart == null) - { keyframe.bodyFacing = facing; } + { keyframe.BodyFacing = facing; } else if (Workspace.selectedBodyPart.isHead) - { keyframe.headFacing = facing; } + { keyframe.HeadFacing = facing; } - Workspace.Instance.GetCurrentPawnAnimationClip().BuildSimpleCurves(); - Workspace.Instance.RecordEvent("Actor position / orientation"); + Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves(); + Workspace.RecordEvent("Actor position / orientation"); } } } \ No newline at end of file diff --git a/Assets/Scripts/GUI/ActorKeyframeCard.cs.meta b/Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs.meta similarity index 100% rename from Assets/Scripts/GUI/ActorKeyframeCard.cs.meta rename to Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs.meta diff --git a/Assets/Scripts/GUI/Cards/AnimationDefCard.cs b/Assets/Scripts/GUI/Cards/AnimationDefCard.cs new file mode 100644 index 00000000..015eb7b0 --- /dev/null +++ b/Assets/Scripts/GUI/Cards/AnimationDefCard.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.UI; + +namespace RimWorldAnimationStudio +{ + public class AnimationDefCard : MonoBehaviour + { + public InputField defNameField; + public InputField labelField; + + public void Start() + { + EventsManager.onAnimationDefChanged.AddListener(delegate { UpdateInputFields(); }); + + defNameField.onEndEdit.AddListener(delegate { + Workspace.animationDef.DefName = defNameField.text; + Workspace.MakeHistoricRecord("AnimationDef update"); + }); + + labelField.onEndEdit.AddListener(delegate { + Workspace.animationDef.Label = labelField.text; + Workspace.MakeHistoricRecord("AnimationDef update"); + }); + + UpdateInputFields(); + } + + public void UpdateInputFields() + { + defNameField.SetTextWithoutNotify(Workspace.animationDef.DefName); + labelField.SetTextWithoutNotify(Workspace.animationDef.Label); + } + } +} diff --git a/Assets/Scripts/GUI/AnimationDefCard.cs.meta b/Assets/Scripts/GUI/Cards/AnimationDefCard.cs.meta similarity index 100% rename from Assets/Scripts/GUI/AnimationDefCard.cs.meta rename to Assets/Scripts/GUI/Cards/AnimationDefCard.cs.meta diff --git a/Assets/Scripts/GUI/Cards/StageCard.cs b/Assets/Scripts/GUI/Cards/StageCard.cs new file mode 100644 index 00000000..10bfe5d2 --- /dev/null +++ b/Assets/Scripts/GUI/Cards/StageCard.cs @@ -0,0 +1,63 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.EventSystems; + +namespace RimWorldAnimationStudio +{ + public class StageCard : MonoBehaviour, IPointerClickHandler + { + public Text stageName; + public InputField stageNameField; + public Image banner; + + public void OnNameChange() + { + stageName.text = stageNameField.text; + stageNameField.gameObject.SetActive(false); + + Workspace.GetCurrentAnimationStage().StageName = stageName.text; + Workspace.RecordEvent("Stage renamed"); + } + + public void OnMoveStage(int delta) + { + int siblingCount = transform.parent.childCount; + int index = Mathf.Clamp(transform.GetSiblingIndex() + delta, 0, siblingCount - 1); + + transform.SetSiblingIndex(index); + } + + public void Initialize(string stageName) + { + this.stageName.text = stageName; + } + + public void Update() + { + if (Workspace.StageID == transform.GetSiblingIndex()) + { banner.gameObject.SetActive(true); } + + else + { + banner.gameObject.SetActive(false); + stageNameField.gameObject.SetActive(false); + } + } + + public void OnPointerClick(PointerEventData eventData) + { + if (eventData.clickCount >= 2) + { + stageNameField.text = stageName.text; + stageNameField.gameObject.SetActive(true); + } + + if (Workspace.StageID != transform.GetSiblingIndex()) + { Workspace.RecordEvent("Stage selected"); } + + Workspace.StageID = transform.GetSiblingIndex(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/GUI/StageCard.cs.meta b/Assets/Scripts/GUI/Cards/StageCard.cs.meta similarity index 100% rename from Assets/Scripts/GUI/StageCard.cs.meta rename to Assets/Scripts/GUI/Cards/StageCard.cs.meta diff --git a/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs b/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs index d627854c..b5afa00b 100644 --- a/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs +++ b/Assets/Scripts/GUI/DialogBoxes/DialogBox.cs @@ -67,9 +67,9 @@ namespace RimWorldAnimationStudio if (field?.text == null || field.text == "") { return; } - AlienRaceDefs.AddDef(new AlienRaceDef(field.text)); + PawnRaceDefs.AddDef(new PawnRaceDef(field.text)); - ApplicationManager.Instance.SaveAlienRaceDefs(); + ApplicationManager.Instance.SavePawnRaceDefs(); Initialize(true); } diff --git a/Assets/Scripts/GUI/DialogBoxes/RaceSettingsDialog.cs b/Assets/Scripts/GUI/DialogBoxes/RaceSettingsDialog.cs index d1e50e8d..2c62131b 100644 --- a/Assets/Scripts/GUI/DialogBoxes/RaceSettingsDialog.cs +++ b/Assets/Scripts/GUI/DialogBoxes/RaceSettingsDialog.cs @@ -21,21 +21,21 @@ namespace RimWorldAnimationStudio { Reset(); - AlienRaceDef alienRaceDef = GetCurrentRaceDef(); - if (alienRaceDef == null) return; + PawnRaceDef pawnRaceDef = GetCurrentRaceDef(); + if (pawnRaceDef == null) return; - isHumanoidToggle.SetIsOnWithoutNotify(alienRaceDef.isHumanoid); + isHumanoidToggle.SetIsOnWithoutNotify(pawnRaceDef.isHumanoid); Text bodyGraphicsTitle = AddCloneObjectToParent(raceSettingsWindow, 2).GetComponent(); bodyGraphicsTitle.text = "Body graphic filepaths"; - List allTags = alienRaceDef.isHumanoid ? Tags.bodyTypes : new List() { "None" }; + List allTags = pawnRaceDef.isHumanoid ? DefaultTags.bodyTypes : new List() { "None" }; foreach (string bodyType in allTags) { string _bodyType = bodyType; - if (alienRaceDef.isHumanoid) + if (pawnRaceDef.isHumanoid) { Text bodyTypeTitle = AddCloneObjectToParent(raceSettingsWindow, 2).GetComponent(); bodyTypeTitle.text = bodyType; @@ -49,15 +49,15 @@ namespace RimWorldAnimationStudio filepath.GetComponent().text = facing.ToString(); filepath.transform.Find("FilepathButton").GetComponent