Character

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 on a Unit

CharacterFeature is the IUnitFeature that wires a Unit to its 3D presence:

csharp
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.

The face

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:
    1. Expression layer: a crossfade from a snapshot of the current face to a target 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.
    2. Blink: 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.
    3. Mid-path corrections: a shape named 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.

Kind-driven visuals

  • 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.
  • Expression keys are whatever your FaceExpressionCatalog holds; the package defines none.

Sub-systems

  • 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.
  • Timeline: ExpressionTrack binds a FaceController; ExpressionClip plays a FaceExpressionSO.

Asmdef + namespace

CupkekGames.Character (runtime), CupkekGames.Character.Editor (inspectors, FaceRigValidator).

Dependencies

  • com.cupkekgames.units (for IUnitFeature + UnitView)
  • com.cupkekgames.data (for AssetCatalog)
  • com.cupkekgames.animations (for IAnimationStateController + AnimationKinds)
  • Plus the foundation set used by HumonoidCharacter: services, timesystem, addressableassets, scenemanagement, sequencer, settings, gamesave, vfx

Upgrading from 0.3

0.4.0 replaces the blend-shape system:

0.30.4
BlendShapeControllerFaceController (same script GUID; renderers are collected automatically)
BlendShapeListSOFaceExpressionSO (same script GUID; list only non-zero channels)
BlendShapeDatabaseFaceExpressionCatalog + FaceExpressions
BlendShapeDatabaseVFXEmoteVFXDatabase (same script GUID)
BlendShapeKindsyour catalog's keys
BlendShapeListBlend, AutoExpression, AutoExpressionListremoved
HumonoidCharacter.PlayExpression(database, kind, duration)PlayExpression(key, holdSeconds)
CharacterFeature.BlendShapeControllerCharacterFeature.Face

Repository

Cupkek-Games/CupkekGames-Character

Settings

Theme

Light

Contrast

Material

Dark

Dim

Material Dark

System

Sidebar(Light & Contrast only)

Light
Dark

Font Family

DM Sans

Wix

Inclusive Sans

AR One Sans

Direction

LTR
RTL