Models & Flats

Prerequisites


Explores and exports all of Daggerfall’s 3D models, cities, and dungeons.
Works like a visual atlas for searching and exploring anywhere in Daggerfall’s world.

Opens and exports Daggerfall’s image files, including billboard textures.

The code library that interfaces between Daggerfall’s DOS game files and Daggerfall Unity. The included Importer allow to explore specifics models and billboards (disable Billboard Batch) as well as towns and dungeons layouts. Your best option is to download Daggerfall Unity from Github (video tutorial), as it contains all the tools and it allows to test models directly in game.

Core Features


Common

Once you have the Unity Editor running, you can import a model placing a fbx or obj file in a subfolder of  Assets, for example Assets/Resources/Models, Assets/Resources/Flats or Assets/Game/Addons/MyMod. You can find all required informations about Unity and Models at this page, but here are provided the essential parts.

  • Models exported from Daggerfall Modelling are forty times bigger than they need to be in order to be used in Unity, so you need to scale them down by 0.025.
  • Unity engine reads models as Y-up not Z-up so you need to address this in your modelling software. If is blender, you can use this plugin.
  • Your model can’t have more than 65,534 vertices. If needed, split your model in several parts and put them together inside a prefab. You can also include additional components such as lights and particle effects.
  • If the model is supposed to collide with the player, check Generate colliders in the mesh inspector inside the Unity editor.
  • When you replace an exterior model, is a good idea to provide a LOD Group.
  • Wind is natively supported for SpeedTrees and trees created with the Unity Tree Creator. Additionally, it can affect particle systems through the External Forces module.
  • When you build a mod you only need to pack this parent mesh/prefab; children such as meshes, materials, particle effects etc. are automatically imported.
  • Materials named Archive_Record-0 will be affected by custom textures provided by loose files.

Models

Model replacements included with a mod are automatically seeked by filename, which must correspond to the numeric index as shown by Daggerfall Modelling.

Replacements aren’t limited to static meshes. Any GameObject (Prefab when serialized in editor) is supported, provided that all components on the object are known by the game (the topic of custom components is addressed here). For example, this means that you can include particle systems or additional lights.

There is a standard naming to support Daggerfall season and climate variations, as shown in the list below:

  1. ID
  2. ID_ClimateSeason (1)

(1) Desert has no seasons: use ID_Desert.

Climates

  • Desert
  • Mountain
  • Temperate
  • Swamp

Seasons

  • Fall
  • Spring
  • Summer
  • Winter

The base name is used as a per-mod fallback, following load order. The base name (meaning the ID) matches everything. For example a mod that only provides base models can be extended by other mods with specific seasons and climates, while the base model is still used for the non-provided seasons and climates. But if mod with base is loaded in a lower position, load order is respected and “overrides” everything.

Flats

The original game used billboards (sprites) to render characters, enemies, animals and small props instead of 3d models. While is possible to only replace billboard textures, providing a full 3d replacement is also supported. Prefabs must be named archive_record, as they appear from Daggerfall Imaging, and bundled in a mod as usual.

These models are placed in game assuming the origin is at the center of their base, while rotation on the up axis is randomized to make up for the camera-following movement of 2d billboards (this process can be customized via scripting by adding a component that extends IObjectPositioner).

Mobile Person Assets

It is possible to write a Monobehaviour class that handles the instantiation process for npcs graphic assets, meaning the people that wanders around towns. This component must inherit from MobilePersonAsset and be added to a prefab named MobilePersonAsset. This component will serve as a provider for wandering npcs, replacing  MobilePersonBillboard class.

using UnityEngine; using DaggerfallWorkshop;
using DaggerfallWorkshop.Game.Entity;
using DaggerfallWorkshop.Game.Utility.ModSupport;

namespace MobilePersonCubeMod
{
    [ImportedComponent]
    public class MobilePersonCube : MobilePersonAsset
    {
        MeshRenderer meshRenderer;

        public override bool IsIdle { get; set; }
        
        private void Awake()
        {
            meshRenderer = GetComponent<MeshRenderer>();
        }

        public override void SetPerson(Races race, Genders gender, int personVariant, bool isGuard, int personFaceVariant, int personFaceRecordId)
        {
            Vector3 size = GetSize();
            Trigger.height = size.y * 1.2f;
            Trigger.radius = size.x * 1.2f;
        }

        public override Vector3 GetSize()
        {
            return meshRenderer.bounds.size;
        }
    }
}

Advanced


Object Positioner

Props and sprites in Daggerfall are often bad positioned and this becomes apparent with high screen resolutions and higher quality assets. A component named ObjectPositioner is provided to fix most of these offending situations, such as houses furniture or dungeon treasures. This component has a direction property, which is the local space oriented axis along which the asset is transitioned.

Custom positioning can also be achieved with any component that implements the IObjectPositioner interface.

Wall Prop Positioner

Normally, models are instantiated with the same rotation as originals while flat replacements have a random rotation for increased variety.  There are some situations, though, where a random rotation is not appropriate. Wall torches, for example, are camera-facing billboards in the original game, but when we replace them with a 3d model we want them to have a specific position; unfortunately this is not immediate because the rotation amount for every torch is not specified in the game: it’s simply not necessary for billboards.

To overcome this issue we can use a component which will find the position of the wall at run time and rotate the torch accordingly. This one can be found under the name WallPropPositioner

FaceWall

OBSOLETE: Use WallPropPositioner

Normally, models are instantiated with the same rotation as originals while flat replacements have a random rotation for increased variety.  There are some situations, though, where a random rotation is not appropriate. Wall torches, for example, are camera-facing billboards in the original game, but when we replace them with a 3d model we want them to have a specific position; unfortunately this is not immediate because the rotation amount for every torch is not specified in the game: it’s simply not necessary for billboards.

To overcome this issue we can use a script which will find the position of the wall at run time and rotate the torch accordingly. This can be found in the inspector of the Unity editor and added as a component of the GameObject (Add Component).

Max Distance

The wall will be seeked inside this radius. Big values can cause wrong results.

Align To Wall 

Make the GameObject parallel to non-straight walls.

Minor Angle To Ignore

REMOVED: this is now deprecated

Angles lower than this will be ignored.

Rotation Correction

REMOVED: this is now deprecated

The actual rotation is corrected by this value to take small inaccuracies into account.

Move Near Wall

Translate the GameObject so that it touches the wall.

Fix Clipping

REMOVED: this is now always true

Fix issue where GameObject clips with the wall if the origin is next to it.

Destroy On Bad Position

REMOVED: this is now always false

Remove the GameObject if it can’t be positioned correctly.

DayNight

Daggerfall has dinamic changes during the day time flow; for example towns buildings have a light blue emission map for windows when the sun is up, while a yellow map is used at night.

To reproduce this behaviour on imported models we can use the component DayNight, which can also toggle lights and particles of lamps and torches.

Toggle Lighting

Turn on lights and particles at night time, turn them off at day time.

  • SelectedOnly: Toggle only selected lights and particle.
  • All: Toggle all lights and particle in the prefab and its children.

Particles

Selected Particle Systems  (only for SelectedOnly).

Lights

Selected Lights  (only for SelectedOnly).

Emission Colors

Update the color applied to the emissive material according to day time.

  • NoColors: Does nothing.
  • DaggerfallColors: Use Daggerfall colors.
  • CustomColors: Use specified colors.

Material Index

The index for the MeshRenderer of the material whose emission color will be dinamically changed (only for DaggerfallColors and CustomColors).

This is found from Inspector -> Mesh Renderer -> Materials.  This material can (and typically should) have an emission map, while emission color and emission strength will be overridden with day and night colors and strengths.

Day Color

The HDR color applied to the emission map at day time (only for CustomColors).

Daggerfall Unity default is #406E80.

Night Color

The HDR color applied to the emission map at night time (only for CustomColors).

Daggerfall Unity default is #CC922D.

Doors

Exteriors

Transition from exterior to interior is implemented through a trigger placed in the same position as the door on the mesh. This trigger is indipendent from the mesh, so there aren’t any troubles with imported building as long as the door is in the same position as the original.

Nevertheless, sometime you may want to slightly alter the door position for aesthetic purposes. In this case it’s possible to include with your model both a textured door which is visible in the game and an invisible door in the correct position which acts as the collider for the trigger effect.

This is as simple as a planar mesh, with the same size of the door and enabled Generate Colliders. To achieve transparency set the material rendering mode to Cutout and albedo to a color with full alpha, for example #00000000.

There is also an experimental component named CustomDoor which allows to defines door positions with triggers.

Interiors

There are two prefabs for doors, DaggerfallActionDoor [Interior] and DaggerfallActionDoor [Dungeon], both of them placed inside Assets/Prefabs/Scene. The entire action door prefab is replaced when models with the corresponding  model ID are provided, so mod authors need to ensure that DaggerfallActionDoor, DaggerfallAudioSource and other required components (or compatible replacements) are present.