LogoLogo
  • Get Started
  • Getting Started
    • Initial Setup
    • Create Your First Game
    • API Reference
    • Build Your First World Map
    • Multiplayer Testing
    • Use Templates & Examples
    • Styling & Assets
      • Modeling Guidelines
      • Texturing Guidelines
      • Default Assets
  • Build Faster With AI Tools
  • SDK Guides
    • Assets
    • Audio & SFX
      • Audio Manager
    • Blocks & Chunks
      • Block Types
      • Block Type Registry
      • Chunks
      • Chunk Lattice
    • Camera
    • Chat & Commands
    • Debugging
    • Entities
      • Animations
      • Block Entities
      • Colliders & Hitbox
      • Child Entities
      • Entity Controllers
        • Base Entity Controller
        • Pathfinding Entity Controller
        • DefaultPlayer Entity Controller
        • Simple Entity Controller
      • Entity Manager
      • Model Entities
      • Movement & Pathfinding
      • Player Controlled Entities
    • Events
    • Input & Controls
    • Lighting
      • Ambient Light
      • Light Manager
      • Point Lights
      • Spot Lights
      • Sun Light (Directional)
    • Mobile
    • Persisted Data
    • Players
      • Player Manager
      • Persisted Player Data
    • Plugins
    • Physics
      • Colliders
      • Collision Groups
      • Debugging
      • Gravity
      • Raycasts
      • Rigid Bodies
    • User Interface
      • Overlay UI
      • Scene UIs
      • Scene UI Manager
    • Worlds
      • Map Data Format
  • Helpful Resources
    • HYTOPIA Architecture & Platform Overview
    • Useful Third-Party Tools
Powered by GitBook
On this page
  • GLTF Animations
  • Types Of Animations
  • Animation Blending & Playback
  • Starting And Stopping Animations
  • One-shot Animations
  • Animations & Entity Colliders
Export as PDF
  1. SDK Guides
  2. Entities

Animations

PreviousEntitiesNextBlock Entities

Last updated 9 days ago

, which are entities that have a modelUri when created, can have their in-game animation state completely controlled and blended using the Entity animation methods.

Animations do not work with .

GLTF Animations

The HYTOPIA SDK expects all possible animations of a model to be included in a model's .gltf file. Model animations are referenced by their name. For example, if your .gltf file has an animation called idle that you want to play and loop as soon as an entity spawns, you'd do that as follows:

const myEntity = new Entity({
  modelUri: 'models/npcs/cow.gltf',
  modelLoopedAnimations: [ 'idle' ], // animations here will play looped when entity spawns
  // .. the rest of your entity options
});

Types Of Animations

HYTOPIA currently supports two types of animations.

  • Looped Animations - These are animations that will contiue to play over and over again from start to finish in a smooth manner until they are explicitly stopped.

  • One-shot Animations - These are animations that will play from start to finish only once, or until they are explicitly stopped or restarted.

Animation Blending & Playback

At this time, all played animations for a model entity are equally blended in the visual playback state of the entity in game. This means you can play multiple GLTF model animations at the same time and they will blend equally between the same model node that may be involved in multiple playing animations.

Starting And Stopping Animations

For model entities, we can easily start, stop and filter the played animations of an entity. Here's an example of how our DefaultCharacterController internally handles animation state changes based on player inputs.

Animation state is internally tracked - so invoking start or stop of animations that are in an irrelevant state won't cause unusual animation states or performance overhead.

// tickPlayerMovement is a method from BaseCharacterController
// it is called each tick when associated with an entity
// controlled by a player (PlayerEntity)
public tickPlayerMovement(inputState: PlayerInputState, orientationState: PlayerOrientationState, deltaTimeMs: number) {
  // current pressed keystate of the controlling 
  // player of the entity  has pressed this tick.
  const { w, a, s, d, sp, sh, ml } = inputState;
  
  // ... Other character controller logic

  if (this.isGrounded && (w || a || s || d)) {
    if (isRunning) {
      // Stop all animations that aren't run
      this.entity.stopModelAnimations(Array.from(this.entity.modelLoopedAnimations).filter(v => v !== 'run'));
      // Play run animation, if it's already playing it won't be restarted since it's looped
      this.entity.startModelLoopedAnimations([ 'run' ]);
    } else {
      // Stop all animations that aren't walk
      this.entity.stopModelAnimations(Array.from(this.entity.modelLoopedAnimations).filter(v => v !== 'walk'));
      // Play walk animation, if it's already playing it won't be restarted since it's looped
      this.entity.startModelLoopedAnimations([ 'walk' ]);
    }
  } else {
    // Stop all animations that aren't idle
    this.entity.stopModelAnimations(Array.from(this.entity.modelLoopedAnimations).filter(v => v !== 'idle'));
    // Play idle animation, if it's already playing it won't be restarted since it's looped
    this.entity.startModelLoopedAnimations([ 'idle' ]);
  }
  
  if (ml) { // player pressed the left mouse button
    // Play our animation named 'simple_interact' once./
    this.entity.startModelOneshotAnimations([ 'simple_interact' ]);
  }
  
  // ... Other character controller logic
}

One-shot Animations

One-shot animations are exactly what they sound like. An animation that plays only once. This is great for things like a gun-shooting effect when the player presses a button in game to fire a weapon, or a movement of a player's hand each time they click to interact with something, etc.

Let's assume our PlayerEntity model assigned to a player when they join a game has a dance animation, and a hand waving animation called wave. We'll play then as a one-shot when a player joins.

world.on(PlayerEvent.JOINED_WORLD, ({ player }) => {
  const playerEntity = new DefaultPlayerEntity({
    player,
    name: 'Player',
  });
  
  playerEntity.spawn(world, { x: 0, y: 10, z: 0 });
  
  // Note: An entity must be spawned to start/stop animations,
  // otherwise the invoked animation methods will throw an error.
  
  // dance and wave animation is assumed to exist in the my-player.gltf
  // file. Both animations will play and blend together.
  playerEntity.startModelOneshotAnimations([ 'dance', 'wave' ]);
});

Animations & Entity Colliders

It's important to note that the animation state of model entities is entirely visual. Played animations will not automatically alter or move the collider(s) of an entity even if the entity is visually moving relative to it's collider because of the animation.

If you need your collider to move along with the animation state played, you'll need to implement this manually with your own timings and logic to alter the translation and rotation of the entity collider(s) relative to the animation played.

Model Entities
Block Entities
Run, walk and idle animations based on our WASD player inputs for movement.