{"id":13661211,"url":"https://github.com/OlegDzhuraev/Core","last_synced_at":"2025-04-24T23:32:07.746Z","repository":{"id":125503104,"uuid":"371966415","full_name":"OlegDzhuraev/Core","owner":"OlegDzhuraev","description":"My tools and extensions for Unity engine, which I'm use in all my projects to speedup development.","archived":false,"fork":false,"pushed_at":"2025-04-19T17:13:20.000Z","size":242,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-19T20:14:58.035Z","etag":null,"topics":["csharp","gamedev","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OlegDzhuraev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-05-29T12:22:27.000Z","updated_at":"2025-04-19T17:13:23.000Z","dependencies_parsed_at":"2023-11-22T18:38:10.630Z","dependency_job_id":"3c02676e-2ff8-4291-80f0-ab2a1954583b","html_url":"https://github.com/OlegDzhuraev/Core","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlegDzhuraev%2FCore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlegDzhuraev%2FCore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlegDzhuraev%2FCore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OlegDzhuraev%2FCore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OlegDzhuraev","download_url":"https://codeload.github.com/OlegDzhuraev/Core/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250727748,"owners_count":21477366,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","gamedev","unity"],"created_at":"2024-08-02T05:01:31.097Z","updated_at":"2025-04-24T23:32:02.735Z","avatar_url":"https://github.com/OlegDzhuraev.png","language":"C#","funding_links":[],"categories":["C\\#"],"sub_categories":[],"readme":"# Core\nMy tools and extensions for Unity Engine, which I'm use in all my projects to speedup development. It allows to reduce amount of code - by implementing frequently used functionality. Mainly there stored tools, which is not enough big or good to move them in their own repos.\n\nThis repo was exposed to public only just because I want to import it easily with Package Manager, but if you're interested, feel free to use it.\n\nList of the main included features you can read below. \n\n## Tools\nTools can be found in the top menu, the button named **Tools**.\n\n### Setup Project Tool\nTool allows to atuo-generate project folders structure and quckly tune most frequently needed for me Editor and Project settings.\n\n## Level Design Tools\nThese tools also can be found in the top menu in **Tools** menu item.\n\n### Transform Randomize\nAllows to randomize rotation, scale and position of the scene-selected transforms.\n\n## Extensions\nContains some extensions for Transform, Color, Vectors, Random and other components. Some examples below.\n\n### Random extensions\nGet random element from a list or array:\n```cs\nList\u003cT\u003e someList = new List\u003cT\u003e();\n\nvoid Start() \n{\n  var randomedT = someList.Random();\n}\n```\n\nRandomize vector values:\n```cs\nVector3 vec = RandomExtensions.GetRandomizedVector3(-5f, 5f);\n```\n\n### Physics extensions\nYou can quickly find objects of specific type T in sphere:\n```cs\nPhysicsExtensions.GetObjectsOfTypeInSphere\u003cT\u003e(pos, radius);\n\n// for 2d\nPhysicsExtensions.GetObjectsOfTypeIn2DCircle\u003cT\u003e(pos, radius);\n```\n\n## Audio\nAllows to play audio directly from code without setting up AudioSources in prefabs.\n\nFull initialization and usage example:\n```cs\nusing InsaneOne.Core;\nusing UnityEngine;\n\npublic class TestAudio : MonoBehaviour\n{\n  [SerializeField] AudioClip clip;\n\n  void Start()\n  {\n    // Initializes Core Audio system\n    Audio.Init();\n\n    // Configurations for 3D and 2D sounds.\n    var data3DSound = new AudioGroupData()\n    {\n      Is3D = true,\n      MinDistance3D = 2f,\n      MaxDistance3D = 60f,\n      DopplerLevel = 0f\n    };\n      \n    var data2DSound = new AudioGroupData() { Is3D = false };\n\n    // Setting up some different audio layers, both for 3d and 2d sounds. Audio layers is useful to limiting specific type sounds amount,\n    // also audio layer stores audio settings, for example Min/Max distance or Audio Mixer Group (see code for more info).\n    Audio.UpdateLayer(AudioLayer.Interaction, data3DSound);\n    Audio.AddSourcesInLayer(AudioLayer.Interaction, 8);\n      \n    Audio.UpdateLayer(AudioLayer.Ambience, data3DSound);\n    Audio.AddSourcesInLayer(AudioLayer.Ambience, 3);\n      \n    Audio.UpdateLayer(AudioLayer.UI, data2DSound);\n    Audio.AddSourcesInLayer(AudioLayer.UI, 2);\n  }\n\n  void Update()\n  {\n    // Playing 3D audio (Interaction audio layer was setup as 3d earlier) in specified layer with 50% volume and 10% pitch randomization at transform position.\n    if (Input.GetMouseButtonDown(0))\n      Audio.Play(AudioLayer.Interaction, clip, transform.position, 0.5f, 0.1f);\n  }\n}\n\n// Used just to make more readable code\npublic static class AudioLayer\n{\n  public const int Ambience = 10;\n  public const int Interaction = 20;\n  public const int UI = 100;\n}\n```\n### AudioData\nExtension for AudioClip. Allows to setup more sound settings in the inspector:\n- Sound variations\n- Volume\n- Pitch random\n- Loop toggle\n\nCan be used with Audio system, described above.\nMain idea is to move sound setup from the prefab AudioSource settings to ScriptableObject or your own scripts. \n\n```cs\n[SerializeField] AudioData data;\n\n// \u003c...\u003e\nAudio.Play(AudioLayer.Interaction, data, transform.position);\n```\n\n### SoundMixer\nAllows to mix several AudioSources, driven by some mix paramter. For example, changing sound by Engine RPM change.\n\n```cs\nusing InsaneOne.Core;\nusing UnityEngine;\n\npublic class TestSoundMix : MonoBehaviour\n{\n  SoundMixer soundMixer;\n  \n  void Start()\n  {\n      // setup audio system before below code runs (see prev example), if you want to use this system\n\n      // getting audio from the Audio system of previous example. You can use AudioSources directly, if you dont need this system.\n      Audio.TryGetFreeSource(AudioLayer.Interaction, out var sourceA);\n      Audio.TryGetFreeSource(AudioLayer.Interaction, out var sourceB);\n\n      // initialization of the sound mixer (you can pass any audio sources amount)\n      soundMixer = new SoundMixer(sourceA, sourceB);\n  }\n\n  void Update()\n  {\n    // set any mix value from 0 to 1, and volume of specified sounds will be changed accordingly\n    if (Input.GetKeyDown(KeyCode.Alpha1)) \n        soundMixer.UpdateMix(0.5f);\n\n    if (Input.GetKeyDown(KeyCode.Alpha2)) \n        soundMixer.UpdateMix(Random.Range(0f, 1f));\n\n    // you also can tween your value and pass it to the UpdateMix method.\n  }\n}\n```\n\n## Templates\nIn the Project Manager window, in context menu now exist a new partition **InsaneOne/Templates**, which includes some ready code file templates, which are frequently used by me in gamedev. Possible, will be removed in future or reworked to smth better, actually not very useful.\n\n## UI\nI've added some new elements and templates for UI, which is missing in Unity default package. Now it still very simple, but I want to improve it in future.\n\n**Floating panel** - allows to create floating in a 3d world (following some object) UI-panel with some info.\n\n**TabControl** - classic tab control element.\n\n**PopupWindow** - allows to create a popup window with any title, text and Apply/Cancel buttons with apply callback.\n\n**Fader** - commonly used in a game projects. Fades screen alpha into some color. Requires DOTween.\n\n## Localization\nRepo contains localization extension, which allows to read CSV-based localization and translate ingame texts for selected language.\n\n```cs\n// firstly, you need to run this in some game initialization code:\nLocalization.Initialize();\n\n// use SetLanguage to change game lang:\nLocalization.SetLanguage(\"English\"); // id of the lang\n\n// Get any localized text:\nvar text = Localization.GetText(\"localeString\");\n```\n\nAlso, there exist useful component for localization without code - **LocalizedTMPText**. Add it to your text object and write localeId in its text field.\n\nLocalization uses **StreamingAssets** to contain a localization file - to allow modify it without game rebuild or allow modding of localization for players.\n\n## Architect\nSome code architect ready-made things. Probably not the best ones :)\n\n### Context\nContext class allows you to semi-automatically provide some specific context data-class to any of your components.\n\nInitialization:\n```cs\nclass GameBootstrap : MonoBehaviour\n{\n  void Awake()\n  {\n    var context = new YourContext(); // YourContext - it can be any your class with data, which should be shared.\n    // setup here your context class with required data\n    Context\u003cYourContext\u003e.Initialize(context); // will initialize all objects on scene, which have components, deriven from the ContextBehaviour\u003cYourContext\u003e by injecting your context.\n  }\n}\n```\n\nIn order to provide context to a new spawned objects, use Context.Spawn() instead of GameObject.Instantiate():\n```cs\nContext\u003cYourContext\u003e.Spawn(prefab, new Vector3(15, 0, 25)); // you can pass position, rotation and parent like in the original GameObject.Instantiate\n```\n\nContext access in your component:\n```cs\nclass YourClass : ContextBehaviour\u003cYourContext\u003e\n{\n  void Start()\n  {\n    Debug.Log(context.SomeVariable); // you can access any context variable now.\n  }\n}\n```\n\n**Note:** You need to initialize Context in **Awake** before any other components. Use **ScriptExecutionOrder** for this.\n\nAdditional info: The **Context** class is implemented in this way to reduce the number of required actions on the developer's part. An alternative would be some kind of initialization of ContextBehaviour via Awake method of this abstract class, but I found it uneffective to override this method in your own classes every time.\n\n### ServiceLocator\nAlternative to the Singleton.\n\n```cs\n// setup in the game initialization code:\nServiceLocator.Register(new SomeClass());\n\n// ...\n\n// usage in any other class:\nvar someClass = ServiceLocator.Get\u003cSomeClass\u003e();\n```\n\n## Components\nThis library contains some built-in components. You can check it in the Sources/Components folder.\n\nIn this partition can be found info about some of these components.\n\n### Teams\nA lot of games have teams for game players and NPCs. There is implementation for this functionality.\n\nCurrently, team is **int** value.\n\n**How to use:**\n```cs\n[SerializeField] GameObject enemy;\n\nvoid Start()\n{\n  gameObject.SetTeam(0); // setting this object team\n  enemy.SetTeam(1); // setting different team to the enemy object\n}\n\nvoid Update()\n{\n  var myTeam = gameObject.GetTeam(); // getting team of this object\n  var enemyTeam = enemy.GetTeam(); // getting Enemy object team.\n\n  if (myTeam != enemyTeam)\n    DoAttack(enemy); // proceed some action if teams are different\n}\n```\n\nActually, this code works with custom **TeamBehaviour** component - adds it to any teamed objects, and stores actual object team in this component.\n\nYou can also create TeamsSettings asset, and setup, which teams will be enemies to others. To create it, click **RMB** in **Project Window**, and in the context menu select **InsaneOne** -\u003e **TeamsSettings**.\n\nAfter creation, drag'n'drop it to the field **Teams Settings** of the **CoreData** asset (which is created automatically).\n\nTo use your teams settings:\n\n```cs\nvar isEnemies = gameObject.IsTeamEnemyTo(otherGameObject); // API can change\n```\n\n## Utility\n\n### Pause Utility\nAllows to pause game and use multiple pause affectors object. \nSo, for example, two different objects wants to pause game. Next call of unpause will actually **not** unpause game until **both** affector objects call it. \n\n```cs\nusing InsaneOne.Core.Utility;\n\nclass SomePauserObject : MonoBehaviour, IPauseAffector\n{\n  void SomeAction()\n  {\n    PauseUtility.Pause(this);\n  }\n\n  void SomeOtherAction()\n  {\n    PauseUtility.Unpause(this);\n  }\n}\n```\n\n### Timer\nDeltatime-based timer to speedup any timer-based features creation.\n```cs\nTimer timer;\n\nvoid Start() \n{\n  timer = new Timer(5f);\n}\n\nvoid Update() \n{\n  timer.DoTick()\n  \n  if (timer.IsReady())\n  {\n    // do something\n  }\n}\n```\n\n### DelayedDestruction\nAllows to destroy a GameObject with attached component with the time delay.\n```cs\ngameObject.DelayedDestroy(3f);\n```\n\n### MainCamera\nMost of the projects use only one camera, which can be received by calling Camera.main. But in the old Unity versions it is not cached and can cause performance issues. This utility helps to solve this problem by caching the Main Camera. \n\n```cs\nvar cam = MainCamera.Cached;\n```\n\n## Shaders\nThis repo contains some PBR shaders, mainly to allow load textures from one mask (Metal-Roughness-AO, etc).\n\n## License\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOlegDzhuraev%2FCore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FOlegDzhuraev%2FCore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FOlegDzhuraev%2FCore/lists"}