├── .editorconfig ├── .github └── workflows │ └── publish.workflow.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── CandyCoded.env.asmdef ├── CandyCoded.env.asmdef.meta ├── Editor.meta ├── Editor ├── CandyCoded.env.Editor.asmdef ├── CandyCoded.env.Editor.asmdef.meta ├── Scripts.meta └── Scripts │ ├── BuildTools.cs │ ├── BuildTools.cs.meta │ ├── EnvironmentFileEditor.cs │ └── EnvironmentFileEditor.cs.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Scripts.meta ├── Scripts ├── env.cs └── env.cs.meta ├── package.json └── package.json.meta /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*.cs] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.{json,md}] 13 | indent_style = space 14 | indent_size = 2 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | # CSharp and Visual Basic code style settings: 21 | [*.cs] 22 | dotnet_style_require_accessibility_modifiers = always:suggestion 23 | dotnet_style_readonly_field = true:warning 24 | 25 | # CSharp and Visual Basic code style settings: 26 | [*.cs] 27 | dotnet_style_object_initializer = true:suggestion 28 | dotnet_style_collection_initializer = true:suggestion 29 | dotnet_style_prefer_auto_properties = true:suggestion 30 | 31 | # CSharp code style settings: 32 | [*.cs] 33 | csharp_style_var_for_built_in_types = true:suggestion 34 | csharp_style_var_when_type_is_apparent = true:suggestion 35 | csharp_style_var_elsewhere = true:suggestion 36 | 37 | # CSharp code style settings: 38 | [*.cs] 39 | csharp_style_expression_bodied_methods = false:silent 40 | csharp_style_expression_bodied_constructors = false:silent 41 | csharp_style_expression_bodied_operators = false:silent 42 | csharp_style_expression_bodied_properties = true:suggestion 43 | csharp_style_expression_bodied_indexers = true:suggestion 44 | csharp_style_expression_bodied_accessors = true:suggestion 45 | 46 | # CSharp code style settings: 47 | [*.cs] 48 | csharp_style_inlined_variable_declaration = true:suggestion 49 | 50 | # CSharp code style settings: 51 | [*.cs] 52 | csharp_prefer_braces = true:silent 53 | 54 | # .NET formatting settings: 55 | [*.cs] 56 | dotnet_sort_system_directives_first = true 57 | 58 | # CSharp formatting settings: 59 | [*.cs] 60 | csharp_new_line_before_open_brace = all 61 | csharp_new_line_before_else = true 62 | csharp_new_line_before_catch = true 63 | csharp_new_line_before_finally = true 64 | csharp_new_line_before_members_in_object_initializers = true 65 | csharp_new_line_before_members_in_anonymous_types = true 66 | csharp_new_line_between_query_expression_clauses = true 67 | 68 | # CSharp formatting settings: 69 | [*.cs] 70 | csharp_indent_case_contents = true 71 | csharp_indent_switch_labels = true 72 | 73 | # CSharp formatting settings: 74 | [*.cs] 75 | csharp_space_after_cast = false 76 | csharp_space_after_keywords_in_control_flow_statements = true 77 | csharp_space_between_method_declaration_parameter_list_parentheses = false 78 | csharp_space_between_method_call_parameter_list_parentheses = false 79 | csharp_space_between_parentheses = false 80 | csharp_space_before_colon_in_inheritance_clause = true 81 | csharp_space_after_colon_in_inheritance_clause = true 82 | csharp_space_around_binary_operators = before_and_after 83 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 84 | csharp_space_between_method_call_name_and_opening_parenthesis = false 85 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 86 | 87 | # CSharp formatting settings: 88 | [*.cs] 89 | csharp_preserve_single_line_statements = false 90 | csharp_preserve_single_line_blocks = false 91 | 92 | # Rider Specific Settings: 93 | 94 | ## Blank Lines 95 | 96 | [*.cs] 97 | csharp_blank_lines_around_region = 1 98 | csharp_blank_lines_inside_region = 1 99 | csharp_blank_lines_before_single_line_comment = 1 100 | csharp_keep_blank_lines_in_declarations = 1 101 | csharp_remove_blank_lines_near_braces_in_declarations = false 102 | csharp_blank_lines_after_start_comment = 1 103 | csharp_blank_lines_between_using_groups = 0 104 | csharp_blank_lines_after_using_list = 0 105 | csharp_blank_lines_around_namespace = 1 106 | csharp_blank_lines_inside_namespace = 1 107 | csharp_blank_lines_around_type = 1 108 | csharp_blank_lines_inside_type = 1 109 | csharp_blank_lines_around_field = 1 110 | csharp_blank_lines_around_single_line_field = 1 111 | csharp_blank_lines_around_property = 1 112 | csharp_blank_lines_around_single_line_property = 1 113 | csharp_blank_lines_around_auto_property = 1 114 | csharp_blank_lines_around_single_line_auto_property = 1 115 | csharp_blank_lines_around_invocable = 1 116 | csharp_blank_lines_around_single_line_invocable = 1 117 | csharp_blank_lines_around_local_method = 1 118 | csharp_keep_blank_lines_in_code = 1 119 | csharp_remove_blank_lines_near_braces_in_code = false 120 | csharp_blank_lines_around_local_method = 1 121 | csharp_blank_lines_around_single_line_local_method = 1 122 | csharp_blank_lines_before_control_transfer_statements = 1 123 | csharp_blank_lines_after_control_transfer_statements = 1 124 | csharp_blank_lines_before_block_statements = 1 125 | csharp_blank_lines_after_block_statements = 1 126 | csharp_blank_lines_before_multiline_statements = 1 127 | csharp_blank_lines_after_multiline_statements = 1 128 | 129 | ## Brace Layout 130 | 131 | [*.cs] 132 | csharp_type_declaration_braces = next_line 133 | csharp_indent_inside_namespace = true 134 | csharp_invocable_declaration_braces = next_line 135 | csharp_anonymous_method_declaration_braces = next_line 136 | csharp_accessor_owner_declaration_braces = next_line 137 | csharp_accessor_declaration_braces = next_line 138 | csharp_case_block_braces = next_line 139 | csharp_initializer_braces = next_line 140 | csharp_other_braces = next_line 141 | csharp_allow_comment_after_lbrace = false 142 | csharp_empty_block_style = multiline 143 | 144 | ## Code Style 145 | 146 | csharp_for_built_in_types = use_var 147 | csharp_for_simple_types = use_var 148 | csharp_for_other_types = use_var 149 | csharp_prefer_explicit_discard_declaration = true 150 | csharp_instance_members_qualify_members = none 151 | csharp_instance_members_qualify_declared_in = this_class 152 | csharp_default_private_modifier = explicit 153 | csharp_default_internal_modifier = explicit 154 | 155 | ## Line Breaks 156 | 157 | [*.cs] 158 | csharp_place_type_attribute_on_same_line = false 159 | csharp_place_method_attribute_on_same_line = false 160 | csharp_place_accessorholder_attribute_on_same_line = false 161 | csharp_place_accessor_attribute_on_same_line = false 162 | csharp_place_field_attribute_on_same_line = false 163 | 164 | csharp_keep_existing_declaration_block_arrangement = false 165 | csharp_place_abstract_accessorholder_on_single_line = true 166 | csharp_place_simple_accessorholder_on_single_line = false 167 | csharp_place_accessor_with_attrs_holder_on_single_line = true 168 | csharp_place_simple_accessor_on_single_line = true 169 | csharp_place_simple_method_on_single_line = false 170 | 171 | ## Spaces 172 | 173 | [*.cs] 174 | csharp_extra_spaces = remove_all 175 | csharp_space_after_keywords_in_control_flow_statements = true 176 | csharp_space_between_method_call_name_and_opening_parenthesis = false 177 | csharp_space_before_typeof_parentheses = false 178 | csharp_space_before_default_parentheses = false 179 | csharp_space_before_checked_parentheses = false 180 | csharp_space_before_sizeof_parentheses = false 181 | csharp_space_before_nameof_parentheses = false 182 | csharp_space_between_keyword_and_expression = true 183 | csharp_space_between_keyword_and_type = true 184 | csharp_space_within_if_parentheses = false 185 | csharp_space_within_while_parentheses = false 186 | csharp_space_within_catch_parentheses = false 187 | csharp_space_within_switch_parentheses = false 188 | csharp_space_within_for_parentheses = false 189 | csharp_space_within_foreach_parentheses = false 190 | csharp_space_within_using_parentheses = false 191 | csharp_space_within_lock_parentheses = false 192 | csharp_space_within_fixed_parentheses = false 193 | csharp_space_within_parentheses = false 194 | csharp_space_between_typecast_parentheses = false 195 | csharp_space_between_method_declaration_parameter_list_parentheses = false 196 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 197 | csharp_space_between_method_call_parameter_list_parentheses = false 198 | csharp_space_within_typeof_parentheses = false 199 | csharp_space_within_default_parentheses = false 200 | csharp_space_within_checked_parentheses = false 201 | csharp_space_within_sizeof_parentheses = false 202 | csharp_space_within_nameof_parentheses = false 203 | csharp_space_before_open_square_brackets = false 204 | csharp_space_between_square_brackets = false 205 | csharp_space_between_empty_square_brackets = false 206 | csharp_space_before_type_parameter_angle = false 207 | csharp_space_before_type_argument_angle = false 208 | csharp_space_within_type_parameter_angles = false 209 | csharp_space_within_type_argument_angles = false; 210 | csharp_space_before_singleline_accessorholder = true 211 | csharp_space_in_singleline_accessorholder = true 212 | csharp_space_between_accessors_in_singleline_property = true 213 | csharp_space_within_empty_braces = true 214 | csharp_space_in_singleline_method = true 215 | csharp_space_in_singleline_anonymous_method = true 216 | csharp_space_within_single_line_array_initializer_braces = true 217 | csharp_space_around_assignment_op = true 218 | csharp_space_around_logical_op = true 219 | csharp_space_around_equality_op = true 220 | csharp_space_around_relational_op = true 221 | csharp_space_around_bitwise_op = true 222 | csharp_space_around_additive_op = true 223 | csharp_space_around_multiplicative_op = true 224 | csharp_space_around_shift_op = true 225 | csharp_space_around_nullcoalescing_op = true 226 | csharp_space_around_arrow_op = true 227 | csharp_space_after_logical_not_op = false 228 | csharp_space_after_unary_minus_op = false 229 | csharp_space_after_unary_plus_op = false 230 | csharp_space_after_ampersand_op = false 231 | csharp_space_after_asterik_op = false 232 | csharp_space_near_postfix_and_prefix_op = false 233 | csharp_space_before_ternary_quest = true 234 | csharp_space_after_ternary_quest = true 235 | csharp_space_before_ternary_colon = true 236 | csharp_space_after_ternary_colon = true 237 | csharp_space_before_comma = false 238 | csharp_space_after_comma = true 239 | csharp_space_before_semicolon_in_for_statement = false 240 | csharp_space_after_semicolon_in_for_statement = true 241 | csharp_space_before_semicolon = false 242 | csharp_space_before_colon_in_inheritance_clause = true 243 | csharp_space_after_colon_in_inheritance_clause = true 244 | csharp_space_before_type_parameter_constraint_colon = true 245 | csharp_space_after_type_parameter_constraint_colon = true 246 | csharp_space_before_colon_in_case = false 247 | csharp_space_after_colon_in_case = true 248 | csharp_space_before_attribute_colon = true 249 | csharp_space_after_attribute_colon = true 250 | csharp_space_between_attribute_sections = true 251 | csharp_space_between_square_brackets = false 252 | csharp_space_after_attributes = true 253 | csharp_space_after_cast = false 254 | csharp_space_around_dot = false 255 | csharp_space_around_lambda_arrow = true 256 | csharp_space_before_pointer_asterik_declaration = false 257 | csharp_space_before_nullable_mark = false 258 | csharp_space_around_alias_eq = true 259 | csharp_space_before_trailing_comment = true 260 | csharp_space_after_operator_keyword = true 261 | 262 | ## Resharper 263 | 264 | [*.cs] 265 | resharper_check_namespace_highlighting = do_not_show 266 | resharper_inconsistent_naming_highlighting = do_not_show 267 | resharper_member_can_be_private_global_highlighting = do_not_show 268 | resharper_unused_member_global_highlighting = do_not_show 269 | resharper_introduce_optional_parameters_global_highlighting = do_not_show 270 | resharper_delegate_subtraction_highlighting = do_not_show 271 | -------------------------------------------------------------------------------- /.github/workflows/publish.workflow.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*.*.*' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | publish: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Check out repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Install Node.js 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: '22' 21 | registry-url: 'https://registry.npmjs.org' 22 | 23 | - name: Update NPM to latest 24 | run: npm install npm@latest -g 25 | 26 | - name: Print Node.js and NPM version 27 | run: | 28 | node -v 29 | npm -v 30 | 31 | - name: NPM whoami 32 | run: npm whoami 33 | env: 34 | NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 35 | 36 | - name: Publish package 37 | run: npm publish 38 | env: 39 | NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | 3 | .idea/ 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [v1.1.5](https://github.com/CandyCoded/env/tree/v1.1.5) - (2025-02-26) 4 | 5 | [Full Changelog](https://github.com/CandyCoded/env/compare/v1.1.4...v1.1.5) 6 | 7 | - [hotfix] Only created resources dir if env file exists. [#16](https://github.com/CandyCoded/env/pull/16) 8 | 9 | ## [v1.1.4](https://github.com/CandyCoded/env/tree/v1.1.4) - (2025-02-26) 10 | 11 | [Full Changelog](https://github.com/CandyCoded/env/compare/v1.1.3...v1.1.4) 12 | 13 | - [hotfix] Added missing meta files. [#15](https://github.com/CandyCoded/env/pull/15) 14 | 15 | ## [v1.1.3](https://github.com/CandyCoded/env/tree/v1.1.3) - (2025-02-26) 16 | 17 | [Full Changelog](https://github.com/CandyCoded/env/compare/v1.1.2...v1.1.3) 18 | 19 | - [hotfix] Check that file exists before parsing. [#14](https://github.com/CandyCoded/env/pull/14) 20 | - [hotfix] Check length of dictionary before parsing and returning. [#13](https://github.com/CandyCoded/env/pull/13) 21 | - [hotfix] Fixed dictionary usage. [#12](https://github.com/CandyCoded/env/pull/12) 22 | 23 | ## [v1.1.2](https://github.com/CandyCoded/env/tree/v1.1.2) - (2022-08-04) 24 | 25 | [Full Changelog](https://github.com/CandyCoded/env/compare/v1.1.1...v1.1.2) 26 | 27 | - [hotfix] Check to see if editor file exists before copying path to runtime folder. [#5](https://github.com/CandyCoded/env/pull/5) 28 | 29 | ## [v1.1.1](https://github.com/CandyCoded/env/tree/v1.1.1) - (2021-11-04) 30 | 31 | [Full Changelog](https://github.com/CandyCoded/env/compare/v1.1.0...v1.1.1) 32 | 33 | - Fixed compatibility with windows [#3](https://github.com/CandyCoded/env/pull/3) 34 | 35 | ## [v1.1.0](https://github.com/CandyCoded/env/tree/v1.1.0) - (2021-04-03) 36 | 37 | [Full Changelog](https://github.com/CandyCoded/env/compare/v1.0.0...v1.1.0) 38 | 39 | - [feat] Added editor panel. [#2](https://github.com/CandyCoded/env/pull/2) 40 | - [feat] Added SerializeEnvironmentDictionary method. [#1](https://github.com/CandyCoded/env/pull/1) 41 | 42 | ## [v1.0.0](https://github.com/CandyCoded/env/tree/v1.0.0) - (2021-03-09) 43 | 44 | - Initial release! 🎉 45 | 46 | _This changelog was generated with **[generate-local-changelog](https://github.com/neogeek/generate-local-changelog)**_ 47 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c1e25e2ba2d841c29290f35905f2eff 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /CandyCoded.env.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CandyCoded.env" 3 | } 4 | -------------------------------------------------------------------------------- /CandyCoded.env.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0022c094e0c7f481288196a6d3e9ce33 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3847acd751fc4701a479642c2730a756 3 | timeCreated: 1615267424 -------------------------------------------------------------------------------- /Editor/CandyCoded.env.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CandyCoded.env.Editor", 3 | "references": [ 4 | "GUID:0022c094e0c7f481288196a6d3e9ce33" 5 | ], 6 | "includePlatforms": [ 7 | "Editor" 8 | ], 9 | "excludePlatforms": [], 10 | "allowUnsafeCode": false, 11 | "overrideReferences": false, 12 | "precompiledReferences": [], 13 | "autoReferenced": true, 14 | "defineConstraints": [], 15 | "versionDefines": [], 16 | "noEngineReferences": false 17 | } 18 | -------------------------------------------------------------------------------- /Editor/CandyCoded.env.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3be1a0372af54c52a1bc7dc647f54d5e 3 | timeCreated: 1615267435 -------------------------------------------------------------------------------- /Editor/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9b7da44ee0d444daa16ea7293d0dc7e 3 | timeCreated: 1615267481 -------------------------------------------------------------------------------- /Editor/Scripts/BuildTools.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Scott Doxey. All Rights Reserved. Licensed under the MIT License. See LICENSE in the project root for license information. 2 | 3 | using System; 4 | using System.IO; 5 | using UnityEditor; 6 | using UnityEditor.Build; 7 | using UnityEditor.Build.Reporting; 8 | 9 | namespace CandyCoded.env.Editor 10 | { 11 | 12 | public class BuildTools : IPreprocessBuildWithReport, IPostprocessBuildWithReport 13 | { 14 | 15 | private bool _resourcesDirCreated; 16 | 17 | public void OnPostprocessBuild(BuildReport report) 18 | { 19 | 20 | FileUtil.DeleteFileOrDirectory(_resourcesDirCreated ? env.resourcesDirPath : env.runtimeFilePath); 21 | 22 | _resourcesDirCreated = false; 23 | 24 | } 25 | 26 | public int callbackOrder { get; } 27 | 28 | public void OnPreprocessBuild(BuildReport report) 29 | { 30 | 31 | if (File.Exists(env.runtimeFilePath)) 32 | { 33 | 34 | throw new Exception($"{env.runtimeFilePath} already exists. Remove this file before continuing."); 35 | 36 | } 37 | 38 | if (File.Exists(env.editorFilePath)) 39 | { 40 | 41 | if (!Directory.Exists(env.resourcesDirPath)) 42 | { 43 | 44 | Directory.CreateDirectory(env.resourcesDirPath); 45 | 46 | _resourcesDirCreated = true; 47 | 48 | } 49 | 50 | FileUtil.CopyFileOrDirectory(env.editorFilePath, env.runtimeFilePath); 51 | 52 | } 53 | 54 | } 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Editor/Scripts/BuildTools.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 724aa1685dbc44d392d72d6235b7f96c 3 | timeCreated: 1615267481 -------------------------------------------------------------------------------- /Editor/Scripts/EnvironmentFileEditor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Scott Doxey. All Rights Reserved. Licensed under the MIT License. See LICENSE in the project root for license information. 2 | 3 | #if UNITY_EDITOR 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using UnityEditor; 9 | using UnityEngine; 10 | 11 | namespace CandyCoded.env.Editor 12 | { 13 | 14 | public class EnvironmentFileEditor : EditorWindow 15 | { 16 | 17 | private Vector2 scrollPosition; 18 | 19 | private List> tempConfig = new List>(); 20 | 21 | private void Update() 22 | { 23 | 24 | if (EditorApplication.isPlaying && !EditorApplication.isPaused) 25 | { 26 | 27 | Repaint(); 28 | 29 | } 30 | 31 | } 32 | 33 | private void OnEnable() 34 | { 35 | 36 | LoadEnvironmentFile(); 37 | 38 | } 39 | 40 | private void OnGUI() 41 | { 42 | 43 | if (!File.Exists(env.editorFilePath)) 44 | { 45 | 46 | if (GUILayout.Button("Create .env File")) 47 | { 48 | 49 | try 50 | { 51 | 52 | File.WriteAllText(env.editorFilePath, 53 | env.SerializeEnvironmentDictionary( 54 | new Dictionary { { "VARIABLE_NAME", "VALUE" } })); 55 | 56 | LoadEnvironmentFile(); 57 | 58 | } 59 | catch (Exception err) 60 | { 61 | 62 | EditorUtility.DisplayDialog("Error", err.Message, "Ok"); 63 | 64 | } 65 | 66 | } 67 | 68 | return; 69 | 70 | } 71 | 72 | scrollPosition = GUILayout.BeginScrollView(scrollPosition); 73 | 74 | for (var i = 0; i < tempConfig.Count; i += 1) 75 | { 76 | 77 | GUILayout.BeginHorizontal(); 78 | 79 | var key = GUILayout.TextField(tempConfig[i].Item1, GUILayout.ExpandWidth(false), 80 | GUILayout.Width(position.width * 0.25f)); 81 | 82 | var value = GUILayout.TextField(tempConfig[i].Item2, GUILayout.ExpandWidth(true)); 83 | 84 | if (tempConfig.Count == 1) 85 | { 86 | 87 | GUI.enabled = false; 88 | 89 | } 90 | 91 | if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) 92 | { 93 | 94 | tempConfig.RemoveAt(i); 95 | 96 | continue; 97 | 98 | } 99 | 100 | if (tempConfig.Count == 1) 101 | { 102 | 103 | GUI.enabled = true; 104 | 105 | } 106 | 107 | if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) 108 | { 109 | 110 | tempConfig.Insert(i + 1, new Tuple("", "")); 111 | 112 | continue; 113 | 114 | } 115 | 116 | GUILayout.EndHorizontal(); 117 | 118 | if (!key.Equals(tempConfig[i].Item1) || !value.Equals(tempConfig[i].Item2)) 119 | { 120 | 121 | tempConfig[i] = new Tuple(key, value); 122 | 123 | } 124 | 125 | } 126 | 127 | if (GUILayout.Button("Save Changes")) 128 | { 129 | 130 | try 131 | { 132 | 133 | File.WriteAllText(env.editorFilePath, env.SerializeEnvironmentDictionary( 134 | tempConfig.ToDictionary(item => item.Item1, item => item.Item2))); 135 | 136 | } 137 | catch (Exception err) 138 | { 139 | 140 | EditorUtility.DisplayDialog("Error", err.Message, "Ok"); 141 | 142 | } 143 | 144 | } 145 | 146 | if (GUILayout.Button("Revert Changes")) 147 | { 148 | 149 | LoadEnvironmentFile(); 150 | 151 | } 152 | 153 | if (GUILayout.Button("Delete .env File")) 154 | { 155 | 156 | if (EditorUtility.DisplayDialog("Confirm", $"Delete {env.editorFilePath}?", "Ok", "Cancel")) 157 | { 158 | 159 | File.Delete(env.editorFilePath); 160 | 161 | } 162 | 163 | } 164 | 165 | GUILayout.EndScrollView(); 166 | 167 | } 168 | 169 | [MenuItem("Window/CandyCoded/Environment File Editor")] 170 | public static void ShowWindow() 171 | { 172 | 173 | GetWindow(typeof(EnvironmentFileEditor), false, "Environment File Editor", true); 174 | 175 | } 176 | 177 | private void LoadEnvironmentFile() 178 | { 179 | 180 | if (File.Exists(env.editorFilePath)) 181 | { 182 | 183 | tempConfig = env.ParseEnvironmentFile().Select(item => new Tuple(item.Key, item.Value)) 184 | .ToList(); 185 | 186 | } 187 | 188 | } 189 | 190 | } 191 | 192 | } 193 | #endif 194 | -------------------------------------------------------------------------------- /Editor/Scripts/EnvironmentFileEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cff657a75704ca293a63fa3c914a9ab 3 | timeCreated: 1617436287 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 Scott Doxey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 349c5bc9fb47c42e99d73e6dd91a3c8b 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # env 2 | 3 | > Use `.env` files in your Unity projects. 4 | 5 | [![npm](https://img.shields.io/npm/v/xyz.candycoded.env)](https://www.npmjs.com/package/xyz.candycoded.env) 6 | 7 | ### Unity Package Manager 8 | 9 | 10 | 11 | #### Git 12 | 13 | ```json 14 | { 15 | "dependencies": { 16 | "xyz.candycoded.env": "https://github.com/CandyCoded/env.git#v1.1.5", 17 | ... 18 | } 19 | } 20 | ``` 21 | 22 | #### Scoped UPM Registry 23 | 24 | ```json 25 | { 26 | "dependencies": { 27 | "xyz.candycoded.env": "1.1.5", 28 | ... 29 | }, 30 | "scopedRegistries": [ 31 | { 32 | "name": "candycoded", 33 | "url": "https://registry.npmjs.com", 34 | "scopes": ["xyz.candycoded"] 35 | } 36 | ] 37 | } 38 | ``` 39 | 40 | ## Usage 41 | 42 | Create a `.env` file at the root of your project, outside of the `Assets/` folder, and paste the following content: 43 | 44 | ``` 45 | DEBUG=true 46 | ``` 47 | 48 | Or use the Editor panel found by navigating to **Window** > **CandyCoded** > **Environment File Editor**. 49 | 50 | 51 | 52 | 53 | > Note: Don't forget to add `.env` to your `.gitignore` file before committing any changes! 54 | 55 | Now you can reference the variables and their values with the key specified in the `.env` file. Supported value types 56 | are `string`, `bool`, `double`, `float`, and `int`. 57 | 58 | ```csharp 59 | if (env.TryParseEnvironmentVariable("DEBUG", out bool isDebug)) 60 | { 61 | Debug.Log($"Debug Mode is: {(isDebug ? "ON" : "OFF")}"); 62 | } 63 | ``` 64 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12714644fb99d4b4d8ebde55ac0096af 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cea83d9a96b548d580858a96aa58e21e 3 | timeCreated: 1615267409 -------------------------------------------------------------------------------- /Scripts/env.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Scott Doxey. All Rights Reserved. Licensed under the MIT License. See LICENSE in the project root for license information. 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using UnityEngine; 9 | 10 | namespace CandyCoded.env 11 | { 12 | 13 | public static class env 14 | { 15 | 16 | public const string filename = "env"; 17 | 18 | public static readonly string editorFilePath = Path.Combine(Application.dataPath, "../", $".{filename}"); 19 | 20 | public static readonly string resourcesDirPath = Path.Combine(Application.dataPath, "Resources"); 21 | 22 | public static readonly string runtimeFilePath = Path.Combine(resourcesDirPath, $"{filename}.txt"); 23 | 24 | private static Dictionary _variables = new(); 25 | 26 | public static Dictionary variables 27 | { 28 | get 29 | { 30 | if (_variables.Count == 0) 31 | { 32 | _variables = ParseEnvironmentFile(); 33 | } 34 | 35 | return _variables; 36 | } 37 | } 38 | 39 | public static Dictionary ParseEnvironmentFile(string contents) 40 | { 41 | 42 | return contents.Trim().Split(new string[] { Environment.NewLine }, StringSplitOptions.None).Where(l => 43 | !string.IsNullOrWhiteSpace(l) && !l.StartsWith("#") && 44 | l.IndexOf("=", StringComparison.Ordinal) != -1) 45 | .ToDictionary(l => l.Substring(0, l.IndexOf("=", StringComparison.Ordinal)).Trim(), 46 | l => l.Substring(l.IndexOf("=", StringComparison.Ordinal) + 1).Trim().Trim('"', '\'')); 47 | 48 | } 49 | 50 | public static string SerializeEnvironmentDictionary(Dictionary dictionary) 51 | { 52 | 53 | if (dictionary.Any(item => string.IsNullOrEmpty(item.Key))) 54 | { 55 | 56 | throw new Exception("One or more keys are missing! Please fix and try again."); 57 | 58 | } 59 | 60 | return string.Join(Environment.NewLine, 61 | dictionary.Select(item => $"{item.Key}={item.Value}")); 62 | 63 | } 64 | 65 | public static Dictionary ParseEnvironmentFile() 66 | { 67 | 68 | #if UNITY_EDITOR 69 | if (File.Exists(editorFilePath)) 70 | { 71 | return ParseEnvironmentFile(File.ReadAllText(editorFilePath, Encoding.UTF8)); 72 | } 73 | #else 74 | var contents = Resources.Load(filename); 75 | 76 | if (contents) 77 | { 78 | return ParseEnvironmentFile(contents.text); 79 | } 80 | #endif 81 | return new Dictionary(); 82 | 83 | } 84 | 85 | public static bool TryParseEnvironmentVariable(string key, out string value) 86 | { 87 | 88 | return variables.TryGetValue(key, out value); 89 | 90 | } 91 | 92 | public static bool TryParseEnvironmentVariable(string key, out bool value) 93 | { 94 | 95 | return bool.TryParse(variables[key], out value); 96 | 97 | } 98 | 99 | public static bool TryParseEnvironmentVariable(string key, out double value) 100 | { 101 | 102 | return double.TryParse(variables[key], out value); 103 | 104 | } 105 | 106 | public static bool TryParseEnvironmentVariable(string key, out float value) 107 | { 108 | 109 | return float.TryParse(variables[key], out value); 110 | 111 | } 112 | 113 | public static bool TryParseEnvironmentVariable(string key, out int value) 114 | { 115 | 116 | return int.TryParse(variables[key], out value); 117 | 118 | } 119 | 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /Scripts/env.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca1c9375e8403436b8d16d7631e807f6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xyz.candycoded.env", 3 | "displayName": "env", 4 | "version": "1.1.5", 5 | "unity": "2019.1", 6 | "unityRelease": "0f1", 7 | "description": "Use .env files in your Unity projects.", 8 | "license": "MIT", 9 | "dependencies": {}, 10 | "keywords": [ 11 | "env" 12 | ], 13 | "author": { 14 | "name": "Scott Doxey", 15 | "email": "hello@scottdoxey.com", 16 | "homepage": "http://scottdoxey.com/" 17 | }, 18 | "homepage": "https://github.com/CandyCoded/env", 19 | "repository": { 20 | "type": "git", 21 | "url": "git@github.com:CandyCoded/env.git" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 78bfe04bf0a7746929b8cd9cd29778b4 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------