Generating navigation mesh – DayZ
No edit summary |
(Removed no longer working links and adjusted the documentation.) |
||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{GameCategory|dayz|Terrain Editing}} | |||
==Overview== | == Overview == | ||
This page describes the basics of generating navigation mesh file (often called 'navmesh') for your terrain. Navmesh for your terrain is not mandatory (game will cope without it), but it contains essential data for the AI (obstacles, door links, jump links,..) without which it wont be able to navigate properly (AI entities will stand frozen on their spawn point). For guaranteed | This page describes the basics of generating navigation mesh file (often called 'navmesh') for your terrain. Navmesh for your terrain is not mandatory (game will cope without it), but it contains essential data for the AI (obstacles, door links, jump links,..) without which it wont be able to navigate properly (AI entities will stand frozen on their spawn point). For guaranteed behavior of the AI, it is '''necessary to re-generate navmesh after each new terrain build''' (each time wrp is binarized to be precise). | ||
Requirements: | Requirements: | ||
Line 10: | Line 9: | ||
* Have a '''working custom terrain''' (mod) files, '''binarized and packed into pbo'''. | * Have a '''working custom terrain''' (mod) files, '''binarized and packed into pbo'''. | ||
==Game config== | == Game config == | ||
In order to get your navmesh generated and then loaded by the game, configuration file (precisely your ''CfgWorlds'' entry) for your terrain '''has to contain Navmesh class'''. This class contains all the necessary parameters for generation and also later use in the game. | In order to get your navmesh generated and then loaded by the game, configuration file (precisely your ''CfgWorlds'' entry) for your terrain '''has to contain Navmesh class'''. This class contains all the necessary parameters for generation and also later use in the game. | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
class CfgWorlds | class CfgWorlds | ||
{ | { | ||
/* ... */ | |||
class yourterrain: CAWorld | |||
{ | { | ||
navmeshName="\path\to\your\navmesh\file.nm"; | /* ... */ | ||
class Navmesh | |||
{ | |||
navmeshName="\path\to\your\navmesh\file.nm"; | |||
filterIsolatedIslandsOnLoad = true; | |||
visualiseOffset = 0.0; | |||
class GenParams | |||
{ | { | ||
tileWidth = 50.0; | |||
cellSize1 = 0.25; | |||
cellSize2 = 0.1; | |||
cellSize3 = 0.1; | |||
filterIsolatedIslands = true; | |||
seedPosition[] = {7500, 0, 7500}; | |||
class Agent | |||
class | |||
{ | { | ||
diameter = 0.6; | |||
standHeight = 1.5; | |||
crouchHeight = 1.0; | |||
proneHeight = 0.5; | |||
maxStepHeight = 0.45; | |||
maxSlope = 60.0; | |||
}; | }; | ||
class | |||
{ | class Links | ||
jumpLength = 1.50; | { | ||
jumpHeight = 0.50; | class ZedJump387_050 | ||
{ | |||
jumpLength = 1.50; | |||
jumpHeight = 0.50; | |||
minCenterHeight = 0.3; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump0"; | |||
flags[] = {"jumpOver"}; | |||
color = 0x66ff0000; | |||
}; | |||
class ZedJump388_050 | |||
{ | |||
jumpLength = 1.50; | |||
jumpHeight = 0.50; | |||
minCenterHeight = -0.5; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump0"; | |||
flags[] = {"jumpOver"}; | |||
color = 0x66dd5500; | |||
}; | |||
class ZedJump387_110 | |||
{ | |||
jumpLength = 3.90; | |||
jumpHeight = 1.1; | |||
minCenterHeight = 0.5; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump0"; | |||
flags[] = {"jumpOver"}; | |||
color = 0x66008000; | |||
}; | |||
class ZedJump420_160 | |||
{ | |||
jumpLength = 4.0; | |||
jumpHeight = 1.6; | |||
minCenterHeight = 1.1; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump0"; | |||
flags[] = {"jumpOver"}; | |||
color = 0x660000ff; | |||
}; | |||
class ZedJump265_210 | |||
{ | |||
jumpLength = 2.45; | |||
jumpHeight = 2.5; | |||
minCenterHeight = 1.8; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump0"; | |||
flags[] = {"climb"}; | |||
color = 0x669400d3; | |||
}; | |||
class Fence50_110deer | |||
{ | |||
typeId = 100; | |||
jumpLength = 8.0; | |||
jumpHeight = 1.1; | |||
minCenterHeight = 0.5; | |||
jumpDropdownMin = 1.0; | |||
jumpDropdownMax = -1.0; | |||
areaType="jump2"; | |||
flags[] = {"jumpOver"}; | |||
color = 0x66aaaaFF; | |||
}; | |||
class Fence110_160deer | |||
{ | |||
typeId = 101; | |||
jumpLength = 8.0; | |||
jumpHeight = 1.6; | |||
minCenterHeight = 1.1; | |||
jumpDropdownMin = 1.0; | |||
jumpDropdownMax = -1.0; | |||
areaType="jump3"; | |||
flags[] = {"jumpOver"}; | |||
color = 0x6624fff8; | |||
}; | |||
class Fence50_110hen | |||
{ | |||
typeId = 110; | |||
jumpLength = 4.0; | |||
jumpHeight = 1.1; | |||
minCenterHeight = 0.5; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump4"; | |||
flags[] = {"jumpOver"}; | |||
color = 0xFFFFAA00; | |||
}; | |||
class Fence110_160hen | |||
{ | |||
typeId = 111; | |||
jumpLength = 4.0; | |||
jumpHeight = 1.6; | |||
minCenterHeight = 1.1; | |||
jumpDropdownMin = 0.5; | |||
jumpDropdownMax = -0.5; | |||
areaType="jump4"; | |||
flags[] = {"jumpOver"}; | |||
color = 0xFFFFAA00; | |||
}; | |||
}; | }; | ||
}; | }; | ||
}; | }; | ||
/* ... */ | |||
}; | }; | ||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 167: | Line 165: | ||
*''seedPosition'' - parameter should ideally be the center of your map (in meters) | *''seedPosition'' - parameter should ideally be the center of your map (in meters) | ||
==Generation process== | == Generation process == | ||
Navmesh generation requires a '''working terrain in the game''', so make sure your terrain contains everything you want and you can access it in the game without any issues (can be done by running the game and using simple empty mission, see workshop item called | Navmesh generation requires a '''working terrain in the game''', so make sure your terrain contains everything you want and you can access it in the game without any issues (can be done by running the game and using simple empty mission, see workshop item called {{Link|https://steamcommunity.com/sharedfiles/filedetails/?id{{=}}1558331009|Sandbox}} for an example). | ||
For the generation itself, you are going to need to do following: | For the generation itself, you are going to need to do following: | ||
* Setup a completely empty mission on your terrain ( | * Setup a completely empty mission (folder should be called empty.yourworldname) on your terrain with a following init.c file: | ||
* | void main() | ||
{ | |||
} | |||
class CustomMission: MissionServer | |||
{ | |||
override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName) | |||
{ | |||
Entity playerEnt; | |||
playerEnt = GetGame().CreatePlayer(identity, characterName, Vector(2681, 0, 10070), 0, "NONE");//Creates random player | |||
Class.CastTo(m_player, playerEnt); | |||
GetGame().SelectPlayer(identity, m_player); | |||
return m_player; | |||
} | |||
override void StartingEquipSetup(PlayerBase player, bool clothesChosen) | |||
{ | |||
player.RemoveAllItems(); | |||
} | |||
}; | |||
Mission CreateCustomMission(string path) | |||
{ | |||
return new CustomMission(); | |||
} | |||
* Use a server config that is pointing to the empty mission (you can take server cfg from the server files for example). | |||
* Run DayZDiag_x64 (located near other game executables, make sure it is not blocked by the firewall) using following parameters: | * Run DayZDiag_x64 (located near other game executables, make sure it is not blocked by the firewall) using following parameters: | ||
DayZDiag_x64 -server -mod=yourmodfolder -startNavmeshDataServer -port=2302 -config=ServerDZNV.cfg | DayZDiag_x64 -server -mod=yourmodfolder -startNavmeshDataServer -port=2302 -config=ServerDZNV.cfg | ||
Line 183: | Line 208: | ||
Be ware of the fact that on a single machine, generation can take quite some time (depends on the size and complexity of the terrain) and can be quite taxing on your HW. | Be ware of the fact that on a single machine, generation can take quite some time (depends on the size and complexity of the terrain) and can be quite taxing on your HW. | ||
==Using the generation output== | == Using the generation output == | ||
After navmesh generation is finished (progress reaches 100%), make sure '''NOT to close the tool''' and use ''File > Save NavMesh''. This will open up a window offering you to choose a location, where the navmesh file can be saved. Make sure to include ''.nm'' at the end of the file-name. The full path should correspond to the one you have defined in the navmesh config (see game config part of this article). | After navmesh generation is finished (progress reaches 100%), make sure '''NOT to close the tool''' and use ''File > Save NavMesh''. This will open up a window offering you to choose a location, where the navmesh file can be saved. Make sure to include ''.nm'' at the end of the file-name. The full path should correspond to the one you have defined in the navmesh config (see game config part of this article). |
Latest revision as of 08:34, 22 October 2024
Overview
This page describes the basics of generating navigation mesh file (often called 'navmesh') for your terrain. Navmesh for your terrain is not mandatory (game will cope without it), but it contains essential data for the AI (obstacles, door links, jump links,..) without which it wont be able to navigate properly (AI entities will stand frozen on their spawn point). For guaranteed behavior of the AI, it is necessary to re-generate navmesh after each new terrain build (each time wrp is binarized to be precise).
Requirements:
- DayZ and DayZ Tools package installed.
- Have a working custom terrain (mod) files, binarized and packed into pbo.
Game config
In order to get your navmesh generated and then loaded by the game, configuration file (precisely your CfgWorlds entry) for your terrain has to contain Navmesh class. This class contains all the necessary parameters for generation and also later use in the game.
class CfgWorlds
{
/* ... */
class yourterrain: CAWorld
{
/* ... */
class Navmesh
{
navmeshName="\path\to\your\navmesh\file.nm";
filterIsolatedIslandsOnLoad = true;
visualiseOffset = 0.0;
class GenParams
{
tileWidth = 50.0;
cellSize1 = 0.25;
cellSize2 = 0.1;
cellSize3 = 0.1;
filterIsolatedIslands = true;
seedPosition[] = {7500, 0, 7500};
class Agent
{
diameter = 0.6;
standHeight = 1.5;
crouchHeight = 1.0;
proneHeight = 0.5;
maxStepHeight = 0.45;
maxSlope = 60.0;
};
class Links
{
class ZedJump387_050
{
jumpLength = 1.50;
jumpHeight = 0.50;
minCenterHeight = 0.3;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump0";
flags[] = {"jumpOver"};
color = 0x66ff0000;
};
class ZedJump388_050
{
jumpLength = 1.50;
jumpHeight = 0.50;
minCenterHeight = -0.5;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump0";
flags[] = {"jumpOver"};
color = 0x66dd5500;
};
class ZedJump387_110
{
jumpLength = 3.90;
jumpHeight = 1.1;
minCenterHeight = 0.5;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump0";
flags[] = {"jumpOver"};
color = 0x66008000;
};
class ZedJump420_160
{
jumpLength = 4.0;
jumpHeight = 1.6;
minCenterHeight = 1.1;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump0";
flags[] = {"jumpOver"};
color = 0x660000ff;
};
class ZedJump265_210
{
jumpLength = 2.45;
jumpHeight = 2.5;
minCenterHeight = 1.8;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump0";
flags[] = {"climb"};
color = 0x669400d3;
};
class Fence50_110deer
{
typeId = 100;
jumpLength = 8.0;
jumpHeight = 1.1;
minCenterHeight = 0.5;
jumpDropdownMin = 1.0;
jumpDropdownMax = -1.0;
areaType="jump2";
flags[] = {"jumpOver"};
color = 0x66aaaaFF;
};
class Fence110_160deer
{
typeId = 101;
jumpLength = 8.0;
jumpHeight = 1.6;
minCenterHeight = 1.1;
jumpDropdownMin = 1.0;
jumpDropdownMax = -1.0;
areaType="jump3";
flags[] = {"jumpOver"};
color = 0x6624fff8;
};
class Fence50_110hen
{
typeId = 110;
jumpLength = 4.0;
jumpHeight = 1.1;
minCenterHeight = 0.5;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump4";
flags[] = {"jumpOver"};
color = 0xFFFFAA00;
};
class Fence110_160hen
{
typeId = 111;
jumpLength = 4.0;
jumpHeight = 1.6;
minCenterHeight = 1.1;
jumpDropdownMin = 0.5;
jumpDropdownMax = -0.5;
areaType="jump4";
flags[] = {"jumpOver"};
color = 0xFFFFAA00;
};
};
};
};
/* ... */
};
};
We recommend you to use config above as the parameters are closely tied to the performance, AI and its animations. It is recommended to only change parameters listed below.
- navmeshName - parameter corresponds to the path to the generated navmesh file, navmesh files can be quite large (hundreds of MBs) so plan accordingly where it will be kept in your data
- seedPosition - parameter should ideally be the center of your map (in meters)
Generation process
Navmesh generation requires a working terrain in the game, so make sure your terrain contains everything you want and you can access it in the game without any issues (can be done by running the game and using simple empty mission, see workshop item called Sandbox for an example).
For the generation itself, you are going to need to do following:
- Setup a completely empty mission (folder should be called empty.yourworldname) on your terrain with a following init.c file:
void main() { } class CustomMission: MissionServer { override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName) { Entity playerEnt; playerEnt = GetGame().CreatePlayer(identity, characterName, Vector(2681, 0, 10070), 0, "NONE");//Creates random player Class.CastTo(m_player, playerEnt); GetGame().SelectPlayer(identity, m_player); return m_player; } override void StartingEquipSetup(PlayerBase player, bool clothesChosen) { player.RemoveAllItems(); } }; Mission CreateCustomMission(string path) { return new CustomMission(); }
- Use a server config that is pointing to the empty mission (you can take server cfg from the server files for example).
- Run DayZDiag_x64 (located near other game executables, make sure it is not blocked by the firewall) using following parameters:
DayZDiag_x64 -server -mod=yourmodfolder -startNavmeshDataServer -port=2302 -config=ServerDZNV.cfg
- Run NavMeshGenerator tool (from DayZ Tools package) and make sure it is not blocked by the firewall.
- Use Generation > Connect Data Server (built-in log should tell if it was a success or not).
- After successful connection to the local server, use Generation > Start generation.
- Confirm following window and the generation process should start.
Be ware of the fact that on a single machine, generation can take quite some time (depends on the size and complexity of the terrain) and can be quite taxing on your HW.
Using the generation output
After navmesh generation is finished (progress reaches 100%), make sure NOT to close the tool and use File > Save NavMesh. This will open up a window offering you to choose a location, where the navmesh file can be saved. Make sure to include .nm at the end of the file-name. The full path should correspond to the one you have defined in the navmesh config (see game config part of this article).