How to Define Prefabs: Prelude

This page is not a guide, but since prefabs are extremely complicated, this is a dedicated page to help you choose which guide to use.

If you are looking for a guide for how to define prefab data that combines the components of multiple existing prefabs, please see How to Define Prefabs: Aggregate.

If you are looking for a guide to define prefab data for a Component, first we need to figure out its type based on its serialized representation. The following table summarizes the types, and links to the relevant guide. For additional detail, refer to the code snippets below the table.

ComponentSerialized representationExample(s)Prefab DataGuide
YourTypeSelfYourTypePositionPositionSimple
YourTypeMultiple – V1(..), V2(..)CameraCameraPrefabAdapter
YourTypeSubset of YourTypeAudioListenerAudioPrefabAsset
Handle<A>Loaded from A::DataMesh, TextureMeshData, TexturePrefabAsset
ManyHandlesData that component stores handles ofMaterialMaterialPrefabMulti-Handle

Serialized Representation

  • Self

    This is where the Component type itself is completely serializable – the data is self-contained.

    extern crate amethyst;
    extern crate serde;
    
    use amethyst::ecs::{storage::DenseVecStorage, Component};
    use serde::{Deserialize, Serialize};
    
    #[derive(Component, Debug, Deserialize, Serialize /* .. */)]
    pub struct Position(pub f32, pub f32, pub f32);
    

    Applicable guide: How to Define Prefabs: Simple.

  • Multiple

    This is where are multiple ways to construct the component, and a user should be able to choose which one to use.

    extern crate amethyst;
    extern crate serde;
    
    use amethyst::ecs::{storage::DenseVecStorage, Component};
    use serde::{Deserialize, Serialize};
    
    #[derive(Component, Debug, Deserialize, Serialize /* .. */)]
    pub struct Position {
        pub x: f32,
        pub y: f32,
        pub z: f32,
    };
    
    impl From<(i32, i32, i32)> for Position {
        fn from((x, y, z): (i32, i32, i32)) -> Position {
            Position {
                x: x as f32,
                y: y as f32,
                z: z as f32,
            }
        }
    }
    
    impl From<(f32, f32, f32)> for Position {
        fn from((x, y, z): (f32, f32, f32)) -> Position {
            Position { x, y, z }
        }
    }
    

    Applicable guide: How to Define Prefabs: Adapter.

  • Component Subset

    This is where most of the component is serializable, but there is also data that is only accessible at runtime, such as a device ID or an asset handle.

    extern crate amethyst_audio;
    extern crate amethyst_core;
    
    use amethyst_audio::output::Output;
    use amethyst_core::{
        math::Point3,
        ecs::{storage::HashMapStorage, Component},
    };
    
    #[derive(Debug, Component)]
    #[storage(HashMapStorage)]
    pub struct AudioListener {
        /// Output used by this listener to emit sounds to
        pub output: Output, // <--- NOTE: Only available at runtime
        // ..
        /// Position of the left ear relative to the global transform on this entity.
        pub left_ear: Point3<f32>,
        /// Position of the right ear relative to the global transform on this entity.
        pub right_ear: Point3<f32>,
    }
    

    Applicable guide: How to Define Prefabs: Asset.

  • Asset

    When using Handle<A> as a component, A must impl Asset, and therefore A::Data must be serializable.

    This is where you want to load A as part of a prefab.

    Applicable guide: How to Define Prefabs: Asset.

  • Multi-Handle

    This is where the Component itself stores Handle<_>s.

    extern crate amethyst;
    
    use amethyst::{
        assets::Handle,
        ecs::{storage::DenseVecStorage, Component},
        renderer::Texture,
    };
    
    /// Material struct.
    #[derive(Clone, PartialEq)]
    pub struct Material {
        /// Diffuse map.
        pub albedo: Handle<Texture>,
        /// Emission map.
        pub emission: Handle<Texture>,
        // ..
    }
    
    impl Component for Material {
        type Storage = DenseVecStorage<Self>;
    }
    

    Applicable guide: How to Define Prefabs: Multi-Handle.