Weapon Collimator Creation – Arma Reforger
(Created page with "{{TOC|side}} ==Tutorial Goal== In this tutorial you will learn about: *Adjusting collimator mesh & UVs *Proper placement of sockets for collimator related functionality *Col...") |
No edit summary |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{TOC|side}} | {{TOC|side}} | ||
*Adjusting collimator mesh & UVs | == Tutorial Goal == | ||
*Proper placement of sockets for collimator related functionality | |||
*Collimator material configuration | {{Messagebox | ||
*Collimator prefab configuration | | In this tutorial you will learn about: | ||
{{Feature|informative|If you | * Adjusting collimator mesh & UVs | ||
==Structure Preparation== | * Proper placement of sockets for collimator related functionality | ||
* Collimator material configuration | |||
* Collimator prefab configuration | |||
|💬 | |||
|#CDF | |||
}} | |||
{{Feature|informative|If you do not have any experience with Workbench yet, it is recommended to go through [[Arma Reforger:Weapon Modding|modded weapon tutorial]] to familiarise with some of the Workbench concepts.}} | |||
{{Messagebox | |||
| Sources files for this tutorial can be found at {{Link|https://github.com/BohemiaInteractive/Arma-Reforger-Samples/tree/main/SampleMod_NewWeapon|Arma Reforger Samples Github repository}}. | |||
|📥 | |||
| orange | |||
}} | |||
== Structure Preparation == | |||
While sticking to official structure is not mandatory and there are no engine restrictions asset wise about it, it is recommended to follow guidelines listed here - [[Arma Reforger:Directory Structure|Data (file) structure]] - to ensure that all automation plugins are parsing your assets correctly and make it later easy to navigate. | While sticking to official structure is not mandatory and there are no engine restrictions asset wise about it, it is recommended to follow guidelines listed here - [[Arma Reforger:Directory Structure|Data (file) structure]] - to ensure that all automation plugins are parsing your assets correctly and make it later easy to navigate. | ||
Line 16: | Line 29: | ||
[[File:armareforger-new-weapon-collimator-structure.png]] | [[File:armareforger-new-weapon-collimator-structure.png]] | ||
=Model Preparation= | |||
== Model Preparation == | |||
The model must be prepared in Blender accordingly. Besides the normal setup of colliders, optics memory points and weapon snap point there are two additional considerations | The model must be prepared in Blender accordingly. Besides the normal setup of colliders, optics memory points and weapon snap point there are two additional considerations | ||
===Plane UV=== | === Plane UV === | ||
We need a grayscale reticle texture of square aspect ratio with the "aimpoint" in the center. The geometry of the projection plane needs to extend all the way to the edge of the texture (for now). See the image below for an idea on how this should look | We need a grayscale reticle texture of square aspect ratio with the "aimpoint" in the center. The geometry of the projection plane needs to extend all the way to the edge of the texture (for now). See the image below for an idea on how this should look | ||
Line 28: | Line 44: | ||
</gallery> | </gallery> | ||
===Geometry Definition=== | === Geometry Definition === | ||
In the prefab for the collimator, you will need to define the upper and lower edge of the projection plane. While this can be done without any memory points, using two empties is the easiest and most precise way. | |||
In the prefab for the collimator, you will need to define the upper and lower edge of the projection plane. While this can be done without any memory points, using two empties is the easiest and most precise way. | |||
In examples below, '''collimator_BR''' (''for bottom right'') and '''collimator_TL''' (''for top left'') is used: <gallery mode="nolines" widths="450" heights="400"> | In examples below, '''collimator_BR''' (''for bottom right'') and '''collimator_TL''' (''for top left'') is used: <gallery mode="nolines" widths="450" heights="400"> | ||
Line 35: | Line 52: | ||
File:armareforger-new-weapon-collimator-sockets-2.png | File:armareforger-new-weapon-collimator-sockets-2.png | ||
File:armareforger-new-weapon-collimator-sockets-3.png | File:armareforger-new-weapon-collimator-sockets-3.png | ||
</gallery>{{Feature|1=informative|2=Don't forget to import sockets by checking [[Arma_Reforger:Weapon_Optic_Creation#Model_Import_.26_Registration|'''Export Scene Hierarchy''']] option in '''Import Settings''' of the model - without that, your sockets won't be imported.}}Since collimator plane need to use separate material, don't forget to assign different material to this selection. | </gallery>{{Feature|1=informative|2=Don't forget to import sockets by checking [[Arma_Reforger:Weapon_Optic_Creation#Model_Import_.26_Registration|'''Export Scene Hierarchy''']] option in '''Import Settings''' of the model - without that, your sockets won't be imported.}}Since collimator plane need to use separate material, don't forget to assign different material to this selection. | ||
[[File:armareforger-new-weapon-collimator-material-slot.png]] | |||
The rest of the model is the same as usual - you can find more info about mesh configuration (including RIS setup) and import procedure in [[Arma Reforger:Weapon Optic Creation#Mesh preparation|'''Weapon Optic Creation''' tutorial]]. | |||
== Reticle Material == | |||
[[File:armareforger-new-weapon-collimator-material-settings2.png|thumb|629x629px|Basic material settings]] | [[File:armareforger-new-weapon-collimator-material-settings2.png|thumb|629x629px|Basic material settings]] | ||
Once model is imported and material is created, it is time to start work on material. If you named your material in model "''collimator''" then by default, a new Enfusion material called .emat will be created in '''Data''' folder next to the FBX file. This new material is also using PBRBasic class which is more than sufficient for collimator reticle. | Once model is imported and material is created, it is time to start work on material. If you named your material in model "''collimator''" then by default, a new Enfusion material called .emat will be created in '''Data''' folder next to the FBX file. This new material is also using PBRBasic class which is more than sufficient for collimator reticle. | ||
[[File:armareforger-new-weapon-collimator-material-settings1.png]] | [[File:armareforger-new-weapon-collimator-material-settings1.png]] | ||
Open collimator material and then in '''Basic material maps and its modifiers''' section assign '''black and white texture''' (''where black represents transparent pixels'') to '''Opacity Map''' field. It is possible to assign multiple textures - this can be done by expanding '''textures''' parameter and then adding new entries in the array via plus button. | Open collimator material and then in '''Basic material maps and its modifiers''' section assign '''black and white texture''' (''where black represents transparent pixels'') to '''Opacity Map''' field. It is possible to assign multiple textures - this can be done by expanding '''textures''' parameter and then adding new entries in the array via plus button. | ||
In theory, for an addon you can have one "master collimator" material that contains all possible reticles, since we will be able to "filter" them later in the prefab config. It is also possible to '''switch between reticles''' via | In theory, for an addon you can have one "master collimator" material that contains all possible reticles, since we will be able to "filter" them later in the prefab config. It is also possible to '''switch between reticles''' via the {{Link|enfusion://ScriptEditor/Scripts/Game/Weapon/Sights/SCR_CollimatorSightsComponent.c;102|API which is provided by SCR_CollimatorSightsComponent}} although keep in mind, that such feature is not implemented in vanilla game. | ||
After setting reticle (or multiple reticles), make sure to set '''ClampU''' and '''ClampV''' so that the texture does not wrap. | After setting reticle (or multiple reticles), make sure to set '''ClampU''' and '''ClampV''' so that the texture does not wrap. | ||
Line 65: | Line 84: | ||
{{Clear}} | {{Clear}} | ||
===Manual Material Corrections=== | === Manual Material Corrections === | ||
Unfortunately, at the time of writing, there is no way to set script bindings within the workbench, everything needs to be done in a text editor. You need to load the emat file into a text editor and manually add the following segments{{Feature|1=important|2=This manual tweak is also necessary when inheriting from material with such tweaks. In most cases though, it is enough to copy paste '''Refs''' section}} | Unfortunately, at the time of writing, there is no way to set script bindings within the workbench, everything needs to be done in a text editor. You need to load the emat file into a text editor and manually add the following segments{{Feature|1=important|2=This manual tweak is also necessary when inheriting from material with such tweaks. In most cases though, it is enough to copy paste '''Refs''' section}} | ||
After opening .emat file in text editor, located TCModFuncs segment and Refs segments to both '''TCModShift & TCModScale''' classes (''you can also paste & replace whole TCModFunc segment'')<syntaxhighlight lang="c#"> | After opening .emat file in text editor, located TCModFuncs segment and Refs segments to both '''TCModShift & TCModScale''' classes (''you can also paste & replace whole TCModFunc segment'')<syntaxhighlight lang="c#"> | ||
TCModFuncs { | |||
TCModShift "{5CDCD917EA1E1A1B}" { | |||
ShiftU 0 | |||
ShiftV 0 | |||
Refs { | |||
"ShiftU" "SCR_CollimatorControllerComponent.m_fUCoord" | "ShiftU" "SCR_CollimatorControllerComponent.m_fUCoord" | ||
"ShiftV" "SCR_CollimatorControllerComponent.m_fVCoord" | "ShiftV" "SCR_CollimatorControllerComponent.m_fVCoord" | ||
} | } | ||
} | |||
TCModScale "{5D60B8B11F689A05}" { | |||
ScaleU 1 | |||
ScaleV 1 | |||
CenterU 0.5 | |||
CenterV 0.5 | |||
Refs { | |||
"ScaleU" "SCR_CollimatorControllerComponent.m_fUScale" | |||
"ScaleV" "SCR_CollimatorControllerComponent.m_fVScale" | |||
} | } | ||
} | } | ||
</syntaxhighlight>Next ,copy paste those refs at the bottom of the material:<syntaxhighlight lang="c#"> | } | ||
</syntaxhighlight> | |||
Next ,copy paste those refs at the bottom of the material: | |||
<syntaxhighlight lang="c#"> | |||
Refs { | Refs { | ||
"Color" | |||
"SCR_CollimatorControllerComponent.m_vColor" | |||
"Emissive" | |||
"SCR_CollimatorControllerComponent.m_vEmissive" | |||
"EmissiveLV" | |||
"SCR_CollimatorControllerComponent.m_fEmissiveLV" | |||
"OpacityMap" | |||
"SCR_CollimatorControllerComponent.m_ReticleMap" | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{Feature| | {{Feature|warning| | ||
Also note that while the Refs at the bottom gets saved when you save the emat in Workbench, '''the one at the top (inside the TCModShift) will not''', so you will have to add them again if you make changes. | |||
}} | |||
Full material example <spoiler><syntaxhighlight lang="c#"> | Full material example: | ||
<spoiler><syntaxhighlight lang="c#"> | |||
MatPBRBasic { | MatPBRBasic { | ||
Color 1 0 0 1 | Color 1 0 0 1 | ||
Line 115: | Line 140: | ||
ReceiveShadow 0 | ReceiveShadow 0 | ||
TCModFuncs { | TCModFuncs { | ||
TCModShift "{5CDCD917EA1E1A1B}" { | |||
ShiftU 0 | |||
ShiftV 0 | |||
Refs { | |||
"ShiftU" "SCR_CollimatorControllerComponent.m_fUCoord" | |||
"ShiftV" "SCR_CollimatorControllerComponent.m_fVCoord" | |||
} | |||
} | |||
TCModScale "{5D60B8B11F689A05}" { | |||
ScaleU 1 | |||
ScaleV 1 | |||
CenterU 0.5 | |||
CenterV 0.5 | |||
Refs { | |||
"ScaleU" "SCR_CollimatorControllerComponent.m_fUScale" | |||
"ScaleV" "SCR_CollimatorControllerComponent.m_fVScale" | |||
} | |||
} | |||
} | } | ||
AlphaTest 0.088 | AlphaTest 0.088 | ||
Line 139: | Line 164: | ||
OpacityMap "{C9DCB787E3AA1C41}Assets/Weapons/Attachments/Optics/SampleCollimator_01/Data/collimator_dot_A.edds" "{2BBE7CC9FAEEC02B}Assets/Weapons/Attachments/Optics/SampleCollimator_01/Data/collimator_chevron_A.edds" clampu clampv anim( 0 ) | OpacityMap "{C9DCB787E3AA1C41}Assets/Weapons/Attachments/Optics/SampleCollimator_01/Data/collimator_dot_A.edds" "{2BBE7CC9FAEEC02B}Assets/Weapons/Attachments/Optics/SampleCollimator_01/Data/collimator_chevron_A.edds" clampu clampv anim( 0 ) | ||
Refs { | Refs { | ||
"Color" | |||
"SCR_CollimatorControllerComponent.m_vColor" | |||
"Emissive" | |||
"SCR_CollimatorControllerComponent.m_vEmissive" | |||
"EmissiveLV" | |||
"SCR_CollimatorControllerComponent.m_fEmissiveLV" | |||
"OpacityMap" | |||
"SCR_CollimatorControllerComponent.m_ReticleMap" | |||
} | } | ||
} | } | ||
</syntaxhighlight | </syntaxhighlight> | ||
</spoiler> | |||
When you are done with those modifications, '''save your changes''' in text editor and '''restart the Workbench'''. | |||
{{Feature|warning| | |||
Refs will stop working every time you do some changes in the material like modification of color or emissive value.<br>A full Workbench restart is required to fix this issue. | |||
}} | |||
== Prefab == | |||
=== Creation === | |||
Collimator prefab setup is quite similar to regular optic as described in [[Arma Reforger:Weapon Optic Creation#Creation|'''Weapon Optic Creation''' tutorial]] but there are some differences. Main difference is fact that {{Link|enfusion://ResourceManager/~ArmaReforger:Prefabs/Weapons/Attachments/Optics/WeaponOptic_Base.et|WeaponOptic_Base.et}} contains '''SCR_2DPIPSightsComponent''' which is not desired in this case. Since you cannot delete inherited components and disabled prefabs still have some memory footprint, it is recommended to either: | Collimator prefab setup is quite similar to regular optic as described in [[Arma Reforger:Weapon Optic Creation#Creation|'''Weapon Optic Creation''' tutorial]] but there are some differences. Main difference is fact that {{Link|enfusion://ResourceManager/~ArmaReforger:Prefabs/Weapons/Attachments/Optics/WeaponOptic_Base.et|WeaponOptic_Base.et}} contains '''SCR_2DPIPSightsComponent''' which is not desired in this case. Since you cannot delete inherited components and disabled prefabs still have some memory footprint, it is recommended to either: | ||
Line 572: | Line 195: | ||
=== Adding Components === | === Adding Components === | ||
First, begin by [[Arma Reforger:Prefabs Basics#Add component button|adding '''SCR_CollimatorSightsComponent''' | Next, it will be necessary to add two, collimator specific, components to the prefab - '''SCR_CollimatorSightsComponent & SCR_CollimatorControllerComponent.''' | ||
First, begin by [[Arma Reforger:Prefabs Basics#Add component button|adding '''SCR_CollimatorSightsComponent''' to collimator prefab]], which is quite standard procedure. After that, it will be necessary to add '''SCR_CollimatorControllerComponent''' as a child component of '''SCR_CollimatorSightsComponent''' via [[Arma Reforger:Prefabs Basics#Adding child component|Add child component action]]. If everything was done correctly, you should end up with something like this | |||
[[File:armareforger-new-weapon-collimator-components.png]] | [[File:armareforger-new-weapon-collimator-components.png]] | ||
=== Configuration === | === Configuration === | ||
'''SCR_CollimatorSightsComponent''' does not have any attributes that need to be taken care of, all set up is done in '''SCR_CollimatorSightsComponent'''. | |||
[[File:armareforger-new-weapon-collimator-basesights.png]] {{Feature| | Set up the sight points, eye point and all other parameters of the '''SCR_CollimatorSightsComponent''' normally - you can referer to [[Arma Reforger:Weapon Optic Creation#Setting base sight properties|Weapon Optic Tutorial]] for more info. | ||
[[File:armareforger-new-weapon-collimator-basesights.png]] | |||
{{Feature|informative|'''The Front and Rear Sight Points are optional'''; if undefined the direction of the sight is calculated from the given Collimator projection plane (see below).}} | |||
[[File:armareforger-new-weapon-collimator-main-configuration.png|thumb|580x580px|Collimator section]] | [[File:armareforger-new-weapon-collimator-main-configuration.png|thumb|580x580px|Collimator section]] | ||
The "'''Collimator'''" category contains all the relevant settings and most of the work will be performed in this section: | The "'''Collimator'''" category contains all the relevant settings and most of the work will be performed in this section: | ||
*'''Collimator Top Left''', '''Collimator Bottom Right''' and '''Collimator Center''': | * '''Collimator Top Left''', '''Collimator Bottom Right''' and '''Collimator Center''': | ||
**These settings are used to define the projection plane of the collimator sight. The Top Left and Bottom right points are mandatory. The center point is optional, and it is highly recommended to leave it empty. You can specify bone names and offset or just a numerical offset in the PointInfo. | **These settings are used to define the projection plane of the collimator sight. The Top Left and Bottom right points are mandatory. The center point is optional, and it is highly recommended to leave it empty. You can specify bone names and offset or just a numerical offset in the PointInfo. | ||
*'''Collimator Aspect Ratio''' | * '''Collimator Aspect Ratio''' | ||
**Set to true by default, it specifies that the collimator reticle textures have a 1:1 aspect ratio. There is usually no good reason to disable this | ** Set to true by default, it specifies that the collimator reticle textures have a 1:1 aspect ratio. There is usually no good reason to disable this | ||
==== Reticle Setup ==== | ==== Reticle Setup ==== | ||
[[File:armareforger-new-weapon-collimator-reticle-size.png|thumb|412x412px|Example showing proportions of reticle width to whole texture|alt=|left]]'''Reticle Default Angular Size''' and '''Reticle Default Texture Portion''' | [[File:armareforger-new-weapon-collimator-reticle-size.png|thumb|412x412px|Example showing proportions of reticle width to whole texture|alt=|left]]'''Reticle Default Angular Size''' and '''Reticle Default Texture Portion''' | ||
*This defines the angular size of the reticle. A collimator reticle will always appear a certain size, regardless of how close the observer is to the projection plane. Angular size is specified in degrees. The default HWS Holo sight has a reticle angular size of 68 MOA (minutes of arc), which translates to about 1.13 degrees (60 MOA is one degree). This means that the reticle is approximately the size of a human at 100 meters distance. | * This defines the angular size of the reticle. A collimator reticle will always appear a certain size, regardless of how close the observer is to the projection plane. Angular size is specified in degrees. The default HWS Holo sight has a reticle angular size of 68 MOA (minutes of arc), which translates to about 1.13 degrees (60 MOA is one degree). This means that the reticle is approximately the size of a human at 100 meters distance. | ||
*'''Reticle Default Texture Portion''' describes how much of the given texture is actually covered by the reticle. Principle is same as described in [[Arma Reforger:Weapon Optic Creation#Reticle 2|Weapon Optic Tutorial]]. In the above case, the reticle is 9% of the entire texture (see image) | * '''Reticle Default Texture Portion''' describes how much of the given texture is actually covered by the reticle. Principle is same as described in [[Arma Reforger:Weapon Optic Creation#Reticle 2|Weapon Optic Tutorial]]. In the above case, the reticle is 9% of the entire texture (see image) | ||
*Note that both of these values can be overridden in the '''Reticle Infos''' array, see below. If any or both of these values are zero, then the reticle is taken "as-is" and no angular size adjustment is made at all. | *Note that both of these values can be overridden in the '''Reticle Infos''' array, see below. If any or both of these values are zero, then the reticle is taken "as-is" and no angular size adjustment is made at all. | ||
{{Clear}} | {{Clear}} | ||
==== Default Reticle Color and Reticle Colors array ==== | ==== Default Reticle Color and Reticle Colors array ==== | ||
[[File:armareforger-new-weapon-collimator-color-array.png|alt=|left|550x550px]] | [[File:armareforger-new-weapon-collimator-color-array.png|alt=|left|550x550px]] | ||
Line 609: | Line 235: | ||
==== Misc Parameters ==== | ==== Misc Parameters ==== | ||
*'''ADS Activation/Deactivation percentage''' | * '''ADS Activation/Deactivation percentage''' | ||
**The collimator sight is disabled when not aiming down sights to avoid unnecessary calculations. During the blend-in and blend-out of the Aim Down Sights, the sight is enabled. These two values give a percentage when the sights are enabled during the blend in. The default is 50% (0.5), which causes the reticle to "slide in" and "slide out" of view. If the sights are very open, a smaller value might be required for either. | ** The collimator sight is disabled when not aiming down sights to avoid unnecessary calculations. During the blend-in and blend-out of the Aim Down Sights, the sight is enabled. These two values give a percentage when the sights are enabled during the blend in. The default is 50% (0.5), which causes the reticle to "slide in" and "slide out" of view. If the sights are very open, a smaller value might be required for either. | ||
*'''Daylight/Night brightness''' | * '''Daylight/Night brightness''' | ||
**These values specify the brightness of the glowy bits of the reticle during daytime or night time. The night time brightness is selected via the '''Reticle Illumination toggle''' feature also available on some scopes, only that this makes the reticle less bright, but the semantics are the same. | ** These values specify the brightness of the glowy bits of the reticle during daytime or night time. The night time brightness is selected via the '''Reticle Illumination toggle''' feature also available on some scopes, only that this makes the reticle less bright, but the semantics are the same. | ||
{{Clear}} | |||
== Testing == | |||
Once all those steps were completed, you should be to verify in game if collimator is working correctly. First thing to test might be parallax effect when freelook is turned - reticle should stay on target no matter at which angle you are looking at it. During movement, you should also observe natural sway of the reticle which is showing actual aiming point of the rifle. | |||
[[File:armareforger-new-weapon-collimator-test1.gif]] | |||
[[File:armareforger-new-weapon-collimator-test2.gif]] | |||
=== Potential Traps === | |||
There are a number of things you can check to see why the sights do not work as expected: | |||
* Check that the UV mapping of the collimator projection is correct. Since most reticles are at least symmetrical in one axis, a flipped UV map is hard to detect. If the movement looks highly exaggerated in one direction, or simply wrong, check the UV coordinates first. A collimator should look like there is a glowing reticle floating in mid-air, and head movement should move the sights itself but not the collimator. | |||
* The collimator functionality only works in game and does not work in World editor. Weapon sights only work when in ADS, while vehicle sights only work from a specific seat. | |||
== Script API == | |||
{| class="wikitable" | |||
! Method | |||
! Description | |||
|- | |||
| <enforce>void SetReticleSize(float angularSize, float reticlePortion)</enforce> | |||
| Set the reticle size in degrees. <enforce inline>reticlePortion</enforce> determines the portion of the reticle that is covered by this (see above) | |||
|- | |||
| <enforce>float GetReticleAngularSize()</enforce> | |||
| Return the current angular size of the reticle | |||
|- | |||
| <enforce>float GetReticlePortion()</enforce> | |||
| Return the current reticle portion (see above) | |||
|- | |||
| <enforce>int GetNumReticles()</enforce> | |||
| Get the number of different reticles confiigured for this sight. Typically 1, but might have more that can be switched around | |||
|- | |||
| <enforce>bool IsReticleValid(int index)</enforce> | |||
| Check if the given reticle index is a valid reticle or not. Returns false if invalid | |||
|- | |||
| <enforce>BaseCollimatorReticleInfo GetReticleByIndex(int index)</enforce> | |||
| If valid, returns the reticle info for the given reticle index, which includes angular size, reticle portion, index and a boolean that indicates whether or not this reticle overrides the globally set reticle size and portion. | |||
|- | |||
| <enforce>int GetCurrentReticleShape()</enforce> | |||
| Returns the index of the currently active reticle. | |||
|- | |||
| <enforce>void ReticleNextShape()</enforce> | |||
<enforce>void ReticlePreviousShape()</enforce> | |||
| Cycles forward or backward through the array of reticles, wrapping at the ends. | |||
|- | |||
| <enforce>bool SetReticleShapeByIndex(int iIndex)</enforce> | |||
| Set the current reticle by specifiyng its index. Returns false if the index was invalid. | |||
|- | |||
| <enforce>int GetNumColors()</enforce> | |||
| Get the number of defined reticle colors. Typically 1, but a sight can define multiple colors for its reticles. | |||
|- | |||
| <enforce>int IsColorValid(int index)</enforce> | |||
| Returns true if the given index is a valid color. | |||
|- | |||
| <enforce>BaseCollimatorReticleColor GetColorByIndex(int index)</enforce> | |||
| Returns the indexed reticle color, or null if the color is invalid. Colors are defined by two fields, reticle and glow color, which can be gotten ''via'' <enforce inline>vector GetReticleColor()</enforce> and <enforce inline>vector GetGlowColor()</enforce> from the structure | |||
|- | |||
| <enforce>int GetCurrentColor()</enforce> | |||
| Get the currently active color index | |||
|- | |||
| <enforce>void ReticleNextColor()</enforce> | |||
<enforce>void ReticlePreviousColor()</enforce> | |||
|Cycle up or down the current reticle color, wrapping at the edge cases. If only one color is defined, this does nothing. | |||
|- | |||
| <enforce>bool SetReticleColorByIndex(int iIndex)</enforce> | |||
| Set the color by index. If index is invalid, the function returns false. | |||
|- | |||
| <enforce>float GetNormalizedLightIntensity()</enforce> | |||
| Returns a floating point value between 0 and 1 which represents the normalized light intensity currently "experienced" by the sights. Internally, this is used to calculate the dot brightness for auto brightness correction. The value is only valid if auto brightness is enabled. | |||
|- | |||
| <enforce>void SetVerticalAngularCorrection(float fAngle)</enforce> | |||
| Sets the vertical angular correction of the reticle, in mils. This value can be used for zeroing, for example in the XM60 helicopter sight | |||
|- | |||
| <enforce>float GetVerticalAngularCorrection()</enforce> | |||
| Returns the current angular correction of the reticle, in mils. | |||
|- | |||
| <enforce>void SetHorizontalAngularCorrection(float fAngle)</enforce> | |||
| Sets the horizontal angular correction of the reticle, in mils. This value can be used for windage adjustments | |||
|- | |||
| <enforce>float GetHorizontalAngularCorrection()</enforce> | |||
| Returns the current horizontal angular correction for the reticle, in mils. | |||
|- | |||
| <enforce>bool IsSightActive()</enforce> | |||
| Returns false if the sight is disabled by script. If the sight is NOT disabled by script, it will return true, but that doesn't necessarily mean that the sight is actually active, only that it isn't forced off. | |||
|- | |||
| <enforce>void SetSightForcedOff(bool forceOff)</enforce> | |||
| Force the sight off if <enforce inline>forceOff</enforce> is true. This will suppress any display of the reticle. Setting this to false might or might not make the reticle visible. This can only force the sight off, otherwise it behaves normally, as expected. | |||
|- | |||
| <enforce>void EnableManualBrightness(bool bEnable)</enforce> | |||
| Enables manual brightness control. If enabled, all other functionality for brightness control (automatic brightness, day/night toggle) is inhibited. | |||
|- | |||
| <enforce>bool IsManualBrightnessEnabled()</enforce> | |||
| Returns true if manual brightness control is active, false otherwise | |||
|- | |||
| <enforce>void SetManualBrightness(float fBrightness, bool bClamp)</enforce> | |||
| | |||
Set the manual brightness to the given floating point value. The <enforce inline>fBrightness</enforce> value MUST be greater or equal to zero, and SHOULD be between 0 and 1. Values higher than 1 are possible. | |||
Typically, if <enforce inline>bClamp</enforce> is true, the brightness value interpolates between daylight and night time invensity. | |||
If <enforce inline>bClamp</enforce> is false, then night time intensity is ignored, and the <enforce inline>fBrightness</enforce> factor interpolates between zero and daylight brightness. | |||
Values greater than 1 boost the brightness beyond daylight brightness. Internally, the value will be capped to the maximum brightness supported by Enfusion (which is 22). | |||
So if your daylight brightness is, say, 10, setting the fBrightness factor to 2 will make the reticle appear with a brightness of 20. | |||
|- | |||
| <enforce>float GetManualBrightness()</enforce> | |||
| Return the currently selected brightness factor. | |||
|- | |||
| <enforce>bool GetManualBrightnessClamp()</enforce> | |||
| Returns true if the manual brightness is currently clamped between day and night. | |||
|} | |||
{{GameCategory|armaR|Modding|Tutorials|Assets}} | |||
{{GameCategory|armaR|Modding|Tutorials|Assets|Weapon Creation}} |
Latest revision as of 11:34, 4 December 2024
Tutorial Goal
Structure Preparation
While sticking to official structure is not mandatory and there are no engine restrictions asset wise about it, it is recommended to follow guidelines listed here - Data (file) structure - to ensure that all automation plugins are parsing your assets correctly and make it later easy to navigate.
Therefore, your first task will be preparing following file structure
Model Preparation
The model must be prepared in Blender accordingly. Besides the normal setup of colliders, optics memory points and weapon snap point there are two additional considerations
Plane UV
We need a grayscale reticle texture of square aspect ratio with the "aimpoint" in the center. The geometry of the projection plane needs to extend all the way to the edge of the texture (for now). See the image below for an idea on how this should look
Note that if the model's geometry allows it, you can use a simple rectangular projection plane instead, but it cannot "stick out" of the casing. Some optics like the Russian OKP-7 which have a completely open projection plane must be shaped accordingly.
Geometry Definition
In the prefab for the collimator, you will need to define the upper and lower edge of the projection plane. While this can be done without any memory points, using two empties is the easiest and most precise way.
In examples below, collimator_BR (for bottom right) and collimator_TL (for top left) is used:
Since collimator plane need to use separate material, don't forget to assign different material to this selection.
The rest of the model is the same as usual - you can find more info about mesh configuration (including RIS setup) and import procedure in Weapon Optic Creation tutorial.
Reticle Material
Once model is imported and material is created, it is time to start work on material. If you named your material in model "collimator" then by default, a new Enfusion material called .emat will be created in Data folder next to the FBX file. This new material is also using PBRBasic class which is more than sufficient for collimator reticle.
Open collimator material and then in Basic material maps and its modifiers section assign black and white texture (where black represents transparent pixels) to Opacity Map field. It is possible to assign multiple textures - this can be done by expanding textures parameter and then adding new entries in the array via plus button.
In theory, for an addon you can have one "master collimator" material that contains all possible reticles, since we will be able to "filter" them later in the prefab config. It is also possible to switch between reticles via the API which is provided by SCR_CollimatorSightsComponent although keep in mind, that such feature is not implemented in vanilla game.
After setting reticle (or multiple reticles), make sure to set ClampU and ClampV so that the texture does not wrap.
Next, in General section of the material settings, modify following properties
- Change Sort to Translucent
- Disable Cast Shadow & Receive Shadow properties
- Add TCModFunc array in the general section, click the "+" sign and add a TCModShift & TCModScale to it.
- Change Blend Mode to AlphaBlend
- Adjust Alpha Test & Alpha Mul to achieve desired reticle transparency
Manual Material Corrections
Unfortunately, at the time of writing, there is no way to set script bindings within the workbench, everything needs to be done in a text editor. You need to load the emat file into a text editor and manually add the following segments
After opening .emat file in text editor, located TCModFuncs segment and Refs segments to both TCModShift & TCModScale classes (you can also paste & replace whole TCModFunc segment)
TCModFuncs {
TCModShift "{5CDCD917EA1E1A1B}" {
ShiftU 0
ShiftV 0
Refs {
"ShiftU" "SCR_CollimatorControllerComponent.m_fUCoord"
"ShiftV" "SCR_CollimatorControllerComponent.m_fVCoord"
}
}
TCModScale "{5D60B8B11F689A05}" {
ScaleU 1
ScaleV 1
CenterU 0.5
CenterV 0.5
Refs {
"ScaleU" "SCR_CollimatorControllerComponent.m_fUScale"
"ScaleV" "SCR_CollimatorControllerComponent.m_fVScale"
}
}
}
Next ,copy paste those refs at the bottom of the material:
Refs {
"Color"
"SCR_CollimatorControllerComponent.m_vColor"
"Emissive"
"SCR_CollimatorControllerComponent.m_vEmissive"
"EmissiveLV"
"SCR_CollimatorControllerComponent.m_fEmissiveLV"
"OpacityMap"
"SCR_CollimatorControllerComponent.m_ReticleMap"
}
Full material example:
MatPBRBasic {
Color 1 0 0 1
Emissive 1 0 0 0
EmissiveLV 9.538
ApplyAlbedoToEmissive 0
Sort translucent
CastShadow 0
ReceiveShadow 0
TCModFuncs {
TCModShift "{5CDCD917EA1E1A1B}" {
ShiftU 0
ShiftV 0
Refs {
"ShiftU" "SCR_CollimatorControllerComponent.m_fUCoord"
"ShiftV" "SCR_CollimatorControllerComponent.m_fVCoord"
}
}
TCModScale "{5D60B8B11F689A05}" {
ScaleU 1
ScaleV 1
CenterU 0.5
CenterV 0.5
Refs {
"ScaleU" "SCR_CollimatorControllerComponent.m_fUScale"
"ScaleV" "SCR_CollimatorControllerComponent.m_fVScale"
}
}
}
AlphaTest 0.088
AlphaMul 0.707
BlendMode AlphaBlend
OpacityMap "{C9DCB787E3AA1C41}Assets/Weapons/Attachments/Optics/SampleCollimator_01/Data/collimator_dot_A.edds" "{2BBE7CC9FAEEC02B}Assets/Weapons/Attachments/Optics/SampleCollimator_01/Data/collimator_chevron_A.edds" clampu clampv anim( 0 )
Refs {
"Color"
"SCR_CollimatorControllerComponent.m_vColor"
"Emissive"
"SCR_CollimatorControllerComponent.m_vEmissive"
"EmissiveLV"
"SCR_CollimatorControllerComponent.m_fEmissiveLV"
"OpacityMap"
"SCR_CollimatorControllerComponent.m_ReticleMap"
}
}
When you are done with those modifications, save your changes in text editor and restart the Workbench.
Prefab
Creation
Collimator prefab setup is quite similar to regular optic as described in Weapon Optic Creation tutorial but there are some differences. Main difference is fact that WeaponOptic_Base.et contains SCR_2DPIPSightsComponent which is not desired in this case. Since you cannot delete inherited components and disabled prefabs still have some memory footprint, it is recommended to either:
- Create new prefab inheriting from Attachment_Base.et and manually add components which are present in WeaponOptic_Base.et except SCR_2DPIPSightsComponent
- Duplicate in addon WeaponOptic_Base.et prefab and remove from it SCR_2DPIPSightsComponent component
In most cases, it will be easier to use 2nd method (duplication) for creation of the new prefab. Once new prefab is created and adjusted, don't forget to put it in some proper folder (check structure paragraph at the top of the page).
Adding Components
Next, it will be necessary to add two, collimator specific, components to the prefab - SCR_CollimatorSightsComponent & SCR_CollimatorControllerComponent.
First, begin by adding SCR_CollimatorSightsComponent to collimator prefab, which is quite standard procedure. After that, it will be necessary to add SCR_CollimatorControllerComponent as a child component of SCR_CollimatorSightsComponent via Add child component action. If everything was done correctly, you should end up with something like this
Configuration
SCR_CollimatorSightsComponent does not have any attributes that need to be taken care of, all set up is done in SCR_CollimatorSightsComponent.
Set up the sight points, eye point and all other parameters of the SCR_CollimatorSightsComponent normally - you can referer to Weapon Optic Tutorial for more info.
The "Collimator" category contains all the relevant settings and most of the work will be performed in this section:
- Collimator Top Left, Collimator Bottom Right and Collimator Center:
- These settings are used to define the projection plane of the collimator sight. The Top Left and Bottom right points are mandatory. The center point is optional, and it is highly recommended to leave it empty. You can specify bone names and offset or just a numerical offset in the PointInfo.
- Collimator Aspect Ratio
- Set to true by default, it specifies that the collimator reticle textures have a 1:1 aspect ratio. There is usually no good reason to disable this
Reticle Setup
Reticle Default Angular Size and Reticle Default Texture Portion
- This defines the angular size of the reticle. A collimator reticle will always appear a certain size, regardless of how close the observer is to the projection plane. Angular size is specified in degrees. The default HWS Holo sight has a reticle angular size of 68 MOA (minutes of arc), which translates to about 1.13 degrees (60 MOA is one degree). This means that the reticle is approximately the size of a human at 100 meters distance.
- Reticle Default Texture Portion describes how much of the given texture is actually covered by the reticle. Principle is same as described in Weapon Optic Tutorial. In the above case, the reticle is 9% of the entire texture (see image)
- Note that both of these values can be overridden in the Reticle Infos array, see below. If any or both of these values are zero, then the reticle is taken "as-is" and no angular size adjustment is made at all.
Default Reticle Color and Reticle Colors array
The settings here are ignored if there are no reticle colors defined, and the settings of the emat are used. Otherwise the color in the emat is ignored and the default reticle color specifies the color used for the reticle. Each BaseCollimatorReticleColor entry has two color values, a reticle color and a glow color. The glow color is the emissive part of the material, while the reticle color is the base color used. They should normally be relatively close, but experimentation is possible.
Default Reticle Index and Reticle Info array
If the reticle info array is empty, then the default reticle index specifies the texture index in the emat texture array of the collimator material. Otherwise, the Default Reticle Index specifies the index into the Reticle Info array. The Reticle Infos array consists of BaseCollimatorReticleInfo structures. The first field, Reticle Index, specifies the texture index from the emat. The second field is a checkbox which defaults to off. If disabled like this, the angular size and reticle portion are taken from the specified default values. If checked, two new fields will appear - an override for the Reticle Default Angular Size and one for the Reticle Default Texture Portion. Again, either one of these set to 0 will disabled reticle angular size FOR THIS RETICLE only. The example in the picture below specifies three different reticles: The first one is using the default values with the first reticle texture in the emat. The second one overrides the angular size to be twice as big. The third one uses a different texture but does not override any of the angular size/portion settings.
Misc Parameters
- ADS Activation/Deactivation percentage
- The collimator sight is disabled when not aiming down sights to avoid unnecessary calculations. During the blend-in and blend-out of the Aim Down Sights, the sight is enabled. These two values give a percentage when the sights are enabled during the blend in. The default is 50% (0.5), which causes the reticle to "slide in" and "slide out" of view. If the sights are very open, a smaller value might be required for either.
- Daylight/Night brightness
- These values specify the brightness of the glowy bits of the reticle during daytime or night time. The night time brightness is selected via the Reticle Illumination toggle feature also available on some scopes, only that this makes the reticle less bright, but the semantics are the same.
Testing
Once all those steps were completed, you should be to verify in game if collimator is working correctly. First thing to test might be parallax effect when freelook is turned - reticle should stay on target no matter at which angle you are looking at it. During movement, you should also observe natural sway of the reticle which is showing actual aiming point of the rifle.
Potential Traps
There are a number of things you can check to see why the sights do not work as expected:
- Check that the UV mapping of the collimator projection is correct. Since most reticles are at least symmetrical in one axis, a flipped UV map is hard to detect. If the movement looks highly exaggerated in one direction, or simply wrong, check the UV coordinates first. A collimator should look like there is a glowing reticle floating in mid-air, and head movement should move the sights itself but not the collimator.
- The collimator functionality only works in game and does not work in World editor. Weapon sights only work when in ADS, while vehicle sights only work from a specific seat.
Script API
Method | Description |
---|---|
Set the reticle size in degrees. reticlePortion determines the portion of the reticle that is covered by this (see above) | |
Return the current angular size of the reticle | |
Return the current reticle portion (see above) | |
Get the number of different reticles confiigured for this sight. Typically 1, but might have more that can be switched around | |
Check if the given reticle index is a valid reticle or not. Returns false if invalid | |
If valid, returns the reticle info for the given reticle index, which includes angular size, reticle portion, index and a boolean that indicates whether or not this reticle overrides the globally set reticle size and portion. | |
Returns the index of the currently active reticle. | |
void ReticleNextShape() void ReticlePreviousShape() |
Cycles forward or backward through the array of reticles, wrapping at the ends. |
Set the current reticle by specifiyng its index. Returns false if the index was invalid. | |
Get the number of defined reticle colors. Typically 1, but a sight can define multiple colors for its reticles. | |
Returns true if the given index is a valid color. | |
Returns the indexed reticle color, or null if the color is invalid. Colors are defined by two fields, reticle and glow color, which can be gotten via vector GetReticleColor() and vector GetGlowColor() from the structure | |
Get the currently active color index | |
void ReticleNextColor() void ReticlePreviousColor() |
Cycle up or down the current reticle color, wrapping at the edge cases. If only one color is defined, this does nothing. |
Set the color by index. If index is invalid, the function returns false. | |
Returns a floating point value between 0 and 1 which represents the normalized light intensity currently "experienced" by the sights. Internally, this is used to calculate the dot brightness for auto brightness correction. The value is only valid if auto brightness is enabled. | |
Sets the vertical angular correction of the reticle, in mils. This value can be used for zeroing, for example in the XM60 helicopter sight | |
Returns the current angular correction of the reticle, in mils. | |
Sets the horizontal angular correction of the reticle, in mils. This value can be used for windage adjustments | |
Returns the current horizontal angular correction for the reticle, in mils. | |
Returns false if the sight is disabled by script. If the sight is NOT disabled by script, it will return true, but that doesn't necessarily mean that the sight is actually active, only that it isn't forced off. | |
Force the sight off if forceOff is true. This will suppress any display of the reticle. Setting this to false might or might not make the reticle visible. This can only force the sight off, otherwise it behaves normally, as expected. | |
Enables manual brightness control. If enabled, all other functionality for brightness control (automatic brightness, day/night toggle) is inhibited. | |
Returns true if manual brightness control is active, false otherwise | |
Set the manual brightness to the given floating point value. The fBrightness value MUST be greater or equal to zero, and SHOULD be between 0 and 1. Values higher than 1 are possible. Typically, if bClamp is true, the brightness value interpolates between daylight and night time invensity. If bClamp is false, then night time intensity is ignored, and the fBrightness factor interpolates between zero and daylight brightness. Values greater than 1 boost the brightness beyond daylight brightness. Internally, the value will be capped to the maximum brightness supported by Enfusion (which is 22). So if your daylight brightness is, say, 10, setting the fBrightness factor to 2 will make the reticle appear with a brightness of 20. | |
Return the currently selected brightness factor. | |
Returns true if the manual brightness is currently clamped between day and night. |