-
-
Save TigerHix/2cb8052b0e8aeeb7f9cb796dc7edc6a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"categories": [ | |
{ | |
"title": "Attack", | |
"entries": [ | |
{ | |
"label": "Attack 01", | |
"value": "katana-animations://data/Assets/KatanaAnimations/attack_01.anim" | |
}, | |
{ | |
"label": "Attack 02", | |
"value": "katana-animations://data/Assets/KatanaAnimations/attack_02.anim" | |
}, | |
{ | |
"label": "Attack 03", | |
"value": "katana-animations://data/Assets/KatanaAnimations/attack_03.anim" | |
}, | |
{ | |
"label": "Jump Attack", | |
"value": "katana-animations://data/Assets/KatanaAnimations/attack_jump.anim" | |
} | |
] | |
}, | |
{ | |
"title": "Combo", | |
"entries": [ | |
{ | |
"label": "Combo 01", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_01.anim" | |
}, | |
{ | |
"label": "Combo 02", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_02.anim" | |
}, | |
{ | |
"label": "Combo 03", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_03.anim" | |
}, | |
{ | |
"label": "Combo 04", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_04.anim" | |
}, | |
{ | |
"label": "Combo 05", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_05.anim" | |
}, | |
{ | |
"label": "Combo 06", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_06.anim" | |
}, | |
{ | |
"label": "Combo 07", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_07.anim" | |
}, | |
{ | |
"label": "Combo 08", | |
"value": "katana-animations://data/Assets/KatanaAnimations/combo_08.anim" | |
} | |
] | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Newtonsoft.Json; | |
using UMod; | |
using UnityEngine; | |
using Warudo.Core; | |
using Warudo.Core.Attributes; | |
using Warudo.Core.Data; | |
using Warudo.Core.Plugins; | |
using Warudo.Core.Resource; | |
namespace KatanaAnimations { | |
/** | |
** An example plugin that adds some katana animations to any character animation dropdown (such as Character -> Default Idle Animation). | |
**/ | |
[PluginType(Id = "KatanaAnimations", Name = "Katana Animations", Description = "Provides katana animations.", Author = "TigerHix", Version = "1.0.0")] | |
public class KatanaAnimationsPlugin : Plugin { | |
protected override void OnCreate() { | |
// Load animations from a JSON file. | |
// ModHost.Assets.Load is similar to Unity's Resources.Load, but you use the former in Warudo Mods. | |
// The path here is the relative path (i.e. from Unity project root) of the asset you are trying to load. Must start with "Assets/". | |
var json = ModHost.Assets.Load<TextAsset>("Assets/KatanaAnimations/Animations.json"); | |
if (json == null) { | |
Debug.LogError("[KatanaAnimations] Failed to load Animations.json"); | |
return; | |
} | |
// Here we deserialize the JSON into an autocomplete list (that is used for providing data in Warudo's dropdown menus). | |
// You can of course deserialize into your own data format, but you will have to convert it to an AutoCompleteList to display it in the menu anyway, so formatting your data as AutoCompleteList is more straightforward. | |
var animationCatalog = JsonConvert.DeserializeObject<AutoCompleteList>(json.text); | |
// Register a resource provider and resource resolver. | |
// Resource URIs in Warudo are just... URIs. For example: | |
// A prop in the Props folder: prop://data/MyProp.warudo | |
// A character in a workshop item: character://workshop/123456789/Character.warudo (123456789 is workshop item ID) | |
// These URIs are internal to Warudo, so when creating/loading prop & character mods, you don't see them. | |
// | |
// However, since we are trying to provide animations from our mod folder, we need to define our custom URI format. | |
// Here, we define our URI as: katana-animations://data/animation_filename | |
// We register a provider that will provide a list of animations included in the mod, which is read from the JSON above. | |
// We also register a resolver, that will create the Unity AnimationClip based on a URI that matches our format. | |
var rm = Context.ResourceManager; | |
rm.RegisterProvider(new KatanaAnimationsAnimationResourceProvider(animationCatalog), this); | |
rm.RegisterUriResolver(new KatanaAnimationsAnimationResourceUriResolver(ModHost), this); | |
} | |
public class KatanaAnimationsAnimationResourceProvider : IResourceProvider { | |
// This is the section title that is shown in the dropdown menu | |
public string ResourceProviderName => "Katana Animations"; | |
private readonly AutoCompleteList catalog; | |
internal KatanaAnimationsAnimationResourceProvider(AutoCompleteList catalog) { | |
this.catalog = catalog; | |
} | |
public List<Resource> ProvideResources(string query) { | |
// Query is the "resource type". For example, in the Character asset, the Default Idle Animation data input is defined as: | |
// | |
// [DataInput] | |
// [AutoCompleteResource("CharacterAnimation")] | |
// public string DefaultIdleAnimation; | |
// | |
// When the user opens the dropdown, Context.ResourceManager.ProvideResources("CharacterAnimation") is called. Then every provider is queried to check if they can provide resource URIs for the resource type "CharacterAnimation". | |
// | |
if (query == "CharacterAnimation") { | |
// Map JSON entries to a list of Resources. | |
return catalog.categories.SelectMany(category => { | |
return category.entries.Select(it => new Resource { | |
category = category.title, | |
label = it.label, | |
uri = new Uri(it.value) | |
}); | |
}).ToList(); | |
} | |
return null; | |
} | |
} | |
public class KatanaAnimationsAnimationResourceUriResolver : IResourceUriResolver { | |
private readonly ModHost modHost; | |
internal KatanaAnimationsAnimationResourceUriResolver(ModHost modHost) { | |
this.modHost = modHost; | |
} | |
public object Resolve(Uri uri) { | |
// Check if the URI is in the format: katana-animations://data/XXXX | |
if (uri.Scheme != "katana-animations" || uri.Authority != "data") return null; | |
// Parse filename from URI | |
var path = uri.LocalPath.TrimStart('/'); | |
// Load that file from the mod | |
return modHost.Assets.Load<AnimationClip>(path); | |
} | |
} | |
} | |
} |
Built-in resource types and what URI resolvers are expected to return:
Character
- expectsGameObject
CharacterAnimation
(e.g. Character, Play Character Idle Animation node) - expectsAnimationClip
Environment
- expectsScene
orValueTuple<ModHost, Scene>
Image
(e.g. Screen) - expectsWarudo.Plugins.Core.Utils.ImageResource
Music
(e.g. Music Player) - expectsstring
(absolute file path)Particle
(e.g. Throw Prop At Character node) - expectsGameObject
Prop
- expectsGameObject
Sound
(e.g. Play Sound node, Throw Prop At Character node) - expectsAudioClip
Video
(e.g. Screen) - expectsstring
(absolute file path)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: Animation files are not included for obvious reasons. In this example, they are located under
Assets/KatanaAnimations/
.