Skip to content

Instantly share code, notes, and snippets.

@Naraenda
Last active January 27, 2026 16:02
Show Gist options
  • Select an option

  • Save Naraenda/68a237fffb6eeef1af00dc54c9acd9b1 to your computer and use it in GitHub Desktop.

Select an option

Save Naraenda/68a237fffb6eeef1af00dc54c9acd9b1 to your computer and use it in GitHub Desktop.
Warudo ARKit To Unified Expressions Node Test
using UnityEngine;
using System.Collections.Generic;
using Warudo.Core.Attributes;
using Warudo.Core.Graphs;
using Warudo.Core.Scenes;
using Warudo.Plugins.Core.Assets;
using Warudo.Plugins.Core.Assets.Cinematography;
[NodeType(
Id = "545a376a-050f-4b4d-8b6c-c6a46b168f36",
Title = "Convert ARKit To UE",
Category ="Character")]
public class ConvertARKitToUnifiedExpressions : Node {
Dictionary<string, (string, float)[]> conversions = new()
{
// EyeLook
{"EyeLookOutLeft" , new[] { ("eyeLookOutLeft" , 1.0f) }},
{"EyeLookOutRight" , new[] { ("eyeLookOutRight" , 1.0f) }},
{"EyeLookInLeft" , new[] { ("eyeLookInLeft" , 1.0f) }},
{"EyeLookInRight" , new[] { ("eyeLookInRight" , 1.0f) }},
{"EyeLookUpLeft" , new[] { ("eyeLookUpLeft" , 1.0f) }},
{"EyeLookUpRight" , new[] { ("eyeLookUpRight" , 1.0f) }},
{"EyeLookDownLeft" , new[] { ("eyeLookDownLeft" , 1.0f) }},
{"EyeLookDownRight" , new[] { ("eyeLookDownRight" , 1.0f) }},
// EyeBlink
{"EyeClosedLeft" , new[] { ("eyeBlinkLeft" , 1.0f) }},
{"EyeClosedRight" , new[] { ("eyeBlinkRight" , 1.0f) }},
// EyeSquint
{"EyeSquintLeft" , new[] { ("eyeSquintLeft" , 1.0f) }},
{"EyeSquintRight" , new[] { ("eyeSquintRight" , 1.0f) }},
// EyeWide
{"EyeWideLeft" , new[] { ("eyeWideLeft" , 1.0f) }},
{"EyeWideRight" , new[] { ("eyeWideRight" , 1.0f) }},
// Brow
{"BrowDownLeft" , new[] { ("browDownLeft" , 1.0f) }},
{"BrowDownRight" , new[] { ("browDownRight" , 1.0f) }},
{"BrowInnerUp" , new[] { ("browInnerUp" , 1.0f) }},
{"BrowOuterUpLeft" , new[] { ("browOuterUpLeft" , 1.0f) }},
{"BrowOuterUpRight" , new[] { ("browOuterUpRight" , 1.0f) }},
// Cheeks
{"CheekSquintLeft" , new[] { ("cheekSquintLeft" , 1.0f) }},
{"CheekSquintRight" , new[] { ("cheekSquintRight" , 1.0f) }},
{"CheekPuffLeft" , new[] { ("cheekPuff" , 1.0f) }},
{"CheekPuffRight" , new[] { ("cheekPuff" , 1.0f) }},
// Jaw
{"JawOpen" , new[] { ("jawOpen" , 1.0f) }},
{"JawLeft" , new[] { ("jawLeft" , 1.0f) }},
{"JawRight" , new[] { ("jawRight" , 1.0f) }},
{"JawForward" , new[] { ("jawForward" , 1.0f) }},
{"MouthClosed" , new[] { ("mouthClose" , 1.0f) }},
// Lip
{"LipSuckUpper" , new[] { ("mouthRollUpper" , 1.0f) }},
{"LipSuckLower" , new[] { ("mouthRollLower" , 1.0f) }},
{"LipFunnel" , new[] { ("mouthFunnel" , 1.0f) }},
{"LipPucker" , new[] { ("mouthPucker" , 1.0f) }},
// Mouth
{"MouthUpperUpLeft" , new[] { ("mouthUpperUpLeft" , 1.0f) }},
{"MouthUpperUpRight" , new[] { ("mouthUpperUpRight" , 1.0f) }},
{"MouthLowerDownLeft" , new[] { ("mouthLowerDownLeft" , 1.0f) }},
{"MouthLowerDownRight", new[] { ("mouthLowerDownRight", 1.0f) }},
{"MouthLeft" , new[] { ("mouthLeft" , 1.0f) }},
{"MouthRight" , new[] { ("mouthRight" , 1.0f) }},
// MouthSmile
{"MouthSmileLeft" , new[] { ("mouthSmileLeft" , 1.0f) }},
{"MouthSmileRight" , new[] { ("mouthSmileRight" , 1.0f) }},
// MouthSmile
{"MouthFrownLeft" , new[] { ("mouthFrownLeft" , 1.0f) }},
{"MouthFrownRight" , new[] { ("mouthFrownRight" , 1.0f) }},
// MouthStretch
{"MouthStretchLeft" , new[] { ("mouthStretchLeft" , 1.0f) }},
{"MouthStretchRight" , new[] { ("mouthStretchRight" , 1.0f) }},
// MouthDimple
{"MouthDimpleLeft" , new[] { ("mouthDimpleLeft" , 1.0f) }},
{"MouthDimpleRight" , new[] { ("mouthDimpleRight" , 1.0f) }},
// MouthRaiser
{"MouthRaiserUpper" , new[] { ("mouthShrugUpper" , 1.0f) }},
{"MouthRaiserLower" , new[] { ("mouthShrugLower" , 1.0f) }},
// MouthDimple
{"MouthPressLeft" , new[] { ("mouthPressLeft" , 1.0f) }},
{"MouthPressRight" , new[] { ("mouthPressRight" , 1.0f) }},
// MouthTightener
{"MouthTightenerLeft" , new[] { ("mouthPressLeft" , 1.0f) }},
{"MouthTightenerRight", new[] { ("mouthPressRight" , 1.0f) }},
// Tongue
// {"TongueOut", new[] { ("tongueOut", 1.0f) }},
};
// We save the dictionary seperately as it's more performant!
private Dictionary<string, float> shapes = new Dictionary<string, float>();
[DataInput]
[Label("ARKit BlendShapes List")]
public Dictionary<string, float> ARKBlendshapes;
[DataOutput]
[Label("UE BlendShapes List")]
public Dictionary<string, float> UEBlendshapes(){
// For every converted shapekey we need to make...
foreach(var (shape, weights) in conversions){
// Sum up according to the weights
float sum = 0;
// By looking at each weight
foreach(var (source, weight) in weights){
// If we can find the source shape
if (ARKBlendshapes.ContainsKey(source)) {
// Add it to our sum!
sum += ARKBlendshapes[source];
}
}
// Finally add the shapekey to our dictionary!
shapes[shape] = sum;
}
return shapes;
}
}
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non-commercial, and by any
// means.
//
// In jurisdictions that recognize copyright laws, the author or authors
// of this software dedicate any and all copyright interest in the
// software to the public domain. We make this dedication for the benefit
// of the public at large and to the detriment of our heirs and
// successors. We intend this dedication to be an overt act of
// relinquishment in perpetuity of all present and future rights to this
// software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to <https://unlicense.org>
@Naraenda
Copy link
Author

My old tracking stuff always emits tongout for some reason. If it works for you then you should definitely keep it enabled 🐱

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment