diff --git a/README.md b/README.md index fdd2f39..8e238fc 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,18 @@ You can download the [latest release here](https://github.com/Epicguru/AdvancedA Other mods may be compatible. The mods listed above are just the mods that have patches made by Epicguru. [Click here to see how to create a patch yourself!](Source/TweakTutorial/AuthorTweaks.md) + +## For modders and maintainers +Legal: please see the LICENSE for what you can and can not do with this mod's source code and assets. +I would appreciate being contacted if you plan to do a major fork or continuation of this mod: I can be contacted by opening an issue on this Github page, or on discord under the @epicguru handle. + +### How to build +Clone this repository into your Mods folder. +The recommended IDE is Rider, but Visual Studio should also work. Visual Studio Code (VS Code) will *NOT* work! +There is a seperate solution file and folder for each major Rimworld version, such as `1.4` and `1.5`. +Simply open the solution for the current version and build the entire solution (`Ctrl+Shift+B` will build everything). +There is no need to link up any assembly or project references, it is all done via NuGet packages. +All the assemblies will be put into the correct folders automatically. + +### Creating new animations +See the [Animation Creation Guide](Source/AnimationTutorial/AnimationTutorial.md). \ No newline at end of file diff --git a/Source/1.4/.idea/.idea.AnimationMod/.idea/.gitignore b/Source/1.4/.idea/.idea.AnimationMod/.idea/.gitignore new file mode 100644 index 0000000..70c23e6 --- /dev/null +++ b/Source/1.4/.idea/.idea.AnimationMod/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/projectSettingsUpdater.xml +/contentModel.xml +/.idea.AnimationMod.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/Source/1.4/.idea/.idea.AnimationMod/.idea/.name b/Source/1.4/.idea/.idea.AnimationMod/.idea/.name new file mode 100644 index 0000000..1ab0477 --- /dev/null +++ b/Source/1.4/.idea/.idea.AnimationMod/.idea/.name @@ -0,0 +1 @@ +AnimationMod \ No newline at end of file diff --git a/Source/1.4/.idea/.idea.AnimationMod/.idea/indexLayout.xml b/Source/1.4/.idea/.idea.AnimationMod/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/Source/1.4/.idea/.idea.AnimationMod/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Source/1.4/.idea/.idea.AnimationMod/.idea/vcs.xml b/Source/1.4/.idea/.idea.AnimationMod/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/Source/1.4/.idea/.idea.AnimationMod/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Source/1.4/ThingGenerator/Tweaks/ItemTweakData.cs b/Source/1.4/ThingGenerator/Tweaks/ItemTweakData.cs index 20151d6..95b9908 100644 --- a/Source/1.4/ThingGenerator/Tweaks/ItemTweakData.cs +++ b/Source/1.4/ThingGenerator/Tweaks/ItemTweakData.cs @@ -292,7 +292,7 @@ public ISweepProvider GetSweepProvider() { Core.Error($"Failed to create instance of ISweepProvider '{klass.FullName}':", e); return null; -; } + } } cachedSweepProvider = instance; diff --git a/Source/1.5/AnimationMod/AnimDef.cs b/Source/1.5/AnimationMod/AnimDef.cs index 02cd58f..5413744 100644 --- a/Source/1.5/AnimationMod/AnimDef.cs +++ b/Source/1.5/AnimationMod/AnimDef.cs @@ -1,19 +1,19 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.IO; using System.Linq; using System.Xml.Serialization; using AM.AMSettings; +using AM.Data; using AM.Idle; using AM.RendererWorkers; using AM.Reqs; using AM.Sweep; using JetBrains.Annotations; +using LudeonTK; using RimWorld; using UnityEngine; using Verse; -using LudeonTK; namespace AM; @@ -72,7 +72,7 @@ public static void ReloadAllAnimations() continue; def.resolvedData = AnimData.Load(def.FullDataPath, false); - def.resolvedNonLethalData = File.Exists(def.FullNonLethalDataPath) ? AnimData.Load(def.FullNonLethalDataPath, false) : def.resolvedData; + def.resolvedNonLethalData = AnimData.Load(def.FullNonLethalDataPath, false) ?? def.resolvedData; } } @@ -100,21 +100,29 @@ public virtual string FullDataPath { get { - var mod = modContentPack; - if (mod == null) + string dataName = data.Trim(); + if (dataName.EndsWith(".json")) { - Core.Error($"This def '{defName}' has no modContentPack, so FullDataPath cannot be resolved! Returning relative path instead..."); - return data; + dataName = dataName[..^5]; } - string relative = data.Trim(); - if (string.IsNullOrWhiteSpace(new FileInfo(relative).Extension)) - relative += ".json"; + return AnimDataSourceManager.TryGetDataFilePath(dataName); + } + } + public virtual string FullNonLethalDataPath + { + get + { + string dataName = data.Trim(); + if (dataName.EndsWith(".json")) + { + dataName = dataName[..^5]; + } + dataName += "_NL"; - return Path.Combine(mod.RootDir, "Animations", relative); + return AnimDataSourceManager.TryGetDataFilePath(dataName); } } - public virtual string FullNonLethalDataPath => FullDataPath.Replace(".json", "_NL.json"); public AnimData Data { get @@ -214,11 +222,8 @@ public void SetDefaultSData() protected virtual void ResolveData() { - if (File.Exists(FullDataPath)) - resolvedData = AnimData.Load(FullDataPath); - - if (File.Exists(FullNonLethalDataPath)) - resolvedNonLethalData = AnimData.Load(FullNonLethalDataPath); + resolvedData = AnimData.Load(FullDataPath); + resolvedNonLethalData = AnimData.Load(FullNonLethalDataPath); } public T TryGetAdditionalData(string id, T defaultValue = default) @@ -265,7 +270,7 @@ public override IEnumerable ConfigErrors() if (string.IsNullOrWhiteSpace(data)) yield return "Animation has no data path! Please specify the location of the data file using the data tag."; - else if (!File.Exists(FullDataPath)) + else if (FullDataPath == null) // Means not found in the file system. yield return $"Failed to find animation file at '{FullDataPath}'!"; if (type is AnimType.Execution or AnimType.Duel or AnimType.Idle && weaponFilter == null) diff --git a/Source/1.5/AnimationMod/Core.cs b/Source/1.5/AnimationMod/Core.cs index 5f9a336..4dd7bd5 100644 --- a/Source/1.5/AnimationMod/Core.cs +++ b/Source/1.5/AnimationMod/Core.cs @@ -1,4 +1,13 @@ -using AM.AMSettings; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using AM.AMSettings; +using AM.Data; using AM.Hands; using AM.Patches; using AM.Retexture; @@ -7,13 +16,6 @@ using ModRequestAPI; using ModRequestAPI.Models; using RimWorld; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; using UnityEngine; using Verse; @@ -162,7 +164,7 @@ private static void AddParser(Func func) ParseHelper.Parsers.Register(func); } - private static void PatchVBE() + private static void PatchVanillaBackgroundsExpanded() { if (ModLister.GetActiveModWithIdentifier("vanillaexpanded.backgrounds") == null) return; @@ -187,7 +189,7 @@ private static async Task UploadMissingModData(IEnumerable li var client = new ModRequestClient(); await client.TryPostModRequests(list); } - + public Core(ModContentPack content) : base(content) { AddParsers(); @@ -222,11 +224,21 @@ public Core(ModContentPack content) : base(content) AddLateLoadAction(true, "Applying settings...", Settings.PostLoadDefs); AddLateLoadAction(true, "Matching textures with mods...", PreCacheAllRetextures); AddLateLoadAction(true, "Loading weapon tweak data...", LoadAllTweakData); - AddLateLoadAction(true, "Patch VBE", PatchVBE); + AddLateLoadAction(true, "Patch VBE", PatchVanillaBackgroundsExpanded); AddLateLoadAction(true, "Apply final patches", Patch_Verb_MeleeAttack_ApplyMeleeDamageToTarget.PatchAll); AddLateLoadAction(true, "Cache gloves", HandUtility.DoInitialLoading); AddLateLoadEvents(); + + // This needs to be done now, before defs are loaded. + try + { + AnimDataSourceManager.ScanForDataFiles(); + } + catch (Exception e) + { + Error("Failed to scan for animation data files.", e); + } } private static void RegisterWeaponDefOverrides() diff --git a/Source/1.5/AnimationMod/Data/AnimData.cs b/Source/1.5/AnimationMod/Data/AnimData.cs index 72bf96b..382ebd4 100644 --- a/Source/1.5/AnimationMod/Data/AnimData.cs +++ b/Source/1.5/AnimationMod/Data/AnimData.cs @@ -75,10 +75,12 @@ private static Mesh MakeMesh(Vector2 size, bool flipX, bool flipY) tris[3] = 0; tris[4] = 2; tris[5] = 3; - Mesh mesh = new(); - mesh.name = $"AM Mesh: {flipX}, {flipY}"; - mesh.vertices = verts; - mesh.uv = (flipX && flipY) ? fxy : flipX ? fx : flipY ? fy : normal; + var mesh = new Mesh + { + name = $"AM Mesh: {flipX}, {flipY}", + vertices = verts, + uv = (flipX && flipY) ? fxy : flipX ? fx : flipY ? fy : normal + }; mesh.SetTriangles(tris, 0); mesh.RecalculateNormals(); mesh.RecalculateBounds(); @@ -88,7 +90,9 @@ private static Mesh MakeMesh(Vector2 size, bool flipX, bool flipY) public static AnimData Load(string filePath, bool allowFromCache = true, bool saveToCache = true) { if (filePath == null) + { return null; + } if (allowFromCache) { diff --git a/Source/1.5/AnimationMod/Data/AnimDataSourceManager.cs b/Source/1.5/AnimationMod/Data/AnimDataSourceManager.cs new file mode 100644 index 0000000..15f3463 --- /dev/null +++ b/Source/1.5/AnimationMod/Data/AnimDataSourceManager.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.IO; +using Verse; + +namespace AM.Data; + +public static class AnimDataSourceManager +{ + private static readonly Dictionary dataNameToFilePath = new Dictionary(); + + public static void ScanForDataFiles() + { + dataNameToFilePath.Clear(); + + var activeMods = LoadedModManager.RunningModsListForReading; + int modsWithDataCount = 0; + Core.Log($"Scanning {activeMods.Count} mods for animation data..."); + + foreach (var mod in activeMods) + { + string dir = mod.RootDir; + + string expectedPath = Path.Combine(dir, "Animations"); + if (!Directory.Exists(expectedPath)) + { + continue; + } + + string animFolderAbsolute = new FileInfo(expectedPath).FullName; + bool any = false; + + foreach (string filePath in Directory.GetFiles(expectedPath, "*.json", SearchOption.AllDirectories)) + { + string absolute = new FileInfo(filePath).FullName; + string relative = absolute[(animFolderAbsolute.Length + 1)..]; + string relativeWithoutExtension = Path.GetFileNameWithoutExtension(relative); + + dataNameToFilePath[relativeWithoutExtension] = absolute; + any = true; + } + + if (any) + { + modsWithDataCount++; + } + } + + Core.Log($"Found {modsWithDataCount} mod folders with animation data, total {dataNameToFilePath.Count} loadable files."); + } + + public static string TryGetDataFilePath(string dataName) => dataNameToFilePath.GetValueOrDefault(dataName); +} diff --git a/Source/AnimationTutorial/AnimSaveFolder.png b/Source/AnimationTutorial/AnimSaveFolder.png new file mode 100644 index 0000000..1e9cbbc Binary files /dev/null and b/Source/AnimationTutorial/AnimSaveFolder.png differ diff --git a/Source/AnimationTutorial/AnimStarter.png b/Source/AnimationTutorial/AnimStarter.png new file mode 100644 index 0000000..c82208b Binary files /dev/null and b/Source/AnimationTutorial/AnimStarter.png differ diff --git a/Source/AnimationTutorial/AnimationTutorial.md b/Source/AnimationTutorial/AnimationTutorial.md new file mode 100644 index 0000000..521723d --- /dev/null +++ b/Source/AnimationTutorial/AnimationTutorial.md @@ -0,0 +1,176 @@ +# Creating new animations + +**HELP**: If you get stuck on any part of this guide, or have any questions about the systems available, I can normally be contacted on Discord under the @epicguru handle or by opening an issue on this page. + +## Basic setup +First, you need to clone or download the Melee Animation mod into your local `Mods` folder from the Github page: you can't just copy the Steam version because it does not include the source files. +Next, you will need your own mod set up to put the new animations into. +You should have a mod folder set up, with an `About.xml` file so that the mod can load correctly, even if the mod has no content or code. +Next **create a new folder** inside your mod folder, call it `Animations`. +Your mod folder structure should now look like this: +``` +MyModName/ +├─ About/ +│ ├─ About.xml +├─ Animations/ +├─ Defs/ +... +``` + +## Setting up the editor + +Open the folder of your local copy of the Melee Animation mod. +Inside the `Source/Animations` folder is a Unity project that is used to create the animations for this mod. +The [Unity Animation Editor](https://docs.unity3d.com/6000.0/Documentation/Manual/animeditor-UsingAnimationEditor.html) is used to create animations using keyframes - if you have used Blender, Spine or other keyframe animation software, you will find it quite easy to use. +A full Unity and Unity animation tutorial is outside the scope of this guide, so please take some time to understand the editor if you are not already familiar with it. + + - Install Unity Editor version 6 (6000.0) or above. + - Add the Animation project, in the `Source/Animations`, to Hub to allow you to open it: ![Open Project](OpenProject.png "Open the project") + - Open the Animation project. You may see a warning about changing the unity editor version, this is fine. + - Once the project has opened (this may take a while the first time), you should see a button in the top menu called `Melee Animation`. + Click this button, then click `Set Export Location`. This will tell the editor where to put the animation files that you create. + ![Set export location](ExportLocation1.png "Set the export location") + - Set the export location to the `Animations` folder, inside your mod folder, that you created earlier. + - From the top menu, select *File > Open Scene* and open the scene at `Assets/Scenes/SampleScene.unity`. You should now have something like this: ![Raw scene](RawScene.png "Raw scene") + - Next you need to adjust the camera so that it is suitable to animate characters. In the top-right of the Scene view, click the following in this order: + 1. The green *Y* arrow. + 2. The center white box. + 3. The 'lock' icon. +![Camera setup](CameraSetup.png "Camera setup") + - Almost ready to animate! Make sure you have the *Animation* window open, press `Ctrl+6` if it is not open to open it quickly. + +## What rig to use? +In the hierarchy on the left you will see several game objects with different names. Each of these 'rigs' are used to create different types of animations. +![Rigs](Rigs.png "Rigs") +A breakdown of the existing rigs are as follows: +| Rig Name | Used For | +|--------------------------|----------------------------------------------------------------------------------------------------------| +| Pawn Pair | Generic two-pawn rig, used for almost all execution and duel animations. | +| Pawn Pair Detatched Head | Two-pawn rig, used for execution animations that need to behead the victim. | +| Pawn Pair Weebstick | Rig used for the Scarlet Edge unique skill execution. | +| Pawn Pair GaeBulg | Rig used for the GaeBulg unique execution. | +| GilgameshVictim | Rig used for the Mystic Summon unique skill execution. | +| IdleAnims: Tiny | Rig used for the idle animations for Tiny weapons, including movement, attacking and flavour animations. | +| IdleAnims: Medium | Same as above, for Medium weapons. | +| IdleAnims: Colossal | Same as above, for Colossal weapons. | + + +**Generally you will want to use the `Pawn Pair` rig to create execution animations.** + +Start by clicking on the Pawn Pair object and enabling it in the Inspector tab: +![Enable](EnablePawnPair.png "Enable") + +You should now see something like this: +![Scene view](FullScene.png "Full scene") +If you do not see the two pawns, double click on the Pawn Pair object, this will focus the scene camera on them. +You can zoom using the scroll wheel, and move the camera by pressing down the middle mouse button and dragging. + +## Animation controls +As a reminder, this will not be a full 'how to use Unity animator' tutorial. +Instead, I will explain the controls that are unique to this Rimworld animation rig. +I will explain how to make a simple execution animation, from there you should be able to create your own. I also suggest inspecting the existing animations to figure out how they all work. +- First, let's create a new animation. You can name the animation anything you want, and it does not matter where you save the animation (`.anim` file) as long as it is somewhere under the `Assets` folder. +![Create 1](Create1.png "Full scene") +![Create 2](Create2.png "Full scene") +![Create 3](AnimSaveFolder.png "Full scene") +I will create a new animation called *Execution_Tutorial*, but name yours whatever you want. +- Now you can begin animating! + Let me explain some of the specific controls in the rig. Expand the `Pawn Pair` hierarchy so that you can see some of the inner parts. + Here is a list of the parts and what they do/are: + 1. **BodyA**: This is the attacking pawn's body. You can move, rotate and show/hide the pawn using this part. + 2. **BodyB**: This is the victim pawn's body. This is the pawn that is being executed. + 3. **PawnAHolding**: This is a combination of the attacking pawn's hands and weapon. This will be your main control to swing the weapon around. Notice that this part is not a child of the body: this means that they move independently of each other, I find that this is easier to animate. You will see that the weapon looks like a Vanilla longsword: this will be replaced in-game with whatever the pawn is using automatically. + 4. **PawnBHolding**: Same as above, but for the victim pawn. Note that this is hidden by default, you must manually enable it in your animation if you want the victim pawn to show their hands or weapon. + 5. **WeaponACutoff**: This is a special, invisible object that is used to allow the attacking pawn's weapon to stick 'through' the victim. + This is an optional feature that will be explained later. + +I need to go into a bit more detail for certain parts. + +### Draw order / Layering +You can change the order that things draw in by changing the Z position of them. + +### Showing and hiding objects +You can simply enable or disable game objects to hide or show them, this includes the entire pawn if you want to hide the pawn. + +### Pawn facing direction +The pawn's rotation can be animated simply by rotating the game object, but in order to change the direction they are *facing* (north, east, south, west), you need to select the Body object (*BodyA* or *BodyB*). You will see a Pawn Body component in the inspector, which contains a *Direction* property. This property can be changed to change the direction the pawn is facing, and of course this property can be keyframed. +![Facing](Facing.png "Full scene") + +### Moving hands away from weapon +If for some reason you want to move a pawn's hands away from their weapon, you can do this by expanding the *PawnAHolding* object. Inside you will have two hand objects which you can move independently of the weapon, which is the object called *ItemA*. + +### Stabbing the weapon through/into something +Remeber the *WeaponACutoff* object? This is used to allow the main weapon to stab through or into an object. +Select the *ItemA* object, and in the Inspector you will see *Split Draw Mode* at the bottom. This controls how the weapon draws. +![Split Draw Mode](SplitDrawMode.png "Full scene") + +I will explain each mode: +- **None**: This is the default mode. The entire weapon is drawn. +- **Before**: The weapon is only drawn *before* the cutoff point; the part past the cutoff point is invisible. +- **After**: The weapon is only drawn *after* the cutoff point; the part before the cutoff point is invisible. +- **Before and After**: The weapon is drawn before and after the cutoff point, but the part after the cutoff point is put in the background i.e. behind the enemy pawn. This is useful to show the sword sticking through the enemy. + +Please inspect the existing animations to get a better understanding of how the modes work, and how the cutoff object is placed to achieve the desired effect. Remember, if you do not want to bother with this system, you do not have to use it. + +**Important note**: The split draw mode does not show up in the editor! It will only work in Rimworld. + +## Animation events +Animation events are an important part of the animations. They tell the mod when certain events occur during the animation, such as a pawn being hit, or killed, or when to play a sound effect or spawn a particle effect. +Fully explaining the event system is outside of the scope of this tutorial (contact me for details if you need them), but I will explain the essentials: + +**First, the 'kill' event tells the mod when (and how) the animation should end if the execution outcome is 'killed'.** +This is how it works: the mod will determine the outcome of the execution attempt. If the outcome is 'kill', then the animation will play up until the point that a 'kill' event is encountered. If the outcome is anything else, then the animation will play all the way to the end, ignoring the kill event. This is important because it allows you to design the animation to account for the pawn dying or surviving: please see the `Execution_Shank` animation in the editor for an example of this in action. + +Here is how you add events to your animation: +First, move the animation to the time that you want to put the event at, then click this button to create a new event: +![Create event](EventButton.png "Full scene") +Next, in the Inspector window, set the *Function* to `AnimationDataCreator > Methods > AnimEvent (AnimBase)`: +![Set event](EventBaseSelect.png "Full scene") +Finally, click the round button to set the type of event, and select the `Kill_HeartStab` event. This event means that the victim pawn will be killed by being stabbed in the heart. It is possible to change the specific killing blow, but it is outside the scope of this tutorial, contact me if necessary. +![Kill event](KillEvent.png "Full scene") + +**Important**: If you do not add a Kill event to your execution animation, it will never kill or injure the victim! So make sure to add the event, even if it is on the last frame of the animation. + +## Exporting the animation +Finally, you are ready to export your animation(s). +First, select the `Pawn Pair` object in the Heriarchy (or whatever rig you are using). +Then make sure that your animation is currently selected in the Animation window. +Finally, in the Inspector window, click the *Save to file* button: this will export **the currently active animation** to your mod folder. You need to repeat this process for each of your animations. +**Do *not* click the Save ALL to file button**, because this will export all of the vanilla animations to your mod folder. +![Save](SaveToFile.png "Full scene") + +Congrats! You should now have a file called `Execution_Tutorial.json` inside the `Animations` folder in your mod. That json file is the data that the mod loads to play your animation. There is only one final step to get your animation into the game. + +## Creating an animation def +The final step to getting the animation in the game is to create an animation def to tell the animation mod about your new execution animation. +Create a new XML def file in your mod's `Defs` folder. +Inside the def file, add the following Def: +```XML + + MyMod_Execution_Tutorial + + Execution_Tutorial.json + + Short_Stab, Long_Stab + + +``` +You should obviously change the name, def name etc. as needed. +The `weaponFilter` property is important: this determines what type of weapon(s) are allowed to do your execution animation. +In the example above, any short stabbing weapon, or long stabbing weapon is allowed to do the animation. +Here are all the possible options: +`Short_Stab`, `Short_Blunt`, `Short_Sharp`, `Long_Stab`, `Long_Blunt`, `Long_Sharp`. +Stabbing weapons are those with a sharp point, blunt weapons are those with a blunt edge, and sharp weapons are those with a sharp edge. +Weapons can be part of more than one category, for example a longsword is both `Long_Sharp` and `Long_Stab`. + +--- + +# Testing your animation + +That is all! If you've made it this far, well done. You can now see your execution animation in-game by opening the developer actions window, then going to the *Melee Animation* category and clicking *Open Debugger*. +In the popup that opens, change it's type to *Animation Starter*. This will allow you to select your animation from the dropdown menu and play it on any two pawns of your liking! +![Starter](AnimStarter.png "Full scene") + +## Publishing your animations + +To share your animations with others, simply share your mod with the `Animations` folder. \ No newline at end of file diff --git a/Source/AnimationTutorial/CameraSetup.png b/Source/AnimationTutorial/CameraSetup.png new file mode 100644 index 0000000..18a8272 Binary files /dev/null and b/Source/AnimationTutorial/CameraSetup.png differ diff --git a/Source/AnimationTutorial/Create1.png b/Source/AnimationTutorial/Create1.png new file mode 100644 index 0000000..b58b772 Binary files /dev/null and b/Source/AnimationTutorial/Create1.png differ diff --git a/Source/AnimationTutorial/Create2.png b/Source/AnimationTutorial/Create2.png new file mode 100644 index 0000000..4be844c Binary files /dev/null and b/Source/AnimationTutorial/Create2.png differ diff --git a/Source/AnimationTutorial/EnablePawnPair.png b/Source/AnimationTutorial/EnablePawnPair.png new file mode 100644 index 0000000..665a67d Binary files /dev/null and b/Source/AnimationTutorial/EnablePawnPair.png differ diff --git a/Source/AnimationTutorial/EventBaseSelect.png b/Source/AnimationTutorial/EventBaseSelect.png new file mode 100644 index 0000000..a953790 Binary files /dev/null and b/Source/AnimationTutorial/EventBaseSelect.png differ diff --git a/Source/AnimationTutorial/EventButton.png b/Source/AnimationTutorial/EventButton.png new file mode 100644 index 0000000..efcb018 Binary files /dev/null and b/Source/AnimationTutorial/EventButton.png differ diff --git a/Source/AnimationTutorial/ExportLocation1.png b/Source/AnimationTutorial/ExportLocation1.png new file mode 100644 index 0000000..2041e91 Binary files /dev/null and b/Source/AnimationTutorial/ExportLocation1.png differ diff --git a/Source/AnimationTutorial/Facing.png b/Source/AnimationTutorial/Facing.png new file mode 100644 index 0000000..150ef03 Binary files /dev/null and b/Source/AnimationTutorial/Facing.png differ diff --git a/Source/AnimationTutorial/FullScene.png b/Source/AnimationTutorial/FullScene.png new file mode 100644 index 0000000..554484b Binary files /dev/null and b/Source/AnimationTutorial/FullScene.png differ diff --git a/Source/AnimationTutorial/KillEvent.png b/Source/AnimationTutorial/KillEvent.png new file mode 100644 index 0000000..553ac00 Binary files /dev/null and b/Source/AnimationTutorial/KillEvent.png differ diff --git a/Source/AnimationTutorial/OpenProject.png b/Source/AnimationTutorial/OpenProject.png new file mode 100644 index 0000000..829bf14 Binary files /dev/null and b/Source/AnimationTutorial/OpenProject.png differ diff --git a/Source/AnimationTutorial/RawScene.png b/Source/AnimationTutorial/RawScene.png new file mode 100644 index 0000000..f1d70f8 Binary files /dev/null and b/Source/AnimationTutorial/RawScene.png differ diff --git a/Source/AnimationTutorial/Rigs.png b/Source/AnimationTutorial/Rigs.png new file mode 100644 index 0000000..56f5cb6 Binary files /dev/null and b/Source/AnimationTutorial/Rigs.png differ diff --git a/Source/AnimationTutorial/SaveToFile.png b/Source/AnimationTutorial/SaveToFile.png new file mode 100644 index 0000000..7a1154d Binary files /dev/null and b/Source/AnimationTutorial/SaveToFile.png differ diff --git a/Source/AnimationTutorial/SplitDrawMode.png b/Source/AnimationTutorial/SplitDrawMode.png new file mode 100644 index 0000000..e4204df Binary files /dev/null and b/Source/AnimationTutorial/SplitDrawMode.png differ diff --git a/Source/Animations/Assets/Scenes/SampleScene.unity b/Source/Animations/Assets/Scenes/SampleScene.unity index ddf5a2e..b582d9e 100644 --- a/Source/Animations/Assets/Scenes/SampleScene.unity +++ b/Source/Animations/Assets/Scenes/SampleScene.unity @@ -2537,146 +2537,6 @@ MonoBehaviour: FrameIndex: 0 SplitDrawPivot: {fileID: 0} SplitDrawMode: 0 ---- !u!1 &371353037 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 371353038} - - component: {fileID: 371353040} - - component: {fileID: 371353039} - m_Layer: 0 - m_Name: BodyA - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &371353038 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 371353037} - serializedVersion: 2 - 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_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 1417317145} - - {fileID: 825323544} - m_Father: {fileID: 485215799} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &371353039 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 371353037} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0fda39bc171ca0a419f2f933cc0221b7, type: 3} - m_Name: - m_EditorClassIdentifier: - Direction: 3 ---- !u!114 &371353040 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 371353037} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3ac72458fde51c546a95b850d16b9030, type: 3} - m_Name: - m_EditorClassIdentifier: - CustomName: BodyA - TexturePath: Naked_Female_east - DoNotIncludeTexture: 1 - IdleOffset: {x: 0, y: 0} - IdleRotation: 0 - IdleScale: {x: 1.5, y: 1.5} - IdleFlipX: 0 - IdleFlipY: 0 - TransparentByDefault: 0 - Tint: {r: 1, g: 1, b: 1, a: 1} - DataA: 0 - DataB: 0 - DataC: 0 - FlipX: 1 - FlipY: 0 - FrameIndex: 0 - SplitDrawPivot: {fileID: 0} - SplitDrawMode: 0 ---- !u!1 &381651223 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 381651224} - - component: {fileID: 381651225} - m_Layer: 0 - m_Name: HandGrabSparks - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!4 &381651224 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 381651223} - serializedVersion: 2 - 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_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 485215799} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &381651225 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 381651223} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3ac72458fde51c546a95b850d16b9030, type: 3} - m_Name: - m_EditorClassIdentifier: - CustomName: - TexturePath: AM/HandGrabSparks - DoNotIncludeTexture: 0 - IdleOffset: {x: 0, y: 0} - IdleRotation: 0 - IdleScale: {x: 1, y: 1} - IdleFlipX: 0 - IdleFlipY: 0 - TransparentByDefault: 0 - Tint: {r: 1, g: 1, b: 1, a: 1} - DataA: 0 - DataB: 0 - DataC: 0 - FlipX: 0 - FlipY: 0 - FrameIndex: 0 - SplitDrawPivot: {fileID: 0} - SplitDrawMode: 0 --- !u!1 &392469733 GameObject: m_ObjectHideFlags: 0 @@ -3180,97 +3040,6 @@ Transform: - {fileID: 564682611} m_Father: {fileID: 1955818713} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &485215796 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 485215799} - - component: {fileID: 485215798} - - component: {fileID: 485215797} - m_Layer: 0 - m_Name: TEMP_ENEMY - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!95 &485215797 -Animator: - serializedVersion: 7 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 485215796} - m_Enabled: 1 - m_Avatar: {fileID: 0} - m_Controller: {fileID: 9100000, guid: 65811b72c281da243bde4dd8d449a755, type: 2} - m_CullingMode: 0 - m_UpdateMode: 0 - m_ApplyRootMotion: 0 - m_LinearVelocityBlending: 0 - m_StabilizeFeet: 0 - m_AnimatePhysics: 0 - m_WarningMessage: - m_HasTransformHierarchy: 1 - m_AllowConstantClipSamplingOptimization: 1 - m_KeepAnimatorStateOnDisable: 0 - m_WriteDefaultValuesOnDisable: 0 ---- !u!114 &485215798 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 485215796} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 1035ec63e739b8e43b63587ca5c339e4, type: 3} - m_Name: - m_EditorClassIdentifier: - Clip: {fileID: 7400000, guid: d6701493e381514418599c0b2489ca73, type: 2} - SweepParams: {fileID: 11400000, guid: 8b5f4250e25ad0743a6923a3d261879b, type: 2} - AllowLoadingFromJson: 0 - SweepDisplayMode: 3 - SweepGhostTime: 0.25 - OverridePairs: - - PartName: HandA - Texture: {fileID: 2800000, guid: c1217ca012db3f64ba08c19db5e8cec1, type: 3} - PreventDraw: 0 - - PartName: HandB - Texture: {fileID: 2800000, guid: c1217ca012db3f64ba08c19db5e8cec1, type: 3} - PreventDraw: 0 - - PartName: HandA2 - Texture: {fileID: 2800000, guid: c1217ca012db3f64ba08c19db5e8cec1, type: 3} - PreventDraw: 0 - - PartName: HandB2 - Texture: {fileID: 2800000, guid: c1217ca012db3f64ba08c19db5e8cec1, type: 3} - PreventDraw: 0 - InspectAllCurves: 0 - Points: [] - MirrorHorizontal: 0 - MirrorVertical: 0 ---- !u!4 &485215799 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 485215796} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 1, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 371353038} - - {fileID: 381651224} - m_Father: {fileID: 0} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &500098915 GameObject: m_ObjectHideFlags: 0 @@ -5557,68 +5326,6 @@ MonoBehaviour: FrameIndex: 0 SplitDrawPivot: {fileID: 0} SplitDrawMode: 0 ---- !u!1 &825323543 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 825323544} - - component: {fileID: 825323545} - m_Layer: 0 - m_Name: Clothes IGNORED - m_TagString: AnimIgnore - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 0 ---- !u!4 &825323544 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 825323543} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0.026061773, z: 0} - m_LocalScale: {x: 3.2099998, y: 1, z: 1.9699999} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 371353038} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &825323545 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 825323543} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3ac72458fde51c546a95b850d16b9030, type: 3} - m_Name: - m_EditorClassIdentifier: - CustomName: - TexturePath: AM/Weapons/Weebstick_Glint - DoNotIncludeTexture: 0 - IdleOffset: {x: 0, y: 0} - IdleRotation: 54 - IdleScale: {x: 1, y: 1} - IdleFlipX: 0 - IdleFlipY: 0 - TransparentByDefault: 0 - Tint: {r: 0, g: 0.29352832, b: 1, a: 1} - DataA: 0 - DataB: 0 - DataC: 0 - FlipX: 0 - FlipY: 0 - FrameIndex: 0 - SplitDrawPivot: {fileID: 0} - SplitDrawMode: 0 --- !u!1 &833215059 GameObject: m_ObjectHideFlags: 0 @@ -7798,6 +7505,37 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} +--- !u!1 &1131283762 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1131283763} + m_Layer: 0 + m_Name: ------------------------------------------------ + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1131283763 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1131283762} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0.6496845, y: -0.000000020475019, z: 0.17175692} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1132258801 GameObject: m_ObjectHideFlags: 0 @@ -9210,68 +8948,6 @@ Transform: - {fileID: 188105328} m_Father: {fileID: 1914720448} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &1417317144 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1417317145} - - component: {fileID: 1417317146} - m_Layer: 0 - m_Name: HeadA - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1417317145 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1417317144} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0.05, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 371353038} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &1417317146 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1417317144} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3ac72458fde51c546a95b850d16b9030, type: 3} - m_Name: - m_EditorClassIdentifier: - CustomName: HeadA - TexturePath: Female_Average_Normal_east - DoNotIncludeTexture: 1 - IdleOffset: {x: 0.1, y: 0.34} - IdleRotation: 0 - IdleScale: {x: 1.5, y: 1.5} - IdleFlipX: 0 - IdleFlipY: 0 - TransparentByDefault: 0 - Tint: {r: 1, g: 1, b: 1, a: 1} - DataA: 0 - DataB: 0 - DataC: 0 - FlipX: 1 - FlipY: 0 - FrameIndex: 0 - SplitDrawPivot: {fileID: 0} - SplitDrawMode: 0 --- !u!1 &1429335593 GameObject: m_ObjectHideFlags: 0 @@ -12720,7 +12396,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 1035ec63e739b8e43b63587ca5c339e4, type: 3} m_Name: m_EditorClassIdentifier: - Clip: {fileID: 7400000, guid: f218eae606a8dc54d9071bb894e18021, type: 2} + Clip: {fileID: 7400000, guid: 613098d2841809246b480d7444c6d018, type: 2} SweepParams: {fileID: 11400000, guid: 8b5f4250e25ad0743a6923a3d261879b, type: 2} AllowLoadingFromJson: 0 SweepDisplayMode: 3 @@ -14020,16 +13696,16 @@ SceneRoots: m_Roots: - {fileID: 1130584381} - {fileID: 1464914356} + - {fileID: 343237699} + - {fileID: 1131283763} + - {fileID: 1914720448} + - {fileID: 1694323724} - {fileID: 913407784} - {fileID: 890458934} - {fileID: 336345000} - - {fileID: 343237699} - {fileID: 523862470} - {fileID: 1550348914} - - {fileID: 1914720448} - {fileID: 1768372577} - - {fileID: 1694323724} - {fileID: 1156962771} - {fileID: 1047008476} - {fileID: 758745603} - - {fileID: 485215799} diff --git a/Source/Animations/UserSettings/Layouts/default-6000.dwlt b/Source/Animations/UserSettings/Layouts/default-6000.dwlt index a165a2b..f2a8edb 100644 --- a/Source/Animations/UserSettings/Layouts/default-6000.dwlt +++ b/Source/Animations/UserSettings/Layouts/default-6000.dwlt @@ -611,7 +611,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: b25e0000 m_LastClickedID: 24242 - m_ExpandedIDs: 000000007a600000 + m_ExpandedIDs: m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -640,7 +640,7 @@ MonoBehaviour: scrollPos: {x: 0, y: 0} m_SelectedIDs: m_LastClickedID: 0 - m_ExpandedIDs: 000000007a600000 + m_ExpandedIDs: m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: