com.cupkekgames.character: humanoid character primitives. Bundles model spawn, animation engine, a layered face (expressions, blink, eye aim), eye movement, and slot-based accessories into a single CharacterFeature you attach to any Unit. Visual vocabularies are string keys, so domain games extend them without forking the package.
CharacterFeature is the IUnitFeature that wires a Unit to its 3D presence:
unit.AddFeature(new CharacterFeature());
// after spawning the prefab via your pool/scene:
unit.GetFeature<CharacterFeature>().SetCharacter(spawnedGameObject);
var feature = unit.GetFeature<CharacterFeature>();
feature.AnimationController.Play(AnimationKinds.Idle);
feature.Character.PlayExpression("Joy", holdSeconds: 2f);The feature exposes the resolved sub-systems (AnimationEngine, AnimationController, Face, EyeMovement) so callers route through one entry point. The matching CharacterDefinition (an IUnitFeatureDefinition) carries the prefab reference (ModelCharacterSO) on the unit's UnitDefinitionSO.
A face is often split across many meshes (face, brows, lashes, eyes, teeth, tongue), each carrying only the shape keys that move it. The face system treats all of them as one face.
FaceRig binds every child SkinnedMeshRenderer with shape keys, by shape name. One channel name (jawOpen) drives every mesh that has it, and blendshape indices are resolved at bind time, so a re-export that reorders shapes changes nothing.FaceController composes the face once per frame, after animation, and writes each channel once:
FaceExpressionSO. Play(expression, holdSeconds) returns to the rest face when the hold ends; SetRest changes the rest face (a mood face, for example). Snap and ApplyNow write immediately, for edit-mode preview.Blink01 closes the blink channels (eyeBlinkLeft / eyeBlinkRight by default). Each expression declares a FaceBlinkPolicy; faces whose eyes are already shaped closed use Suppress, and the gate crossfades with the face.X_mid stores the correction between the linear halfway shape of X and the right one. It is driven automatically from X's weight on a triangle (0 at both ends, 100 at the midpoint). Meshes without _mid keys are unaffected.
Channels no expression or blink ever touched are never written, so body shape keys keep their authored values.FaceExpressionSO is an absolute state: it lists only the channels that move, and every channel it does not list is 0 while it shows. Switching faces never leaves residue.FaceExpressionCatalog (an AssetCatalog<FaceExpressionSO>) maps keys (Neutral, Joy, …) to expressions. FaceExpressions.GetRequired(key) searches every registered catalog and throws on an unknown key.Blinker blinks at random intervals by driving Blink01. It knows no shape names and runs under every expression.EyeAim aims both eyes at the look-at target after animation, in parallel (one rotation for both, so near targets never cross the eyes), clamped to a maximum angle. Eye bones default to the Animator's humanoid eye bones and the target to HumonoidCharacter.EyeTarget.EmoteVFXDatabase (optional) maps expression keys to emote VFX, played by HumonoidCharacter.PlayExpression.FaceRigValidator.Check(character, expressions) (editor) checks a character against the contract: meshes named like bones (which can silently turn a Humanoid rig Generic), invalid avatars, shape keys that rest non-zero, X_mid keys without X, missing blink channels or rest face, missing Blinker / EyeAim, and expression channels the face lacks. Run it from tests over your character prefabs.
AnimationClipKinds: character clips (Walking, Waving, Talking01, JumpForJoy, Cheer1, Mining, ChestOpen, …). Keyed by AnimationDatabase.VisualAccessoryRoleKinds: accessory slot roles (DEFAULT, MINING). Saved on CharacterVisualAccessory.Role so a single mesh can be authored once and re-bound per gameplay context.FaceExpressionCatalog holds; the package defines none.HumonoidCharacter (MonoBehaviour, on the prefab): entry point. Resolves FaceController, IAnimationStateController, IAnimationEngine and EyeMovement from children. Exposes Head (the humanoid head bone unless set), EmotionTarget and EyeTarget.AnimationDatabase + AnimatorControllerLayerDatabase: kind-keyed clip lookup, layered controllers.EyeMovement: natural saccade-style movement of the look-at target.CharacterVisualAccessories + CharacterVisualAccessory: slot system for swappable equipped meshes (hats, tools, weapons) keyed by role. Call FaceController.RebuildRig() after swapping meshes that carry face shape keys.ModelCharacterSO: the SO wrapper around the character prefab reference, held on CharacterDefinition.ExpressionTrack binds a FaceController; ExpressionClip plays a FaceExpressionSO.CupkekGames.Character (runtime), CupkekGames.Character.Editor (inspectors, FaceRigValidator).
com.cupkekgames.units (for IUnitFeature + UnitView)com.cupkekgames.data (for AssetCatalog)com.cupkekgames.animations (for IAnimationStateController + AnimationKinds)HumonoidCharacter: services, timesystem, addressableassets, scenemanagement, sequencer, settings, gamesave, vfx0.4.0 replaces the blend-shape system:
| 0.3 | 0.4 |
|---|---|
BlendShapeController | FaceController (same script GUID; renderers are collected automatically) |
BlendShapeListSO | FaceExpressionSO (same script GUID; list only non-zero channels) |
BlendShapeDatabase | FaceExpressionCatalog + FaceExpressions |
BlendShapeDatabaseVFX | EmoteVFXDatabase (same script GUID) |
BlendShapeKinds | your catalog's keys |
BlendShapeListBlend, AutoExpression, AutoExpressionList | removed |
HumonoidCharacter.PlayExpression(database, kind, duration) | PlayExpression(key, holdSeconds) |
CharacterFeature.BlendShapeController | CharacterFeature.Face |
Settings
Theme
Light
Contrast
Material
Dark
Dim
Material Dark
System
Sidebar(Light & Contrast only)
Font Family
DM Sans
Wix
Inclusive Sans
AR One Sans
Direction