mirror of
				https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
				synced 2024-08-15 00:43:27 +00:00 
			
		
		
		
	Squashed commit of the following:
commitaf4dab5546Author: AbstractConcept <abstract.concept@mail.com> Date: Mon Oct 31 19:58:41 2022 -0500 Code refactor commite14a12f2abAuthor: AbstractConcept <abstract.concept@mail.com> Date: Mon Oct 31 00:44:53 2022 -0500 Code refactor commit5ca7e486f8Author: AbstractConcept <abstract.concept@mail.com> Date: Fri Oct 28 19:52:58 2022 -0500 Code refactor commita55ba7b95bAuthor: AbstractConcept <abstract.concept@mail.com> Date: Fri Oct 28 00:28:51 2022 -0500 Code refactor commit757badf4f6Author: AbstractConcept <abstract.concept@mail.com> Date: Thu Oct 27 00:56:04 2022 -0500 Code refactor
This commit is contained in:
		
							parent
							
								
									cd4711a8e5
								
							
						
					
					
						commit
						bb2cc29393
					
				
					 603 changed files with 9200 additions and 7528 deletions
				
			
		
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -65,6 +65,7 @@
 | 
			
		|||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="Assets\Editor\AdvancedPolygonColliderEditor.cs" />
 | 
			
		||||
    <Compile Include="Assets\Editor\ButtonWithKeyCodeEditor.cs" />
 | 
			
		||||
    <Compile Include="Assets\Editor\FindMissingScriptsRecursively.cs" />
 | 
			
		||||
    <Compile Include="Assets\Editor\KeyframeSliderEditor.cs" />
 | 
			
		||||
    <Reference Include="UnityEngine">
 | 
			
		||||
      <HintPath>C:/Program Files/Unity/Hub/Editor/2019.4.20f1/Editor/Data/Managed/UnityEngine/UnityEngine.dll</HintPath>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,34 +67,43 @@
 | 
			
		|||
    <Compile Include="Assets\Scripts\AdvancedPolygonCollider\AdvancedPolygonColliderUtilities.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\Actor.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\ActorAddon.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AlienRaceDef.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AlienRaceOffset.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AnimationClips\AnimationClip.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AnimationClips\PawnAnimationClip.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AnimationClips\ThingAnimationClip.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\ActorAddonDef.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AddonKeyFrame.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AnimationDef.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\AnimationStage.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\BodyTypeOffset.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\ButtonWithKeyCode.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\Chaser.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\Defs.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\KeyFrames\AddonKeyFrame.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\KeyFrames\Keyframe.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\KeyFrames\PawnKeyframe.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\KeyFrames\ThingKeyFrame.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\PawnAnimationClip.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\PawnKeyframe.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\PawnRaceDef.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\AnimationComponents\PawnRaceOffset.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Data\ActorPosition.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Data\Constants.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Data\DefaultTags.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Data\Enums.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\DefParents\ActorAddonDefs.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\DefParents\AnimationDefs.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\DefParents\PawnRaceDefs.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Extensions\IListExtensions.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Extensions\ObjectExtensions.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Extensions\TransformExtensions.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Extensions\Vector3Extension.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ActorAddonCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ActorBody.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ActorBodyPart.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ActorCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ActorKeyframeCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ActorManipulator.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Actors\ActorBody.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Actors\ActorBodyPart.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\AddSoundDefButton.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\AnimationDefCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\AddonAnchorDropdown.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\AnimationLengthsCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\AnimationTimeline.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\ButtonWithKeyCode.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\ActorAddonCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\ActorAddonKeyframeCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\ActorCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\ActorKeyframeCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\AnimationControlCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\AnimationDefCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\StageCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Cards\StageLoopsCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Chaser.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\DialogBoxes\ConsoleMessagesDialog.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\DialogBoxes\DialogBox.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\DialogBoxes\RaceSettingsDialog.cs" />
 | 
			
		||||
| 
						 | 
				
			
			@ -108,32 +117,32 @@
 | 
			
		|||
    <Compile Include="Assets\Scripts\GUI\DialogBoxes\SelectSexTypesDialog.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\DialogBoxes\SelectSoundDefDialog.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\DropdownMenu.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\InactiveDuringAnimationPreview.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\KeybindLabel.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\KeyframeSlider.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\LinearScale.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Props\SexProp.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Props\SexPropManager.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\QuiverToggle.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\RequiresAnimationDef.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\SelectActorLayerButton.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\SelectRaceDropdown.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\SnapToKeyframe.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\StageCard.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Tooltip.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Graphics\DirectionalGraphic.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Tooltips\Tooltip.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\GUI\Tooltips\TooltipMessage.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Graphics\GraphicData.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Graphics\MultiDirectionalGraphic.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Graphics\SingleGraphic.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Keybinds\Keybind.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Keybinds\KeybindConfig.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Managers\AnimationController.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Managers\ApplicationManager.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Managers\CameraController.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Managers\EventsManager.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Managers\InputManager.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Managers\StageCardManager.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Math\Constants\Constants.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Math\Constants\Enums.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Math\CurvePoint.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Math\GenMath.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Math\SimpleCurve.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\SexProp.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\SexPropManager.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Singleton.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Strings\NumberValidator.cs" />
 | 
			
		||||
    <Compile Include="Assets\Scripts\Utilities\PawnUtility.cs" />
 | 
			
		||||
| 
						 | 
				
			
			@ -146,10 +155,11 @@
 | 
			
		|||
    <Compile Include="Assets\StandaloneFileBrowser\StandaloneFileBrowserLinux.cs" />
 | 
			
		||||
    <Compile Include="Assets\StandaloneFileBrowser\StandaloneFileBrowserMac.cs" />
 | 
			
		||||
    <Compile Include="Assets\StandaloneFileBrowser\StandaloneFileBrowserWindows.cs" />
 | 
			
		||||
    <None Include="Assets\StreamingAssets\alienRaceDefs.xml" />
 | 
			
		||||
    <None Include="Assets\StreamingAssets\pawnRaceDefs.xml" />
 | 
			
		||||
    <None Include="Assets\StreamingAssets\AnimationDefs\newAnimationDef.xml" />
 | 
			
		||||
    <None Include="Assets\StreamingAssets\keybindConfig.xml" />
 | 
			
		||||
    <None Include="Assets\StreamingAssets\customTags.xml" />
 | 
			
		||||
    <None Include="Assets\StreamingAssets\actorAddonDefs.xml" />
 | 
			
		||||
    <Reference Include="UnityEngine">
 | 
			
		||||
      <HintPath>C:/Program Files/Unity/Hub/Editor/2019.4.20f1/Editor/Data/Managed/UnityEngine/UnityEngine.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								Assembly-CSharp.csproj.user
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Assembly-CSharp.csproj.user
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <ProjectView>ProjectFiles</ProjectView>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										130
									
								
								Assets/Editor/FindMissingScriptsRecursively.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								Assets/Editor/FindMissingScriptsRecursively.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
using UnityEditor;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace AndroidUltimatePlugin.Helpers.Editor
 | 
			
		||||
{
 | 
			
		||||
    public class FindMissingScriptsRecursively : EditorWindow
 | 
			
		||||
    {
 | 
			
		||||
        static int _goCount = 0, _componentsCount = 0, _missingCount = 0;
 | 
			
		||||
 | 
			
		||||
        [MenuItem("Window/FindMissingScriptsRecursively")]
 | 
			
		||||
        public static void ShowWindow()
 | 
			
		||||
        {
 | 
			
		||||
            GetWindow(typeof(FindMissingScriptsRecursively));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnGUI()
 | 
			
		||||
        {
 | 
			
		||||
            if (GUILayout.Button("Find Missing Scripts in selected GameObjects"))
 | 
			
		||||
            {
 | 
			
		||||
                FindInSelected();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (GUILayout.Button("Find Missing Scripts"))
 | 
			
		||||
            {
 | 
			
		||||
                FindAll();
 | 
			
		||||
            }
 | 
			
		||||
            EditorGUILayout.BeginHorizontal();
 | 
			
		||||
            {
 | 
			
		||||
                EditorGUILayout.LabelField("Component Scanned:");
 | 
			
		||||
                EditorGUILayout.LabelField("" + (_componentsCount == -1 ? "---" : _componentsCount.ToString()));
 | 
			
		||||
            }
 | 
			
		||||
            EditorGUILayout.EndHorizontal();
 | 
			
		||||
            
 | 
			
		||||
            EditorGUILayout.BeginHorizontal();
 | 
			
		||||
            {
 | 
			
		||||
                EditorGUILayout.LabelField("Object Scanned:");
 | 
			
		||||
                EditorGUILayout.LabelField("" + (_goCount == -1 ? "---" : _goCount.ToString()));
 | 
			
		||||
            }
 | 
			
		||||
            EditorGUILayout.EndHorizontal();
 | 
			
		||||
            
 | 
			
		||||
            EditorGUILayout.BeginHorizontal();
 | 
			
		||||
            {
 | 
			
		||||
                EditorGUILayout.LabelField("Possible Missing Scripts:");
 | 
			
		||||
                EditorGUILayout.LabelField("" + (_missingCount == -1 ? "---" : _missingCount.ToString()));
 | 
			
		||||
            }
 | 
			
		||||
            EditorGUILayout.EndHorizontal();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void FindAll()
 | 
			
		||||
        {
 | 
			
		||||
            _componentsCount = 0;
 | 
			
		||||
            _goCount = 0;
 | 
			
		||||
            _missingCount = 0;
 | 
			
		||||
            
 | 
			
		||||
            string[] assetsPaths = AssetDatabase.GetAllAssetPaths();
 | 
			
		||||
 | 
			
		||||
            foreach (string assetPath in assetsPaths)
 | 
			
		||||
            {
 | 
			
		||||
                Object[] data = LoadAllAssetsAtPath(assetPath);
 | 
			
		||||
                foreach (Object o in data)
 | 
			
		||||
                {
 | 
			
		||||
                    if (o != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (o is GameObject)
 | 
			
		||||
                        {
 | 
			
		||||
                            FindInGO((GameObject) o);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            Debug.Log($"Searched {_goCount} GameObjects, {_componentsCount} components, found {_missingCount} missing");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Object[] LoadAllAssetsAtPath(string assetPath)
 | 
			
		||||
        {
 | 
			
		||||
            return typeof(SceneAsset).Equals(AssetDatabase.GetMainAssetTypeAtPath(assetPath))
 | 
			
		||||
                ?
 | 
			
		||||
                // prevent error "Do not use readobjectthreaded on scene objects!"
 | 
			
		||||
                new[] {AssetDatabase.LoadMainAssetAtPath(assetPath)}
 | 
			
		||||
                : AssetDatabase.LoadAllAssetsAtPath(assetPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void FindInSelected()
 | 
			
		||||
        {
 | 
			
		||||
            GameObject[] go = Selection.gameObjects;
 | 
			
		||||
            _goCount = 0;
 | 
			
		||||
            _componentsCount = 0;
 | 
			
		||||
            _missingCount = 0;
 | 
			
		||||
            foreach (GameObject g in go)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                FindInGO(g);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Debug.Log($"Searched {_goCount} GameObjects, {_componentsCount} components, found {_missingCount} missing");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void FindInGO(GameObject g)
 | 
			
		||||
        {
 | 
			
		||||
            _goCount++;
 | 
			
		||||
            Component[] components = g.GetComponents<Component>();
 | 
			
		||||
            for (int i = 0; i < components.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                _componentsCount++;
 | 
			
		||||
                if (components[i] == null)
 | 
			
		||||
                {
 | 
			
		||||
                    _missingCount++;
 | 
			
		||||
                    string s = g.name;
 | 
			
		||||
                    Transform t = g.transform;
 | 
			
		||||
                    while (t.parent != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        var parent = t.parent;
 | 
			
		||||
                        s = parent.name + "/" + s;
 | 
			
		||||
                        t = parent;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Debug.Log(s + " has an empty script attached in position: " + i, g);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Now recurse through each child GO (if there are any):
 | 
			
		||||
            foreach (Transform childT in g.transform)
 | 
			
		||||
            {
 | 
			
		||||
                //Debug.Log("Searching " + childT.name  + " " );
 | 
			
		||||
                FindInGO(childT.gameObject);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: a3449cf2dd7e0444bbc5a7b654cf10c5
 | 
			
		||||
guid: f991f27152653b841901199172a12809
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
							
								
								
									
										3120
									
								
								Assets/Resources/Prefabs/ActorAddonCard.prefab
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3120
									
								
								Assets/Resources/Prefabs/ActorAddonCard.prefab
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										7
									
								
								Assets/Resources/Prefabs/ActorAddonCard.prefab.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Assets/Resources/Prefabs/ActorAddonCard.prefab.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 013f4bcdcb176e2478c081219c513821
 | 
			
		||||
PrefabImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										905
									
								
								Assets/Resources/Prefabs/ActorAddonKeyframeCard.prefab
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										905
									
								
								Assets/Resources/Prefabs/ActorAddonKeyframeCard.prefab
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,905 @@
 | 
			
		|||
%YAML 1.1
 | 
			
		||||
%TAG !u! tag:unity3d.com,2011:
 | 
			
		||||
--- !u!1 &2959214801869174166
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214801869174167}
 | 
			
		||||
  - component: {fileID: 2959214801869174163}
 | 
			
		||||
  - component: {fileID: 2959214801869174162}
 | 
			
		||||
  - component: {fileID: 2959214801869174165}
 | 
			
		||||
  - component: {fileID: 2959214801869174164}
 | 
			
		||||
  - component: {fileID: 2959214801869174160}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: rotationField
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214801869174167
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214801869174166}
 | 
			
		||||
  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: 2959214803873671157}
 | 
			
		||||
  m_Father: {fileID: 2959214802706661728}
 | 
			
		||||
  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: 240, y: 0}
 | 
			
		||||
  m_SizeDelta: {x: 60, y: 30}
 | 
			
		||||
  m_Pivot: {x: 0, y: 1}
 | 
			
		||||
--- !u!222 &2959214801869174163
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214801869174166}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214801869174162
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214801869174166}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_Type: 1
 | 
			
		||||
  m_PreserveAspect: 0
 | 
			
		||||
  m_FillCenter: 1
 | 
			
		||||
  m_FillMethod: 4
 | 
			
		||||
  m_FillAmount: 1
 | 
			
		||||
  m_FillClockwise: 1
 | 
			
		||||
  m_FillOrigin: 0
 | 
			
		||||
  m_UseSpriteMesh: 0
 | 
			
		||||
  m_PixelsPerUnitMultiplier: 1
 | 
			
		||||
--- !u!114 &2959214801869174165
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214801869174166}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Navigation:
 | 
			
		||||
    m_Mode: 0
 | 
			
		||||
    m_SelectOnUp: {fileID: 0}
 | 
			
		||||
    m_SelectOnDown: {fileID: 0}
 | 
			
		||||
    m_SelectOnLeft: {fileID: 0}
 | 
			
		||||
    m_SelectOnRight: {fileID: 0}
 | 
			
		||||
  m_Transition: 1
 | 
			
		||||
  m_Colors:
 | 
			
		||||
    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
 | 
			
		||||
    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
 | 
			
		||||
    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
 | 
			
		||||
    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
 | 
			
		||||
    m_ColorMultiplier: 1
 | 
			
		||||
    m_FadeDuration: 0.1
 | 
			
		||||
  m_SpriteState:
 | 
			
		||||
    m_HighlightedSprite: {fileID: 0}
 | 
			
		||||
    m_PressedSprite: {fileID: 0}
 | 
			
		||||
    m_SelectedSprite: {fileID: 0}
 | 
			
		||||
    m_DisabledSprite: {fileID: 0}
 | 
			
		||||
  m_AnimationTriggers:
 | 
			
		||||
    m_NormalTrigger: Normal
 | 
			
		||||
    m_HighlightedTrigger: Highlighted
 | 
			
		||||
    m_PressedTrigger: Pressed
 | 
			
		||||
    m_SelectedTrigger: Selected
 | 
			
		||||
    m_DisabledTrigger: Disabled
 | 
			
		||||
  m_Interactable: 1
 | 
			
		||||
  m_TargetGraphic: {fileID: 2959214801869174162}
 | 
			
		||||
  m_TextComponent: {fileID: 2959214803873671154}
 | 
			
		||||
  m_Placeholder: {fileID: 0}
 | 
			
		||||
  m_ContentType: 0
 | 
			
		||||
  m_InputType: 0
 | 
			
		||||
  m_AsteriskChar: 42
 | 
			
		||||
  m_KeyboardType: 0
 | 
			
		||||
  m_LineType: 0
 | 
			
		||||
  m_HideMobileInput: 0
 | 
			
		||||
  m_CharacterValidation: 0
 | 
			
		||||
  m_CharacterLimit: 0
 | 
			
		||||
  m_OnEndEdit:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls:
 | 
			
		||||
      - m_Target: {fileID: 0}
 | 
			
		||||
        m_MethodName: OnValueChanged
 | 
			
		||||
        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_OnValueChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
 | 
			
		||||
  m_CustomCaretColor: 0
 | 
			
		||||
  m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
 | 
			
		||||
  m_Text: 0.000
 | 
			
		||||
  m_CaretBlinkRate: 0.85
 | 
			
		||||
  m_CaretWidth: 1
 | 
			
		||||
  m_ReadOnly: 0
 | 
			
		||||
  m_ShouldActivateOnSelect: 1
 | 
			
		||||
--- !u!114 &2959214801869174164
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214801869174166}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 1f3886223a697384abc8109a51c855e2, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  valiationType: 2
 | 
			
		||||
--- !u!114 &2959214801869174160
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214801869174166}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 92068b39ed172084296a595f5a09e54b, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
--- !u!1 &2959214802527417763
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214802527417760}
 | 
			
		||||
  - component: {fileID: 2959214802527417774}
 | 
			
		||||
  - component: {fileID: 2959214802527417761}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: Text
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214802527417760
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802527417763}
 | 
			
		||||
  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: 2959214802834023108}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
  m_AnchorMin: {x: 0, y: 0}
 | 
			
		||||
  m_AnchorMax: {x: 1, y: 1}
 | 
			
		||||
  m_AnchoredPosition: {x: 0, y: -0.5}
 | 
			
		||||
  m_SizeDelta: {x: -20, y: -13}
 | 
			
		||||
  m_Pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
--- !u!222 &2959214802527417774
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802527417763}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214802527417761
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802527417763}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_FontData:
 | 
			
		||||
    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
 | 
			
		||||
    m_FontSize: 14
 | 
			
		||||
    m_FontStyle: 0
 | 
			
		||||
    m_BestFit: 0
 | 
			
		||||
    m_MinSize: 10
 | 
			
		||||
    m_MaxSize: 40
 | 
			
		||||
    m_Alignment: 0
 | 
			
		||||
    m_AlignByGeometry: 0
 | 
			
		||||
    m_RichText: 0
 | 
			
		||||
    m_HorizontalOverflow: 1
 | 
			
		||||
    m_VerticalOverflow: 0
 | 
			
		||||
    m_LineSpacing: 1
 | 
			
		||||
  m_Text: 0.000
 | 
			
		||||
--- !u!1 &2959214802659385800
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214802659385801}
 | 
			
		||||
  - component: {fileID: 2959214802659385847}
 | 
			
		||||
  - component: {fileID: 2959214802659385846}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: Text
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214802659385801
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802659385800}
 | 
			
		||||
  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: 2959214803241694089}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
  m_AnchorMin: {x: 0, y: 0}
 | 
			
		||||
  m_AnchorMax: {x: 1, y: 1}
 | 
			
		||||
  m_AnchoredPosition: {x: 0, y: -0.5}
 | 
			
		||||
  m_SizeDelta: {x: -20, y: -13}
 | 
			
		||||
  m_Pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
--- !u!222 &2959214802659385847
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802659385800}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214802659385846
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802659385800}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_FontData:
 | 
			
		||||
    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
 | 
			
		||||
    m_FontSize: 14
 | 
			
		||||
    m_FontStyle: 0
 | 
			
		||||
    m_BestFit: 0
 | 
			
		||||
    m_MinSize: 10
 | 
			
		||||
    m_MaxSize: 40
 | 
			
		||||
    m_Alignment: 0
 | 
			
		||||
    m_AlignByGeometry: 0
 | 
			
		||||
    m_RichText: 0
 | 
			
		||||
    m_HorizontalOverflow: 1
 | 
			
		||||
    m_VerticalOverflow: 0
 | 
			
		||||
    m_LineSpacing: 1
 | 
			
		||||
  m_Text: 0.000
 | 
			
		||||
--- !u!1 &2959214802706661731
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214802706661728}
 | 
			
		||||
  - component: {fileID: 2959214802706661729}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: ActorAddonKeyframeCard
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 0
 | 
			
		||||
--- !u!224 &2959214802706661728
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802706661731}
 | 
			
		||||
  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: 2959214803289300818}
 | 
			
		||||
  - {fileID: 2959214803241694089}
 | 
			
		||||
  - {fileID: 2959214802834023108}
 | 
			
		||||
  - {fileID: 2959214801869174167}
 | 
			
		||||
  m_Father: {fileID: 0}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
  m_AnchorMin: {x: 0, y: 1}
 | 
			
		||||
  m_AnchorMax: {x: 0, y: 1}
 | 
			
		||||
  m_AnchoredPosition: {x: 0, y: -155}
 | 
			
		||||
  m_SizeDelta: {x: 310, y: 30}
 | 
			
		||||
  m_Pivot: {x: 0, y: 0.5}
 | 
			
		||||
--- !u!114 &2959214802706661729
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802706661731}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 8a63bb35c73985c46b65383f08d4afd9, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  addonName: none
 | 
			
		||||
  label: {fileID: 2959214803289300819}
 | 
			
		||||
  xOffsetField: {fileID: 2959214803241694135}
 | 
			
		||||
  zOffsetField: {fileID: 2959214802834023106}
 | 
			
		||||
  rotationField: {fileID: 2959214801869174165}
 | 
			
		||||
--- !u!1 &2959214802834023111
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214802834023108}
 | 
			
		||||
  - component: {fileID: 2959214802834023104}
 | 
			
		||||
  - component: {fileID: 2959214802834023107}
 | 
			
		||||
  - component: {fileID: 2959214802834023106}
 | 
			
		||||
  - component: {fileID: 2959214802834023109}
 | 
			
		||||
  - component: {fileID: 2959214802834023105}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: posOffsetZField
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214802834023108
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802834023111}
 | 
			
		||||
  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: 2959214802527417760}
 | 
			
		||||
  m_Father: {fileID: 2959214802706661728}
 | 
			
		||||
  m_RootOrder: 2
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
  m_AnchorMin: {x: 0, y: 1}
 | 
			
		||||
  m_AnchorMax: {x: 0, y: 1}
 | 
			
		||||
  m_AnchoredPosition: {x: 175, y: 0}
 | 
			
		||||
  m_SizeDelta: {x: 60, y: 30}
 | 
			
		||||
  m_Pivot: {x: 0, y: 1}
 | 
			
		||||
--- !u!222 &2959214802834023104
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802834023111}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214802834023107
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802834023111}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_Type: 1
 | 
			
		||||
  m_PreserveAspect: 0
 | 
			
		||||
  m_FillCenter: 1
 | 
			
		||||
  m_FillMethod: 4
 | 
			
		||||
  m_FillAmount: 1
 | 
			
		||||
  m_FillClockwise: 1
 | 
			
		||||
  m_FillOrigin: 0
 | 
			
		||||
  m_UseSpriteMesh: 0
 | 
			
		||||
  m_PixelsPerUnitMultiplier: 1
 | 
			
		||||
--- !u!114 &2959214802834023106
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802834023111}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Navigation:
 | 
			
		||||
    m_Mode: 0
 | 
			
		||||
    m_SelectOnUp: {fileID: 0}
 | 
			
		||||
    m_SelectOnDown: {fileID: 0}
 | 
			
		||||
    m_SelectOnLeft: {fileID: 0}
 | 
			
		||||
    m_SelectOnRight: {fileID: 0}
 | 
			
		||||
  m_Transition: 1
 | 
			
		||||
  m_Colors:
 | 
			
		||||
    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
 | 
			
		||||
    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
 | 
			
		||||
    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
 | 
			
		||||
    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
 | 
			
		||||
    m_ColorMultiplier: 1
 | 
			
		||||
    m_FadeDuration: 0.1
 | 
			
		||||
  m_SpriteState:
 | 
			
		||||
    m_HighlightedSprite: {fileID: 0}
 | 
			
		||||
    m_PressedSprite: {fileID: 0}
 | 
			
		||||
    m_SelectedSprite: {fileID: 0}
 | 
			
		||||
    m_DisabledSprite: {fileID: 0}
 | 
			
		||||
  m_AnimationTriggers:
 | 
			
		||||
    m_NormalTrigger: Normal
 | 
			
		||||
    m_HighlightedTrigger: Highlighted
 | 
			
		||||
    m_PressedTrigger: Pressed
 | 
			
		||||
    m_SelectedTrigger: Selected
 | 
			
		||||
    m_DisabledTrigger: Disabled
 | 
			
		||||
  m_Interactable: 1
 | 
			
		||||
  m_TargetGraphic: {fileID: 2959214802834023107}
 | 
			
		||||
  m_TextComponent: {fileID: 2959214802527417761}
 | 
			
		||||
  m_Placeholder: {fileID: 0}
 | 
			
		||||
  m_ContentType: 0
 | 
			
		||||
  m_InputType: 0
 | 
			
		||||
  m_AsteriskChar: 42
 | 
			
		||||
  m_KeyboardType: 0
 | 
			
		||||
  m_LineType: 0
 | 
			
		||||
  m_HideMobileInput: 0
 | 
			
		||||
  m_CharacterValidation: 0
 | 
			
		||||
  m_CharacterLimit: 0
 | 
			
		||||
  m_OnEndEdit:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls:
 | 
			
		||||
      - m_Target: {fileID: 0}
 | 
			
		||||
        m_MethodName: OnValueChanged
 | 
			
		||||
        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_OnValueChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
 | 
			
		||||
  m_CustomCaretColor: 0
 | 
			
		||||
  m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
 | 
			
		||||
  m_Text: 0.000
 | 
			
		||||
  m_CaretBlinkRate: 0.85
 | 
			
		||||
  m_CaretWidth: 1
 | 
			
		||||
  m_ReadOnly: 0
 | 
			
		||||
  m_ShouldActivateOnSelect: 1
 | 
			
		||||
--- !u!114 &2959214802834023109
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802834023111}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 1f3886223a697384abc8109a51c855e2, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  valiationType: 2
 | 
			
		||||
--- !u!114 &2959214802834023105
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214802834023111}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 92068b39ed172084296a595f5a09e54b, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
--- !u!1 &2959214803241694088
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214803241694089}
 | 
			
		||||
  - component: {fileID: 2959214803241694133}
 | 
			
		||||
  - component: {fileID: 2959214803241694132}
 | 
			
		||||
  - component: {fileID: 2959214803241694135}
 | 
			
		||||
  - component: {fileID: 2959214803241694134}
 | 
			
		||||
  - component: {fileID: 2959214803241694130}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: posOffsetXField
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214803241694089
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803241694088}
 | 
			
		||||
  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: 2959214802659385801}
 | 
			
		||||
  m_Father: {fileID: 2959214802706661728}
 | 
			
		||||
  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: 110, y: 0}
 | 
			
		||||
  m_SizeDelta: {x: 60, y: 30}
 | 
			
		||||
  m_Pivot: {x: 0, y: 1}
 | 
			
		||||
--- !u!222 &2959214803241694133
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803241694088}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214803241694132
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803241694088}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_Type: 1
 | 
			
		||||
  m_PreserveAspect: 0
 | 
			
		||||
  m_FillCenter: 1
 | 
			
		||||
  m_FillMethod: 4
 | 
			
		||||
  m_FillAmount: 1
 | 
			
		||||
  m_FillClockwise: 1
 | 
			
		||||
  m_FillOrigin: 0
 | 
			
		||||
  m_UseSpriteMesh: 0
 | 
			
		||||
  m_PixelsPerUnitMultiplier: 1
 | 
			
		||||
--- !u!114 &2959214803241694135
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803241694088}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Navigation:
 | 
			
		||||
    m_Mode: 0
 | 
			
		||||
    m_SelectOnUp: {fileID: 0}
 | 
			
		||||
    m_SelectOnDown: {fileID: 0}
 | 
			
		||||
    m_SelectOnLeft: {fileID: 0}
 | 
			
		||||
    m_SelectOnRight: {fileID: 0}
 | 
			
		||||
  m_Transition: 1
 | 
			
		||||
  m_Colors:
 | 
			
		||||
    m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
    m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
 | 
			
		||||
    m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
 | 
			
		||||
    m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
 | 
			
		||||
    m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
 | 
			
		||||
    m_ColorMultiplier: 1
 | 
			
		||||
    m_FadeDuration: 0.1
 | 
			
		||||
  m_SpriteState:
 | 
			
		||||
    m_HighlightedSprite: {fileID: 0}
 | 
			
		||||
    m_PressedSprite: {fileID: 0}
 | 
			
		||||
    m_SelectedSprite: {fileID: 0}
 | 
			
		||||
    m_DisabledSprite: {fileID: 0}
 | 
			
		||||
  m_AnimationTriggers:
 | 
			
		||||
    m_NormalTrigger: Normal
 | 
			
		||||
    m_HighlightedTrigger: Highlighted
 | 
			
		||||
    m_PressedTrigger: Pressed
 | 
			
		||||
    m_SelectedTrigger: Selected
 | 
			
		||||
    m_DisabledTrigger: Disabled
 | 
			
		||||
  m_Interactable: 1
 | 
			
		||||
  m_TargetGraphic: {fileID: 2959214803241694132}
 | 
			
		||||
  m_TextComponent: {fileID: 2959214802659385846}
 | 
			
		||||
  m_Placeholder: {fileID: 0}
 | 
			
		||||
  m_ContentType: 0
 | 
			
		||||
  m_InputType: 0
 | 
			
		||||
  m_AsteriskChar: 42
 | 
			
		||||
  m_KeyboardType: 0
 | 
			
		||||
  m_LineType: 0
 | 
			
		||||
  m_HideMobileInput: 0
 | 
			
		||||
  m_CharacterValidation: 0
 | 
			
		||||
  m_CharacterLimit: 0
 | 
			
		||||
  m_OnEndEdit:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls:
 | 
			
		||||
      - m_Target: {fileID: 0}
 | 
			
		||||
        m_MethodName: OnValueChanged
 | 
			
		||||
        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_OnValueChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
 | 
			
		||||
  m_CustomCaretColor: 0
 | 
			
		||||
  m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412}
 | 
			
		||||
  m_Text: 0.000
 | 
			
		||||
  m_CaretBlinkRate: 0.85
 | 
			
		||||
  m_CaretWidth: 1
 | 
			
		||||
  m_ReadOnly: 0
 | 
			
		||||
  m_ShouldActivateOnSelect: 1
 | 
			
		||||
--- !u!114 &2959214803241694134
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803241694088}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 1f3886223a697384abc8109a51c855e2, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  valiationType: 2
 | 
			
		||||
--- !u!114 &2959214803241694130
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803241694088}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 92068b39ed172084296a595f5a09e54b, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
--- !u!1 &2959214803289300821
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214803289300818}
 | 
			
		||||
  - component: {fileID: 2959214803289300816}
 | 
			
		||||
  - component: {fileID: 2959214803289300819}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: Label
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214803289300818
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803289300821}
 | 
			
		||||
  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: 2959214802706661728}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  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: 0}
 | 
			
		||||
  m_SizeDelta: {x: 90, y: 30}
 | 
			
		||||
  m_Pivot: {x: 0, y: 1}
 | 
			
		||||
--- !u!222 &2959214803289300816
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803289300821}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214803289300819
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803289300821}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_FontData:
 | 
			
		||||
    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
 | 
			
		||||
    m_FontSize: 14
 | 
			
		||||
    m_FontStyle: 0
 | 
			
		||||
    m_BestFit: 0
 | 
			
		||||
    m_MinSize: 10
 | 
			
		||||
    m_MaxSize: 40
 | 
			
		||||
    m_Alignment: 3
 | 
			
		||||
    m_AlignByGeometry: 0
 | 
			
		||||
    m_RichText: 1
 | 
			
		||||
    m_HorizontalOverflow: 0
 | 
			
		||||
    m_VerticalOverflow: 0
 | 
			
		||||
    m_LineSpacing: 1
 | 
			
		||||
  m_Text: Label
 | 
			
		||||
--- !u!1 &2959214803873671156
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 2959214803873671157}
 | 
			
		||||
  - component: {fileID: 2959214803873671155}
 | 
			
		||||
  - component: {fileID: 2959214803873671154}
 | 
			
		||||
  m_Layer: 5
 | 
			
		||||
  m_Name: Text
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 1
 | 
			
		||||
--- !u!224 &2959214803873671157
 | 
			
		||||
RectTransform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803873671156}
 | 
			
		||||
  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: 2959214801869174167}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
  m_AnchorMin: {x: 0, y: 0}
 | 
			
		||||
  m_AnchorMax: {x: 1, y: 1}
 | 
			
		||||
  m_AnchoredPosition: {x: 0, y: -0.5}
 | 
			
		||||
  m_SizeDelta: {x: -20, y: -13}
 | 
			
		||||
  m_Pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
--- !u!222 &2959214803873671155
 | 
			
		||||
CanvasRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803873671156}
 | 
			
		||||
  m_CullTransparentMesh: 0
 | 
			
		||||
--- !u!114 &2959214803873671154
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2959214803873671156}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
 | 
			
		||||
  m_RaycastTarget: 1
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls: []
 | 
			
		||||
  m_FontData:
 | 
			
		||||
    m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
 | 
			
		||||
    m_FontSize: 14
 | 
			
		||||
    m_FontStyle: 0
 | 
			
		||||
    m_BestFit: 0
 | 
			
		||||
    m_MinSize: 10
 | 
			
		||||
    m_MaxSize: 40
 | 
			
		||||
    m_Alignment: 0
 | 
			
		||||
    m_AlignByGeometry: 0
 | 
			
		||||
    m_RichText: 0
 | 
			
		||||
    m_HorizontalOverflow: 1
 | 
			
		||||
    m_VerticalOverflow: 0
 | 
			
		||||
    m_LineSpacing: 1
 | 
			
		||||
  m_Text: 0.000
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 5e55dd63d3d4ece48ad5e588c55d5602
 | 
			
		||||
PrefabImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -1,348 +1,5 @@
 | 
			
		|||
%YAML 1.1
 | 
			
		||||
%TAG !u! tag:unity3d.com,2011:
 | 
			
		||||
--- !u!1 &111030959124096607
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 523924871185930481}
 | 
			
		||||
  - component: {fileID: 3345967395353432914}
 | 
			
		||||
  - component: {fileID: 7181959437973434010}
 | 
			
		||||
  - component: {fileID: 8578366366517098866}
 | 
			
		||||
  - component: {fileID: 2696481706634536602}
 | 
			
		||||
  m_Layer: 0
 | 
			
		||||
  m_Name: ActorHandRight
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 0
 | 
			
		||||
--- !u!4 &523924871185930481
 | 
			
		||||
Transform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 111030959124096607}
 | 
			
		||||
  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: 7929422520673851209}
 | 
			
		||||
  m_RootOrder: 5
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
--- !u!212 &3345967395353432914
 | 
			
		||||
SpriteRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 111030959124096607}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_CastShadows: 0
 | 
			
		||||
  m_ReceiveShadows: 0
 | 
			
		||||
  m_DynamicOccludee: 1
 | 
			
		||||
  m_MotionVectors: 1
 | 
			
		||||
  m_LightProbeUsage: 1
 | 
			
		||||
  m_ReflectionProbeUsage: 1
 | 
			
		||||
  m_RayTracingMode: 0
 | 
			
		||||
  m_RenderingLayerMask: 1
 | 
			
		||||
  m_RendererPriority: 0
 | 
			
		||||
  m_Materials:
 | 
			
		||||
  - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_StaticBatchInfo:
 | 
			
		||||
    firstSubMesh: 0
 | 
			
		||||
    subMeshCount: 0
 | 
			
		||||
  m_StaticBatchRoot: {fileID: 0}
 | 
			
		||||
  m_ProbeAnchor: {fileID: 0}
 | 
			
		||||
  m_LightProbeVolumeOverride: {fileID: 0}
 | 
			
		||||
  m_ScaleInLightmap: 1
 | 
			
		||||
  m_ReceiveGI: 1
 | 
			
		||||
  m_PreserveUVs: 0
 | 
			
		||||
  m_IgnoreNormalsForChartDetection: 0
 | 
			
		||||
  m_ImportantGI: 0
 | 
			
		||||
  m_StitchLightmapSeams: 1
 | 
			
		||||
  m_SelectedEditorRenderState: 0
 | 
			
		||||
  m_MinimumChartSize: 4
 | 
			
		||||
  m_AutoUVMaxDistance: 0.5
 | 
			
		||||
  m_AutoUVMaxAngle: 89
 | 
			
		||||
  m_LightmapParameters: {fileID: 0}
 | 
			
		||||
  m_SortingLayerID: -2115984483
 | 
			
		||||
  m_SortingLayer: 22
 | 
			
		||||
  m_SortingOrder: 3
 | 
			
		||||
  m_Sprite: {fileID: 21300000, guid: 68b94fce550ad52498142c9433df954b, type: 3}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_FlipX: 0
 | 
			
		||||
  m_FlipY: 0
 | 
			
		||||
  m_DrawMode: 0
 | 
			
		||||
  m_Size: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
  m_AdaptiveModeThreshold: 0.5
 | 
			
		||||
  m_SpriteTileMode: 0
 | 
			
		||||
  m_WasSpriteAssigned: 1
 | 
			
		||||
  m_MaskInteraction: 0
 | 
			
		||||
  m_SpriteSortPoint: 0
 | 
			
		||||
--- !u!60 &7181959437973434010
 | 
			
		||||
PolygonCollider2D:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 111030959124096607}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_Density: 1
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_IsTrigger: 0
 | 
			
		||||
  m_UsedByEffector: 0
 | 
			
		||||
  m_UsedByComposite: 0
 | 
			
		||||
  m_Offset: {x: 0, y: 0}
 | 
			
		||||
  m_SpriteTilingProperty:
 | 
			
		||||
    border: {x: 0, y: 0, z: 0, w: 0}
 | 
			
		||||
    pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
    oldSize: {x: 1.0039216, y: 1.0039216}
 | 
			
		||||
    newSize: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
    adaptiveTilingThreshold: 0.5
 | 
			
		||||
    drawMode: 0
 | 
			
		||||
    adaptiveTiling: 0
 | 
			
		||||
  m_AutoTiling: 0
 | 
			
		||||
  m_Points:
 | 
			
		||||
    m_Paths:
 | 
			
		||||
    - - {x: -0.013513514, y: -0.035135135}
 | 
			
		||||
      - {x: 0.029729731, y: -0.029729731}
 | 
			
		||||
      - {x: 0.040540542, y: -0.0027027028}
 | 
			
		||||
      - {x: 0.045945946, y: 0.12162162}
 | 
			
		||||
      - {x: 0.013513514, y: 0.15945946}
 | 
			
		||||
      - {x: -0.024324324, y: 0.14864865}
 | 
			
		||||
      - {x: -0.040540542, y: 0.12162162}
 | 
			
		||||
      - {x: -0.024324324, y: -0.029729731}
 | 
			
		||||
    - - {x: -0.056756757, y: 0.008108108}
 | 
			
		||||
      - {x: -0.051351354, y: 0.072972976}
 | 
			
		||||
      - {x: -0.056756757, y: 0.029729731}
 | 
			
		||||
    - - {x: 0.056756757, y: 0.008108108}
 | 
			
		||||
      - {x: 0.056756757, y: 0.01891892}
 | 
			
		||||
    - - {x: 0.056756757, y: 0.07837838}
 | 
			
		||||
      - {x: 0.062162165, y: 0.1}
 | 
			
		||||
      - {x: 0.056756757, y: 0.089189194}
 | 
			
		||||
--- !u!114 &8578366366517098866
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 111030959124096607}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 8c55c83d4c4dd1145ad5fbbab3c3df36, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  AlphaTolerance: 50
 | 
			
		||||
  DistanceThreshold: 2
 | 
			
		||||
  Scale: 1
 | 
			
		||||
  Decompose: 0
 | 
			
		||||
  RunInPlayMode: 1
 | 
			
		||||
  UseCache: 0
 | 
			
		||||
  lastAlphaTolerance: 20
 | 
			
		||||
  lastScale: 1
 | 
			
		||||
  lastDistanceThreshold: 2
 | 
			
		||||
  lastDecompose: 0
 | 
			
		||||
  lastSprite: {fileID: 21300000, guid: 38c0bc38c0d71b04cb11a1eb610990e1, type: 3}
 | 
			
		||||
  lastRect:
 | 
			
		||||
    serializedVersion: 2
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 256
 | 
			
		||||
    height: 256
 | 
			
		||||
  lastOffset: {x: 128, y: 128}
 | 
			
		||||
  lastPixelsPerUnit: 185
 | 
			
		||||
  lastFlipX: 0
 | 
			
		||||
  lastFlipY: 0
 | 
			
		||||
  editorCache: []
 | 
			
		||||
--- !u!114 &2696481706634536602
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 111030959124096607}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: b23e33f312d52c642b86f5f2138f4030, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  bodyPartRenderer: {fileID: 3345967395353432914}
 | 
			
		||||
  parent: {fileID: -4411442180840688308}
 | 
			
		||||
  isHead: 0
 | 
			
		||||
  addonName: right hand
 | 
			
		||||
  isSelected: 0
 | 
			
		||||
--- !u!1 &2846713953308910856
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 7268521810611446429}
 | 
			
		||||
  - component: {fileID: 4070361490379091543}
 | 
			
		||||
  - component: {fileID: 2766569757332877970}
 | 
			
		||||
  - component: {fileID: 1056544768350913866}
 | 
			
		||||
  - component: {fileID: 8546380208971044199}
 | 
			
		||||
  m_Layer: 0
 | 
			
		||||
  m_Name: ActorHandLeft
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 0
 | 
			
		||||
--- !u!4 &7268521810611446429
 | 
			
		||||
Transform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2846713953308910856}
 | 
			
		||||
  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: 7929422520673851209}
 | 
			
		||||
  m_RootOrder: 4
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
--- !u!212 &4070361490379091543
 | 
			
		||||
SpriteRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2846713953308910856}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_CastShadows: 0
 | 
			
		||||
  m_ReceiveShadows: 0
 | 
			
		||||
  m_DynamicOccludee: 1
 | 
			
		||||
  m_MotionVectors: 1
 | 
			
		||||
  m_LightProbeUsage: 1
 | 
			
		||||
  m_ReflectionProbeUsage: 1
 | 
			
		||||
  m_RayTracingMode: 0
 | 
			
		||||
  m_RenderingLayerMask: 1
 | 
			
		||||
  m_RendererPriority: 0
 | 
			
		||||
  m_Materials:
 | 
			
		||||
  - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_StaticBatchInfo:
 | 
			
		||||
    firstSubMesh: 0
 | 
			
		||||
    subMeshCount: 0
 | 
			
		||||
  m_StaticBatchRoot: {fileID: 0}
 | 
			
		||||
  m_ProbeAnchor: {fileID: 0}
 | 
			
		||||
  m_LightProbeVolumeOverride: {fileID: 0}
 | 
			
		||||
  m_ScaleInLightmap: 1
 | 
			
		||||
  m_ReceiveGI: 1
 | 
			
		||||
  m_PreserveUVs: 0
 | 
			
		||||
  m_IgnoreNormalsForChartDetection: 0
 | 
			
		||||
  m_ImportantGI: 0
 | 
			
		||||
  m_StitchLightmapSeams: 1
 | 
			
		||||
  m_SelectedEditorRenderState: 0
 | 
			
		||||
  m_MinimumChartSize: 4
 | 
			
		||||
  m_AutoUVMaxDistance: 0.5
 | 
			
		||||
  m_AutoUVMaxAngle: 89
 | 
			
		||||
  m_LightmapParameters: {fileID: 0}
 | 
			
		||||
  m_SortingLayerID: -2115984483
 | 
			
		||||
  m_SortingLayer: 22
 | 
			
		||||
  m_SortingOrder: 3
 | 
			
		||||
  m_Sprite: {fileID: 21300000, guid: 68b94fce550ad52498142c9433df954b, type: 3}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_FlipX: 0
 | 
			
		||||
  m_FlipY: 0
 | 
			
		||||
  m_DrawMode: 0
 | 
			
		||||
  m_Size: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
  m_AdaptiveModeThreshold: 0.5
 | 
			
		||||
  m_SpriteTileMode: 0
 | 
			
		||||
  m_WasSpriteAssigned: 1
 | 
			
		||||
  m_MaskInteraction: 0
 | 
			
		||||
  m_SpriteSortPoint: 0
 | 
			
		||||
--- !u!60 &2766569757332877970
 | 
			
		||||
PolygonCollider2D:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2846713953308910856}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_Density: 1
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_IsTrigger: 0
 | 
			
		||||
  m_UsedByEffector: 0
 | 
			
		||||
  m_UsedByComposite: 0
 | 
			
		||||
  m_Offset: {x: 0, y: 0}
 | 
			
		||||
  m_SpriteTilingProperty:
 | 
			
		||||
    border: {x: 0, y: 0, z: 0, w: 0}
 | 
			
		||||
    pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
    oldSize: {x: 1.0039216, y: 1.0039216}
 | 
			
		||||
    newSize: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
    adaptiveTilingThreshold: 0.5
 | 
			
		||||
    drawMode: 0
 | 
			
		||||
    adaptiveTiling: 0
 | 
			
		||||
  m_AutoTiling: 0
 | 
			
		||||
  m_Points:
 | 
			
		||||
    m_Paths:
 | 
			
		||||
    - - {x: -0.013513514, y: -0.035135135}
 | 
			
		||||
      - {x: 0.035135135, y: -0.01891892}
 | 
			
		||||
      - {x: 0.040540542, y: 0.13243243}
 | 
			
		||||
      - {x: 0.01891892, y: 0.15405406}
 | 
			
		||||
      - {x: -0.013513514, y: 0.15405406}
 | 
			
		||||
      - {x: -0.035135135, y: 0.13243243}
 | 
			
		||||
      - {x: -0.024324324, y: -0.024324324}
 | 
			
		||||
--- !u!114 &1056544768350913866
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2846713953308910856}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 8c55c83d4c4dd1145ad5fbbab3c3df36, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  AlphaTolerance: 50
 | 
			
		||||
  DistanceThreshold: 2
 | 
			
		||||
  Scale: 1
 | 
			
		||||
  Decompose: 0
 | 
			
		||||
  RunInPlayMode: 1
 | 
			
		||||
  UseCache: 0
 | 
			
		||||
  lastAlphaTolerance: 50
 | 
			
		||||
  lastScale: 1
 | 
			
		||||
  lastDistanceThreshold: 2
 | 
			
		||||
  lastDecompose: 0
 | 
			
		||||
  lastSprite: {fileID: 21300000, guid: 38c0bc38c0d71b04cb11a1eb610990e1, type: 3}
 | 
			
		||||
  lastRect:
 | 
			
		||||
    serializedVersion: 2
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 256
 | 
			
		||||
    height: 256
 | 
			
		||||
  lastOffset: {x: 128, y: 128}
 | 
			
		||||
  lastPixelsPerUnit: 185
 | 
			
		||||
  lastFlipX: 0
 | 
			
		||||
  lastFlipY: 0
 | 
			
		||||
  editorCache: []
 | 
			
		||||
--- !u!114 &8546380208971044199
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 2846713953308910856}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: b23e33f312d52c642b86f5f2138f4030, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  bodyPartRenderer: {fileID: 4070361490379091543}
 | 
			
		||||
  parent: {fileID: -4411442180840688308}
 | 
			
		||||
  isHead: 0
 | 
			
		||||
  addonName: left hand
 | 
			
		||||
  isSelected: 0
 | 
			
		||||
--- !u!1 &3158459618386162366
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
| 
						 | 
				
			
			@ -485,182 +142,6 @@ MonoBehaviour:
 | 
			
		|||
  lastFlipX: 0
 | 
			
		||||
  lastFlipY: 0
 | 
			
		||||
  editorCache: []
 | 
			
		||||
--- !u!1 &5655091321662588893
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 366978152691480472}
 | 
			
		||||
  - component: {fileID: 7367385255154626542}
 | 
			
		||||
  - component: {fileID: 4321381840095243507}
 | 
			
		||||
  - component: {fileID: 6499847047946158724}
 | 
			
		||||
  - component: {fileID: 3259083001588921112}
 | 
			
		||||
  m_Layer: 0
 | 
			
		||||
  m_Name: ActorSexToy
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 0
 | 
			
		||||
--- !u!4 &366978152691480472
 | 
			
		||||
Transform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 5655091321662588893}
 | 
			
		||||
  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: 7929422520673851209}
 | 
			
		||||
  m_RootOrder: 3
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
--- !u!212 &7367385255154626542
 | 
			
		||||
SpriteRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 5655091321662588893}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_CastShadows: 0
 | 
			
		||||
  m_ReceiveShadows: 0
 | 
			
		||||
  m_DynamicOccludee: 1
 | 
			
		||||
  m_MotionVectors: 1
 | 
			
		||||
  m_LightProbeUsage: 1
 | 
			
		||||
  m_ReflectionProbeUsage: 1
 | 
			
		||||
  m_RayTracingMode: 0
 | 
			
		||||
  m_RenderingLayerMask: 1
 | 
			
		||||
  m_RendererPriority: 0
 | 
			
		||||
  m_Materials:
 | 
			
		||||
  - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_StaticBatchInfo:
 | 
			
		||||
    firstSubMesh: 0
 | 
			
		||||
    subMeshCount: 0
 | 
			
		||||
  m_StaticBatchRoot: {fileID: 0}
 | 
			
		||||
  m_ProbeAnchor: {fileID: 0}
 | 
			
		||||
  m_LightProbeVolumeOverride: {fileID: 0}
 | 
			
		||||
  m_ScaleInLightmap: 1
 | 
			
		||||
  m_ReceiveGI: 1
 | 
			
		||||
  m_PreserveUVs: 0
 | 
			
		||||
  m_IgnoreNormalsForChartDetection: 0
 | 
			
		||||
  m_ImportantGI: 0
 | 
			
		||||
  m_StitchLightmapSeams: 1
 | 
			
		||||
  m_SelectedEditorRenderState: 0
 | 
			
		||||
  m_MinimumChartSize: 4
 | 
			
		||||
  m_AutoUVMaxDistance: 0.5
 | 
			
		||||
  m_AutoUVMaxAngle: 89
 | 
			
		||||
  m_LightmapParameters: {fileID: 0}
 | 
			
		||||
  m_SortingLayerID: -2115984483
 | 
			
		||||
  m_SortingLayer: 22
 | 
			
		||||
  m_SortingOrder: 2
 | 
			
		||||
  m_Sprite: {fileID: 21300000, guid: c8db866783ad2a3498006437fd914bc4, type: 3}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_FlipX: 0
 | 
			
		||||
  m_FlipY: 0
 | 
			
		||||
  m_DrawMode: 0
 | 
			
		||||
  m_Size: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
  m_AdaptiveModeThreshold: 0.5
 | 
			
		||||
  m_SpriteTileMode: 0
 | 
			
		||||
  m_WasSpriteAssigned: 1
 | 
			
		||||
  m_MaskInteraction: 0
 | 
			
		||||
  m_SpriteSortPoint: 0
 | 
			
		||||
--- !u!60 &4321381840095243507
 | 
			
		||||
PolygonCollider2D:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 5655091321662588893}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_Density: 1
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_IsTrigger: 0
 | 
			
		||||
  m_UsedByEffector: 0
 | 
			
		||||
  m_UsedByComposite: 0
 | 
			
		||||
  m_Offset: {x: 0, y: 0}
 | 
			
		||||
  m_SpriteTilingProperty:
 | 
			
		||||
    border: {x: 0, y: 0, z: 0, w: 0}
 | 
			
		||||
    pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
    oldSize: {x: 1.5058824, y: 1.5058824}
 | 
			
		||||
    newSize: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
    adaptiveTilingThreshold: 0.5
 | 
			
		||||
    drawMode: 0
 | 
			
		||||
    adaptiveTiling: 0
 | 
			
		||||
  m_AutoTiling: 0
 | 
			
		||||
  m_Points:
 | 
			
		||||
    m_Paths:
 | 
			
		||||
    - - {x: -0.013513514, y: -0.035135135}
 | 
			
		||||
      - {x: 0.029729731, y: -0.029729731}
 | 
			
		||||
      - {x: 0.040540542, y: -0.0027027028}
 | 
			
		||||
      - {x: 0.045945946, y: 0.12162162}
 | 
			
		||||
      - {x: 0.013513514, y: 0.15945946}
 | 
			
		||||
      - {x: -0.024324324, y: 0.14864865}
 | 
			
		||||
      - {x: -0.040540542, y: 0.12162162}
 | 
			
		||||
      - {x: -0.024324324, y: -0.029729731}
 | 
			
		||||
    - - {x: -0.056756757, y: 0.008108108}
 | 
			
		||||
      - {x: -0.051351354, y: 0.072972976}
 | 
			
		||||
      - {x: -0.056756757, y: 0.029729731}
 | 
			
		||||
    - - {x: 0.056756757, y: 0.008108108}
 | 
			
		||||
      - {x: 0.056756757, y: 0.01891892}
 | 
			
		||||
    - - {x: 0.056756757, y: 0.07837838}
 | 
			
		||||
      - {x: 0.062162165, y: 0.1}
 | 
			
		||||
      - {x: 0.056756757, y: 0.089189194}
 | 
			
		||||
--- !u!114 &6499847047946158724
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 5655091321662588893}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 8c55c83d4c4dd1145ad5fbbab3c3df36, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  AlphaTolerance: 50
 | 
			
		||||
  DistanceThreshold: 2
 | 
			
		||||
  Scale: 1
 | 
			
		||||
  Decompose: 0
 | 
			
		||||
  RunInPlayMode: 1
 | 
			
		||||
  UseCache: 0
 | 
			
		||||
  lastAlphaTolerance: 20
 | 
			
		||||
  lastScale: 1
 | 
			
		||||
  lastDistanceThreshold: 2
 | 
			
		||||
  lastDecompose: 0
 | 
			
		||||
  lastSprite: {fileID: 21300000, guid: 38c0bc38c0d71b04cb11a1eb610990e1, type: 3}
 | 
			
		||||
  lastRect:
 | 
			
		||||
    serializedVersion: 2
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 256
 | 
			
		||||
    height: 256
 | 
			
		||||
  lastOffset: {x: 128, y: 128}
 | 
			
		||||
  lastPixelsPerUnit: 185
 | 
			
		||||
  lastFlipX: 0
 | 
			
		||||
  lastFlipY: 0
 | 
			
		||||
  editorCache: []
 | 
			
		||||
--- !u!114 &3259083001588921112
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 5655091321662588893}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: b23e33f312d52c642b86f5f2138f4030, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  bodyPartRenderer: {fileID: 7367385255154626542}
 | 
			
		||||
  parent: {fileID: -4411442180840688308}
 | 
			
		||||
  isHead: 0
 | 
			
		||||
  addonName: dildo
 | 
			
		||||
  isSelected: 0
 | 
			
		||||
--- !u!1 &7929422519883802246
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
| 
						 | 
				
			
			@ -818,9 +299,7 @@ MonoBehaviour:
 | 
			
		|||
  m_EditorClassIdentifier: 
 | 
			
		||||
  bodyPartRenderer: {fileID: 7929422519883802244}
 | 
			
		||||
  parent: {fileID: -4411442180840688308}
 | 
			
		||||
  isHead: 1
 | 
			
		||||
  addonName: 
 | 
			
		||||
  isSelected: 0
 | 
			
		||||
  bodyPart: head
 | 
			
		||||
--- !u!1 &7929422520673851210
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
| 
						 | 
				
			
			@ -852,9 +331,6 @@ Transform:
 | 
			
		|||
  - {fileID: 7516402502875270591}
 | 
			
		||||
  - {fileID: 7929422519883802245}
 | 
			
		||||
  - {fileID: 4090857286061458930}
 | 
			
		||||
  - {fileID: 366978152691480472}
 | 
			
		||||
  - {fileID: 7268521810611446429}
 | 
			
		||||
  - {fileID: 523924871185930481}
 | 
			
		||||
  m_Father: {fileID: 0}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
| 
						 | 
				
			
			@ -871,10 +347,9 @@ MonoBehaviour:
 | 
			
		|||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  actorID: 0
 | 
			
		||||
  isSelected: 0
 | 
			
		||||
  bodyRenderer: {fileID: 5996161745621340017}
 | 
			
		||||
  headRenderer: {fileID: 7929422519883802244}
 | 
			
		||||
  appendageRenderer: {fileID: 4251726083449519904}
 | 
			
		||||
  actorBodyPartPrefab: {fileID: 6079743031150361545, guid: ffbd7531e8f98f94dba0fddefcae2441,
 | 
			
		||||
    type: 3}
 | 
			
		||||
--- !u!1 &9122292209377678227
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
| 
						 | 
				
			
			@ -1048,6 +523,4 @@ MonoBehaviour:
 | 
			
		|||
  m_EditorClassIdentifier: 
 | 
			
		||||
  bodyPartRenderer: {fileID: 4251726083449519904}
 | 
			
		||||
  parent: {fileID: -4411442180840688308}
 | 
			
		||||
  isHead: 0
 | 
			
		||||
  addonName: 
 | 
			
		||||
  isSelected: 0
 | 
			
		||||
  bodyPart: appendage
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										176
									
								
								Assets/Resources/Prefabs/ActorBodyPArt.prefab
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								Assets/Resources/Prefabs/ActorBodyPArt.prefab
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,176 @@
 | 
			
		|||
%YAML 1.1
 | 
			
		||||
%TAG !u! tag:unity3d.com,2011:
 | 
			
		||||
--- !u!1 &3972152003096792844
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  serializedVersion: 6
 | 
			
		||||
  m_Component:
 | 
			
		||||
  - component: {fileID: 8967445332558757705}
 | 
			
		||||
  - component: {fileID: 2259458396607883071}
 | 
			
		||||
  - component: {fileID: 4800170110735377442}
 | 
			
		||||
  - component: {fileID: 2544842580858030677}
 | 
			
		||||
  - component: {fileID: 6079743031150361545}
 | 
			
		||||
  m_Layer: 0
 | 
			
		||||
  m_Name: ActorBodyPArt
 | 
			
		||||
  m_TagString: Untagged
 | 
			
		||||
  m_Icon: {fileID: 0}
 | 
			
		||||
  m_NavMeshLayer: 0
 | 
			
		||||
  m_StaticEditorFlags: 0
 | 
			
		||||
  m_IsActive: 0
 | 
			
		||||
--- !u!4 &8967445332558757705
 | 
			
		||||
Transform:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 3972152003096792844}
 | 
			
		||||
  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: 0}
 | 
			
		||||
  m_RootOrder: 0
 | 
			
		||||
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 | 
			
		||||
--- !u!212 &2259458396607883071
 | 
			
		||||
SpriteRenderer:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 3972152003096792844}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_CastShadows: 0
 | 
			
		||||
  m_ReceiveShadows: 0
 | 
			
		||||
  m_DynamicOccludee: 1
 | 
			
		||||
  m_MotionVectors: 1
 | 
			
		||||
  m_LightProbeUsage: 1
 | 
			
		||||
  m_ReflectionProbeUsage: 1
 | 
			
		||||
  m_RayTracingMode: 0
 | 
			
		||||
  m_RenderingLayerMask: 1
 | 
			
		||||
  m_RendererPriority: 0
 | 
			
		||||
  m_Materials:
 | 
			
		||||
  - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
 | 
			
		||||
  m_StaticBatchInfo:
 | 
			
		||||
    firstSubMesh: 0
 | 
			
		||||
    subMeshCount: 0
 | 
			
		||||
  m_StaticBatchRoot: {fileID: 0}
 | 
			
		||||
  m_ProbeAnchor: {fileID: 0}
 | 
			
		||||
  m_LightProbeVolumeOverride: {fileID: 0}
 | 
			
		||||
  m_ScaleInLightmap: 1
 | 
			
		||||
  m_ReceiveGI: 1
 | 
			
		||||
  m_PreserveUVs: 0
 | 
			
		||||
  m_IgnoreNormalsForChartDetection: 0
 | 
			
		||||
  m_ImportantGI: 0
 | 
			
		||||
  m_StitchLightmapSeams: 1
 | 
			
		||||
  m_SelectedEditorRenderState: 0
 | 
			
		||||
  m_MinimumChartSize: 4
 | 
			
		||||
  m_AutoUVMaxDistance: 0.5
 | 
			
		||||
  m_AutoUVMaxAngle: 89
 | 
			
		||||
  m_LightmapParameters: {fileID: 0}
 | 
			
		||||
  m_SortingLayerID: -2115984483
 | 
			
		||||
  m_SortingLayer: 22
 | 
			
		||||
  m_SortingOrder: 2
 | 
			
		||||
  m_Sprite: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 1, g: 1, b: 1, a: 1}
 | 
			
		||||
  m_FlipX: 0
 | 
			
		||||
  m_FlipY: 0
 | 
			
		||||
  m_DrawMode: 0
 | 
			
		||||
  m_Size: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
  m_AdaptiveModeThreshold: 0.5
 | 
			
		||||
  m_SpriteTileMode: 0
 | 
			
		||||
  m_WasSpriteAssigned: 0
 | 
			
		||||
  m_MaskInteraction: 0
 | 
			
		||||
  m_SpriteSortPoint: 0
 | 
			
		||||
--- !u!60 &4800170110735377442
 | 
			
		||||
PolygonCollider2D:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 3972152003096792844}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_Density: 1
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_IsTrigger: 0
 | 
			
		||||
  m_UsedByEffector: 0
 | 
			
		||||
  m_UsedByComposite: 0
 | 
			
		||||
  m_Offset: {x: 0, y: 0}
 | 
			
		||||
  m_SpriteTilingProperty:
 | 
			
		||||
    border: {x: 0, y: 0, z: 0, w: 0}
 | 
			
		||||
    pivot: {x: 0.5, y: 0.5}
 | 
			
		||||
    oldSize: {x: 1.5058824, y: 1.5058824}
 | 
			
		||||
    newSize: {x: 1.3837838, y: 1.3837838}
 | 
			
		||||
    adaptiveTilingThreshold: 0.5
 | 
			
		||||
    drawMode: 0
 | 
			
		||||
    adaptiveTiling: 0
 | 
			
		||||
  m_AutoTiling: 0
 | 
			
		||||
  m_Points:
 | 
			
		||||
    m_Paths:
 | 
			
		||||
    - - {x: -0.013513514, y: -0.035135135}
 | 
			
		||||
      - {x: 0.029729731, y: -0.029729731}
 | 
			
		||||
      - {x: 0.040540542, y: -0.0027027028}
 | 
			
		||||
      - {x: 0.045945946, y: 0.12162162}
 | 
			
		||||
      - {x: 0.013513514, y: 0.15945946}
 | 
			
		||||
      - {x: -0.024324324, y: 0.14864865}
 | 
			
		||||
      - {x: -0.040540542, y: 0.12162162}
 | 
			
		||||
      - {x: -0.024324324, y: -0.029729731}
 | 
			
		||||
    - - {x: -0.056756757, y: 0.008108108}
 | 
			
		||||
      - {x: -0.051351354, y: 0.072972976}
 | 
			
		||||
      - {x: -0.056756757, y: 0.029729731}
 | 
			
		||||
    - - {x: 0.056756757, y: 0.008108108}
 | 
			
		||||
      - {x: 0.056756757, y: 0.01891892}
 | 
			
		||||
    - - {x: 0.056756757, y: 0.07837838}
 | 
			
		||||
      - {x: 0.062162165, y: 0.1}
 | 
			
		||||
      - {x: 0.056756757, y: 0.089189194}
 | 
			
		||||
--- !u!114 &2544842580858030677
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 3972152003096792844}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: 8c55c83d4c4dd1145ad5fbbab3c3df36, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  AlphaTolerance: 50
 | 
			
		||||
  DistanceThreshold: 2
 | 
			
		||||
  Scale: 1
 | 
			
		||||
  Decompose: 0
 | 
			
		||||
  RunInPlayMode: 1
 | 
			
		||||
  UseCache: 0
 | 
			
		||||
  lastAlphaTolerance: 20
 | 
			
		||||
  lastScale: 1
 | 
			
		||||
  lastDistanceThreshold: 2
 | 
			
		||||
  lastDecompose: 0
 | 
			
		||||
  lastSprite: {fileID: 21300000, guid: 38c0bc38c0d71b04cb11a1eb610990e1, type: 3}
 | 
			
		||||
  lastRect:
 | 
			
		||||
    serializedVersion: 2
 | 
			
		||||
    x: 0
 | 
			
		||||
    y: 0
 | 
			
		||||
    width: 256
 | 
			
		||||
    height: 256
 | 
			
		||||
  lastOffset: {x: 128, y: 128}
 | 
			
		||||
  lastPixelsPerUnit: 185
 | 
			
		||||
  lastFlipX: 0
 | 
			
		||||
  lastFlipY: 0
 | 
			
		||||
  editorCache: []
 | 
			
		||||
--- !u!114 &6079743031150361545
 | 
			
		||||
MonoBehaviour:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
  m_CorrespondingSourceObject: {fileID: 0}
 | 
			
		||||
  m_PrefabInstance: {fileID: 0}
 | 
			
		||||
  m_PrefabAsset: {fileID: 0}
 | 
			
		||||
  m_GameObject: {fileID: 3972152003096792844}
 | 
			
		||||
  m_Enabled: 1
 | 
			
		||||
  m_EditorHideFlags: 0
 | 
			
		||||
  m_Script: {fileID: 11500000, guid: b23e33f312d52c642b86f5f2138f4030, type: 3}
 | 
			
		||||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  bodyPartRenderer: {fileID: 2259458396607883071}
 | 
			
		||||
  parent: {fileID: 0}
 | 
			
		||||
  bodyPart: 
 | 
			
		||||
							
								
								
									
										7
									
								
								Assets/Resources/Prefabs/ActorBodyPArt.prefab.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Assets/Resources/Prefabs/ActorBodyPArt.prefab.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: ffbd7531e8f98f94dba0fddefcae2441
 | 
			
		||||
PrefabImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +181,7 @@ MonoBehaviour:
 | 
			
		|||
  m_Name: 
 | 
			
		||||
  m_EditorClassIdentifier: 
 | 
			
		||||
  m_Material: {fileID: 0}
 | 
			
		||||
  m_Color: {r: 0.5, g: 0, b: 0, a: 0.5019608}
 | 
			
		||||
  m_Color: {r: 0.5, g: 0, b: 0, a: 1}
 | 
			
		||||
  m_RaycastTarget: 0
 | 
			
		||||
  m_Maskable: 1
 | 
			
		||||
  m_OnCullStateChanged:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ MonoBehaviour:
 | 
			
		|||
    m_HorizontalOverflow: 0
 | 
			
		||||
    m_VerticalOverflow: 0
 | 
			
		||||
    m_LineSpacing: 1
 | 
			
		||||
  m_Text: New Stage
 | 
			
		||||
  m_Text: Empty
 | 
			
		||||
--- !u!1 &533195464737222177
 | 
			
		||||
GameObject:
 | 
			
		||||
  m_ObjectHideFlags: 0
 | 
			
		||||
| 
						 | 
				
			
			@ -207,18 +207,7 @@ MonoBehaviour:
 | 
			
		|||
  m_CharacterLimit: 0
 | 
			
		||||
  m_OnEndEdit:
 | 
			
		||||
    m_PersistentCalls:
 | 
			
		||||
      m_Calls:
 | 
			
		||||
      - m_Target: {fileID: 2278168916950142456}
 | 
			
		||||
        m_MethodName: OnNameChange
 | 
			
		||||
        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: []
 | 
			
		||||
| 
						 | 
				
			
			@ -647,6 +636,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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 473 B After Width: | Height: | Size: 2.6 KiB  | 
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 7aa731da3144dfa43b36c2e79b76a763
 | 
			
		||||
guid: 6dc4b8e8006e2c049be7c1849ad84c39
 | 
			
		||||
TextureImporter:
 | 
			
		||||
  internalIDToNameTable: []
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -8,80 +8,143 @@ namespace RimWorldAnimationStudio
 | 
			
		|||
{
 | 
			
		||||
    public class Actor
 | 
			
		||||
    {
 | 
			
		||||
        [XmlArray("defNames"), XmlArrayItem("li")] public List<string> defNames = new List<string>();
 | 
			
		||||
        [XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List<string> bodyDefTypes = new List<string>();
 | 
			
		||||
        [XmlArray("requiredGender"), XmlArrayItem("li")] public List<string> requiredGender = new List<string>();
 | 
			
		||||
        [XmlArray("requiredGenitals"), XmlArrayItem("li")] public List<string> requiredGenitals = new List<string>();      
 | 
			
		||||
        [XmlArray("raceOffsets"), XmlArrayItem("li")] public List<AlienRaceOffset> raceOffsets = new List<AlienRaceOffset>();
 | 
			
		||||
        [XmlArray("blacklistedRaces"), XmlArrayItem("li")] public List<string> blacklistedRaces = new List<string>();      
 | 
			
		||||
        // Data to/from animationDef
 | 
			
		||||
        [XmlArray("defNames"), XmlArrayItem("li")] public List<string> defNames;
 | 
			
		||||
        [XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List<string> bodyDefTypes;
 | 
			
		||||
        [XmlArray("requiredGenitals"), XmlArrayItem("li")] public List<string> requiredGenitals;      
 | 
			
		||||
        [XmlArray("raceOffsets"), XmlArrayItem("li")] public List<PawnRaceOffset> raceOffsets;
 | 
			
		||||
        [XmlArray("tags"), XmlArrayItem("li")] public List<string> 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<string> DefNames 
 | 
			
		||||
        { 
 | 
			
		||||
            get { return defNames.NullOrEmpty() ? defNames = new List<string>() : defNames; } 
 | 
			
		||||
            set { defNames = value.NotNullOrEmpty() ? value : null; } 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetAlienRaceDef(string alienRaceDefName)
 | 
			
		||||
        {
 | 
			
		||||
            AlienRaceDef alienRaceDef = AlienRaceDefs.GetNamed(alienRaceDefName);
 | 
			
		||||
 | 
			
		||||
            if (alienRaceDef != null)
 | 
			
		||||
            { this.alienRaceDef = alienRaceDef; }
 | 
			
		||||
        [XmlIgnore] public List<string> BodyDefTypes 
 | 
			
		||||
        { 
 | 
			
		||||
            get { return bodyDefTypes.NullOrEmpty() ? bodyDefTypes = new List<string>() : bodyDefTypes; } 
 | 
			
		||||
            set { bodyDefTypes = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Vector3 GetAlienRaceOffset()
 | 
			
		||||
        {
 | 
			
		||||
            if (alienRaceDef == null)
 | 
			
		||||
            { alienRaceDef = AlienRaceDefs.GetNamed("Human"); }
 | 
			
		||||
        [XmlIgnore] public List<string> RequiredGenitals 
 | 
			
		||||
        { 
 | 
			
		||||
            get { return requiredGenitals.NullOrEmpty() ? requiredGenitals = new List<string>() : requiredGenitals; } 
 | 
			
		||||
            set { requiredGenitals = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            AlienRaceOffset raceOffset = raceOffsets.FirstOrDefault(x => x.defName == alienRaceDef.defName);
 | 
			
		||||
        [XmlIgnore] public List<PawnRaceOffset> RaceOffsets { 
 | 
			
		||||
            get { return raceOffsets.NullOrEmpty() ? raceOffsets = new List<PawnRaceOffset>() : raceOffsets; } 
 | 
			
		||||
            set { raceOffsets = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<string> Tags 
 | 
			
		||||
        { 
 | 
			
		||||
            get { return tags.NullOrEmpty() ? tags = new List<string>() : tags; } 
 | 
			
		||||
            set { tags = value.NotNullOrEmpty() ? value : null; } 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public BodyTypeOffset BodyTypeOffset
 | 
			
		||||
        { 
 | 
			
		||||
            get { return bodyTypeOffset == null ? bodyTypeOffset = new BodyTypeOffset() : bodyTypeOffset; } 
 | 
			
		||||
            set { bodyTypeOffset = value; } 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool Initiator 
 | 
			
		||||
        { 
 | 
			
		||||
            get { return initiator == true; } 
 | 
			
		||||
            set { if (value) { initiator = true; } else initiator = null; } 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool ControlGenitalAngle
 | 
			
		||||
        { 
 | 
			
		||||
            get { return controlGenitalAngle == true; } 
 | 
			
		||||
            set { if (value) { controlGenitalAngle = true; } else controlGenitalAngle = null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool IsFucking 
 | 
			
		||||
        { 
 | 
			
		||||
            get { return isFucking == true; } 
 | 
			
		||||
            set { if (value) { isFucking = true; } else isFucking = null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool IsFucked
 | 
			
		||||
        { 
 | 
			
		||||
            get { return isFucked == true; } 
 | 
			
		||||
            set { if (value) { isFucked = true; } else isFucked = null; } 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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,35 @@ 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);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ActorPosition GetCurrentPosition()
 | 
			
		||||
        {
 | 
			
		||||
            return GetPositionAtTick(Workspace.StageTick);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ActorPosition GetPositionAtTick(int atTick)
 | 
			
		||||
        {
 | 
			
		||||
            return new ActorPosition(GetActorID(), atTick);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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() { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: ca7cd67490c5773499bff5c06907bdf7
 | 
			
		||||
guid: 63a9fd7a0256e9849bc2bc07403528e8
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,28 +4,75 @@ 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 GraphicData graphicData;
 | 
			
		||||
        public bool? render;
 | 
			
		||||
 | 
			
		||||
        // Data serialization control
 | 
			
		||||
        public bool ShouldSerializeanchorName() { return string.IsNullOrEmpty(anchorName) == false && anchorName.ToLower() != "none"; }
 | 
			
		||||
        public bool ShouldSerializeanchoringActor() { return anchoringActor.HasValue; }
 | 
			
		||||
        public bool ShouldSerializerender() { return render == true; }
 | 
			
		||||
 | 
			
		||||
        // 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; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public string AnchorName
 | 
			
		||||
        {
 | 
			
		||||
            get { return anchorName; }
 | 
			
		||||
            set { anchorName = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public string Layer
 | 
			
		||||
        {
 | 
			
		||||
            get { return layer; }
 | 
			
		||||
            set { layer = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore]
 | 
			
		||||
        public GraphicData GraphicData
 | 
			
		||||
        {
 | 
			
		||||
            get { return graphicData; }
 | 
			
		||||
            set { graphicData = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool Render
 | 
			
		||||
        {
 | 
			
		||||
            get { return render == true; }
 | 
			
		||||
            set { render = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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)
 | 
			
		||||
        public ActorAddon(ActorAddonDef actorAddonDef)
 | 
			
		||||
        {
 | 
			
		||||
            this.addonName = addonName;
 | 
			
		||||
            this.scale = scale;
 | 
			
		||||
            this.AddonName = actorAddonDef.addonName;
 | 
			
		||||
            this.GraphicData = actorAddonDef.graphicData.Copy();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: f4d87003a570d5241affe4170ae91045
 | 
			
		||||
guid: 3759e796f4f62b044b9a652e746d79a1
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								Assets/Scripts/AnimationComponents/ActorAddonDef.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Assets/Scripts/AnimationComponents/ActorAddonDef.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorAddonDef
 | 
			
		||||
    {
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public string label;
 | 
			
		||||
        public float scale = 1f;
 | 
			
		||||
 | 
			
		||||
        public GraphicData graphicData;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: c4a44c0d3b9937c48b2ae8501126227e
 | 
			
		||||
guid: 6d836663c2196924eab4a00f4f4ceb3d
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
							
								
								
									
										55
									
								
								Assets/Scripts/AnimationComponents/AddonKeyFrame.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Assets/Scripts/AnimationComponents/AddonKeyFrame.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
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 serialization control
 | 
			
		||||
        public bool ShouldSerializeposX() { return posX.HasValue; }
 | 
			
		||||
        public bool ShouldSerializeposZ() { return posZ.HasValue; }
 | 
			
		||||
        public bool ShouldSerializerotation() { return rotation.HasValue; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // 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; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float PosZ
 | 
			
		||||
        {
 | 
			
		||||
            get { return posZ.HasValue ? posZ.Value : 0f; }
 | 
			
		||||
            set { posZ = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float Rotation
 | 
			
		||||
        {
 | 
			
		||||
            get { return rotation.HasValue ? rotation.Value : 0f; }
 | 
			
		||||
            set { rotation = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Constructors
 | 
			
		||||
        public AddonKeyframe() { }
 | 
			
		||||
 | 
			
		||||
        public AddonKeyframe(string addonName)
 | 
			
		||||
        {
 | 
			
		||||
            this.AddonName = addonName;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 60509e7cd8e74e6419c5c93304440a17
 | 
			
		||||
guid: 339d47b209f50f545a84a8e8c7948ae1
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			@ -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<string> tags;
 | 
			
		||||
 | 
			
		||||
        public virtual int duration { get { return 0; } }
 | 
			
		||||
 | 
			
		||||
        public abstract void BuildSimpleCurves();
 | 
			
		||||
 | 
			
		||||
        public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); }
 | 
			
		||||
 | 
			
		||||
        public virtual void ValidateData() { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<ActorAddon> _addons = new List<ActorAddon>();
 | 
			
		||||
        [XmlIgnore] public List<ActorAddon> addons = new List<ActorAddon>();
 | 
			
		||||
 | 
			
		||||
        [XmlAttribute("Class")] public string className = "Rimworld_Animations.PawnAnimationClip";
 | 
			
		||||
        [XmlArray("keyframes"), XmlArrayItem("li")] public List<PawnKeyframe> keyframes = new List<PawnKeyframe>();
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public Dictionary<int, bool> quiver = new Dictionary<int, bool>();
 | 
			
		||||
        [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");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<ThingKeyframe> keyframes = new List<ThingKeyframe>();
 | 
			
		||||
 | 
			
		||||
        [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;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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,169 @@ 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<string> sexTypes;
 | 
			
		||||
        [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List<string> interactionDefTypes;
 | 
			
		||||
        [XmlArray("actors"), XmlArrayItem("li")] public List<Actor> actors;     
 | 
			
		||||
        [XmlArray("animationStages"), XmlArrayItem("li")] public List<AnimationStage> animationStages;
 | 
			
		||||
 | 
			
		||||
        [XmlArray("sexTypes"), XmlArrayItem("li")] public List<string> sexTypes = new List<string>();
 | 
			
		||||
        [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List<string> interactionDefTypes = new List<string>();
 | 
			
		||||
        [XmlArray("actors"), XmlArrayItem("li")] public List<Actor> actors = new List<Actor>();     
 | 
			
		||||
        [XmlArray("animationStages"), XmlArrayItem("li")] public List<AnimationStage> animationStages = new List<AnimationStage>();
 | 
			
		||||
        
 | 
			
		||||
        [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; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public string Label
 | 
			
		||||
        {
 | 
			
		||||
            get { return label != null && label != "" ? label : "newAnimation"; }
 | 
			
		||||
            set { label = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<string> SexTypes
 | 
			
		||||
        {
 | 
			
		||||
            get { return sexTypes.NullOrEmpty() ? sexTypes = new List<string>() : sexTypes; }
 | 
			
		||||
            set { sexTypes = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<string> InteractionDefTypes
 | 
			
		||||
        {
 | 
			
		||||
            get { return interactionDefTypes.NullOrEmpty() ? interactionDefTypes = new List<string>() : interactionDefTypes; }
 | 
			
		||||
            set { interactionDefTypes = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<Actor> Actors
 | 
			
		||||
        {
 | 
			
		||||
            get { return actors.NullOrEmpty() ? actors = new List<Actor>() : actors; }
 | 
			
		||||
            set { actors = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<AnimationStage> AnimationStages
 | 
			
		||||
        {
 | 
			
		||||
            get { if (animationStages.NullOrEmpty()){ animationStages = new List<AnimationStage>(); } return animationStages; }
 | 
			
		||||
            set { animationStages = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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);
 | 
			
		||||
 | 
			
		||||
            foreach (AnimationStage stage in Workspace.animationDef.AnimationStages)
 | 
			
		||||
            { stage.AddAnimationClip(Workspace.animationDef.Actors.Count - 1); }
 | 
			
		||||
 | 
			
		||||
            Initialize();
 | 
			
		||||
            Workspace.ActorID = Workspace.animationDef.Actors.Count - 1;
 | 
			
		||||
 | 
			
		||||
            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.StageID = Workspace.animationDef.AnimationStages.Count - 1;
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnStageCountChanged();
 | 
			
		||||
            Workspace.RecordEvent("Stage addition");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void CloneAnimationStage()
 | 
			
		||||
        {
 | 
			
		||||
            AnimationStage stage = Workspace.GetCurrentAnimationStage().Copy();         
 | 
			
		||||
            stage.StageName += " (Clone)";
 | 
			
		||||
 | 
			
		||||
            Workspace.animationDef.AnimationStages.Insert(Workspace.StageID + 1, stage);
 | 
			
		||||
            Initialize();
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnStageCountChanged();
 | 
			
		||||
            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--;
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnStageCountChanged();
 | 
			
		||||
            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() { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 9cca833a1987a2749aa6e4d640d32266
 | 
			
		||||
guid: 37ec1f5f150928e42bda942fe97046b9
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,159 @@ 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
 | 
			
		||||
        public string stageName;
 | 
			
		||||
        public int? playTimeTicks;
 | 
			
		||||
        public int? playTimeTicksQuick;
 | 
			
		||||
        public bool? isLooping;
 | 
			
		||||
        [XmlArray("animationClips"), XmlArrayItem("li")] public List<PawnAnimationClip> animationClips;
 | 
			
		||||
 | 
			
		||||
        [XmlArray("animationClips"), XmlArrayItem("li")] public List<PawnAnimationClip> animationClips = new List<PawnAnimationClip>();
 | 
			
		||||
        // Data serialization control
 | 
			
		||||
        public bool ShouldSerializeanimationClips() { return animationClips.NotNullOrEmpty(); }
 | 
			
		||||
 | 
			
		||||
        // Data helper functions
 | 
			
		||||
        [XmlIgnore] public string StageName
 | 
			
		||||
        {
 | 
			
		||||
            get { return string.IsNullOrEmpty(stageName) ? stageName = "NewStage" : stageName; }
 | 
			
		||||
            set { stageName = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int PlayTimeTicks
 | 
			
		||||
        {
 | 
			
		||||
            get { return playTimeTicks.HasValue ? playTimeTicks.Value : 0; }
 | 
			
		||||
            set { playTimeTicks = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int PlayTimeTicksQuick
 | 
			
		||||
        {
 | 
			
		||||
            get { return playTimeTicksQuick.HasValue ? playTimeTicksQuick.Value : 0; }
 | 
			
		||||
            set { playTimeTicksQuick = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool IsLooping
 | 
			
		||||
        {
 | 
			
		||||
            get { return isLooping == true; }
 | 
			
		||||
            set { isLooping = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<PawnAnimationClip> AnimationClips
 | 
			
		||||
        {
 | 
			
		||||
            get { return animationClips.NullOrEmpty() ? animationClips = new List<PawnAnimationClip>() : animationClips; }
 | 
			
		||||
            set { animationClips = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int StageLoopsNormal
 | 
			
		||||
        {
 | 
			
		||||
            get { return Mathf.CeilToInt(PlayTimeTicks / Workspace.StageWindowSize); }
 | 
			
		||||
            set { value = Math.Max(1, value); PlayTimeTicks = value * Workspace.StageWindowSize; IsLooping = value > 1; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int StageLoopsQuick
 | 
			
		||||
        {
 | 
			
		||||
            get { return Mathf.CeilToInt(PlayTimeTicksQuick / Workspace.StageWindowSize); }
 | 
			
		||||
            set { value = Math.Max(0, Math.Min(value, StageLoopsNormal)); PlayTimeTicksQuick = value * Workspace.StageWindowSize; IsLooping = value > 1; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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 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();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Initialize();
 | 
			
		||||
            playTimeTicksQuick = playTimeTicks;
 | 
			
		||||
            EventsManager.OnStageWindowSizeChanged(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        public void ResizeStageWindow(int newStageWindowSize)
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.GetCurrentAnimationStage().stageWindowSize = newStageWindowSize;
 | 
			
		||||
            Workspace.GetCurrentAnimationStage().PlayTimeTicks = newStageWindowSize * StageLoopsNormal;
 | 
			
		||||
            Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick = newStageWindowSize * StageLoopsQuick;
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnStageWindowSizeChanged(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                PawnKeyframe keyframeA = new PawnKeyframe();
 | 
			
		||||
                keyframeA.TickDuration = Constants.defaultAnimationClipLength - 1;
 | 
			
		||||
 | 
			
		||||
                clip.Keyframes.Add(keyframeA);
 | 
			
		||||
 | 
			
		||||
                PawnKeyframe keyframeB = new PawnKeyframe();
 | 
			
		||||
 | 
			
		||||
                clip.Keyframes.Add(keyframeB);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            animationClips.Add(clip);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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(); }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 4d62c568c0ad7ea4ba7ddd3b9aa6d0e9
 | 
			
		||||
guid: 9270822a570a06f41afa00e169af500c
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 6db04cc11995126429fb12578d6620d7
 | 
			
		||||
guid: 1dfd90f8aa6d0e04086e2b4983d42ab6
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 92804390faa29b945818e67cf808b49c
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<string> tags = new List<string>();
 | 
			
		||||
 | 
			
		||||
        public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); }
 | 
			
		||||
 | 
			
		||||
        public virtual void ValidateData() { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: c909440fcfe86c14c9e363377896367c
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -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<AddonKeyframe> _addonKeyframes = new List<AddonKeyframe>();
 | 
			
		||||
        
 | 
			
		||||
        [XmlIgnore] public List<AddonKeyframe> addonKeyframes = new List<AddonKeyframe>();
 | 
			
		||||
        [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<KeyframeSlider>()?.keyframeID == keyframeID)?.GetComponent< KeyframeSlider>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AddonKeyframe GetAddonKeyframe(string addonName)
 | 
			
		||||
        {
 | 
			
		||||
            return addonKeyframes.FirstOrDefault(x => x.addonName == addonName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 48d6c7ac273c73b498a8bf4c33fda2fc
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										354
									
								
								Assets/Scripts/AnimationComponents/PawnAnimationClip.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								Assets/Scripts/AnimationComponents/PawnAnimationClip.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,354 @@
 | 
			
		|||
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<ActorAddon> addons;
 | 
			
		||||
        [XmlAttribute("Class")] public string className = "Rimworld_Animations.PawnAnimationClip";
 | 
			
		||||
        [XmlArray("keyframes"), XmlArrayItem("li")] public List<PawnKeyframe> keyframes;
 | 
			
		||||
        [XmlArray("tags"), XmlArrayItem("li")] public List<string> 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<ActorAddon> Addons
 | 
			
		||||
        {
 | 
			
		||||
            get { return addons.NullOrEmpty() ? addons = new List<ActorAddon>() : addons; }
 | 
			
		||||
            set { addons = value.NotNullOrEmpty() ? value : null;  }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<PawnKeyframe> Keyframes
 | 
			
		||||
        {
 | 
			
		||||
            get { return keyframes.NullOrEmpty() ? keyframes = new List<PawnKeyframe>() : keyframes; }
 | 
			
		||||
            set { keyframes = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore]
 | 
			
		||||
        public List<string> Tags
 | 
			
		||||
        {
 | 
			
		||||
            get { return tags.NullOrEmpty() ? tags = new List<string>() : tags; }
 | 
			
		||||
            set { tags = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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()
 | 
			
		||||
        {
 | 
			
		||||
            // Add addon data (if missing)
 | 
			
		||||
            foreach (ActorAddonDef actorAddonDef in ActorAddonDefs.allDefs)
 | 
			
		||||
            { AddActorAddon(actorAddonDef); }
 | 
			
		||||
 | 
			
		||||
            // 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 building simple curves
 | 
			
		||||
            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(ActorAddonDef actorAddonDef)
 | 
			
		||||
        {
 | 
			
		||||
            if (Addons.Any(x => x.AddonName == actorAddonDef.addonName) == false)
 | 
			
		||||
            { Addons.Add(new ActorAddon(actorAddonDef)); }
 | 
			
		||||
 | 
			
		||||
            foreach (PawnKeyframe keyframe in Keyframes)
 | 
			
		||||
            {
 | 
			
		||||
                if (keyframe.AddonKeyframes.Any(x => x.AddonName == actorAddonDef.addonName) == false)
 | 
			
		||||
                { keyframe.AddonKeyframes.Add(new AddonKeyframe(actorAddonDef.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()
 | 
			
		||||
        {
 | 
			
		||||
            if (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 % duration) / duration;
 | 
			
		||||
 | 
			
		||||
            PawnKeyframe keyframe = new PawnKeyframe();
 | 
			
		||||
            keyframe.BodyAngle = BodyAngle.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.HeadAngle = HeadAngle.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.HeadBob = HeadBob.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.BodyOffsetX = BodyOffsetX.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.BodyOffsetZ = BodyOffsetZ.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.HeadFacing = (int)HeadFacing.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.BodyFacing = (int)BodyFacing.Evaluate(clipPercent);
 | 
			
		||||
            keyframe.GenitalAngle = 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); }
 | 
			
		||||
 | 
			
		||||
            BuildSimpleCurves();
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnKeyframeCountChanged(this);
 | 
			
		||||
            Workspace.RecordEvent("Keyframe addition");           
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void CopyPawnKeyframes()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.copiedKeyframes.Clear();
 | 
			
		||||
 | 
			
		||||
            List<PawnKeyframe> keyframesToClone = Workspace.GetPawnKeyframesByID(Workspace.keyframeID);
 | 
			
		||||
 | 
			
		||||
            foreach (PawnKeyframe keyframe in keyframesToClone)
 | 
			
		||||
            { Workspace.copiedKeyframes.Add(keyframe.Copy()); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PastePawnKeyframes()
 | 
			
		||||
        {
 | 
			
		||||
            int originalWindowSize = Workspace.StageWindowSize;
 | 
			
		||||
 | 
			
		||||
            List<int> 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.GetPawnAnimationClip(targetActorID).Keyframes.First(x => x.atTick == tickToPasteAt);
 | 
			
		||||
                    Workspace.GetAnimationClipThatOwnsKeyframe(oldKeyframe.keyframeID).RemovePawnKeyframe(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();
 | 
			
		||||
 | 
			
		||||
                EventsManager.OnKeyframeCountChanged(clip);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (originalWindowSize != Workspace.StageWindowSize)
 | 
			
		||||
            {
 | 
			
		||||
                Workspace.GetCurrentAnimationStage().StretchStageWindow(originalWindowSize);
 | 
			
		||||
                Workspace.GetCurrentAnimationStage().ResizeStageWindow(originalWindowSize);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Workspace.RecordEvent("Keyframe pasted");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemovePawnKeyframe(int keyframeID, bool force = false)
 | 
			
		||||
        {
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.GetPawnKeyframe(keyframeID);
 | 
			
		||||
            if (keyframe == null || IsOwnerOfKeyframe(keyframeID) == false) 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 (Keyframes.Count <= 2 && force == false)
 | 
			
		||||
            { Debug.LogWarning("Cannot delete key frame - an animation clip must have two or more keyframes"); return; }
 | 
			
		||||
 | 
			
		||||
            Keyframes.Remove(keyframe);
 | 
			
		||||
            BuildSimpleCurves();
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnKeyframeCountChanged(this);
 | 
			
		||||
            Workspace.RecordEvent("Keyframe deletion");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsOwnerOfKeyframe(int keyframeID)
 | 
			
		||||
        {
 | 
			
		||||
            return Keyframes.Any(x => x.keyframeID == keyframeID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public float GetStageTickPercentage()
 | 
			
		||||
        {
 | 
			
		||||
            return (float)(Workspace.StageTick % duration) / duration;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Pre-save / post-load
 | 
			
		||||
        public void OnPreSave()
 | 
			
		||||
        {
 | 
			
		||||
            var temp = Addons.Copy();
 | 
			
		||||
            Addons.Clear();
 | 
			
		||||
 | 
			
		||||
            foreach (ActorAddon addon in temp)
 | 
			
		||||
            {
 | 
			
		||||
                if (addon.Render)
 | 
			
		||||
                { addons.Add(addon); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnPostLoad()
 | 
			
		||||
        {
 | 
			
		||||
            Addons = addons.Copy();
 | 
			
		||||
 | 
			
		||||
            foreach (PawnKeyframe keyframe in Keyframes)
 | 
			
		||||
            {
 | 
			
		||||
                keyframe.OnPostLoad();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: b7f2dc95148378445919ef3ed8705c5d
 | 
			
		||||
guid: bd5a477338567fb4cbb26b913a52ca65
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
							
								
								
									
										238
									
								
								Assets/Scripts/AnimationComponents/PawnKeyframe.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								Assets/Scripts/AnimationComponents/PawnKeyframe.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,238 @@
 | 
			
		|||
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<string> tags;
 | 
			
		||||
        [XmlArray("addonKeyframes"), XmlArrayItem("li")] public List<AddonKeyframe> 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; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float HeadAngle
 | 
			
		||||
        {
 | 
			
		||||
            get { return headAngle.HasValue ? headAngle.Value : (float)(headAngle = 0f); }
 | 
			
		||||
            set { headAngle = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float HeadBob
 | 
			
		||||
        {
 | 
			
		||||
            get { return headBob.HasValue ? headBob.Value : (float)(headBob = 0f); }
 | 
			
		||||
            set { headBob = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float BodyOffsetX
 | 
			
		||||
        {
 | 
			
		||||
            get { return bodyOffsetX.HasValue ? bodyOffsetX.Value : (float)(bodyOffsetX = 0f); }
 | 
			
		||||
            set { bodyOffsetX = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float BodyOffsetZ
 | 
			
		||||
        {
 | 
			
		||||
            get { return bodyOffsetZ.HasValue ? bodyOffsetZ.Value : (float)(bodyOffsetZ = 0f); }
 | 
			
		||||
            set { bodyOffsetZ = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int HeadFacing
 | 
			
		||||
        {
 | 
			
		||||
            get { return headFacing.HasValue ? headFacing.Value : (int)(headFacing = 2); }
 | 
			
		||||
            set { headFacing = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int BodyFacing
 | 
			
		||||
        {
 | 
			
		||||
            get { return bodyFacing.HasValue ? bodyFacing.Value : (int)(bodyFacing = 2); }
 | 
			
		||||
            set { bodyFacing = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public float GenitalAngle
 | 
			
		||||
        {
 | 
			
		||||
            get { return genitalAngle.HasValue ? genitalAngle.Value : (float)(genitalAngle = 0f); }
 | 
			
		||||
            set { genitalAngle = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public bool Quiver
 | 
			
		||||
        {
 | 
			
		||||
            get { return quiver == true; }
 | 
			
		||||
            set { quiver = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public int TickDuration
 | 
			
		||||
        {
 | 
			
		||||
            get { return tickDuration.HasValue ? tickDuration.Value : (int)(tickDuration = 0); }
 | 
			
		||||
            set { tickDuration = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public string SoundEffect
 | 
			
		||||
        {
 | 
			
		||||
            get { return soundEffect; }
 | 
			
		||||
            set { soundEffect = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<string> Tags
 | 
			
		||||
        {
 | 
			
		||||
            get { return tags.NullOrEmpty() ? tags = new List<string>() : tags; }
 | 
			
		||||
            set { tags = value.NotNullOrEmpty() ? value : null; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [XmlIgnore] public List<AddonKeyframe> AddonKeyframes
 | 
			
		||||
        {
 | 
			
		||||
            get { return addonKeyframes.NullOrEmpty() ? addonKeyframes = new List<AddonKeyframe>() : addonKeyframes; }
 | 
			
		||||
            set { addonKeyframes = value.NotNullOrEmpty()? value : null;  }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 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<KeyframeSlider>()?.keyframeID == keyframeID)?.GetComponent< KeyframeSlider>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AddonKeyframe GetAddonKeyframe(string addonName)
 | 
			
		||||
        {
 | 
			
		||||
            return AddonKeyframes.FirstOrDefault(x => x.AddonName == addonName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AdjustActor(Vector2 deltaOffset)
 | 
			
		||||
        {
 | 
			
		||||
            float deltaAngle = -deltaOffset.x * 33.3333f + deltaOffset.y * 33.3333f;
 | 
			
		||||
            int facing = deltaOffset.x < 0 ? 3 : deltaOffset.y < 0 ? 2 : deltaOffset.x > 0 ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
            switch (Workspace.actorManipulationMode)
 | 
			
		||||
            {
 | 
			
		||||
                case ActorManipulationMode.Pan: MoveActor(deltaOffset); break;
 | 
			
		||||
                case ActorManipulationMode.Rotate: RotateActor(deltaAngle); break;
 | 
			
		||||
                case ActorManipulationMode.Face: FaceActor(facing); break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void MoveActor(Vector2 deltaOffset)
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.selectedBodyPart == null)
 | 
			
		||||
            {
 | 
			
		||||
                BodyOffsetX += deltaOffset.x;
 | 
			
		||||
                BodyOffsetZ += deltaOffset.y;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "head")
 | 
			
		||||
            { HeadBob += deltaOffset.y; }
 | 
			
		||||
 | 
			
		||||
            Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RotateActor(float deltaAngle)
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.selectedBodyPart == null)
 | 
			
		||||
            { BodyAngle += deltaAngle; }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "head")
 | 
			
		||||
            { HeadAngle += deltaAngle; }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "appendage")
 | 
			
		||||
            { GenitalAngle -= deltaAngle; }
 | 
			
		||||
 | 
			
		||||
            Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FaceActor(int facing)
 | 
			
		||||
        {
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
 | 
			
		||||
 | 
			
		||||
            if (Workspace.selectedBodyPart == null)
 | 
			
		||||
            { keyframe.BodyFacing = facing; }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "head")
 | 
			
		||||
            { keyframe.HeadFacing = facing; }
 | 
			
		||||
 | 
			
		||||
            Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Pre-save / post-load
 | 
			
		||||
        public void OnPreSave()
 | 
			
		||||
        {
 | 
			
		||||
            SoundEffect = DefaultTags.soundDefs.Concat(CustomTags.soundDefs).Contains(SoundEffect) ? SoundEffect : null;
 | 
			
		||||
 | 
			
		||||
            if (addonKeyframes.NotNullOrEmpty())
 | 
			
		||||
            {
 | 
			
		||||
                var temp = AddonKeyframes.Copy();
 | 
			
		||||
                addonKeyframes.Clear();
 | 
			
		||||
 | 
			
		||||
                foreach (AddonKeyframe addonKeyframe in temp)
 | 
			
		||||
                {
 | 
			
		||||
                    ActorAddon addon = Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID).GetActorAddon(addonKeyframe.AddonName);
 | 
			
		||||
 | 
			
		||||
                    if (addon.Render)
 | 
			
		||||
                    { addonKeyframes.Add(addonKeyframe.Copy()); }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnPostLoad()
 | 
			
		||||
        {
 | 
			
		||||
            AddonKeyframes.Clear();
 | 
			
		||||
 | 
			
		||||
            foreach (AddonKeyframe addonKeyframe in addonKeyframes)
 | 
			
		||||
            {
 | 
			
		||||
                AddonKeyframes.Add(addonKeyframe.Copy());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: fe4a7d5f472a25945bac2d1892a4e2fa
 | 
			
		||||
guid: c8ced38490f6b174984453dc3336a543
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			@ -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<MultiDirectionalGraphic> bodyTypeGraphics = new List<MultiDirectionalGraphic>();
 | 
			
		||||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 5b8a2db320a85494c882518c143b73f7
 | 
			
		||||
guid: 187aef38ea296184b93265071536969c
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
| 
						 | 
				
			
			@ -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 + ")";
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: aeb406e171f70f14f88980439239ca59
 | 
			
		||||
guid: 24eafaf092974414ca90bfd4a8d2e4ba
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
							
								
								
									
										44
									
								
								Assets/Scripts/Data/ActorPosition.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								Assets/Scripts/Data/ActorPosition.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorPosition
 | 
			
		||||
    {
 | 
			
		||||
        public float bodyOffsetX;
 | 
			
		||||
        public float bodyOffsetZ;
 | 
			
		||||
        public float bodyAngle;
 | 
			
		||||
        public float headBob;
 | 
			
		||||
        public float headAngle;
 | 
			
		||||
        public float genitalAngle;
 | 
			
		||||
 | 
			
		||||
        public int bodyFacing;
 | 
			
		||||
        public int headFacing;
 | 
			
		||||
 | 
			
		||||
        public ActorPosition(int actorID, int atTick)
 | 
			
		||||
        {
 | 
			
		||||
            Actor actor = Workspace.GetActor(actorID);
 | 
			
		||||
            PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
 | 
			
		||||
 | 
			
		||||
            float clipPercent = atTick / Workspace.StageWindowSize;
 | 
			
		||||
            if (atTick > Constants.minTick && atTick == clip.duration) clipPercent = 1f;
 | 
			
		||||
 | 
			
		||||
            if (Workspace.GetCurrentAnimationStage().IsLooping == false)
 | 
			
		||||
            { clipPercent = (float)atTick / clip.duration; }
 | 
			
		||||
 | 
			
		||||
            bodyOffsetX = clip.BodyOffsetX.Evaluate(clipPercent);
 | 
			
		||||
            bodyOffsetZ = clip.BodyOffsetZ.Evaluate(clipPercent);
 | 
			
		||||
            bodyAngle = clip.BodyAngle.Evaluate(clipPercent);
 | 
			
		||||
            headBob = clip.HeadBob.Evaluate(clipPercent);
 | 
			
		||||
            headAngle = clip.HeadAngle.Evaluate(clipPercent);
 | 
			
		||||
            genitalAngle = clip.GenitalAngle.Evaluate(clipPercent);
 | 
			
		||||
 | 
			
		||||
            bodyFacing = (int)clip.BodyFacing.Evaluate(clipPercent);
 | 
			
		||||
            headFacing = (int)clip.HeadFacing.Evaluate(clipPercent);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/Data/ActorPosition.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/Data/ActorPosition.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: e2a9b0bb71978ea49909b3e1814303a5
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										53
									
								
								Assets/Scripts/Data/Constants.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Assets/Scripts/Data/Constants.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
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;
 | 
			
		||||
 | 
			
		||||
        // Lists
 | 
			
		||||
        public static Dictionary<string, string> bodyPartAnchorNames = new Dictionary<string, string>()
 | 
			
		||||
        {
 | 
			
		||||
            { "none", "None" },
 | 
			
		||||
            { "torso", "Torso"},
 | 
			
		||||
            { "head", "Head"},
 | 
			
		||||
            { "groin", "Groin"},
 | 
			
		||||
            { "left breast", "Breast (left)"},
 | 
			
		||||
            { "right breast", "Breast (right)"},
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Colors used
 | 
			
		||||
        public static Color ColorWhite = new Color(1f, 1f, 1f);
 | 
			
		||||
        public static Color ColorGreen = new Color(0f, 1f, 0f);
 | 
			
		||||
        public static Color ColorLightGreen = new Color(0.75f, 1f, 0.75f);
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<string> defNames = new List<string>() { "Human", "Wolf_Timber", "Horse"};
 | 
			
		||||
        public static List<string> defNames = new List<string>() { "Human", "Wolf_Timber", "Horse" };
 | 
			
		||||
        public static List<string> bodyParts = new List<string>() { "Penis", "Vagina", "Anus", "Breasts", "Mouth" };
 | 
			
		||||
        public static List<string> bodyDefTypes = new List<string>() { "Human", "Bird", "BeetleLike", "BeetleLikeWithClaw", "MechanicalCentipede", "MechanicalTermite", "Lancer", "Pikeman", "Monkey", "QuadrupedAnimalWithClawsTailAndJowl", "QuadrupedAnimalWithHooves", "QuadrupedAnimalWithHoovesAndHorn", "QuadrupedAnimalWithHoovesAndHump", "QuadrupedAnimalWithHoovesAndTusks", "QuadrupedAnimalWithHoovesTusksAndTrunk", "QuadrupedAnimalWithPaws", "QuadrupedAnimalWithPawsAndTail", "Scyther", "Snake", "TurtleLike" };
 | 
			
		||||
        public static List<string> sexTypes = new List<string>() { "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<string> bodyParts = new List<string>();
 | 
			
		||||
        [XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List<string> bodyDefTypes = new List<string>();
 | 
			
		||||
        [XmlArray("sexTypes"), XmlArrayItem("li")] public List<string> sexTypes = new List<string>();
 | 
			
		||||
        [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List<string> interactionDefTypes = new List<string>(); 
 | 
			
		||||
        [XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List<string> interactionDefTypes = new List<string>();
 | 
			
		||||
        [XmlArray("soundDefs"), XmlArrayItem("li")] public List<string> soundDefs = new List<string>();
 | 
			
		||||
        [XmlArray("bodyTypes"), XmlArrayItem("li")] public static List<string> bodyTypes = new List<string>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class AlienRaceDefs
 | 
			
		||||
    {
 | 
			
		||||
        public static List<AlienRaceDef> allDefs = new List<AlienRaceDef>();
 | 
			
		||||
 | 
			
		||||
        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<string> allTags = Tags.bodyTypes.Concat(CustomTags.bodyTypes).ToList();
 | 
			
		||||
            allTags.Add("None");
 | 
			
		||||
 | 
			
		||||
            List<CardinalDirection> facings = new List<CardinalDirection>() { 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); }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/Data/DefaultTags.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/Data/DefaultTags.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: d2a4f1a7ea83f0544a350664fba7fc49
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: d3f1c8d8d1b51a147b17f5510eebb2cf
 | 
			
		||||
guid: c9a9e093aedeac24687d421f33a98e94
 | 
			
		||||
folderAsset: yes
 | 
			
		||||
DefaultImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
							
								
								
									
										30
									
								
								Assets/Scripts/DefParents/ActorAddonDefs.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Assets/Scripts/DefParents/ActorAddonDefs.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public static class ActorAddonDefs
 | 
			
		||||
    {
 | 
			
		||||
        public static List<ActorAddonDef> allDefs = new List<ActorAddonDef>();
 | 
			
		||||
 | 
			
		||||
        public static ActorAddonDef GetNamed(string addonName)
 | 
			
		||||
        {
 | 
			
		||||
            return allDefs.FirstOrDefault(x => x.addonName == addonName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void AddDef(ActorAddonDef actorAddonDef)
 | 
			
		||||
        {
 | 
			
		||||
            if (allDefs.Any(x => x.addonName == actorAddonDef.addonName)) return;
 | 
			
		||||
 | 
			
		||||
            allDefs.Add(actorAddonDef);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void OnLoad()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/DefParents/ActorAddonDefs.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/DefParents/ActorAddonDefs.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 9fc7248e80b340a42a688378a9cc2296
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -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<AnimationDef> animationDefs = new List<AnimationDef>();
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/DefParents/AnimationDefs.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/DefParents/AnimationDefs.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 6e65e28553800cf489ca2b0bc7e37408
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										53
									
								
								Assets/Scripts/DefParents/PawnRaceDefs.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Assets/Scripts/DefParents/PawnRaceDefs.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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<PawnRaceDef> allDefs = new List<PawnRaceDef>();
 | 
			
		||||
 | 
			
		||||
        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<string> allTags = DefaultTags.bodyTypes.Concat(CustomTags.bodyTypes).ToList();
 | 
			
		||||
            allTags.Add("None");
 | 
			
		||||
 | 
			
		||||
            List<CardinalDirection> facings = new List<CardinalDirection>() { 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); }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/DefParents/PawnRaceDefs.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/DefParents/PawnRaceDefs.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 53e7f97b4bb5a3441884e4795d7e9391
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -1,51 +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 ActorAddonCard : MonoBehaviour
 | 
			
		||||
    {
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public InputField xOffsetField;
 | 
			
		||||
        public InputField zOffsetField;
 | 
			
		||||
        public InputField rotationField;
 | 
			
		||||
 | 
			
		||||
        public void Start()
 | 
			
		||||
        {
 | 
			
		||||
            xOffsetField.onEndEdit.AddListener(delegate { OnFieldValueChanged(); });
 | 
			
		||||
            zOffsetField.onEndEdit.AddListener(delegate { OnFieldValueChanged(); });
 | 
			
		||||
            rotationField.onEndEdit.AddListener(delegate { OnFieldValueChanged(); });
 | 
			
		||||
 | 
			
		||||
            AnimationController.Instance.animationClipTimeField.onValueChanged.AddListener(delegate { OnKeyframeValueChanged(); });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnFieldValueChanged()
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.animationDef == null) return;
 | 
			
		||||
            PawnAnimationClip clip = Workspace.Instance.GetCurrentPawnAnimationClip();
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.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);
 | 
			
		||||
 | 
			
		||||
            clip.BuildSimpleCurves();
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor addon position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnKeyframeValueChanged()
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.animationDef == null) return;
 | 
			
		||||
            PawnAnimationClip clip = Workspace.Instance.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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,104 +0,0 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.EventSystems;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorBody : MonoBehaviour, IPointerClickHandler, IDragHandler, IEndDragHandler
 | 
			
		||||
    {
 | 
			
		||||
        public int actorID;
 | 
			
		||||
        public bool isSelected = false;
 | 
			
		||||
 | 
			
		||||
        public SpriteRenderer bodyRenderer;
 | 
			
		||||
        public SpriteRenderer headRenderer;
 | 
			
		||||
        public SpriteRenderer appendageRenderer;
 | 
			
		||||
 | 
			
		||||
        private Vector3 delta = new Vector3();
 | 
			
		||||
 | 
			
		||||
        public bool actorBodyPartSelected { get { return GetComponentsInChildren<ActorBodyPart>().Any(x => x.isSelected); } }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(int actorID)
 | 
			
		||||
        {
 | 
			
		||||
            this.actorID = actorID;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Update()
 | 
			
		||||
        {
 | 
			
		||||
            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)
 | 
			
		||||
            {
 | 
			
		||||
                ActorBodyPart bodyPart = GetComponentsInChildren<ActorBodyPart>(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)
 | 
			
		||||
        {
 | 
			
		||||
            if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>())
 | 
			
		||||
            { return; }
 | 
			
		||||
 | 
			
		||||
            Activate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Activate();
 | 
			
		||||
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true);
 | 
			
		||||
 | 
			
		||||
            if (keyframe == null)
 | 
			
		||||
            { Debug.LogWarning("Cannot alter actor - no keyframe data available"); return; }
 | 
			
		||||
 | 
			
		||||
            Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 | 
			
		||||
 | 
			
		||||
            if (delta == Vector3.zero)
 | 
			
		||||
            { delta = mousePosition - transform.position; }
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
 | 
			
		||||
            {
 | 
			
		||||
                float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                keyframe.bodyAngle = angle;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
 | 
			
		||||
            {
 | 
			
		||||
                float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                int facing = -Mathf.RoundToInt(angle / 90f );
 | 
			
		||||
                facing = facing < 0 ? facing + 4 : facing;
 | 
			
		||||
 | 
			
		||||
                keyframe.bodyFacing = facing;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
 | 
			
		||||
            clip.BuildSimpleCurves();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnEndDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor position / orientation");
 | 
			
		||||
            delta = Vector3.zero;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Activate()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.actorID = actorID;
 | 
			
		||||
            Workspace.selectedBodyPart = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,155 +0,0 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.EventSystems;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorBodyPart : MonoBehaviour, IPointerClickHandler, IDragHandler, IEndDragHandler
 | 
			
		||||
    {
 | 
			
		||||
        public SpriteRenderer bodyPartRenderer;
 | 
			
		||||
        public ActorBody parent;
 | 
			
		||||
        public bool isHead = false;
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public bool isSelected = false;
 | 
			
		||||
 | 
			
		||||
        private Vector3 delta = new Vector3();
 | 
			
		||||
 | 
			
		||||
        public void Update()
 | 
			
		||||
        {
 | 
			
		||||
            if ((Workspace.actorID == parent.actorID && Workspace.selectedBodyPart == null) || Workspace.selectedBodyPart == this)
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorGreen; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorWhite; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnPointerClick(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>() == null)
 | 
			
		||||
            { return; }
 | 
			
		||||
 | 
			
		||||
            Activate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Activate();
 | 
			
		||||
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true);
 | 
			
		||||
 | 
			
		||||
            if (keyframe == null)
 | 
			
		||||
            { Debug.LogWarning("Cannot alter actor - no keyframe data available"); return; }
 | 
			
		||||
 | 
			
		||||
            Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 | 
			
		||||
 | 
			
		||||
            if (delta == Vector3.zero)
 | 
			
		||||
            { delta = mousePosition - transform.position; }
 | 
			
		||||
 | 
			
		||||
            if (addonName != null && addonName != "")
 | 
			
		||||
            {
 | 
			
		||||
                AddonKeyframe addonKeyframe = keyframe.GetAddonKeyframe(addonName);
 | 
			
		||||
                ActorAddon addon = Workspace.Instance.GetCurrentPawnAnimationClip().GetActorAddon(addonName);
 | 
			
		||||
 | 
			
		||||
                if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
 | 
			
		||||
                {
 | 
			
		||||
                    Vector3 anchor;
 | 
			
		||||
 | 
			
		||||
                    ActorBody anchoringActorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren<ActorBody>()?.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);
 | 
			
		||||
 | 
			
		||||
                    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;
 | 
			
		||||
                        case "groin": anchor = bodyPos + Quaternion.AngleAxis(anchoringActorBody.transform.rotation.eulerAngles.z, Vector3.forward) * PawnUtility.GroinOffsetAt(anchoringActor.bodyType, bodyFacing).FlipAxes(); break;
 | 
			
		||||
                        case "left breast": anchor = bodyPos + Quaternion.AngleAxis(anchoringActorBody.transform.rotation.eulerAngles.z, Vector3.forward) * PawnUtility.BreastLeftOffsetAt(anchoringActor.bodyType, bodyFacing).FlipAxes(); break;
 | 
			
		||||
                        case "right breast": anchor = bodyPos + Quaternion.AngleAxis(anchoringActorBody.transform.rotation.eulerAngles.z, Vector3.forward) * PawnUtility.BreastRightOffsetAt(anchoringActor.bodyType, bodyFacing).FlipAxes(); break;
 | 
			
		||||
                        default: anchor = new Vector3(); break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    transform.position = new Vector3(mousePosition.x, mousePosition.y, 0f);
 | 
			
		||||
 
 | 
			
		||||
                    addonKeyframe.posX = transform.position.x - anchor.x;
 | 
			
		||||
                    addonKeyframe.posZ = transform.position.y - anchor.y;
 | 
			
		||||
 | 
			
		||||
                    ActorKeyframeCard.Instance.transform.GetComponentsInChildren<ActorAddonCard>()?.FirstOrDefault(x => x.addonName == addonName)?.OnKeyframeValueChanged();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
 | 
			
		||||
                {
 | 
			
		||||
                    float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    addonKeyframe.rotation = angle;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
 | 
			
		||||
                {
 | 
			
		||||
                    //float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    //int facing = -Mathf.RoundToInt(angle / 90f);
 | 
			
		||||
                    //facing = facing < 0 ? facing + 4 : facing;
 | 
			
		||||
 | 
			
		||||
                    //keyframe.headFacing = facing;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (isHead)
 | 
			
		||||
            {
 | 
			
		||||
                if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
 | 
			
		||||
                {
 | 
			
		||||
                    // It's stupid but it works
 | 
			
		||||
                    Vector3 localPosA = transform.localPosition;
 | 
			
		||||
                    transform.position = mousePosition - delta;
 | 
			
		||||
                    Vector3 localPosB = transform.localPosition;
 | 
			
		||||
                    transform.localPosition = localPosA;
 | 
			
		||||
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
 | 
			
		||||
                {
 | 
			
		||||
                    float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    int facing = -Mathf.RoundToInt(angle / 90f);
 | 
			
		||||
                    facing = facing < 0 ? facing + 4 : facing;
 | 
			
		||||
 | 
			
		||||
                    keyframe.headFacing = facing;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
 | 
			
		||||
                {
 | 
			
		||||
                    float angle = -Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    keyframe.genitalAngle = angle;
 | 
			
		||||
 | 
			
		||||
                    Workspace.animationDef.actors[Workspace.actorID].controlGenitalAngle = Workspace.animationDef.animationStages.Any(x => x.animationClips[Workspace.actorID].keyframes.Any(y => y.genitalAngle != 0));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(parent.actorID);
 | 
			
		||||
            clip.BuildSimpleCurves();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnEndDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor position / orientation");
 | 
			
		||||
            delta = Vector3.zero;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Activate()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.actorID = parent.actorID;
 | 
			
		||||
            Workspace.selectedBodyPart = this;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<string>() { "Female" }; break;
 | 
			
		||||
            //    case 2: actor.requiredGender = new List<string>() { "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<ActorBody>().Count())
 | 
			
		||||
            { Debug.Log("Waiting for actors to initialize..."); return; }
 | 
			
		||||
 | 
			
		||||
            Actor actor = Workspace.animationDef.actors[Workspace.actorID];
 | 
			
		||||
            ActorBody actorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren<ActorBody>()[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); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,108 +0,0 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.UI;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorKeyframeCard : Singleton<ActorKeyframeCard>
 | 
			
		||||
    {
 | 
			
		||||
        public InputField positionXField;
 | 
			
		||||
        public InputField positionZField;
 | 
			
		||||
        public InputField rotationField;
 | 
			
		||||
        public InputField headBobField;
 | 
			
		||||
        public InputField headRotationField;
 | 
			
		||||
        public InputField appendageRotationField;
 | 
			
		||||
 | 
			
		||||
        public void Update()
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.animationDef == null)
 | 
			
		||||
            { return; }
 | 
			
		||||
 | 
			
		||||
            positionXField.interactable = AnimationController.Instance.isAnimating == false; 
 | 
			
		||||
            positionZField.interactable = AnimationController.Instance.isAnimating == false;
 | 
			
		||||
            rotationField.interactable = AnimationController.Instance.isAnimating == false;
 | 
			
		||||
            headBobField.interactable = AnimationController.Instance.isAnimating == false;
 | 
			
		||||
            headRotationField.interactable = AnimationController.Instance.isAnimating == false;
 | 
			
		||||
            appendageRotationField.interactable = AnimationController.Instance.isAnimating == false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnValueChanged()
 | 
			
		||||
        {
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.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);
 | 
			
		||||
 | 
			
		||||
            Workspace.animationDef.actors[Workspace.actorID].controlGenitalAngle = keyframe.genitalAngle != 0;
 | 
			
		||||
            Workspace.Instance.GetPawnAnimationClip(Workspace.actorID).BuildSimpleCurves();
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AdjustActor(Vector2 deltaOffset)
 | 
			
		||||
        {
 | 
			
		||||
            float deltaAngle = -deltaOffset.x * 33.3333f + deltaOffset.y * 33.3333f;
 | 
			
		||||
            int facing = deltaOffset.x < 0 ? 3 : deltaOffset.y < 0 ? 2 : deltaOffset.x > 0 ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
            switch (Workspace.actorManipulationMode)
 | 
			
		||||
            {
 | 
			
		||||
                case ActorManipulationMode.Pan: MoveActor(deltaOffset); break;
 | 
			
		||||
                case ActorManipulationMode.Rotate: RotateActor(deltaAngle); break;
 | 
			
		||||
                case ActorManipulationMode.Face: FaceActor(facing); break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void MoveActor(Vector2 deltaOffset)
 | 
			
		||||
        {
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true);
 | 
			
		||||
 
 | 
			
		||||
            if (Workspace.selectedBodyPart == null)
 | 
			
		||||
            {
 | 
			
		||||
                keyframe.bodyOffsetX += deltaOffset.x;
 | 
			
		||||
                keyframe.bodyOffsetZ += deltaOffset.y;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.isHead)
 | 
			
		||||
            { keyframe.headBob += deltaOffset.y; }
 | 
			
		||||
 | 
			
		||||
            Workspace.Instance.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RotateActor(float deltaAngle)
 | 
			
		||||
        {
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true);
 | 
			
		||||
 | 
			
		||||
            if (Workspace.selectedBodyPart == null)
 | 
			
		||||
            { keyframe.bodyAngle += deltaAngle; }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.isHead)
 | 
			
		||||
            { keyframe.headAngle += deltaAngle; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { keyframe.genitalAngle -= deltaAngle; }
 | 
			
		||||
 | 
			
		||||
            Workspace.Instance.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FaceActor(int facing)
 | 
			
		||||
        {
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.Instance.GetCurrentPawnKeyframe(true);
 | 
			
		||||
           
 | 
			
		||||
            if (Workspace.selectedBodyPart == null)
 | 
			
		||||
            { keyframe.bodyFacing = facing; }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.selectedBodyPart.isHead)
 | 
			
		||||
            { keyframe.headFacing = facing; }
 | 
			
		||||
 | 
			
		||||
            Workspace.Instance.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.Instance.RecordEvent("Actor position / orientation");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 20033872660014f4295d8ac40800a707
 | 
			
		||||
guid: f3c96477ef8cc42468ea6a39764a2e81
 | 
			
		||||
folderAsset: yes
 | 
			
		||||
DefaultImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
							
								
								
									
										122
									
								
								Assets/Scripts/GUI/Actors/ActorBody.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								Assets/Scripts/GUI/Actors/ActorBody.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,122 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.EventSystems;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorBody : MonoBehaviour, IPointerClickHandler, IDragHandler, IEndDragHandler
 | 
			
		||||
    {
 | 
			
		||||
        public int actorID;
 | 
			
		||||
        public SpriteRenderer bodyRenderer;
 | 
			
		||||
        public ActorBodyPart actorBodyPartPrefab;
 | 
			
		||||
 | 
			
		||||
        private Vector3 dragDelta = new Vector3();
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            EventsManager.onActorBodyPartSelected.AddListener(delegate(ActorBodyPart bodyPart) { OnActorBodyPartSelected(bodyPart); });
 | 
			
		||||
            EventsManager.onActorBodySelected.AddListener(delegate(ActorBody actorBody) { OnActorBodySelected(actorBody); });
 | 
			
		||||
 | 
			
		||||
            if (Workspace.ActorID == actorID)
 | 
			
		||||
            { Activate(); }
 | 
			
		||||
 | 
			
		||||
            foreach (ActorAddonDef actorAddonDef in ActorAddonDefs.allDefs)
 | 
			
		||||
            {
 | 
			
		||||
                ActorBodyPart actorBodyPart = Instantiate(actorBodyPartPrefab, transform);
 | 
			
		||||
                actorBodyPart.Initialize(this, actorAddonDef);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnActorBodySelected(ActorBody actorBody)
 | 
			
		||||
        {
 | 
			
		||||
            if (actorBody == this)
 | 
			
		||||
            { bodyRenderer.color = Constants.ColorGreen; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { bodyRenderer.color = Constants.ColorWhite; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnActorBodyPartSelected(ActorBodyPart bodyPart)
 | 
			
		||||
        {
 | 
			
		||||
            if (bodyPart.parent == this)
 | 
			
		||||
            { bodyRenderer.color = Constants.ColorLightGreen; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { bodyRenderer.color = Constants.ColorWhite; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(int actorID)
 | 
			
		||||
        {
 | 
			
		||||
            this.actorID = actorID;
 | 
			
		||||
 | 
			
		||||
            if (actorID == Workspace.ActorID)
 | 
			
		||||
            { Activate(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnPointerClick(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>())
 | 
			
		||||
            { return; }
 | 
			
		||||
 | 
			
		||||
            Activate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Activate();
 | 
			
		||||
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
 | 
			
		||||
            Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 | 
			
		||||
 | 
			
		||||
            if (dragDelta == Vector3.zero)
 | 
			
		||||
            { dragDelta = mousePosition - transform.position; }
 | 
			
		||||
 | 
			
		||||
            if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
 | 
			
		||||
            {
 | 
			
		||||
                keyframe.BodyOffsetX = mousePosition.x - dragDelta.x - Workspace.GetActor(actorID).GetFinalTransformOffset().x;
 | 
			
		||||
                keyframe.BodyOffsetZ = mousePosition.y - dragDelta.y - Workspace.GetActor(actorID).GetFinalTransformOffset().y;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
 | 
			
		||||
            {
 | 
			
		||||
                float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                keyframe.BodyAngle = angle;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
 | 
			
		||||
            {
 | 
			
		||||
                float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                int facing = -Mathf.RoundToInt(angle / 90f );
 | 
			
		||||
                facing = facing < 0 ? facing + 4 : facing;
 | 
			
		||||
 | 
			
		||||
                keyframe.BodyFacing = facing;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
 | 
			
		||||
            clip.BuildSimpleCurves();
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnPawnKeyframeChanged(keyframe);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnEndDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.RecordEvent("Actor position / orientation");
 | 
			
		||||
            dragDelta = Vector3.zero;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ActorBodyPart GetActorBodyPart(string bodyPart)
 | 
			
		||||
        {
 | 
			
		||||
            return GetComponentsInChildren<ActorBodyPart>(true)?.FirstOrDefault(x => x.bodyPart.ToLower() == bodyPart);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Activate()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.ActorID = actorID;
 | 
			
		||||
            Workspace.selectedBodyPart = null;
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnActorBodySelected(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										165
									
								
								Assets/Scripts/GUI/Actors/ActorBodyPart.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								Assets/Scripts/GUI/Actors/ActorBodyPart.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,165 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.EventSystems;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorBodyPart : MonoBehaviour, IPointerClickHandler, IDragHandler, IEndDragHandler
 | 
			
		||||
    {
 | 
			
		||||
        public SpriteRenderer bodyPartRenderer;
 | 
			
		||||
        public ActorBody parent;
 | 
			
		||||
        public string bodyPart;
 | 
			
		||||
 | 
			
		||||
        private Vector3 dragDelta = new Vector3();
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            if (parent == null) return;
 | 
			
		||||
 | 
			
		||||
            EventsManager.onActorBodyPartSelected.AddListener(delegate (ActorBodyPart bodyPart) { OnActorBodyPartSelected(bodyPart); });
 | 
			
		||||
            EventsManager.onActorBodySelected.AddListener(delegate (ActorBody actorBody) { OnActorBodySelected(actorBody); });
 | 
			
		||||
 | 
			
		||||
            if (Workspace.ActorID == parent.actorID)
 | 
			
		||||
            { parent.Activate(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(ActorBody parent, ActorAddonDef actorAddonDef)
 | 
			
		||||
        {
 | 
			
		||||
            this.parent = parent;
 | 
			
		||||
            this.bodyPart = actorAddonDef.addonName;
 | 
			
		||||
 | 
			
		||||
            bodyPartRenderer.sprite = actorAddonDef.graphicData.GetSprite();
 | 
			
		||||
            bodyPartRenderer.transform.localScale = (Vector3)actorAddonDef.graphicData.GetDrawSize();
 | 
			
		||||
 | 
			
		||||
            Start();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnActorAddonChange(ActorAddon actorAddon)
 | 
			
		||||
        {
 | 
			
		||||
            if (actorAddon.AddonName == bodyPart)
 | 
			
		||||
            { gameObject?.SetActive(actorAddon.Render); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnActorBodySelected(ActorBody actorBody)
 | 
			
		||||
        {
 | 
			
		||||
            if (actorBody == parent)
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorLightGreen; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorWhite; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnActorBodyPartSelected(ActorBodyPart bodyPart)
 | 
			
		||||
        {
 | 
			
		||||
            if (bodyPart == this)
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorGreen; }
 | 
			
		||||
 | 
			
		||||
            else if (bodyPart.parent == parent)
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorLightGreen; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { bodyPartRenderer.color = Constants.ColorWhite; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnPointerClick(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            if (eventData.pointerCurrentRaycast.gameObject.GetComponent<ActorBodyPart>() == null)
 | 
			
		||||
            { return; }
 | 
			
		||||
 | 
			
		||||
            Activate();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Activate();
 | 
			
		||||
 | 
			
		||||
            PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
 | 
			
		||||
            Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 | 
			
		||||
            mousePosition = new Vector3(mousePosition.x, mousePosition.y, 0f);
 | 
			
		||||
 | 
			
		||||
            if (dragDelta == Vector3.zero)
 | 
			
		||||
            { dragDelta = mousePosition - transform.position; }
 | 
			
		||||
 | 
			
		||||
            if (bodyPart.ToLower() == "head")
 | 
			
		||||
            {
 | 
			
		||||
                if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
 | 
			
		||||
                {
 | 
			
		||||
                    // It's stupid, but it works
 | 
			
		||||
                    Vector3 localPosA = transform.localPosition;
 | 
			
		||||
                    transform.position = mousePosition - dragDelta;
 | 
			
		||||
                    Vector3 localPosB = transform.localPosition;
 | 
			
		||||
                    transform.localPosition = localPosA;
 | 
			
		||||
 | 
			
		||||
                    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;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Workspace.actorManipulationMode == ActorManipulationMode.Face)
 | 
			
		||||
                {
 | 
			
		||||
                    float angle = Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    int facing = -Mathf.RoundToInt(angle / 90f);
 | 
			
		||||
                    facing = facing < 0 ? facing + 4 : facing;
 | 
			
		||||
 | 
			
		||||
                    keyframe.HeadFacing = facing;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else if (bodyPart.ToLower() == "appendage")
 | 
			
		||||
            {
 | 
			
		||||
                if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
 | 
			
		||||
                {
 | 
			
		||||
                    float angle = -Vector2.SignedAngle(Vector2.up, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    keyframe.GenitalAngle = angle;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                AddonKeyframe addonKeyframe = keyframe.GetAddonKeyframe(bodyPart);
 | 
			
		||||
                ActorAddon addon = Workspace.GetCurrentPawnAnimationClip().GetActorAddon(bodyPart);
 | 
			
		||||
 | 
			
		||||
                if (Workspace.actorManipulationMode == ActorManipulationMode.Pan)
 | 
			
		||||
                {
 | 
			
		||||
                    ActorBody anchoringActorBody = AnimationController.Instance.actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor);
 | 
			
		||||
                    Vector3 anchor = PawnUtility.GetBodyPartAnchor(anchoringActorBody, addon.anchorName);
 | 
			
		||||
                    transform.position = mousePosition - dragDelta;
 | 
			
		||||
 | 
			
		||||
                    addonKeyframe.PosX = transform.position.x - anchor.x;
 | 
			
		||||
                    addonKeyframe.PosZ = transform.position.y - anchor.y;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Workspace.actorManipulationMode == ActorManipulationMode.Rotate)
 | 
			
		||||
                {
 | 
			
		||||
                    float angle = -Vector2.SignedAngle(Vector2.down, (Vector2)mousePosition - (Vector2)transform.position);
 | 
			
		||||
                    addonKeyframe.Rotation = angle;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PawnAnimationClip clip = Workspace.GetPawnAnimationClip(parent.actorID);
 | 
			
		||||
            clip.BuildSimpleCurves();
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnPawnKeyframeChanged(keyframe);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnEndDrag(PointerEventData eventData)
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.RecordEvent("Actor position / orientation");
 | 
			
		||||
            dragDelta = Vector3.zero;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Activate()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.ActorID = parent.actorID;
 | 
			
		||||
            Workspace.selectedBodyPart = this;
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnActorBodyPartSelected(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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"; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										19
									
								
								Assets/Scripts/GUI/AddonAnchorDropdown.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Assets/Scripts/GUI/AddonAnchorDropdown.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.UI;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class AddonAnchorDropdown : MonoBehaviour
 | 
			
		||||
    {
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            Dropdown dropdown = GetComponent<Dropdown>();
 | 
			
		||||
 | 
			
		||||
            dropdown.ClearOptions();
 | 
			
		||||
            dropdown.AddOptions(Constants.bodyPartAnchorNames.Values.ToList());           
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/GUI/AddonAnchorDropdown.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/GUI/AddonAnchorDropdown.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 6a0ca236433ad584998f9c7a96dc3af8
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								Assets/Scripts/GUI/AnimationLengthsCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Assets/Scripts/GUI/AnimationLengthsCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 AnimationLengthsCard : MonoBehaviour
 | 
			
		||||
    {
 | 
			
		||||
        public Text stageLengthNormalText;      
 | 
			
		||||
        public Text stageLengthQuickText;
 | 
			
		||||
        public Text animationLengthNormalText;
 | 
			
		||||
        public Text animationLengthQuickText;
 | 
			
		||||
        public float spacing = 10f;
 | 
			
		||||
 | 
			
		||||
        private RectTransform rect;
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            rect = GetComponent<RectTransform>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Update()
 | 
			
		||||
        {
 | 
			
		||||
            LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
 | 
			
		||||
            LayoutRebuilder.ForceRebuildLayoutImmediate(transform.parent.GetComponent<RectTransform>());
 | 
			
		||||
            rect.localPosition = new Vector3(rect.localPosition.x, spacing + transform.parent.GetComponent<RectTransform>().sizeDelta.y, rect.localPosition.z);
 | 
			
		||||
 | 
			
		||||
            stageLengthNormalText.text = Workspace.GetCurrentAnimationStage().PlayTimeTicks + " (" + string.Format("{0:0.00}", Workspace.GetCurrentAnimationStage().PlayTimeTicks / 60f) + " s)";
 | 
			
		||||
            animationLengthNormalText.text = Workspace.animationDef.animationTimeTicks + " (" + string.Format("{0:0.00}", Workspace.animationDef.animationTimeTicks / 60f) + " s)";
 | 
			
		||||
            
 | 
			
		||||
            stageLengthQuickText.text = Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick + " (" + string.Format("{0:0.00}", Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick / 60f) + " s)";
 | 
			
		||||
            animationLengthQuickText.text = Workspace.animationDef.animationTimeTicksQuick + " (" + string.Format("{0:0.00}", Workspace.animationDef.animationTimeTicksQuick / 60f) + " s)";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/GUI/AnimationLengthsCard.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/GUI/AnimationLengthsCard.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 060e49b40b1097e46b662059e4e29cdf
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
| 
						 | 
				
			
			@ -11,45 +11,55 @@ namespace RimWorldAnimationStudio
 | 
			
		|||
{
 | 
			
		||||
    public class AnimationTimeline : MonoBehaviour, IPointerClickHandler
 | 
			
		||||
    {
 | 
			
		||||
        public int actorID;
 | 
			
		||||
        public int actorID = -1;
 | 
			
		||||
        public KeyframeSlider keyframeSliderPrefab;
 | 
			
		||||
 | 
			
		||||
        private Transform anchorTransform;
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            EventsManager.onAnimationTimelinesChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onKeyframeCountChanged.AddListener(delegate { UpdateGUI(); });                   
 | 
			
		||||
            EventsManager.onActorIDChanged.AddListener(delegate { UpdateTimelineSelection(); });
 | 
			
		||||
 | 
			
		||||
            UpdateTimelineSelection();
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(int actorID)
 | 
			
		||||
        {
 | 
			
		||||
            anchorTransform = transform.parent;
 | 
			
		||||
            this.actorID = actorID;
 | 
			
		||||
 | 
			
		||||
            PawnAnimationClip clip = Workspace.Instance.GetPawnAnimationClip(actorID);
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ClearKeyframeSliders()
 | 
			
		||||
        {
 | 
			
		||||
            foreach (KeyframeSlider slider in GetComponentsInChildren<KeyframeSlider>())
 | 
			
		||||
            { Destroy(slider.gameObject); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void UpdateGUI()
 | 
			
		||||
        {
 | 
			
		||||
            if (actorID < 0) return;
 | 
			
		||||
 | 
			
		||||
            PawnAnimationClip clip = Workspace.GetPawnAnimationClip(actorID);
 | 
			
		||||
            if (clip == null) return;
 | 
			
		||||
 | 
			
		||||
            clip.BuildSimpleCurves();
 | 
			
		||||
 | 
			
		||||
            foreach (KeyframeSlider slider in GetComponentsInChildren<KeyframeSlider>())
 | 
			
		||||
            { RemovePawnKeyFrame(slider.keyframeID);}
 | 
			
		||||
            ClearKeyframeSliders();
 | 
			
		||||
 | 
			
		||||
            foreach (PawnKeyframe keyframe in clip.keyframes)
 | 
			
		||||
            foreach (PawnKeyframe keyframe in clip.Keyframes)
 | 
			
		||||
            { AddPawnKeyFrame(keyframe.keyframeID); }
 | 
			
		||||
 | 
			
		||||
            /*int keyframeCount = clip.keyframes.Count;
 | 
			
		||||
            int childCount = GetComponentsInChildren<KeyframeSlider>().Count();
 | 
			
		||||
            InitiateUpdateOfGhostFrames();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < Mathf.Max(keyframeCount, childCount); i++)
 | 
			
		||||
            {
 | 
			
		||||
                // Add new keyframe sliders as required
 | 
			
		||||
                if (i >= childCount)
 | 
			
		||||
                { AddPawnKeyFrame(clip.keyframes[i].keyframeID); }
 | 
			
		||||
 | 
			
		||||
                // Get objects to update
 | 
			
		||||
                KeyframeSlider keyframeSlider = GetComponentsInChildren<KeyframeSlider>()[i];
 | 
			
		||||
 | 
			
		||||
                // Update values
 | 
			
		||||
                if (i < keyframeCount)
 | 
			
		||||
                { keyframeSlider.Initialize(this, actorID, clip.keyframes[i].keyframeID); }
 | 
			
		||||
 | 
			
		||||
                // Remove excess objects as required
 | 
			
		||||
                else
 | 
			
		||||
                { RemovePawnKeyFrame(GetComponentsInChildren<KeyframeSlider>()[i].keyframeID); }
 | 
			
		||||
            }*/
 | 
			
		||||
        public void UpdateTimelineSelection()
 | 
			
		||||
        {
 | 
			
		||||
            GetComponent<Image>().color = (Workspace.ActorID == actorID ? Constants.ColorGoldYellow : Constants.ColorMidGrey);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddPawnKeyFrame(int keyframeID)
 | 
			
		||||
| 
						 | 
				
			
			@ -64,19 +74,8 @@ namespace RimWorldAnimationStudio
 | 
			
		|||
            Destroy(keyframeSlider?.gameObject);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Update()
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.actorID == actorID)
 | 
			
		||||
            { GetComponent<Image>().color = Constants.ColorGoldYellow; }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            { GetComponent<Image>().color = Constants.ColorMidGrey; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void InitiateUpdateOfGhostFrames()
 | 
			
		||||
        {
 | 
			
		||||
            if (AnimationController.Instance.IsTimelineDirty()) return;
 | 
			
		||||
 | 
			
		||||
            BroadcastMessage("UpdateGhostFrames");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -86,32 +85,32 @@ namespace RimWorldAnimationStudio
 | 
			
		|||
            int? siblingCount = anchorTransform.parent.GetComponentsInChildren<AnimationTimeline>()?.ToList()?.Count();
 | 
			
		||||
 | 
			
		||||
            if (siblingIndex != null && siblingCount != null && MoveAnimationTimeline(siblingIndex.Value, delta))
 | 
			
		||||
            { AnimationController.Instance.InitializeAnimationTimeline(); }
 | 
			
		||||
            { AnimationController.Instance.Initialize(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										8
									
								
								Assets/Scripts/GUI/Cards.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Assets/Scripts/GUI/Cards.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: c026d569e32726d4eb8821db713d0aac
 | 
			
		||||
folderAsset: yes
 | 
			
		||||
DefaultImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										102
									
								
								Assets/Scripts/GUI/Cards/ActorAddonCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								Assets/Scripts/GUI/Cards/ActorAddonCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,102 @@
 | 
			
		|||
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 ActorAddonCard : MonoBehaviour
 | 
			
		||||
    {
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public Text label;
 | 
			
		||||
        public Toggle toggle;
 | 
			
		||||
        public Dropdown anchorDropdown;
 | 
			
		||||
        public InputField anchoringPawnField;
 | 
			
		||||
        public Dropdown layerDropdown;
 | 
			
		||||
        public ActorAddonKeyframeCard actorAddonKeyframeCard;
 | 
			
		||||
 | 
			
		||||
        private ActorAddonDef actorAddonDef;
 | 
			
		||||
 | 
			
		||||
        private PawnAnimationClip clip { get { return Workspace.GetCurrentPawnAnimationClip(); } }
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(ActorAddonDef actorAddonDef, ActorAddonKeyframeCard actorAddonKeyframeCard)
 | 
			
		||||
        {
 | 
			
		||||
            this.actorAddonDef = actorAddonDef;
 | 
			
		||||
            this.actorAddonKeyframeCard = actorAddonKeyframeCard;
 | 
			
		||||
 | 
			
		||||
            addonName = actorAddonDef.addonName;
 | 
			
		||||
            label.text = actorAddonDef.label;
 | 
			
		||||
 | 
			
		||||
            EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void UpdateGUI()
 | 
			
		||||
        {
 | 
			
		||||
            if (Workspace.animationDef == null || string.IsNullOrEmpty(addonName)) return;
 | 
			
		||||
 | 
			
		||||
            if (clip?.GetActorAddon(addonName) != null)
 | 
			
		||||
            {
 | 
			
		||||
                int i = Constants.bodyPartAnchorNames.Keys.ToList().IndexOf(clip.GetActorAddon(addonName).AnchorName);
 | 
			
		||||
                anchorDropdown.SetValueWithoutNotify(i);
 | 
			
		||||
                layerDropdown.SetValueWithoutNotify(layerDropdown.options.IndexOf(layerDropdown.options.First(x => x.text == clip.GetActorAddon(addonName).Layer)));
 | 
			
		||||
                anchoringPawnField.SetTextWithoutNotify(clip.GetActorAddon(addonName).AnchoringActor.ToString());
 | 
			
		||||
                toggle.SetIsOnWithoutNotify(clip.IsActorAddonVisible(addonName));
 | 
			
		||||
 | 
			
		||||
                anchoringPawnField.interactable = anchorDropdown.value != 0;
 | 
			
		||||
           }         
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnToggleChanged()
 | 
			
		||||
        {
 | 
			
		||||
            if (clip?.GetActorAddon(addonName) != null)
 | 
			
		||||
            { clip.GetActorAddon(addonName).render = toggle.isOn; }
 | 
			
		||||
 | 
			
		||||
            EventsManager.OnPawnKeyframeChanged(null);
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnAnchorChanged()
 | 
			
		||||
        {
 | 
			
		||||
            if (clip?.GetActorAddon(addonName) != null)
 | 
			
		||||
            { clip.GetActorAddon(addonName).AnchorName = Constants.bodyPartAnchorNames.Keys.ElementAt(anchorDropdown.value); }
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnLayerChanged()
 | 
			
		||||
        {
 | 
			
		||||
            if (clip?.GetActorAddon(addonName) != null)
 | 
			
		||||
            { clip.GetActorAddon(addonName).Layer = layerDropdown.options[layerDropdown.value].text; }
 | 
			
		||||
            
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnAnchoringPawnChanged()
 | 
			
		||||
        {
 | 
			
		||||
            if (clip?.GetActorAddon(addonName) != null)
 | 
			
		||||
            {
 | 
			
		||||
                int i = int.Parse(anchoringPawnField.text);
 | 
			
		||||
 | 
			
		||||
                if (i < 0) { i = clip.GetOwningActorID(); }
 | 
			
		||||
                i = Mathf.Clamp(i, 0, Workspace.animationDef.Actors.Count - 1);
 | 
			
		||||
 | 
			
		||||
                clip.GetActorAddon(addonName).AnchoringActor = i;
 | 
			
		||||
                anchoringPawnField.SetTextWithoutNotify(i.ToString());
 | 
			
		||||
            }          
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/GUI/Cards/ActorAddonCard.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/GUI/Cards/ActorAddonCard.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 919aed3c4b9671c4e8dc109c7d608683
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										71
									
								
								Assets/Scripts/GUI/Cards/ActorAddonKeyframeCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								Assets/Scripts/GUI/Cards/ActorAddonKeyframeCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
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 ActorAddonKeyframeCard : MonoBehaviour
 | 
			
		||||
    {
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public Text label;
 | 
			
		||||
        public InputField xOffsetField;
 | 
			
		||||
        public InputField zOffsetField;
 | 
			
		||||
        public InputField rotationField;
 | 
			
		||||
 | 
			
		||||
        private ActorAddonDef actorAddonDef;
 | 
			
		||||
 | 
			
		||||
        public void Start()
 | 
			
		||||
        {
 | 
			
		||||
           
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(ActorAddonDef actorAddonDef)
 | 
			
		||||
        {
 | 
			
		||||
            this.actorAddonDef = actorAddonDef;
 | 
			
		||||
            this.addonName = actorAddonDef.addonName;
 | 
			
		||||
 | 
			
		||||
            label.text = actorAddonDef.label + ":";
 | 
			
		||||
 | 
			
		||||
            EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onPawnKeyframeChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
 | 
			
		||||
            xOffsetField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            zOffsetField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            rotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnValueChanged()
 | 
			
		||||
        {
 | 
			
		||||
            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);
 | 
			
		||||
 | 
			
		||||
            Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.RecordEvent("Actor addon position / orientation");
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void UpdateGUI()
 | 
			
		||||
        {
 | 
			
		||||
            PawnAnimationClip clip = Workspace.GetCurrentPawnAnimationClip();
 | 
			
		||||
 | 
			
		||||
            xOffsetField.SetTextWithoutNotify(string.Format("{0:0.000}", clip.GetActorAddon(addonName).PosX.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize)));
 | 
			
		||||
            zOffsetField.SetTextWithoutNotify(string.Format("{0:0.000}", clip.GetActorAddon(addonName).PosZ.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize)));
 | 
			
		||||
            rotationField.SetTextWithoutNotify(string.Format("{0:0.000}", clip.GetActorAddon(addonName).Rotation.Evaluate((float)Workspace.StageTick / Workspace.StageWindowSize)));
 | 
			
		||||
 | 
			
		||||
            gameObject.SetActive(clip.GetActorAddon(addonName).render == true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										126
									
								
								Assets/Scripts/GUI/Cards/ActorCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								Assets/Scripts/GUI/Cards/ActorCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,126 @@
 | 
			
		|||
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.onAnimationChanged.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");
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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<string> 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));
 | 
			
		||||
            bodyOffsetZField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.BodyTypeOffset.GetOffset(bodyType).z));
 | 
			
		||||
 | 
			
		||||
            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));
 | 
			
		||||
            raceOffsetZField.SetTextWithoutNotify(string.Format("{0:0.000}", actor.GetPawnRaceOffset().z));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								Assets/Scripts/GUI/Cards/ActorKeyframeCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.UI;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class ActorKeyframeCard : Singleton<ActorKeyframeCard>
 | 
			
		||||
    {       
 | 
			
		||||
        public InputField positionXField;
 | 
			
		||||
        public InputField positionZField;
 | 
			
		||||
        public InputField rotationField;
 | 
			
		||||
        public InputField headBobField;
 | 
			
		||||
        public InputField headRotationField;
 | 
			
		||||
        public InputField appendageRotationField;
 | 
			
		||||
 | 
			
		||||
        public ActorAddonCard actorAddonCardPrefab;
 | 
			
		||||
        public ActorAddonKeyframeCard actorAddonKeyframeCardPrefab;
 | 
			
		||||
 | 
			
		||||
        public Transform actorAddonCards;
 | 
			
		||||
        public Transform actorKeyframeCards;
 | 
			
		||||
 | 
			
		||||
        public SelectActorAddonsDialog selectActorAddonsDialog;
 | 
			
		||||
 | 
			
		||||
        private Actor actor { get { return Workspace.GetCurrentActor(); } }
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onActorIDChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onKeyframeCountChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onPawnKeyframeChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
 | 
			
		||||
            positionXField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            positionZField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            rotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            headBobField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            headRotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
            appendageRotationField.onEndEdit.AddListener(delegate { OnValueChanged(); });
 | 
			
		||||
 | 
			
		||||
            foreach (ActorAddonDef actorAddonDef in ActorAddonDefs.allDefs)
 | 
			
		||||
            {
 | 
			
		||||
                ActorAddonKeyframeCard actorAddonKeyframeCard = Instantiate(actorAddonKeyframeCardPrefab, actorKeyframeCards);
 | 
			
		||||
                actorAddonKeyframeCard.Initialize(actorAddonDef);
 | 
			
		||||
 | 
			
		||||
                ActorAddonCard actorAddonCard = Instantiate(actorAddonCardPrefab, actorAddonCards);
 | 
			
		||||
                actorAddonCard.Initialize(actorAddonDef, actorAddonKeyframeCard);
 | 
			
		||||
 | 
			
		||||
                selectActorAddonsDialog.AddActorAddonCard(actorAddonCard);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnValueChanged()
 | 
			
		||||
        {
 | 
			
		||||
            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);
 | 
			
		||||
 | 
			
		||||
            Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
 | 
			
		||||
            Workspace.RecordEvent("Actor position / orientation");
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void UpdateGUI()
 | 
			
		||||
        {
 | 
			
		||||
            ActorPosition actorPosition = actor.GetCurrentPosition();
 | 
			
		||||
 | 
			
		||||
            positionXField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.bodyOffsetX));
 | 
			
		||||
            positionZField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.bodyOffsetZ));
 | 
			
		||||
            rotationField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.bodyAngle));
 | 
			
		||||
            headBobField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.headBob));
 | 
			
		||||
            headRotationField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.headAngle));
 | 
			
		||||
            appendageRotationField.SetTextWithoutNotify(string.Format("{0:0.000}", actorPosition.genitalAngle));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								Assets/Scripts/GUI/Cards/AnimationControlCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								Assets/Scripts/GUI/Cards/AnimationControlCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,93 @@
 | 
			
		|||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using UnityEngine.UI;
 | 
			
		||||
 | 
			
		||||
namespace RimWorldAnimationStudio
 | 
			
		||||
{
 | 
			
		||||
    public class AnimationControlCard : MonoBehaviour
 | 
			
		||||
    {
 | 
			
		||||
        public InputField currentTimeField;
 | 
			
		||||
        public InputField stageWindowLengthField;
 | 
			
		||||
        public InputField playBackSpeedField;
 | 
			
		||||
        public Button playToggleButton;
 | 
			
		||||
        public Slider stageTimelineSlider;
 | 
			
		||||
 | 
			
		||||
        private void Start()
 | 
			
		||||
        {
 | 
			
		||||
            EventsManager.onAnimationChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onStageIDChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onStageTickChanged.AddListener(delegate { UpdateGUI(); });
 | 
			
		||||
            EventsManager.onAnimationToggled.AddListener(delegate { playToggleButton.image.color = Workspace.IsAnimating ? Constants.ColorGoldYellow : Constants.ColorWhite; });
 | 
			
		||||
 | 
			
		||||
            stageTimelineSlider.onValueChanged.AddListener(delegate { OnStageTimelineSliderChange(); });
 | 
			
		||||
            currentTimeField.onEndEdit.AddListener(delegate { OnCurrentTimeFieldChange(); });
 | 
			
		||||
            stageWindowLengthField.onEndEdit.AddListener(delegate { OnStageWindowLengthFieldChange(); });
 | 
			
		||||
            playBackSpeedField.onEndEdit.AddListener(delegate { OnPlayBackSpeedChange(); });
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnStageTimelineSliderChange()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.StageTick = (int)stageTimelineSlider.value;           
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnPlayBackSpeedChange()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.PlayBackSpeed = float.Parse(playBackSpeedField.text);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnCurrentTimeFieldChange()
 | 
			
		||||
        {
 | 
			
		||||
            Workspace.StageTick = Mathf.Clamp(int.Parse(currentTimeField.text), Constants.minTick, Workspace.StageWindowSize);
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void OnStageWindowLengthFieldChange()
 | 
			
		||||
        {
 | 
			
		||||
            int.TryParse(stageWindowLengthField.text, out int newStageWindowSize);
 | 
			
		||||
            newStageWindowSize = Mathf.Clamp(newStageWindowSize, Constants.minAnimationClipLength, Constants.maxAnimationClipLength);
 | 
			
		||||
 | 
			
		||||
            Debug.Log("Resizing animation clip length to " + newStageWindowSize.ToString() + " ticks.");
 | 
			
		||||
 | 
			
		||||
            if (Workspace.stretchKeyframes)
 | 
			
		||||
            { Workspace.GetCurrentAnimationStage().StretchStageWindow(newStageWindowSize); }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                foreach (PawnAnimationClip clip in Workspace.GetCurrentAnimationStage().AnimationClips)
 | 
			
		||||
                {
 | 
			
		||||
                    List<PawnKeyframe> keyframes = clip.Keyframes.Where(x => x.atTick > newStageWindowSize)?.ToList();
 | 
			
		||||
 | 
			
		||||
                    if (keyframes.NullOrEmpty())
 | 
			
		||||
                    { continue; }
 | 
			
		||||
 | 
			
		||||
                    foreach (PawnKeyframe keyframe in keyframes)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (clip.Keyframes.Count <= 2)
 | 
			
		||||
                        { break; }
 | 
			
		||||
 | 
			
		||||
                        clip.RemovePawnKeyframe(keyframe.keyframeID);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Workspace.GetCurrentAnimationStage().ResizeStageWindow(newStageWindowSize);
 | 
			
		||||
            Workspace.RecordEvent("Stage length");
 | 
			
		||||
 | 
			
		||||
            UpdateGUI();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void UpdateGUI()
 | 
			
		||||
        {
 | 
			
		||||
            stageTimelineSlider.maxValue = Workspace.StageWindowSize;
 | 
			
		||||
            stageTimelineSlider.SetValueWithoutNotify(Workspace.StageTick);
 | 
			
		||||
            currentTimeField.SetTextWithoutNotify(Workspace.StageTick.ToString());
 | 
			
		||||
            stageWindowLengthField.SetTextWithoutNotify(Workspace.StageWindowSize.ToString());
 | 
			
		||||
            playBackSpeedField.SetTextWithoutNotify(Workspace.PlayBackSpeed.ToString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								Assets/Scripts/GUI/Cards/AnimationControlCard.cs.meta
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Assets/Scripts/GUI/Cards/AnimationControlCard.cs.meta
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
fileFormatVersion: 2
 | 
			
		||||
guid: 6b414452bfd6c9b4bb99542a51d77468
 | 
			
		||||
MonoImporter:
 | 
			
		||||
  externalObjects: {}
 | 
			
		||||
  serializedVersion: 2
 | 
			
		||||
  defaultReferences: []
 | 
			
		||||
  executionOrder: 0
 | 
			
		||||
  icon: {instanceID: 0}
 | 
			
		||||
  userData: 
 | 
			
		||||
  assetBundleName: 
 | 
			
		||||
  assetBundleVariant: 
 | 
			
		||||
							
								
								
									
										39
									
								
								Assets/Scripts/GUI/Cards/AnimationDefCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Assets/Scripts/GUI/Cards/AnimationDefCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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.onAnimationChanged.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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								Assets/Scripts/GUI/Cards/StageCard.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Assets/Scripts/GUI/Cards/StageCard.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
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;
 | 
			
		||||
 | 
			
		||||
        private int stageID { get { return transform.GetSiblingIndex(); } }
 | 
			
		||||
 | 
			
		||||
        public void Start()
 | 
			
		||||
        {
 | 
			
		||||
            EventsManager.onStageIDChanged.AddListener(delegate { Initialize(stageName.text); });
 | 
			
		||||
            stageNameField.onEndEdit.AddListener(delegate { OnNameChange(); });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Initialize(string stageName)
 | 
			
		||||
        {
 | 
			
		||||
            this.stageName.text = stageName;
 | 
			
		||||
 | 
			
		||||
            if (Workspace.StageID == transform.GetSiblingIndex())
 | 
			
		||||
            {
 | 
			
		||||
                banner.gameObject.SetActive(true);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                banner.gameObject.SetActive(false);
 | 
			
		||||
                stageNameField.gameObject.SetActive(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
        {        
 | 
			
		||||
            Workspace.animationDef.MoveAnimationStage(stageID, delta);        
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue