├── UnityApiExtensions.asmdef ├── CHANGELOG.md.meta ├── LICENSE.md.meta ├── README.md.meta ├── package.json.meta ├── Scripts.meta ├── Scripts ├── Editor.meta ├── Editor │ ├── ExtensionsEditor.asmdef.meta │ ├── MissingScriptsRemover.cs.meta │ ├── ExtensionsEditor.asmdef │ └── MissingScriptsRemover.cs ├── RayExtensions.cs.meta ├── CameraExtensions.cs.meta ├── Color32Extensions.cs.meta ├── ColorExtensions.cs.meta ├── DoubleExtensions.cs.meta ├── FloatExtensions.cs.meta ├── GraphicExtensions.cs.meta ├── IListExtensions.cs.meta ├── ObjectExtensions.cs.meta ├── RectExtensions.cs.meta ├── SceneExtensions.cs.meta ├── SceneReference.cs.meta ├── Vector2Extensions.cs.meta ├── Vector3Extensions.cs.meta ├── Vector4Extensions.cs.meta ├── CanvasScalerExtensions.cs.meta ├── ComponentExtensions.cs.meta ├── GameObjectExtensions.cs.meta ├── IComparableExtensions.cs.meta ├── IEnumerableExtensions.cs.meta ├── IEquatableExtensions.cs.meta ├── QuaternionExtensions.cs.meta ├── RectTransformExtensions.cs.meta ├── RenderTextureExtensions.cs.meta ├── TransformExtensions.cs.meta ├── Vector2IntExtensions.cs.meta ├── Vector3IntExtensions.cs.meta ├── CanvasScalerExtensions.cs ├── IComparableExtensions.cs ├── ObjectExtensions.cs ├── IEquatableExtensions.cs ├── FloatExtensions.cs ├── DoubleExtensions.cs ├── ComponentExtensions.cs ├── SceneExtensions.cs ├── RenderTextureExtensions.cs ├── RayExtensions.cs ├── GameObjectExtensions.cs ├── SceneReference.cs ├── RectExtensions.cs ├── IListExtensions.cs ├── GraphicExtensions.cs ├── ColorExtensions.cs ├── Color32Extensions.cs ├── Vector2IntExtensions.cs ├── IEnumerableExtensions.cs ├── Vector2Extensions.cs ├── RectTransformExtensions.cs ├── QuaternionExtensions.cs ├── Vector3IntExtensions.cs └── CameraExtensions.cs ├── UnityApiExtensions.asmdef.meta ├── package.json ├── CHANGELOG.md ├── .gitignore ├── README.md └── LICENSE.md /UnityApiExtensions.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UnityApiExtensions" 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59b952c0c94bf48f6aa85fcefb18a9ee 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 01d121959599145239331405a9e0213e 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9632a9f444840a54ba10a65fe32f53d4 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8bbc4d4b5c0a045ca93b9bcb3c859492 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f664c25ea3212406aaf11218628e9deb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d742424b27c00be46acef63aecb2bca0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityApiExtensions.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: deb967d224d3144cea6d67fbcbcf76f1 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Scripts/Editor/ExtensionsEditor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd2ef4a1fbbebca45bd1fc8a08112282 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Scripts/RayExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 806de8bab26686340b1c1d5ab89e6d16 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/CameraExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 011c57431a922f94b9c4c7ec1228865f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Color32Extensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9c3dd36d0d04234d9552bc03d712005 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/ColorExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 46af64433c4ccc24ca86f372a1016839 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/DoubleExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 17da1c7c6dda4ed4089383010e1772bf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/FloatExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30859a8f19fdb8c4fa5688034ba0610b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/GraphicExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf5e11ae54ae07e41af44898e1fcf1a3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/IListExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f82871def1670ca418c5fb2b5fecfa3d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/ObjectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bbb53fa295c8a0642946e97049c5ec09 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/RectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9dfdc041ba0f3854583f5647b697919b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/SceneExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a598fe46620e6c048a416c673069442b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/SceneReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43096ef4197f5334ca1912ce59037963 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Vector2Extensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: febd20201d83e6544b100e80b55095cc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Vector3Extensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 40fb2d2ed19fcc74eb3156df03336846 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Vector4Extensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51bdad0bd776d1941bf91a499f2ccf28 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/CanvasScalerExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 218fc879fd65fc44ead13258606df00d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/ComponentExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca8764fd58b995f43a113e4be8d79d28 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/GameObjectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 309420a6293e10c4a8287f7e4c448ac7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/IComparableExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7adbebcfa259ff40b1c501abdbc0f23 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/IEnumerableExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2aec9d7292ca844e86d0a91cb62a2b0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/IEquatableExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba66dc7433551374f8b3e29a4e1c437c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/QuaternionExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c51c5ae7b71fcc7458fc3cc11199cb09 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/RectTransformExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2b0702da89a03c41a1c575e512e700f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/RenderTextureExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90d11e24769720740ac5eb51349bde1a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/TransformExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cebf6ef0a90a05d48b301e1ed031f0ec 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Vector2IntExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4dc2aec85a834354c8b5796859ec0685 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Vector3IntExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c17a3e6254e91bd4a91c1b6ec21a6558 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Scripts/Editor/MissingScriptsRemover.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: baf71069a799ec344b67fc06f9b21182 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": "com.codomaster.extensions", 3 | "version": "1.1.1", 4 | "displayName": "Unity API Extensions", 5 | "description": "This package contains a lot of extension methods for unity, which make developing more convenient.", 6 | "unity": "2021.1", 7 | "author": { 8 | "name": "codomaster ", 9 | "email": "codomaster.me@gmail.com", 10 | "url": "https://t.me/codomaster" 11 | } 12 | } -------------------------------------------------------------------------------- /Scripts/Editor/ExtensionsEditor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ExtensionsEditor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:b52c6daf0f9f3974fb04e400a06c9369" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v1.1.0 2 | ### Fixes and new methods. 3 | - `GetRandomElement` methods renamed to `GetRandom`. 4 | - `Except` and `Shuffled` methods now return list. 5 | - Added `Shuffle` and `Swap` methods to `IList`. 6 | - Added `AsRect` method to `Transform`. Added `Rotate` method to `Vector2`. 7 | 8 | # v1.0.6 9 | ### fixes and updates: 10 | - Added support for `Approx` and `WithRandomSign` methods to `double`. 11 | - Remove `MaxComponentIndex` and `MinComponentIndex` methods, now just use `Max/MinComponent` instead. 12 | - Small fixes. -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /[Uu][Ww][Pp]/ 7 | /[Ll]ogs/ 8 | /[Aa]ssets/[Aa]ssetStoreTools* 9 | /[Uu]serSettings 10 | 11 | # Visual Studio 2015 cache directory and files 12 | /.vs/ 13 | /.vscode/ 14 | /.idea/ 15 | /.vsconfig 16 | 17 | # Autogenerated solution and project files 18 | ExportedObj/ 19 | .consulo/ 20 | *.csproj 21 | *.unityproj 22 | *.sln 23 | *.suo 24 | *.tmp 25 | *.user 26 | *.userprefs 27 | *.pidb 28 | *.booproj 29 | *.svd 30 | *.pdb 31 | 32 | 33 | # Unity3D generated meta files 34 | *.pidb.meta 35 | 36 | # Unity3D Generated File On Crash Reports 37 | sysinfo.txt 38 | 39 | # Builds 40 | *.apk 41 | *.unitypackage -------------------------------------------------------------------------------- /Scripts/CanvasScalerExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class CanvasScalerExtensions 7 | { 8 | /// 9 | /// Get scale factor which canvas scaler calculated when work in mode. 10 | /// 11 | /// The canvas scaler. 12 | /// Calculated scale factor. 13 | public static float GetScaleFactor(this CanvasScaler scaler) 14 | { 15 | return Mathf.Lerp(Screen.width / scaler.referenceResolution.x, Screen.height / scaler.referenceResolution.y, scaler.matchWidthOrHeight); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Scripts/IComparableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class IComparableExtensions 6 | { 7 | /// 8 | /// Checks if the object is on the specified interval. 9 | /// 10 | /// Value type. 11 | /// Target value. 12 | /// Interval's start value. 13 | /// Interval's end value. 14 | /// Is the beginning of the interval included? 15 | /// Is the end of the interval included? 16 | /// if the is between and . 17 | public static bool IsBetween(this T value, T a, T b, bool aInclusive = true, bool bInclusive = true) where T: IComparable 18 | { 19 | if (a.CompareTo(b) == 1) 20 | { 21 | (a, b) = (b, a); 22 | (aInclusive, bInclusive) = (bInclusive, aInclusive); 23 | } 24 | 25 | return (aInclusive ? value.CompareTo(a).EqualsToAny(0, 1) : value.CompareTo(a) == 1) && (bInclusive ? value.CompareTo(b).EqualsToAny(-1, 0) : value.CompareTo(b) == -1); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Scripts/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class ObjectExtensions 6 | { 7 | /// 8 | /// Checks if the equals to all elements of array. 9 | /// 10 | /// Source type. 11 | /// Object to compare. 12 | /// Array with objects to compare. 13 | /// if the all element of are equals to 14 | public static bool EqualsToAll(this object obj, params object[] objects) => objects.All(o => o.Equals(obj)); 15 | 16 | /// 17 | /// Checks if the equals to at least one of elements of array. 18 | /// 19 | /// Source type. 20 | /// Object to compare. 21 | /// Array with objects to compare. 22 | /// if at least one of all elements of are equals to . 23 | public static bool EqualsToAny(this object obj, params object[] objects) => objects.Any(o => o.Equals(obj)); 24 | } 25 | } -------------------------------------------------------------------------------- /Scripts/IEquatableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class IEquatableExtensions 7 | { 8 | /// 9 | /// Checks if the equals to all elements of array. 10 | /// 11 | /// Source type. 12 | /// Object to compare. 13 | /// Array with objects to compare. 14 | /// if the all element of are equals to . 15 | public static bool EqualsToAll(this T value, params T[] values) where T : IEquatable => values.All(o => o.Equals(value)); 16 | 17 | /// 18 | /// Checks if the equals to at least one of elements of array. 19 | /// 20 | /// Source type. 21 | /// Object to compare. 22 | /// Array with objects to compare. 23 | /// if at least one of all elements of are equals to . 24 | public static bool EqualsToAny(this T value, params T[] values) where T : IEquatable => values.Any(o => o.Equals(value)); 25 | } 26 | } -------------------------------------------------------------------------------- /Scripts/FloatExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class FloatExtensions 6 | { 7 | /// 8 | /// Remap a value from one range to another. 9 | /// 10 | /// Source value. 11 | /// Source min. 12 | /// Source max. 13 | /// Target min. 14 | /// Target max 15 | /// Remaped value. 16 | public static float Remap(this float value, float min1, float max1, float min2, float max2) 17 | { 18 | return min2 + (value - min1) * (max2 - min2) / (max1 - min1); 19 | } 20 | 21 | /// 22 | /// Checks for approximate equality with . 23 | /// 24 | /// First operand. 25 | /// Second operand. 26 | /// if the variables are the same. 27 | public static bool Approx(this float value, float other) => Mathf.Approximately(value, other); 28 | 29 | /// 30 | /// Randomly changes the sign (+ or -) of . 31 | /// 32 | /// Target value. 33 | /// Value with randomed sign. 34 | public static float WithRandomSign(this float value) => value * (Random.Range(0, 2) * 2 - 1); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Scripts/DoubleExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Random = UnityEngine.Random; 4 | 5 | namespace Codomaster.Extensions 6 | { 7 | public static class DoubleExtensions 8 | { 9 | /// 10 | /// Remap a value from one range to another. 11 | /// 12 | /// Source value. 13 | /// Source min. 14 | /// Source max. 15 | /// Target min. 16 | /// Target max 17 | /// Remaped value. 18 | public static double Remap(this double value, double min1, double max1, double min2, double max2) 19 | { 20 | return min2 + (value - min1) * (max2 - min2) / (max1 - min1); 21 | } 22 | 23 | /// 24 | /// Checks for approximate equality with and . 25 | /// 26 | /// First operand. 27 | /// Second operand. 28 | /// If difference between and is smaller than this, then result is true. 29 | /// if the variables are the same. 30 | public static bool Approx(this double value, double other, double minDifference = 1E-17) => Math.Abs(value - other) <= minDifference; 31 | 32 | /// 33 | /// Randomly changes the sign (+ or -) of . 34 | /// 35 | /// Target value. 36 | /// Value with randomed sign. 37 | public static double WithRandomSign(this double value) => value * (Random.Range(0, 2) * 2 - 1); 38 | } 39 | } -------------------------------------------------------------------------------- /Scripts/ComponentExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Codomaster.Extensions 6 | { 7 | public static class ComponentExtensions 8 | { 9 | /// 10 | /// Gets component from 's game object. If it no exist, new one will be created. 11 | /// 12 | /// Component type. 13 | /// The component. 14 | /// Game object's component. 15 | public static T GetOrAddComponent(this Component component) where T : Component 16 | { 17 | return component.gameObject.GetOrAddComponent(); 18 | } 19 | 20 | /// 21 | /// Trying to get component in this or any it's children. 22 | /// 23 | /// Component type. 24 | /// The component. 25 | /// Target component. 26 | /// Should we find component on inactive game objects? 27 | /// if component was found. 28 | public static bool TryGetComponentInChildren(this Component sourceComponent, out T component, bool includeInactive = false) where T : Component 29 | { 30 | return component = sourceComponent.gameObject.GetComponentInChildren(includeInactive); 31 | } 32 | 33 | /// 34 | /// Trying to get component in this or any it's parent. 35 | /// 36 | /// Component type. 37 | /// The component. 38 | /// Target component. 39 | /// Should we find component on inactive game objects? 40 | /// if component was found. 41 | public static bool TryGetComponentInParent(this Component sourceComponent, out T component, bool includeInactive = false) where T : Component 42 | { 43 | return component = sourceComponent.gameObject.GetComponentInParent(includeInactive); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Scripts/SceneExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using UnityEngine; 3 | using UnityEngine.SceneManagement; 4 | 5 | namespace Codomaster.Extensions 6 | { 7 | public static class SceneExtensions 8 | { 9 | /// 10 | /// Finds game object in scene with component. 11 | /// 12 | /// Component type. 13 | /// Target scene. 14 | /// Should we find inactive game objects? 15 | /// Founded game object. 16 | public static T FindObjectOfType(this Scene scene, bool includeInactive = false) where T : Component 17 | { 18 | foreach (var root in scene.GetRootGameObjects().Where(r => r.activeSelf || includeInactive)) 19 | { 20 | if (root.TryGetComponentInChildren(out T component, includeInactive)) 21 | return component; 22 | } 23 | 24 | return null; 25 | } 26 | 27 | /// 28 | /// Finds game objects in scene with component. 29 | /// 30 | /// Component type. 31 | /// Target scene. 32 | /// Should we find inactive game objects? 33 | /// Founded game objects. 34 | public static T[] FindObjectsOfType(this Scene scene, bool includeInactive = false) 35 | { 36 | var filtered = scene.GetRootGameObjects().Where(r => r.activeSelf || includeInactive); 37 | return filtered.SelectMany(go => go.GetComponentsInChildren(includeInactive)).ToArray(); 38 | } 39 | 40 | /// 41 | /// Counts the whole number of game objects in scene. 42 | /// 43 | /// Target scene. 44 | /// Should we count inactive game objects? 45 | /// 46 | public static int ObjectsCount(this Scene scene, bool includeInactive = false) 47 | { 48 | var filtered = scene.GetRootGameObjects().Where(r => r.activeSelf || includeInactive); 49 | return filtered.SelectMany(r => r.GetComponentsInChildren(includeInactive)).Count(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Scripts/RenderTextureExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace Codomaster.Extensions 6 | { 7 | public static class RenderTextureExtensions 8 | { 9 | /// 10 | /// Create texture and write to it. 11 | /// 12 | /// The render texture. 13 | /// Created texture. 14 | public static Texture2D ToTexture2D(this RenderTexture renderTexture, TextureFormat format) 15 | { 16 | var texture = new Texture2D(renderTexture.width, renderTexture.height, format, false); 17 | renderTexture.WriteToTexture2D(texture); 18 | 19 | return texture; 20 | } 21 | 22 | /// 23 | /// Write to . 24 | /// 25 | /// The render texture. 26 | /// Texture to write render texture. 27 | public static void WriteToTexture2D(this RenderTexture renderTexture, Texture2D texture) 28 | { 29 | var oldRenderTexture = RenderTexture.active; 30 | RenderTexture.active = renderTexture; 31 | 32 | texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); 33 | texture.Apply(); 34 | 35 | RenderTexture.active = oldRenderTexture; 36 | } 37 | 38 | /// 39 | /// Create sprite and write to it. 40 | /// 41 | /// The render texture. 42 | /// Created sprite. 43 | public static Sprite ToSprite(this RenderTexture renderTexture, TextureFormat format) 44 | { 45 | var texture = renderTexture.ToTexture2D(format); 46 | return Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), new Vector2(0.5f, 0.5f)); 47 | } 48 | 49 | /// 50 | /// Write to . 51 | /// 52 | /// The render texture. 53 | /// Sprite to write render texture. 54 | public static void WriteToSprite(this RenderTexture renderTexture, Sprite sprite) 55 | { 56 | renderTexture.WriteToTexture2D(sprite.texture); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Extensions is a package that contains many extension methods for popular classes in Unity that you can use to write more expressive and concise code. 2 | 3 | For example: 4 | ```C# 5 | // Setting a new global position along the desired axis. 6 | transform.SetPositionX(1f); 7 | 8 | // Setting local rotation through Euler angles along the desired axex. 9 | transform.SetLocalEulerAnglesXZ(45f, 90f); 10 | 11 | // Reset the transformation state to default values (position and rotation to zero, scale to one). 12 | transform.Reset(); 13 | 14 | // Moves one position down in the hierarchy. 15 | transform.SetToNextSibling(); 16 | 17 | // Returns all child objects. 18 | var childs = transform.GetChilds(); 19 | 20 | // Will delete all child objects based on condition. 21 | transform.DestroyChildsWhere(c => c.name == "Enemy"); 22 | 23 | // Assign a position with a zeroed value along the Y axis. 24 | transform.position = otherTransform.position.WithY(0f); 25 | 26 | // Create and return a new vector from components [z, x, y] 27 | transform.position = vector.GetZXY(); 28 | 29 | // Inserts the value 1f along the Y axis. From [x, y] You get [x, 1f, y]. 30 | transform.position = vector2.InsertY(1f); 31 | 32 | // Partially inverts a vector: 33 | var partialNegated = transform.position.WithNegateXZ(); 34 | 35 | // Will check if the vector is homogeneous: 36 | var isUniform = transform.localScale.IsUniform(); 37 | 38 | // Returns the point closest to the vector (used as the position in space) from the specified list. 39 | var closest = transform.position.GetClosestPoint(pointsList); 40 | print($"Point: {closest.point}\nIndex: {closest.index}"); 41 | 42 | // We get a return beam, the beginning of which begins at 10 meters along the original beam. 43 | var reversed = ray.Reversed(10f); 44 | 45 | // Returns a ray deviated from its original direction by a random angle. 46 | var deflected = ray.RandomDeflected(45f); 47 | 48 | // Returns a copy with the color channel value changed. 49 | image.color = someColor.WithGA(1f, 0.5f); 50 | 51 | // Will reassign a value in one range to a value in another. 52 | var x = 0.25f; 53 | var remapped = x.Remap(0f, 1f, 0f, 2f); 54 | 55 | // Returns a random element. 56 | var element = list.GetRandom(); 57 | var elements = list.GetRandoms(3); 58 | 59 | // Will return a random element according to their probabilities (in this example: hello = 35%, bye = 50%, ok = 25%). 60 | var words = new string[] {"hello", "bye", "ok"}; 61 | var random = words.GetRandomWithProbability(35f, 50f, 25f); 62 | 63 | // Returns a shuffled list. 64 | var shuffled = list.Shuffled(); 65 | 66 | // Converts any collection to a string in the format "[1, 2, 3]". 67 | var array = new int[] { 4, -7, 12, 1, 0 }; 68 | print(array.AsString()); // Prints to the console -> [4, -7, 12, 1, 0] 69 | 70 | // Retrieves an element from a list. You can retrieve multiple items at once. 71 | var popped = list.Pop(4); // Retrieved the element at index 4. 72 | 73 | // Retrieves random elements from a list. 74 | var popped = list.PopRandoms(2); // Extracted 2 random elements. 75 | ``` 76 | 77 | And many other extensions! Read more on the wiki page 78 | -------------------------------------------------------------------------------- /Scripts/Editor/MissingScriptsRemover.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using UnityEngine; 4 | using UnityEditor; 5 | public static class FindMissingScriptsRecursively 6 | { 7 | private static float _lastCallTime = 0f; 8 | 9 | [MenuItem("Assets/Remove Missing Scripts")] 10 | [MenuItem("GameObject/Remove Missing Scripts")] 11 | private static void FindAndRemoveMissingInSelected() 12 | { 13 | if (Mathf.Approximately(Time.unscaledTime, _lastCallTime)) 14 | return; 15 | 16 | var selected = Selection.gameObjects.SelectMany(go => go.GetComponentsInChildren(true)).Select(t => t.gameObject); 17 | var prefabs = new HashSet(); 18 | var affectedGameObjects = new List(); 19 | 20 | var removedComponentsCount = 0; 21 | var removedGameObjectsCount = 0; 22 | 23 | foreach (var gameObject in selected) 24 | { 25 | var count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(gameObject); 26 | 27 | if (count == 0) 28 | continue; 29 | 30 | if (PrefabUtility.IsPartOfAnyPrefab(gameObject)) 31 | { 32 | RecursivePrefabSource(gameObject, prefabs, ref removedComponentsCount, ref removedGameObjectsCount); 33 | count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(gameObject); 34 | 35 | if (count == 0) 36 | continue; 37 | } 38 | 39 | Undo.RegisterCompleteObjectUndo(gameObject, "Remove missing scripts"); 40 | GameObjectUtility.RemoveMonoBehavioursWithMissingScript(gameObject); 41 | 42 | affectedGameObjects.Add(gameObject); 43 | removedComponentsCount += count; 44 | removedGameObjectsCount += 1; 45 | } 46 | 47 | if (removedGameObjectsCount == 0) 48 | Debug.Log("There is no selected game objects with missing scripts."); 49 | else 50 | Debug.Log($"Removed {removedComponentsCount} missing scripts from {removedGameObjectsCount} game objects." + 51 | $"\nGame objects: {string.Join(", ", affectedGameObjects.Select(go => go.name))}."); 52 | 53 | _lastCallTime = Time.unscaledTime; 54 | } 55 | 56 | private static void RecursivePrefabSource(GameObject instance, HashSet prefabs, ref int removedComponentsCount, ref int removedGameObjectsCount) 57 | { 58 | var source = PrefabUtility.GetCorrespondingObjectFromSource(instance); 59 | 60 | if (source == null || !prefabs.Add(source)) 61 | return; 62 | 63 | RecursivePrefabSource(source, prefabs, ref removedComponentsCount, ref removedGameObjectsCount); 64 | 65 | var count = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(source); 66 | 67 | if (count > 0) 68 | { 69 | Undo.RegisterCompleteObjectUndo(source, "Remove missing scripts"); 70 | GameObjectUtility.RemoveMonoBehavioursWithMissingScript(source); 71 | 72 | removedComponentsCount += count; 73 | removedGameObjectsCount += 1; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /Scripts/RayExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class RayExtensions 6 | { 7 | /// 8 | /// Create reversed ray. 9 | /// 10 | /// Target ray. 11 | /// Max distance for ray. 12 | /// Reversed ray. 13 | public static Ray Reversed(this Ray ray, float maxDistance) => new Ray(ray.GetPoint(maxDistance), -ray.direction); 14 | 15 | /// 16 | /// Arbitrarily deviates ray direction by a given . 17 | /// 18 | /// Target ray. 19 | /// Angle on which ray will be deflected. 20 | /// Deflected ray. 21 | public static Ray RandomDeflected(this Ray ray, float angle) => RandomDeflected(ray, new Vector2(angle, angle), Vector3.up); 22 | 23 | /// 24 | /// Arbitrarily deviates ray direction by a given , taking into account the axis. 25 | /// 26 | /// Target ray. 27 | /// Angle on which ray will be deflected. 28 | /// Up axis. 29 | /// Deflected ray. 30 | public static Ray RandomDeflected(this Ray ray, float angle, Vector3 up) => RandomDeflected(ray, new Vector2(angle, angle), up); 31 | 32 | /// 33 | /// Arbitrarily deviates ray direction by a given and . 34 | /// 35 | /// Target ray. 36 | /// Angle on which ray will be deflected by X axis. 37 | /// Angle on which ray will be deflected by Y axis. 38 | /// Deflected ray. 39 | public static Ray RandomDeflected(this Ray ray, float angleX, float angleY) => RandomDeflected(ray, new Vector2(angleX, angleY), Vector3.up); 40 | 41 | /// 42 | /// Arbitrarily deviates ray direction by a given and , taking into account the axis. 43 | /// 44 | /// Target ray. 45 | /// Angle on which ray will be deflected by X axis. 46 | /// Angle on which ray will be deflected by Y axis. 47 | /// Up axis. 48 | /// Deflected ray. 49 | public static Ray RandomDeflected(this Ray ray, float angleX, float angleY, Vector3 up) => RandomDeflected(ray, new Vector2(angleX, angleY), up); 50 | 51 | /// 52 | /// Arbitrarily deviates ray direction by a given . 53 | /// 54 | /// Target ray. 55 | /// Angles on which ray will be deflected by X and Y axes. 56 | /// Deflected ray. 57 | public static Ray RandomDeflected(this Ray ray, Vector2 angles) => RandomDeflected(ray, angles, Vector3.up); 58 | 59 | /// 60 | /// Arbitrarily deviates ray direction by a given , taking into account the axis. 61 | /// 62 | /// Target ray. 63 | /// Angles on which ray will be deflected by X and Y axes. 64 | /// Up axis. 65 | /// Deflected ray. 66 | public static Ray RandomDeflected(this Ray ray, Vector2 angles, Vector3 up) => new Ray(ray.origin, ray.direction.RandomDeflected(angles, up)); 67 | } 68 | } -------------------------------------------------------------------------------- /Scripts/GameObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | namespace Codomaster.Extensions 8 | { 9 | public static class GameObjectExtensions 10 | { 11 | /// 12 | /// Gets component from game object. If it no exist, new one will be created. 13 | /// 14 | /// Component type. 15 | /// The gameobject. 16 | /// Game object's component. 17 | public static T GetOrAddComponent(this GameObject gameObject) where T : Component 18 | { 19 | if (gameObject.TryGetComponent(out T component)) 20 | return component; 21 | 22 | return gameObject.AddComponent(); 23 | } 24 | 25 | /// 26 | /// Trying to get component in this or any it's children. 27 | /// 28 | /// Component type. 29 | /// Target gameobject. 30 | /// Target component. 31 | /// Should we find component on inactive game objects? 32 | /// if component was found. 33 | public static bool TryGetComponentInChildren(this GameObject gameObject, out T component, bool includeInactive = false) where T : Component 34 | { 35 | return component = gameObject.GetComponentInChildren(includeInactive); 36 | } 37 | 38 | /// 39 | /// Trying to get component in this or any it's parent. 40 | /// 41 | /// Component type. 42 | /// Target gameobject. 43 | /// Target component. 44 | /// Should we find component on inactive game objects? 45 | /// if component was found. 46 | public static bool TryGetComponentInParent(this GameObject gameObject, out T component, bool includeInactive = false) where T : Component 47 | { 48 | return component = gameObject.GetComponentInParent(includeInactive); 49 | } 50 | 51 | /// 52 | /// Check if game object is in layer mask. 53 | /// 54 | /// Target gameobject. 55 | /// Layer mask for check. 56 | /// if layer mask contain game object's layer. 57 | public static bool IsInLayerMask(this GameObject gameObject, LayerMask layerMask) => ((layerMask.value & (1 << gameObject.layer)) > 0); 58 | 59 | /// 60 | /// Check if game object is in layers. 61 | /// 62 | /// Target gameobject. 63 | /// Layers names for check. 64 | /// if game object's layer is in . 65 | public static bool IsInLayers(this GameObject gameObject, params string[] layerNames) => IsInLayerMask(gameObject, LayerMask.GetMask(layerNames)); 66 | 67 | /// 68 | /// Sets layer to all game object hierarchy. 69 | /// 70 | /// Target game object. 71 | /// Layer to set. 72 | public static void SetLayerRecursive(this GameObject gameObject, string layer) => SetLayerRecursive(gameObject, LayerMask.NameToLayer(layer)); 73 | 74 | /// 75 | /// Sets layer to all game object hierarchy. 76 | /// 77 | /// Target game object. 78 | /// Layer to set. 79 | public static void SetLayerRecursive(this GameObject gameObject, int layer) 80 | { 81 | gameObject.layer = layer; 82 | 83 | foreach (Transform child in gameObject.transform.GetChilds()) 84 | SetLayerRecursive(child.gameObject, layer); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /Scripts/SceneReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityObject = UnityEngine.Object; 4 | using UnityEngine.SceneManagement; 5 | using System.IO; 6 | 7 | #if UNITY_EDITOR 8 | using UnityEditor; 9 | using UnityEditor.SceneManagement; 10 | #endif 11 | 12 | namespace Codomaster.Extensions 13 | { 14 | /// 15 | /// Wrapper for scene asset. 16 | /// 17 | [Serializable] 18 | public class SceneReference : ISerializationCallbackReceiver 19 | { 20 | #if UNITY_EDITOR 21 | [SerializeField] 22 | private UnityObject _sceneObject; 23 | 24 | private bool IsValidSceneObject => _sceneObject && _sceneObject is SceneAsset; 25 | #endif 26 | 27 | [SerializeField] 28 | private string _path; 29 | 30 | /// 31 | /// Path to scene in project. 32 | /// 33 | public string Path 34 | { 35 | get 36 | { 37 | #if UNITY_EDITOR 38 | return GetScenePathFromAsset(); 39 | #else 40 | return _path; 41 | #endif 42 | } 43 | set 44 | { 45 | _path = value; 46 | #if UNITY_EDITOR 47 | _sceneObject = GetSceneAssetFromPath(); 48 | #endif 49 | } 50 | } 51 | 52 | public void OnBeforeSerialize() 53 | { 54 | #if UNITY_EDITOR 55 | if (!IsValidSceneObject && !string.IsNullOrEmpty(_path)) 56 | { 57 | if (!(_sceneObject = GetSceneAssetFromPath())) 58 | _path = null; 59 | 60 | EditorSceneManager.MarkAllScenesDirty(); 61 | return; 62 | } 63 | 64 | _path = GetScenePathFromAsset(); 65 | #endif 66 | } 67 | 68 | public void OnAfterDeserialize() 69 | { 70 | #if UNITY_EDITOR 71 | EditorApplication.update += HandleAfterDeserialize; 72 | #endif 73 | } 74 | 75 | #if UNITY_EDITOR 76 | private void HandleAfterDeserialize() 77 | { 78 | EditorApplication.update -= HandleAfterDeserialize; 79 | 80 | if (IsValidSceneObject) 81 | return; 82 | 83 | if (string.IsNullOrEmpty(_path)) 84 | return; 85 | 86 | if (!(_sceneObject = GetSceneAssetFromPath())) 87 | _path = null; 88 | 89 | if (!Application.isPlaying) 90 | EditorSceneManager.MarkAllScenesDirty(); 91 | } 92 | 93 | private SceneAsset GetSceneAssetFromPath() => string.IsNullOrEmpty(_path) ? null : AssetDatabase.LoadAssetAtPath(_path); 94 | 95 | private string GetScenePathFromAsset() => !_sceneObject ? string.Empty : AssetDatabase.GetAssetPath(_sceneObject); 96 | #endif 97 | 98 | public static implicit operator string(SceneReference sceneReference) => sceneReference.Path; 99 | } 100 | 101 | #region Property Drawer 102 | #if UNITY_EDITOR 103 | [CustomPropertyDrawer(typeof(SceneReference))] 104 | public class SceneReferencePropertyDrawer : PropertyDrawer 105 | { 106 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 107 | { 108 | if (property.serializedObject.isEditingMultipleObjects) 109 | { 110 | GUI.Label(position, "Scene multiediting not supported"); 111 | return; 112 | } 113 | 114 | var sceneAssetProperty = property.FindPropertyRelative("_sceneObject"); 115 | EditorGUI.BeginChangeCheck(); 116 | 117 | sceneAssetProperty.objectReferenceValue = EditorGUI.ObjectField(position, label, sceneAssetProperty.objectReferenceValue, typeof(SceneAsset), false); 118 | 119 | if (EditorGUI.EndChangeCheck() && GetEditorBuildSettingsScene(sceneAssetProperty.objectReferenceValue) == null) 120 | property.FindPropertyRelative("_path").stringValue = string.Empty; 121 | } 122 | 123 | private static EditorBuildSettingsScene GetEditorBuildSettingsScene(UnityObject sceneObject) 124 | { 125 | if (sceneObject is not SceneAsset) 126 | return null; 127 | 128 | var assetPath = AssetDatabase.GetAssetPath(sceneObject); 129 | var assetGuid = new GUID(AssetDatabase.AssetPathToGUID(assetPath)); 130 | 131 | var scenes = EditorBuildSettings.scenes; 132 | for (int i = 0; i < scenes.Length; i++) 133 | { 134 | var scene = scenes[i]; 135 | 136 | if (assetGuid != scene.guid) 137 | continue; 138 | 139 | return scene; 140 | } 141 | 142 | return null; 143 | } 144 | } 145 | #endif 146 | #endregion 147 | } -------------------------------------------------------------------------------- /Scripts/RectExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class RectExtensions 6 | { 7 | /// 8 | /// Sets rect center. 9 | /// 10 | /// Target rect. 11 | /// Value to set. 12 | /// Changed copy ot the 13 | public static Rect WithCenter(this Rect rect, Vector2 center) 14 | { 15 | rect.center = center; 16 | return rect; 17 | } 18 | 19 | /// 20 | /// Sets rect position. 21 | /// 22 | /// Target rect. 23 | /// Value to set. 24 | /// Changed copy ot the 25 | public static Rect WithPosition(this Rect rect, Vector2 position) 26 | { 27 | rect.position = position; 28 | return rect; 29 | } 30 | 31 | /// 32 | /// Sets rect height. 33 | /// 34 | /// Target rect. 35 | /// Value to set. 36 | /// Changed copy ot the 37 | public static Rect WithHeight(this Rect rect, float height) 38 | { 39 | rect.height = height; 40 | return rect; 41 | } 42 | 43 | /// 44 | /// Sets rect width. 45 | /// 46 | /// Target rect. 47 | /// Value to set. 48 | /// Changed copy ot the 49 | public static Rect WithWidth(this Rect rect, float width) 50 | { 51 | rect.width = width; 52 | return rect; 53 | } 54 | 55 | /// 56 | /// Sets rect max point. 57 | /// 58 | /// Target rect. 59 | /// Value to set. 60 | /// Changed copy ot the 61 | public static Rect WithMax(this Rect rect, Vector2 max) 62 | { 63 | rect.max = max; 64 | return rect; 65 | } 66 | 67 | /// 68 | /// Sets rect min point. 69 | /// 70 | /// Target rect. 71 | /// Value to set. 72 | /// Changed copy ot the 73 | public static Rect WithMin(this Rect rect, Vector2 min) 74 | { 75 | rect.min = min; 76 | return rect; 77 | } 78 | 79 | /// 80 | /// Sets rect size. 81 | /// 82 | /// Target rect. 83 | /// Value to set. 84 | /// Changed copy ot the 85 | public static Rect WithSize(this Rect rect, Vector2 size) 86 | { 87 | rect.size = size; 88 | return rect; 89 | } 90 | 91 | /// 92 | /// Sets rect x position. 93 | /// 94 | /// Target rect. 95 | /// Value to set. 96 | /// Changed copy ot the 97 | public static Rect WithX(this Rect rect, float x) 98 | { 99 | rect.x = x; 100 | return rect; 101 | } 102 | 103 | /// 104 | /// Sets rect x position. 105 | /// 106 | /// Target rect. 107 | /// Value to set. 108 | /// Changed copy ot the 109 | public static Rect WithY(this Rect rect, float y) 110 | { 111 | rect.y = y; 112 | return rect; 113 | } 114 | 115 | /// 116 | /// Sets rect x max position. 117 | /// 118 | /// Target rect. 119 | /// Value to set. 120 | /// Changed copy ot the 121 | public static Rect WithXMax(this Rect rect, float xMax) 122 | { 123 | rect.xMax = xMax; 124 | return rect; 125 | } 126 | 127 | /// 128 | /// Sets rect x min position. 129 | /// 130 | /// Target rect. 131 | /// Value to set. 132 | /// Changed copy ot the 133 | public static Rect WithXMin(this Rect rect, float xMin) 134 | { 135 | rect.xMin = xMin; 136 | return rect; 137 | } 138 | 139 | /// 140 | /// Sets rect y max position. 141 | /// 142 | /// Target rect. 143 | /// Value to set. 144 | /// Changed copy ot the 145 | public static Rect WithYMax(this Rect rect, float yMax) 146 | { 147 | rect.yMax = yMax; 148 | return rect; 149 | } 150 | 151 | /// 152 | /// Sets rect y min position. 153 | /// 154 | /// Target rect. 155 | /// Value to set. 156 | /// Changed copy ot the 157 | public static Rect WithYMin(this Rect rect, float yMin) 158 | { 159 | rect.yMin = yMin; 160 | return rect; 161 | } 162 | } 163 | } -------------------------------------------------------------------------------- /Scripts/IListExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace Codomaster.Extensions 7 | { 8 | public static class IListExtensions 9 | { 10 | /// 11 | /// Pops element by . 12 | /// 13 | /// Source type. 14 | /// List with elements. 15 | /// Index of element to pop. 16 | /// The popped element. 17 | public static T Pop(this IList list, int index) 18 | { 19 | var element = list[index]; 20 | list.RemoveAt(index); 21 | 22 | return element; 23 | } 24 | 25 | /// 26 | /// Pops elements by . 27 | /// 28 | /// Source type. 29 | /// List with elements. 30 | /// Indexes of elements to be popped. 31 | /// The popped element. 32 | public static List Pop(this IList list, params int[] indexes) 33 | { 34 | var popped = new List(); 35 | 36 | foreach (var index in indexes) 37 | popped.Add(list[index]); 38 | 39 | foreach (var index in indexes.OrderByDescending(i => i)) 40 | list.RemoveAt(index); 41 | 42 | return popped; 43 | } 44 | 45 | /// 46 | /// Pops random element from . 47 | /// 48 | /// Source type. 49 | /// List with elements. 50 | /// Tuple with popped element and it's index. 51 | public static (T element, int index) PopRandom(this IList list) 52 | { 53 | var index = UnityEngine.Random.Range(0, list.Count); 54 | return (list.Pop(index), index); 55 | } 56 | 57 | /// 58 | /// Pops random elements from list. 59 | /// 60 | /// Source type. 61 | /// List with elements. 62 | /// Count of elements to be popped. 63 | /// Should we clamp by elements count? 64 | /// List of tuples with popped elements and it's indexes. 65 | public static List<(T element, int index)> PopRandoms(this IList list, int count, bool clampCount = false) 66 | { 67 | if (clampCount) 68 | count = Mathf.Clamp(count, 0, list.Count); 69 | 70 | var popped = new List<(T element, int index)>(); 71 | 72 | for (int i = 0; i < count; i++) 73 | popped.Add(list.PopRandom()); 74 | 75 | return popped; 76 | } 77 | 78 | /// 79 | /// Pops random elements from list with specified probability. 80 | /// 81 | /// Source type. 82 | /// List with elements. 83 | /// Probabilities, must match in count with enumerable. 84 | /// Popped element. 85 | public static (T element, int index) PopRandomWithProbability(this IList list, params float[] probabilities) 86 | { 87 | return PopRandomWithProbability(list, (IEnumerable)probabilities); 88 | } 89 | 90 | /// 91 | /// Pops random elements from list with specified probability. 92 | /// 93 | /// Source type. 94 | /// List with elements. 95 | /// Probabilities, must match in count with enumerable. 96 | /// Popped elements. 97 | public static (T element, int index) PopRandomWithProbability(this IList list, IEnumerable probabilities) 98 | { 99 | var random = list.GetRandomWithProbability(probabilities); 100 | Pop(list, random.index); 101 | 102 | return random; 103 | } 104 | 105 | /// 106 | /// Pops random elements from list with specified probability selector. 107 | /// 108 | /// Source type. 109 | /// List with elements. 110 | /// Probabilities selector. 111 | /// Popped elements. 112 | public static (T element, int index) PopRandomWithProbability(this IList list, Func probabilitiesSelector) 113 | { 114 | var random = list.GetRandomWithProbability(probabilitiesSelector); 115 | Pop(list, random.index); 116 | 117 | return random; 118 | } 119 | 120 | /// 121 | /// Removes all elements starts from . 122 | /// 123 | /// Elements type. 124 | /// The list. 125 | /// From what index need starts removing? 126 | public static void RemoveRange(this IList list, int index) 127 | { 128 | for (int i = list.Count - 1; i >= index; i--) 129 | list.RemoveAt(i); 130 | } 131 | 132 | /// 133 | /// Shuffles . 134 | /// 135 | /// Source type. 136 | /// The original list. 137 | /// Shuffled original. 138 | public static IList Shuffle(this IList list) 139 | { 140 | var n = list.Count; 141 | 142 | while (n > 1) 143 | { 144 | var index = UnityEngine.Random.Range(0, --n + 1); 145 | (list[index], list[n]) = (list[n], list[index]); 146 | } 147 | 148 | return list; 149 | } 150 | 151 | /// 152 | /// Swaps two elements. 153 | /// 154 | /// Source type. 155 | /// The original list. 156 | /// First index to swap. 157 | /// Second index to swap. 158 | /// Original list. 159 | public static IList Swap(this IList list, int index1, int index2) 160 | { 161 | (list[index1], list[index2]) = (list[index2], list[index1]); 162 | return list; 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /Scripts/GraphicExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class GraphicExtensions 7 | { 8 | /// 9 | /// Set color's red channel value of the graphic object. 10 | /// 11 | /// Target graphic. 12 | /// Value to set. 13 | /// Changed copy of the color. 14 | public static void SetColorR(this Graphic graphic, float r) => graphic.color = graphic.color.WithR(r); 15 | 16 | /// 17 | /// Set color's green channel value. 18 | /// 19 | /// Target color. 20 | /// Value to set. 21 | /// Changed copy of the color. 22 | public static void SetColorG(this Graphic graphic, float g) => graphic.color = graphic.color.WithG(g); 23 | 24 | /// 25 | /// Set color's blue channel value. 26 | /// 27 | /// Target color. 28 | /// Value to set. 29 | /// Changed copy of the color. 30 | public static void SetColorB(this Graphic graphic, float b) => graphic.color = graphic.color.WithB(b); 31 | 32 | /// 33 | /// Set color's alpha channel value. 34 | /// 35 | /// Target color. 36 | /// Value to set. 37 | /// Changed copy of the color. 38 | public static void SetColorA(this Graphic graphic, float a) => graphic.color = graphic.color.WithA(a); 39 | 40 | /// 41 | /// Set color's red and green channels value. 42 | /// 43 | /// Target color. 44 | /// Value to set in red channel. 45 | /// Value to set in green channel. 46 | /// Changed copy of the color. 47 | public static void SetColorRG(this Graphic graphic, float r, float g) => graphic.color = graphic.color.WithRG(r, g); 48 | 49 | /// 50 | /// Set color's red and blue channels value. 51 | /// 52 | /// Target color. 53 | /// Value to set in red channel. 54 | /// Value to set in blue channel. 55 | /// Changed copy of the color. 56 | public static void SetColorRB(this Graphic graphic, float r, float b) => graphic.color = graphic.color.WithRB(r, b); 57 | 58 | /// 59 | /// Set color's red and alpha channels value. 60 | /// 61 | /// Target color. 62 | /// Value to set in red channel. 63 | /// Value to set in alpha channel. 64 | /// Changed copy of the color. 65 | public static void SetColorRA(this Graphic graphic, float r, float a) => graphic.color = graphic.color.WithRA(r, a); 66 | 67 | /// 68 | /// Set color's green and blue channels value. 69 | /// 70 | /// Target color. 71 | /// Value to set in green channel. 72 | /// Value to set in blue channel. 73 | /// Changed copy of the color. 74 | public static void SetColorGB(this Graphic graphic, float g, float b) => graphic.color = graphic.color.WithGB(g, b); 75 | 76 | /// 77 | /// Set color's green and alpha channels value. 78 | /// 79 | /// Target color. 80 | /// Value to set in green channel. 81 | /// Value to set in alpha channel. 82 | /// Changed copy of the color. 83 | public static void SetColorGA(this Graphic graphic, float g, float a) => graphic.color = graphic.color.WithGA(g, a); 84 | 85 | /// 86 | /// Set color's blue and alpha channels value. 87 | /// 88 | /// Target color. 89 | /// Value to set in blue channel. 90 | /// Value to set in alpha channel. 91 | /// Changed copy of the color. 92 | public static void SetColorBA(this Graphic graphic, float b, float a) => graphic.color = graphic.color.WithBA(b, a); 93 | 94 | /// 95 | /// Set color's red, green and blue channels value. 96 | /// 97 | /// Target color. 98 | /// Value to set in red channel. 99 | /// Value to set in green channel. 100 | /// Value to set in blue channel. 101 | /// Changed copy of the color. 102 | public static void SetColorRGB(this Graphic graphic, float r, float g, float b) => graphic.color = graphic.color.WithRGB(r, g, b); 103 | 104 | /// 105 | /// Set color's red, green and blue channels value. 106 | /// 107 | /// Target color. 108 | /// Color to set. 109 | /// Changed copy of the color. 110 | public static void SetColorRGB(this Graphic graphic, Color color) => graphic.color = color.WithA(graphic.color.a); 111 | 112 | /// 113 | /// Set color's red, green and alpha channels value. 114 | /// 115 | /// Target color. 116 | /// Value to set in red channel. 117 | /// Value to set in green channel. 118 | /// Value to set in alpha channel. 119 | /// Changed copy of the color. 120 | public static void SetColorRGA(this Graphic graphic, float r, float g, float a) => graphic.color = graphic.color.WithRGA(r, g, a); 121 | 122 | /// 123 | /// Set color's red, blue and alpha channels value. 124 | /// 125 | /// Target color. 126 | /// Value to set in red channel. 127 | /// Value to set in blue channel. 128 | /// Value to set in alpha channel. 129 | /// Changed copy of the color. 130 | public static void SetColorRBA(this Graphic graphic, float r, float b, float a) => graphic.color = graphic.color.WithRBA(r, b, a); 131 | 132 | /// 133 | /// Set color's green, blue and alpha channels value. 134 | /// 135 | /// Target color. 136 | /// Value to set in green channel. 137 | /// Value to set in blue channel. 138 | /// Value to set in alpha channel. 139 | /// Changed copy of the color. 140 | public static void SetColorGBA(this Graphic graphic, float g, float b, float a) => graphic.color = graphic.color.WithGBA(g, b, a); 141 | } 142 | } -------------------------------------------------------------------------------- /Scripts/ColorExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class ColorExtensions 6 | { 7 | /// 8 | /// Set value to color's channel. 9 | /// 10 | /// Target color. 11 | /// Channel index of the color. 12 | /// Value to set. 13 | /// Changed copy of the color. 14 | public static Color With(this Color color, int channel, float value) 15 | { 16 | color[channel] = value; 17 | return color; 18 | } 19 | 20 | /// 21 | /// Set color's red channel value. 22 | /// 23 | /// Target color. 24 | /// Value to set. 25 | /// Changed copy of the color. 26 | public static Color WithR(this Color color, float r) => With(color, 0, r); 27 | 28 | /// 29 | /// Set color's green channel value. 30 | /// 31 | /// Target color. 32 | /// Value to set. 33 | /// Changed copy of the color. 34 | public static Color WithG(this Color color, float g) => With(color, 1, g); 35 | 36 | /// 37 | /// Set color's blue channel value. 38 | /// 39 | /// Target color. 40 | /// Value to set. 41 | /// Changed copy of the color. 42 | public static Color WithB(this Color color, float b) => With(color, 2, b); 43 | 44 | /// 45 | /// Set color's alpha channel value. 46 | /// 47 | /// Target color. 48 | /// Value to set. 49 | /// Changed copy of the color. 50 | public static Color WithA(this Color color, float a) => With(color, 3, a); 51 | 52 | /// 53 | /// Set values to color's channels. 54 | /// 55 | /// Target color. 56 | /// First channel index of the color. 57 | /// First channel value. 58 | /// Second channel index of the color. 59 | /// Second channel value. 60 | /// Changed copy of the color. 61 | public static Color With(this Color color, int channel1, float value1, int channel2, float value2) 62 | { 63 | color[channel1] = value1; 64 | color[channel2] = value2; 65 | 66 | return color; 67 | } 68 | 69 | /// 70 | /// Set color's red and green channels value. 71 | /// 72 | /// Target color. 73 | /// Value to set in red channel. 74 | /// Value to set in green channel. 75 | /// Changed copy of the color. 76 | public static Color WithRG(this Color color, float r, float g) => With(color, 0, r, 1, g); 77 | 78 | /// 79 | /// Set color's red and blue channels value. 80 | /// 81 | /// Target color. 82 | /// Value to set in red channel. 83 | /// Value to set in blue channel. 84 | /// Changed copy of the color. 85 | public static Color WithRB(this Color color, float r, float b) => With(color, 0, r, 2, b); 86 | 87 | /// 88 | /// Set color's red and alpha channels value. 89 | /// 90 | /// Target color. 91 | /// Value to set in red channel. 92 | /// Value to set in alpha channel. 93 | /// Changed copy of the color. 94 | public static Color WithRA(this Color color, float r, float a) => With(color, 0, r, 3, a); 95 | 96 | /// 97 | /// Set color's green and blue channels value. 98 | /// 99 | /// Target color. 100 | /// Value to set in green channel. 101 | /// Value to set in blue channel. 102 | /// Changed copy of the color. 103 | public static Color WithGB(this Color color, float g, float b) => With(color, 1, g, 2, b); 104 | 105 | /// 106 | /// Set color's green and alpha channels value. 107 | /// 108 | /// Target color. 109 | /// Value to set in green channel. 110 | /// Value to set in alpha channel. 111 | /// Changed copy of the color. 112 | public static Color WithGA(this Color color, float g, float a) => With(color, 1, g, 3, a); 113 | 114 | /// 115 | /// Set color's blue and alpha channels value. 116 | /// 117 | /// Target color. 118 | /// Value to set in blue channel. 119 | /// Value to set in alpha channel. 120 | /// Changed copy of the color. 121 | public static Color WithBA(this Color color, float b, float a) => With(color, 2, b, 3, a); 122 | 123 | /// 124 | /// Set values to color's channels. 125 | /// 126 | /// Target color. 127 | /// First channel index of the color. 128 | /// First channel value. 129 | /// Second channel index of the color. 130 | /// Second channel value. 131 | /// Third channel index of the color. 132 | /// Third channel value. 133 | /// Changed copy of the color. 134 | public static Color With(this Color color, int channel1, float value1, int channel2, float value2, int channel3, float value3) 135 | { 136 | color[channel1] = value1; 137 | color[channel2] = value2; 138 | color[channel3] = value3; 139 | 140 | return color; 141 | } 142 | 143 | /// 144 | /// Set color's red, green and blue channels value. 145 | /// 146 | /// Target color. 147 | /// Value to set in red channel. 148 | /// Value to set in green channel. 149 | /// Value to set in blue channel. 150 | /// Changed copy of the color. 151 | public static Color WithRGB(this Color color, float r, float g, float b) => With(color, 0, r, 1, g, 2, b); 152 | 153 | /// 154 | /// Set color's red, green and alpha channels value. 155 | /// 156 | /// Target color. 157 | /// Value to set in red channel. 158 | /// Value to set in green channel. 159 | /// Value to set in alpha channel. 160 | /// Changed copy of the color. 161 | public static Color WithRGA(this Color color, float r, float g, float a) => With(color, 0, r, 1, g, 3, a); 162 | 163 | /// 164 | /// Set color's red, blue and alpha channels value. 165 | /// 166 | /// Target color. 167 | /// Value to set in red channel. 168 | /// Value to set in blue channel. 169 | /// Value to set in alpha channel. 170 | /// Changed copy of the color. 171 | public static Color WithRBA(this Color color, float r, float b, float a) => With(color, 0, r, 2, b, 3, a); 172 | 173 | /// 174 | /// Set color's green, blue and alpha channels value. 175 | /// 176 | /// Target color. 177 | /// Value to set in green channel. 178 | /// Value to set in blue channel. 179 | /// Value to set in alpha channel. 180 | /// Changed copy of the color. 181 | public static Color WithGBA(this Color color, float g, float b, float a) => With(color, 1, g, 2, b, 3, a); 182 | } 183 | } -------------------------------------------------------------------------------- /Scripts/Color32Extensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class Color32Extensions 6 | { 7 | /// 8 | /// Set value to color's channel. 9 | /// 10 | /// Target color. 11 | /// Channel index of the color. 12 | /// Value to set. 13 | /// Changed copy of the color. 14 | public static Color32 With(this Color32 color, int channel, byte value) 15 | { 16 | color[channel] = value; 17 | return color; 18 | } 19 | 20 | /// 21 | /// Set color's red channel value. 22 | /// 23 | /// Target color. 24 | /// Value to set. 25 | /// Changed copy of the color. 26 | public static Color32 WithR(this Color32 color, byte r) => With(color, 0, r); 27 | 28 | /// 29 | /// Set color's green channel value. 30 | /// 31 | /// Target color. 32 | /// Value to set. 33 | /// Changed copy of the color. 34 | public static Color32 WithG(this Color32 color, byte g) => With(color, 1, g); 35 | 36 | /// 37 | /// Set color's blue channel value. 38 | /// 39 | /// Target color. 40 | /// Value to set. 41 | /// Changed copy of the color. 42 | public static Color32 WithB(this Color32 color, byte b) => With(color, 2, b); 43 | 44 | /// 45 | /// Set color's alpha channel value. 46 | /// 47 | /// Target color. 48 | /// Value to set. 49 | /// Changed copy of the color. 50 | public static Color32 WithA(this Color32 color, byte a) => With(color, 3, a); 51 | 52 | /// 53 | /// Set values to color's channels. 54 | /// 55 | /// Target color. 56 | /// First channel index of the color. 57 | /// First channel value. 58 | /// Second channel index of the color. 59 | /// Second channel value. 60 | /// Changed copy of the color. 61 | public static Color32 With(this Color32 color, int channel1, byte value1, int channel2, byte value2) 62 | { 63 | color[channel1] = value1; 64 | color[channel2] = value2; 65 | 66 | return color; 67 | } 68 | 69 | /// 70 | /// Set color's red and green channels value. 71 | /// 72 | /// Target color. 73 | /// Value to set in red channel. 74 | /// Value to set in green channel. 75 | /// Changed copy of the color. 76 | public static Color32 WithRG(this Color32 color, byte r, byte g) => With(color, 0, r, 1, g); 77 | 78 | /// 79 | /// Set color's red and blue channels value. 80 | /// 81 | /// Target color. 82 | /// Value to set in red channel. 83 | /// Value to set in blue channel. 84 | /// Changed copy of the color. 85 | public static Color32 WithRB(this Color32 color, byte r, byte b) => With(color, 0, r, 2, b); 86 | 87 | /// 88 | /// Set color's red and alpha channels value. 89 | /// 90 | /// Target color. 91 | /// Value to set in red channel. 92 | /// Value to set in alpha channel. 93 | /// Changed copy of the color. 94 | public static Color32 WithRA(this Color32 color, byte r, byte a) => With(color, 0, r, 3, a); 95 | 96 | /// 97 | /// Set color's green and blue channels value. 98 | /// 99 | /// Target color. 100 | /// Value to set in green channel. 101 | /// Value to set in blue channel. 102 | /// Changed copy of the color. 103 | public static Color32 WithGB(this Color32 color, byte g, byte b) => With(color, 1, g, 2, b); 104 | 105 | /// 106 | /// Set color's green and alpha channels value. 107 | /// 108 | /// Target color. 109 | /// Value to set in green channel. 110 | /// Value to set in alpha channel. 111 | /// Changed copy of the color. 112 | public static Color32 WithGA(this Color32 color, byte g, byte a) => With(color, 1, g, 3, a); 113 | 114 | /// 115 | /// Set color's blue and alpha channels value. 116 | /// 117 | /// Target color. 118 | /// Value to set in blue channel. 119 | /// Value to set in alpha channel. 120 | /// Changed copy of the color. 121 | public static Color32 WithBA(this Color32 color, byte b, byte a) => With(color, 2, b, 3, a); 122 | 123 | /// 124 | /// Set values to color's channels. 125 | /// 126 | /// Target color. 127 | /// First channel index of the color. 128 | /// First channel value. 129 | /// Second channel index of the color. 130 | /// Second channel value. 131 | /// Third channel index of the color. 132 | /// Third channel value. 133 | /// Changed copy of the color. 134 | public static Color32 With(this Color32 color, int channel1, byte value1, int channel2, byte value2, int channel3, byte value3) 135 | { 136 | color[channel1] = value1; 137 | color[channel2] = value2; 138 | color[channel3] = value3; 139 | 140 | return color; 141 | } 142 | 143 | /// 144 | /// Set color's red, green and blue channels value. 145 | /// 146 | /// Target color. 147 | /// Value to set in red channel. 148 | /// Value to set in green channel. 149 | /// Value to set in blue channel. 150 | /// Changed copy of the color. 151 | public static Color32 WithRGB(this Color32 color, byte r, byte g, byte b) => With(color, 0, r, 1, g, 2, b); 152 | 153 | /// 154 | /// Set color's red, green and alpha channels value. 155 | /// 156 | /// Target color. 157 | /// Value to set in red channel. 158 | /// Value to set in green channel. 159 | /// Value to set in alpha channel. 160 | /// Changed copy of the color. 161 | public static Color32 WithRGA(this Color32 color, byte r, byte g, byte a) => With(color, 0, r, 1, g, 3, a); 162 | 163 | /// 164 | /// Set color's red, blue and alpha channels value. 165 | /// 166 | /// Target color. 167 | /// Value to set in red channel. 168 | /// Value to set in blue channel. 169 | /// Value to set in alpha channel. 170 | /// Changed copy of the color. 171 | public static Color32 WithRBA(this Color32 color, byte r, byte b, byte a) => With(color, 0, r, 2, b, 3, a); 172 | 173 | /// 174 | /// Set color's green, blue and alpha channels value. 175 | /// 176 | /// Target color. 177 | /// Value to set in green channel. 178 | /// Value to set in blue channel. 179 | /// Value to set in alpha channel. 180 | /// Changed copy of the color. 181 | public static Color32 WithGBA(this Color32 color, byte g, byte b, byte a) => With(color, 1, g, 2, b, 3, a); 182 | } 183 | } -------------------------------------------------------------------------------- /Scripts/Vector2IntExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class Vector2IntExtensions 7 | { 8 | /// 9 | /// Sets value to vector's axis. 10 | /// 11 | /// Target vector. 12 | /// Axis index of the vector. 13 | /// Value to set. 14 | /// Changed copy of the vector. 15 | public static Vector2Int With(this Vector2Int vector, int axis, int value) 16 | { 17 | vector[axis] = value; 18 | return vector; 19 | } 20 | 21 | /// 22 | /// Sets value to vector's x axis. 23 | /// 24 | /// Target vector. 25 | /// Value to set. 26 | /// Changed copy of the vector. 27 | public static Vector2Int WithX(this Vector2Int vector, int x) => With(vector, 0, x); 28 | 29 | /// 30 | /// Sets value to vector's y axis. 31 | /// 32 | /// Target vector. 33 | /// Value to set. 34 | /// Changed copy of the vector. 35 | public static Vector2Int WithY(this Vector2Int vector, int y) => With(vector, 1, y); 36 | 37 | /// 38 | /// Inverts value of specified axis. 39 | /// 40 | /// The vector. 41 | /// Target axis. 42 | /// Vector with inverted axis value. 43 | public static Vector2Int WithNegate(this Vector2Int vector, int axis) => vector.With(axis, -vector[axis]); 44 | 45 | /// 46 | /// Inverts x axis value. 47 | /// 48 | /// The vector. 49 | /// Vector with inverted axis value. 50 | public static Vector2Int WithNegateX(this Vector2Int vector) => WithNegate(vector, 0); 51 | 52 | /// 53 | /// Inverts y axis value. 54 | /// 55 | /// The vector. 56 | /// Vector with inverted axis value. 57 | public static Vector2Int WithNegateY(this Vector2Int vector) => WithNegate(vector, 1); 58 | 59 | /// 60 | /// Inverts vector. 61 | /// 62 | /// The vector. 63 | /// Inverted vector. 64 | public static Vector2Int Negate(this Vector2Int vector) => new(-vector.x, -vector.y); 65 | 66 | /// 67 | /// Gets inverted vector. 68 | /// 69 | /// Target vector. 70 | /// Inverted vector. 71 | public static Vector2Int GetYX(this Vector2Int vector) => new(vector.y, vector.x); 72 | 73 | /// 74 | /// Inserts value to x axis and extends vector to 3-dimensional. 75 | /// 76 | /// Target vector. 77 | /// Value to set. 78 | /// 3-dimensional vector. 79 | public static Vector3Int InsertX(this Vector2Int vector, int x = 0) => new(x, vector.x, vector.y); 80 | 81 | /// 82 | /// Inserts value to y axis and extends vector to 3-dimensional. 83 | /// 84 | /// Target vector. 85 | /// Value to set. 86 | /// 3-dimensional vector. 87 | public static Vector3Int InsertY(this Vector2Int vector, int y = 0) => new(vector.x, y, vector.y); 88 | 89 | /// 90 | /// Inserts value to z axis and extends vector to 3-dimensional. 91 | /// 92 | /// Target vector. 93 | /// Value to set. 94 | /// 3-dimensional vector. 95 | public static Vector3Int InsertZ(this Vector2Int vector, int z = 0) => new(vector.x, vector.y, z); 96 | 97 | /// 98 | /// Gets max component info from vector. 99 | /// 100 | /// Target vector. 101 | /// Vector's max component tuple info. 102 | public static (int index, int value) MaxComponent(this Vector2Int vector) => vector.x >= vector.y ? (0, vector.x) : (1, vector.y); 103 | 104 | /// 105 | /// Gets min component info from vector. 106 | /// 107 | /// Target vector. 108 | /// Vector's min component tuple info. 109 | public static (int index, int value) MinComponent(this Vector2Int vector) => vector.x <= vector.y ? (0, vector.x) : (1, vector.y); 110 | 111 | /// 112 | /// Creates new vector with absolute components. 113 | /// 114 | /// Target vector. 115 | /// Vector with absolute components. 116 | public static Vector2Int Abs(this Vector2Int vector) => new(Mathf.Abs(vector.x), Mathf.Abs(vector.y)); 117 | 118 | /// 119 | /// Creates new vector with clamped components. 120 | /// 121 | /// Target vector. 122 | /// The minimum floating value to campare agains. 123 | /// The maximum floating value to campare agains. 124 | /// Clamped vector. 125 | public static Vector2Int Clamp(this Vector2Int vector, int min, int max) 126 | { 127 | return new Vector2Int(Mathf.Clamp(vector.x, min, max), Mathf.Clamp(vector.y, min, max)); 128 | } 129 | 130 | /// 131 | /// Create new vector with divided by value components. 132 | /// 133 | /// Target vector. 134 | /// Vector on which divide 135 | /// Divided vector. 136 | public static Vector2Int Divide(this Vector2Int vector, Vector2Int other) 137 | { 138 | return new Vector2Int(vector.x / other.x, vector.y / other.y); 139 | } 140 | 141 | /// 142 | /// Checks if the vector components are equals. 143 | /// 144 | /// Target vector. 145 | /// if vector's components are equals. 146 | public static bool IsUniform(this Vector2Int vector) => vector.x == vector.y; 147 | 148 | /// 149 | /// Gets closest point info from list. 150 | /// 151 | /// Origin point. 152 | /// Compared points. 153 | /// Closest point tuple info. 154 | public static (Vector2Int point, int index) GetClosestPoint(this Vector2Int point, params Vector2Int[] points) 155 | { 156 | return GetClosestPoint(point, (IEnumerable)points); 157 | } 158 | 159 | /// 160 | /// Gets closest point info from list. 161 | /// 162 | /// Origin point. 163 | /// Compared points. 164 | /// Closest point tuple info. 165 | public static (Vector2Int point, int index) GetClosestPoint(this Vector2Int point, IEnumerable points) 166 | { 167 | var enumerator = points.GetEnumerator(); 168 | 169 | var index = -1; 170 | var closestIndex = -1; 171 | var closestPoint = Vector2Int.zero; 172 | var closestDistance = float.MaxValue; 173 | 174 | while (enumerator.MoveNext()) 175 | { 176 | ++index; 177 | var distance = Vector2Int.Distance(point, enumerator.Current); 178 | 179 | if (distance < closestDistance) 180 | { 181 | closestIndex = index; 182 | closestDistance = distance; 183 | closestPoint = enumerator.Current; 184 | } 185 | } 186 | 187 | return (closestPoint, closestIndex); 188 | } 189 | 190 | /// 191 | /// Get the closest point on a ray. 192 | /// 193 | /// A point in space. 194 | /// Start point of ray. 195 | /// Ray direction. Must be normalized. 196 | /// Tuple which contains closest point on line and distance from to calculated point. 197 | public static (Vector2 point, float distance) GetClosestPointOnRay(this Vector2Int point, Vector2 origin, Vector2 direction) 198 | { 199 | return Vector2Extensions.GetClosestPointOnRay(point, origin, direction); 200 | } 201 | 202 | /// 203 | /// Get the closest point on a line segment. 204 | /// 205 | /// A point in space. 206 | /// Start of line segment. 207 | /// End of line segment. 208 | /// Tuple which contains closest point on line and distance from to calculated point. 209 | public static (Vector2 point, float distance) GetClosestPointOnSegment(this Vector2Int point, Vector2 start, Vector2 end) 210 | { 211 | return Vector2Extensions.GetClosestPointOnSegment(point, start, end); 212 | } 213 | } 214 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Scripts/IEnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | using UnityRandom = UnityEngine.Random; 6 | 7 | namespace Codomaster.Extensions 8 | { 9 | public static class IEnumerableExtensions 10 | { 11 | /// 12 | /// Get random element from the . 13 | /// 14 | /// Source type. 15 | /// The enumerable. 16 | /// Random element from enumerable. 17 | public static T GetRandom(this IEnumerable enumerable) => enumerable.ElementAt(UnityRandom.Range(0, enumerable.Count())); 18 | 19 | /// 20 | /// Get random elements from the . 21 | /// 22 | /// Source type. 23 | /// The enumerable. 24 | /// Count of the random elements. 25 | /// Does we need clamp if it greater than elements count. 26 | /// Random elements from enumerable. 27 | public static List GetRandoms(this IEnumerable enumerable, int count, bool clampCount = false) 28 | { 29 | if (clampCount) 30 | count = Mathf.Min(count, enumerable.Count()); 31 | 32 | var poppedIndexes = Enumerable.Range(0, enumerable.Count()).ToList().PopRandoms(count).Select(p => p.element); 33 | return enumerable.Where((el, i) => poppedIndexes.Contains(i)).ToList(); 34 | } 35 | 36 | /// 37 | /// Excepts passed elements from . 38 | /// 39 | /// Source type. 40 | /// The enumerable. 41 | /// Elements to exclude. 42 | /// List without passed elements. 43 | public static List Except(this IEnumerable enumerable, params T[] elements) => enumerable.Except((IEnumerable)elements).ToList(); 44 | 45 | /// 46 | /// Shuffles . 47 | /// 48 | /// Source type. 49 | /// The enumerable. 50 | /// Shuffled copy. 51 | public static List Shuffled(this IEnumerable enumerable) => enumerable.OrderBy(v => UnityRandom.value).ToList(); 52 | 53 | /// 54 | /// Represents an enumerable as a string in the format 55 | /// 56 | /// Source type. 57 | /// The enumerable. 58 | /// String representation of the 59 | public static string AsString(this IEnumerable enumerable) => $"[{string.Join(", ", enumerable)}]"; 60 | 61 | /// 62 | /// Get random element index with probability selector. 63 | /// 64 | /// Enumerable elements type. 65 | /// The enumerable. 66 | /// Probabilities, must match in count with enumerable. 67 | /// Tuple with random element and it's index. 68 | /// Throwed when and counts are not match. 69 | public static (T element, int index) GetRandomWithProbability(this IEnumerable enumerable, params float[] probabilities) => GetRandomWithProbability(enumerable, (IEnumerable)probabilities); 70 | 71 | /// 72 | /// Get random element index with probability selector. 73 | /// 74 | /// Enumerable elements type. 75 | /// The enumerable. 76 | /// Probabilities, must match in count with enumerable. 77 | /// Sum of probabilities. 78 | /// Tuple with random element and it's index. 79 | /// Throwed when and counts are not match. 80 | public static (T element, int index) GetRandomWithProbability(this IEnumerable enumerable, double? probabilitiesSum, params float[] probabilities) => GetRandomWithProbability(enumerable, (IEnumerable)probabilities, (float)probabilitiesSum); 81 | 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | /// 88 | /// Sum of probabilities. 89 | /// Tuple with random element and it's index. 90 | /// Throwed when and counts are not match. 91 | public static (T element, int index) GetRandomWithProbability(this IEnumerable enumerable, IEnumerable probabilities, float? probabilitiesSum = null) 92 | { 93 | var count = enumerable.Count(); 94 | 95 | if (probabilities.Count() != count) 96 | throw new ArgumentException($"Count of probabilities and enumerble elements must be equal."); 97 | 98 | if (count == 0) 99 | throw new ArgumentException($"Enumerable count must be greater than zero"); 100 | 101 | if (probabilitiesSum == null) 102 | { 103 | probabilitiesSum = 0f; 104 | 105 | foreach (var element in probabilities) 106 | probabilitiesSum += element; 107 | } 108 | 109 | var randomValue = UnityRandom.value * probabilitiesSum.Value; 110 | 111 | var sum = 0f; 112 | var index = -1; 113 | 114 | var enumerator = probabilities.GetEnumerator(); 115 | 116 | while (enumerator.MoveNext()) 117 | { 118 | index += 1; 119 | var probability = enumerator.Current; 120 | 121 | sum += probability; 122 | 123 | if (randomValue < sum || randomValue.Approx(sum)) 124 | return (enumerable.ElementAt(index), index); 125 | } 126 | 127 | index = count - 1; 128 | return (enumerable.ElementAt(index), index); 129 | } 130 | 131 | /// 132 | /// 133 | /// 134 | /// 135 | /// 136 | /// Probabilities selector. 137 | /// Sum of probabilities. 138 | /// Tuple with random element and it's index. 139 | /// Throwed when count are zero. 140 | public static (T element, int index) GetRandomWithProbability(this IEnumerable enumerable, Func probabilitySelector, float? probabilitiesSum = null) 141 | { 142 | var count = enumerable.Count(); 143 | 144 | if (count == 0) 145 | throw new ArgumentException($"Enumerable count must be greater than zero"); 146 | 147 | if (probabilitiesSum == null) 148 | { 149 | probabilitiesSum = 0f; 150 | 151 | foreach (var element in enumerable) 152 | probabilitiesSum += probabilitySelector(element); 153 | } 154 | 155 | var randomValue = UnityRandom.value * probabilitiesSum.Value; 156 | 157 | var sum = 0f; 158 | var index = -1; 159 | 160 | var enumerator = enumerable.GetEnumerator(); 161 | 162 | while (enumerator.MoveNext()) 163 | { 164 | index += 1; 165 | var probability = probabilitySelector(enumerator.Current); 166 | 167 | sum += probability; 168 | 169 | if (randomValue < sum || randomValue.Approx(sum)) 170 | return (enumerator.Current, index); 171 | } 172 | 173 | return (enumerator.Current, count - 1); 174 | } 175 | 176 | /// 177 | /// Loops over all elements. 178 | /// 179 | /// Elements type. 180 | /// The enumerable. 181 | /// What to do with each element? 182 | public static void ForEach(this IEnumerable enumerable, Action action) 183 | { 184 | foreach (var element in enumerable) 185 | action(element); 186 | } 187 | 188 | /// 189 | /// Find object with minimal value by expression. 190 | /// 191 | /// Elements type. 192 | /// result type. 193 | /// The enumerable. 194 | /// Expression which used to calculate minimal values. 195 | /// Tuple with minimal value by expression. If there is no elements, then will be returned. 196 | public static (int index, T element) MinBy(this IEnumerable enumerable, Func expression) where U : IComparable 197 | { 198 | var enumerator = enumerable.GetEnumerator(); 199 | 200 | if (!enumerator.MoveNext()) 201 | return (-1, default); 202 | 203 | var minIndex = 0; 204 | var minObj = enumerator.Current; 205 | var minValue = expression(minObj); 206 | 207 | var index = 0; 208 | 209 | while (enumerator.MoveNext()) 210 | { 211 | index += 1; 212 | var otherMinValue = expression(enumerator.Current); 213 | 214 | if (otherMinValue.CompareTo(minValue) > -1) 215 | continue; 216 | 217 | minIndex = index; 218 | minObj = enumerator.Current; 219 | minValue = otherMinValue; 220 | } 221 | 222 | return (minIndex, minObj); 223 | } 224 | 225 | /// 226 | /// Find object with maximal value by expression. 227 | /// 228 | /// Elements type. 229 | /// result type. 230 | /// The enumerable. 231 | /// Expression which used to calculate maximal values. 232 | /// Tuple with maximal value by expression. If there is no elements, then will be returned. 233 | public static (int index, T element) MaxBy(this IEnumerable enumerable, Func expression) where U : IComparable 234 | { 235 | var enumerator = enumerable.GetEnumerator(); 236 | 237 | if (!enumerator.MoveNext()) 238 | return (-1, default); 239 | 240 | var maxIndex = 0; 241 | var maxObj = enumerator.Current; 242 | var maxValue = expression(maxObj); 243 | 244 | var index = 0; 245 | 246 | while (enumerator.MoveNext()) 247 | { 248 | index += 1; 249 | var otherMinValue = expression(enumerator.Current); 250 | 251 | if (otherMinValue.CompareTo(maxValue) < 1) 252 | continue; 253 | 254 | maxIndex = index; 255 | maxObj = enumerator.Current; 256 | maxValue = otherMinValue; 257 | } 258 | 259 | return (maxIndex, maxObj); 260 | } 261 | } 262 | } -------------------------------------------------------------------------------- /Scripts/Vector2Extensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class Vector2Extensions 7 | { 8 | /// 9 | /// Sets value to vector's axis. 10 | /// 11 | /// Target vector. 12 | /// Axis index of the vector. 13 | /// Value to set. 14 | /// Changed copy of the vector. 15 | public static Vector2 With(this Vector2 vector, int axis, float value) 16 | { 17 | vector[axis] = value; 18 | return vector; 19 | } 20 | 21 | /// 22 | /// Sets value to vector's x axis. 23 | /// 24 | /// Target vector. 25 | /// Value to set. 26 | /// Changed copy of the vector. 27 | public static Vector2 WithX(this Vector2 vector, float x) => With(vector, 0, x); 28 | 29 | /// 30 | /// Sets value to vector's y axis. 31 | /// 32 | /// Target vector. 33 | /// Value to set. 34 | /// Changed copy of the vector. 35 | public static Vector2 WithY(this Vector2 vector, float y) => With(vector, 1, y); 36 | 37 | /// 38 | /// Inverts value of specified axis. 39 | /// 40 | /// The vector. 41 | /// Target axis. 42 | /// Vector with inverted axis value. 43 | public static Vector2 WithNegate(this Vector2 vector, int axis) => vector.With(axis, -vector[axis]); 44 | 45 | /// 46 | /// Inverts x axis value. 47 | /// 48 | /// The vector. 49 | /// Vector with inverted axis value. 50 | public static Vector2 WithNegateX(this Vector2 vector) => WithNegate(vector, 0); 51 | 52 | /// 53 | /// Inverts y axis value. 54 | /// 55 | /// The vector. 56 | /// Vector with inverted axis value. 57 | public static Vector2 WithNegateY(this Vector2 vector) => WithNegate(vector, 1); 58 | 59 | /// 60 | /// Inverts vector. 61 | /// 62 | /// The vector. 63 | /// Inverted vector. 64 | public static Vector2 Negate(this Vector2 vector) => new(-vector.x, -vector.y); 65 | 66 | /// 67 | /// Gets inverted vector. 68 | /// 69 | /// Target vector. 70 | /// Inverted vector. 71 | public static Vector2 GetYX(this Vector2 vector) => new(vector.y, vector.x); 72 | 73 | /// 74 | /// Inserts value to x axis and extends vector to 3-dimensional. 75 | /// 76 | /// Target vector. 77 | /// Value to set. 78 | /// 3-dimensional vector. 79 | public static Vector3 InsertX(this Vector2 vector, float x = 0) => new(x, vector.x, vector.y); 80 | 81 | /// 82 | /// Inserts value to y axis and extends vector to 3-dimensional. 83 | /// 84 | /// Target vector. 85 | /// Value to set. 86 | /// 3-dimensional vector. 87 | public static Vector3 InsertY(this Vector2 vector, float y = 0) => new(vector.x, y, vector.y); 88 | 89 | /// 90 | /// Inserts value to z axis and extends vector to 3-dimensional. 91 | /// 92 | /// Target vector. 93 | /// Value to set. 94 | /// 3-dimensional vector. 95 | public static Vector3 InsertZ(this Vector2 vector, float z = 0) => new(vector.x, vector.y, z); 96 | 97 | /// 98 | /// Gets max component from vector. 99 | /// 100 | /// Target vector. 101 | /// Vector's max component tuple info. 102 | public static (int index, float value) MaxComponent(this Vector2 vector) => vector.x >= vector.y ? (0, vector.x) : (1, vector.y); 103 | 104 | /// 105 | /// Gets min component from vector. 106 | /// 107 | /// Target vector. 108 | /// Vector's min component tuple info. 109 | public static (int index, float value) MinComponent(this Vector2 vector) => vector.x <= vector.y ? (0, vector.x) : (1, vector.y); 110 | 111 | /// 112 | /// Remaps all vector's components from one interval to other. 113 | /// 114 | /// Target vector. 115 | /// Min value of the beginning interval. 116 | /// Max value of the beginning interval. 117 | /// Min value of the target interval. 118 | /// Max value of the target interval. 119 | /// Remaped vector. 120 | public static Vector2 Remap(this Vector2 vector, float min1, float max1, float min2, float max2) 121 | { 122 | return new Vector2(vector.x.Remap(min1, max1, min2, max2), vector.y.Remap(min1, max1, min2, max2)); 123 | } 124 | 125 | /// 126 | /// Creates new vector with absolute components. 127 | /// 128 | /// Target vector. 129 | /// Vector with absolute components. 130 | public static Vector2 Abs(this Vector2 vector) => new(Mathf.Abs(vector.x), Mathf.Abs(vector.y)); 131 | 132 | /// 133 | /// Creates new vector with clamped components. 134 | /// 135 | /// Target vector. 136 | /// The minimum floating value to campare agains. 137 | /// The maximum floating value to campare agains. 138 | /// Clamped vector. 139 | public static Vector2 Clamp(this Vector2 vector, float min, float max) 140 | { 141 | return new Vector2(Mathf.Clamp(vector.x, min, max), Mathf.Clamp(vector.y, min, max)); 142 | } 143 | 144 | /// 145 | /// Creates and returns a vector whose components are limited to 0 and 1. 146 | /// 147 | /// Target vector. 148 | /// Clamped vector. 149 | public static Vector2 Clamp01(this Vector2 vector) 150 | { 151 | return new Vector2(Mathf.Clamp01(vector.x), Mathf.Clamp01(vector.y)); 152 | } 153 | 154 | /// 155 | /// Creates and returns a vector whose components are divided by the value. 156 | /// 157 | /// Target vector. 158 | /// Vector on which divide 159 | /// Divided vector. 160 | public static Vector2 Divide(this Vector2 vector, Vector2 other) => vector / other; 161 | 162 | /// 163 | /// Checks if the vector components are equals. 164 | /// 165 | /// Target vector. 166 | /// if vector's components are equals. 167 | public static bool IsUniform(this Vector2 vector) => vector.x.Approx(vector.y); 168 | 169 | /// 170 | /// Calculate evently distributed point position on circle. 171 | /// 172 | /// Index of point. 173 | /// Radius of the circle. 174 | /// Total count of points in circle. 175 | /// Calculated evently distributed point. 176 | public static Vector2 EventlyDistributedPointOnCircle(int index, float radius, int count) 177 | { 178 | var k = index + 0.5f; 179 | var r = Mathf.Sqrt((k) / count); 180 | var theta = Mathf.PI * (1f + Mathf.Sqrt(5f)) * k; 181 | 182 | var x = r * Mathf.Cos(theta) * radius; 183 | var y = r * Mathf.Sin(theta) * radius; 184 | 185 | return new Vector2(x, y); 186 | } 187 | 188 | /// 189 | /// Gets closest point info from list. 190 | /// 191 | /// Origin point. 192 | /// Compared points. 193 | /// Closest point tuple info. 194 | public static (Vector2 point, int index) GetClosestPoint(this Vector2 point, params Vector2[] points) 195 | { 196 | return GetClosestPoint(point, (IEnumerable)points); 197 | } 198 | 199 | /// 200 | /// Gets closest point info from list. 201 | /// 202 | /// Origin point. 203 | /// Compared points. 204 | /// Closest point tuple info. 205 | public static (Vector2 point, int index) GetClosestPoint(this Vector2 point, IEnumerable points) 206 | { 207 | var enumerator = points.GetEnumerator(); 208 | 209 | var index = -1; 210 | var closestIndex = -1; 211 | var closestPoint = Vector2.zero; 212 | var closestDistance = float.MaxValue; 213 | 214 | while (enumerator.MoveNext()) 215 | { 216 | ++index; 217 | var distance = Vector2.Distance(point, enumerator.Current); 218 | 219 | if (distance < closestDistance) 220 | { 221 | closestIndex = index; 222 | closestDistance = distance; 223 | closestPoint = enumerator.Current; 224 | } 225 | } 226 | 227 | return (closestPoint, closestIndex); 228 | } 229 | 230 | /// 231 | /// Get the closest point on a ray. 232 | /// 233 | /// A point in space. 234 | /// Start point of ray. 235 | /// Ray direction. Must be normalized. 236 | /// Tuple which contains closest point on line and distance from to calculated point. 237 | public static (Vector2 point, float distance) GetClosestPointOnRay(this Vector2 point, Vector2 origin, Vector2 direction) 238 | { 239 | var distance = Vector2.Dot(point - origin, direction); 240 | return (origin + direction * distance, distance); 241 | } 242 | 243 | /// 244 | /// Get the closest point on a line segment. 245 | /// 246 | /// A point in space. 247 | /// Start of line segment. 248 | /// End of line segment. 249 | /// Tuple which contains closest point on line and distance from to calculated point. 250 | public static (Vector2 point, float distance) GetClosestPointOnSegment(this Vector2 point, Vector2 start, Vector2 end) 251 | { 252 | var direction = end - start; 253 | var lineMagnitude = direction.magnitude; 254 | direction.Normalize(); 255 | 256 | var distance = Mathf.Clamp(Vector2.Dot(point - start, direction), 0f, lineMagnitude); 257 | return (start + direction * distance, distance); 258 | } 259 | 260 | /// 261 | /// Arbitrarily deviates the direction vector by a given . 262 | /// 263 | /// Target vector. 264 | /// Angle on which vector will be deflected. 265 | /// Deflected directional vector. 266 | public static Vector2 RandomDeflected(this Vector2 direction, float angle) => Quaternion.AngleAxis(Random.value * angle.WithRandomSign(), Vector3.forward) * direction; 267 | 268 | /// 269 | /// Rotates vector around z axis. 270 | /// 271 | /// Target vector. 272 | /// Angle to rotate. 273 | /// Rotated vector. 274 | public static Vector2 Rotate(this Vector2 vector, float angle) => Quaternion.Euler(0f, 0f, angle) * vector; 275 | } 276 | } -------------------------------------------------------------------------------- /Scripts/RectTransformExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class RectTransformExtensions 6 | { 7 | /// 8 | /// Sets size delta x value of the rectTransform. 9 | /// 10 | /// Target rectTransform. 11 | /// Value to set. 12 | public static void SetSizeDeltaX(this RectTransform rectTransform, float x) => rectTransform.sizeDelta = rectTransform.sizeDelta.WithX(x); 13 | 14 | /// 15 | /// Sets size delta y value of the rectTransform. 16 | /// 17 | /// Target rectTransform. 18 | /// Value to set. 19 | public static void SetSizeDeltaY(this RectTransform rectTransform, float y) => rectTransform.sizeDelta = rectTransform.sizeDelta.WithY(y); 20 | 21 | /// 22 | /// Sets anchor min x value of the rectTransform. 23 | /// 24 | /// Target rectTransform. 25 | /// Value to set. 26 | public static void SetAnchorMinX(this RectTransform rectTransform, float x) => rectTransform.anchorMin = rectTransform.anchorMin.WithX(x); 27 | 28 | /// 29 | /// Sets anchor min y value of the rectTransform. 30 | /// 31 | /// Target rectTransform. 32 | /// Value to set. 33 | public static void SetAnchorMinY(this RectTransform rectTransform, float y) => rectTransform.anchorMin = rectTransform.anchorMin.WithY(y); 34 | 35 | /// 36 | /// Sets anchor max x value of the rectTransform. 37 | /// 38 | /// Target rectTransform. 39 | /// Value to set. 40 | public static void SetAnchorMaxX(this RectTransform rectTransform, float x) => rectTransform.anchorMax = rectTransform.anchorMax.WithX(x); 41 | 42 | /// 43 | /// Sets anchor max y value of the rectTransform. 44 | /// 45 | /// Target rectTransform. 46 | /// Value to set. 47 | public static void SetAnchorMaxY(this RectTransform rectTransform, float y) => rectTransform.anchorMax = rectTransform.anchorMax.WithY(y); 48 | 49 | /// 50 | /// Sets offset min x value of the rectTransform. 51 | /// 52 | /// Target rectTransform. 53 | /// Value to set. 54 | public static void SetOffsetMinX(this RectTransform rectTransform, float x) => rectTransform.offsetMin = rectTransform.offsetMin.WithX(x); 55 | 56 | /// 57 | /// Sets offset from left. The same as SetOffsetMinX. 58 | /// 59 | /// Target rectTransform. 60 | /// Offset value. 61 | public static void SetLeft(this RectTransform rectTransform, float x) => SetOffsetMinX(rectTransform, x); 62 | 63 | /// 64 | /// Sets offset min y value of the rectTransform. 65 | /// 66 | /// Target rectTransform. 67 | /// Value to set. 68 | public static void SetOffsetMinY(this RectTransform rectTransform, float y) => rectTransform.offsetMin = rectTransform.offsetMin.WithY(y); 69 | 70 | /// 71 | /// Sets offset from bottom. The same as SetOffsetMinY. 72 | /// 73 | /// Target rectTransform. 74 | /// Offset value. 75 | public static void SetBottom(this RectTransform rectTransform, float y) => SetOffsetMinY(rectTransform, y); 76 | 77 | /// 78 | /// Sets offset max x value of the rectTransform. 79 | /// 80 | /// Target rectTransform. 81 | /// Value to set. 82 | public static void SetOffsetMaxX(this RectTransform rectTransform, float x) => rectTransform.offsetMax = rectTransform.offsetMax.WithX(x); 83 | 84 | /// 85 | /// Sets offset from right. The same as SetOffsetMaxX. 86 | /// 87 | /// Target rectTransform. 88 | /// Offset value. 89 | public static void SetRight(this RectTransform rectTransform, float x) => SetOffsetMaxX(rectTransform, x); 90 | 91 | /// 92 | /// Sets offset max y value of the rectTransform. 93 | /// 94 | /// Target rectTransform. 95 | /// Value to set. 96 | public static void SetOffsetMaxY(this RectTransform rectTransform, float y) => rectTransform.offsetMax = rectTransform.offsetMax.WithY(y); 97 | 98 | /// 99 | /// Sets offset from top. The same as SetOffsetMaxY. 100 | /// 101 | /// Target rectTransform. 102 | /// Offset value. 103 | public static void SetTop(this RectTransform rectTransform, float y) => SetOffsetMaxY(rectTransform, y); 104 | 105 | /// 106 | /// Sets anchor position x value of the rectTransform. 107 | /// 108 | /// Target rectTransform. 109 | /// Value to set. 110 | public static void SetAnchoredPositionX(this RectTransform rectTransform, float x) => rectTransform.anchoredPosition = rectTransform.anchoredPosition.WithX(x); 111 | 112 | /// 113 | /// Sets anchor position y value of the rectTransform. 114 | /// 115 | /// Target rectTransform. 116 | /// Value to set. 117 | public static void SetAnchoredPositionY(this RectTransform rectTransform, float y) => rectTransform.anchoredPosition = rectTransform.anchoredPosition.WithY(y); 118 | 119 | /// 120 | /// Sets anchor position 3d x value of the rectTransform. 121 | /// 122 | /// Target rectTransform. 123 | /// Value to set. 124 | public static void SetAnchoredPosition3DX(this RectTransform rectTransform, float x) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithX(x); 125 | 126 | /// 127 | /// Sets anchor position 3d y value of the rectTransform. 128 | /// 129 | /// Target rectTransform. 130 | /// Value to set. 131 | public static void SetAnchoredPosition3DY(this RectTransform rectTransform, float y) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithY(y); 132 | 133 | /// 134 | /// Sets anchor position 3d z value of the rectTransform. 135 | /// 136 | /// Target rectTransform. 137 | /// Value to set. 138 | public static void SetAnchoredPosition3DZ(this RectTransform rectTransform, float z) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithZ(z); 139 | 140 | /// 141 | /// Sets anchor position 3d x and y values of the rectTransform. 142 | /// 143 | /// Target rectTransform. 144 | /// Value to set. 145 | /// Value to set. 146 | public static void SetAnchoredPosition3DXY(this RectTransform rectTransform, float x, float y) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithXY(x, y); 147 | 148 | /// 149 | /// Sets anchor position 3d x and y values of the rectTransform. 150 | /// 151 | /// Target rectTransform. 152 | /// Position to set. 153 | public static void SetAnchoredPosition3DXY(this RectTransform rectTransform, Vector2 position) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithXY(position.x, position.y); 154 | 155 | /// 156 | /// Sets anchor position 3d x and z values of the rectTransform. 157 | /// 158 | /// Target rectTransform. 159 | /// Value to set. 160 | /// Value to set. 161 | public static void SetAnchoredPosition3DXZ(this RectTransform rectTransform, float x, float z) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithXZ(x, z); 162 | 163 | /// 164 | /// Sets anchor position 3d x and z values of the rectTransform. 165 | /// 166 | /// Target rectTransform. 167 | /// Position to set. 168 | public static void SetAnchoredPosition3DXZ(this RectTransform rectTransform, Vector2 position) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithXZ(position.x, position.y); 169 | 170 | /// 171 | /// Sets anchor position 3d y and z values of the rectTransform. 172 | /// 173 | /// Target rectTransform. 174 | /// Value to set. 175 | /// Value to set. 176 | public static void SetAnchoredPosition3DYZ(this RectTransform rectTransform, float y, float z) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithYZ(y, z); 177 | 178 | /// 179 | /// Sets anchor position 3d y and z values of the rectTransform. 180 | /// 181 | /// Target rectTransform. 182 | /// Position to set. 183 | public static void SetAnchoredPosition3DYZ(this RectTransform rectTransform, Vector2 position) => rectTransform.anchoredPosition3D = rectTransform.anchoredPosition3D.WithYZ(position.x, position.y); 184 | 185 | /// 186 | /// Sets pivot x value of the rectTransform. 187 | /// 188 | /// Target rectTransform. 189 | /// Value to set. 190 | public static void SetPivotX(this RectTransform rectTransform, float x) => rectTransform.pivot = rectTransform.pivot.WithX(x); 191 | 192 | /// 193 | /// Sets pivot y value of the rectTransform. 194 | /// 195 | /// Target rectTransform. 196 | /// Value to set. 197 | public static void SetPivotY(this RectTransform rectTransform, float y) => rectTransform.pivot = rectTransform.pivot.WithY(y); 198 | 199 | /// 200 | /// Sets pivot x value of the rectTransform without any changes min and max points. 201 | /// 202 | /// Target rectTransform. 203 | /// Value to set. 204 | public static void SetPivotOnlyX(this RectTransform rectTransform, float x) 205 | { 206 | var deltaPercent = rectTransform.pivot.x - x; 207 | rectTransform.SetPivotX(x); 208 | rectTransform.SetAnchoredPositionX(rectTransform.anchoredPosition.x - rectTransform.sizeDelta.x * deltaPercent); 209 | } 210 | 211 | /// 212 | /// Sets pivot y value of the rectTransform without any changes min and max points. 213 | /// 214 | /// Target rectTransform. 215 | /// Value to set. 216 | public static void SetPivotOnlyY(this RectTransform rectTransform, float y) 217 | { 218 | var deltaPercent = rectTransform.pivot.y - y; 219 | rectTransform.SetPivotY(y); 220 | rectTransform.SetAnchoredPositionY(rectTransform.anchoredPosition.y - rectTransform.sizeDelta.y * deltaPercent); 221 | } 222 | 223 | /// 224 | /// Sets pivot value of the rectTransform without any changes min and max points. 225 | /// 226 | /// Target rectTransform. 227 | /// Value to set. 228 | public static void SetPivotOnly(this RectTransform rectTransform, Vector2 pivot) => SetPivotOnly(rectTransform, pivot.x, pivot.y); 229 | 230 | /// 231 | /// Sets pivot x and y values of the rectTransform without any changes min and max points. 232 | /// 233 | /// Target rectTransform. 234 | /// Value to set. 235 | /// Value to set. 236 | public static void SetPivotOnly(this RectTransform rectTransform, float x, float y) 237 | { 238 | SetPivotOnlyX(rectTransform, x); 239 | SetPivotOnlyY(rectTransform, y); 240 | } 241 | } 242 | } -------------------------------------------------------------------------------- /Scripts/QuaternionExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Codomaster.Extensions 4 | { 5 | public static class QuaternionExtensions 6 | { 7 | /// 8 | /// Sets to passed . 9 | /// 10 | /// Target quaternion. 11 | /// Axis to set. 12 | /// Value to set. 13 | /// Changed copy of the . 14 | public static Quaternion With(this Quaternion quaternion, int axis, float value) 15 | { 16 | quaternion[axis] = value; 17 | return quaternion; 18 | } 19 | 20 | /// 21 | /// Sets value to x axis. 22 | /// 23 | /// Target quaternion. 24 | /// Value to set. 25 | /// 26 | public static Quaternion WithX(this Quaternion quaternion, float x) => With(quaternion, 0, x); 27 | 28 | /// 29 | /// Sets value to y axis. 30 | /// 31 | /// Target quaternion. 32 | /// Value to set. 33 | /// 34 | public static Quaternion WithY(this Quaternion quaternion, float y) => With(quaternion, 1, y); 35 | 36 | /// 37 | /// Sets value to z axis. 38 | /// 39 | /// Target quaternion. 40 | /// Value to set. 41 | /// 42 | public static Quaternion WithZ(this Quaternion quaternion, float z) => With(quaternion, 2, z); 43 | 44 | /// 45 | /// Sets value to w axis. 46 | /// 47 | /// Target quaternion. 48 | /// Value to set. 49 | /// 50 | public static Quaternion WithW(this Quaternion quaternion, float w) => With(quaternion, 3, w); 51 | 52 | /// 53 | /// Sets values to passed axes. 54 | /// 55 | /// Target quaternion. 56 | /// First axis to set. 57 | /// First value to set. 58 | /// Second axis to set. 59 | /// Second value to set. 60 | /// Changed copy of the . 61 | public static Quaternion With(this Quaternion quaternion, int axis1, float value1, int axis2, float value2) 62 | { 63 | quaternion[axis1] = value1; 64 | quaternion[axis2] = value2; 65 | return quaternion; 66 | } 67 | 68 | /// 69 | /// Sets and values to respective axes. 70 | /// 71 | /// Target quaternion. 72 | /// Value to set. 73 | /// Value to set. 74 | /// 75 | public static Quaternion WithXY(this Quaternion quaternion, float x, float y) => With(quaternion, 0, x, 1, y); 76 | 77 | /// 78 | /// Sets components to specified axes. 79 | /// 80 | /// Target quaternion. 81 | /// Value to set. 82 | /// 83 | public static Quaternion WithXY(this Quaternion quaternion, Vector2 values) => With(quaternion, 0, values.x, 1, values.y); 84 | 85 | /// 86 | /// Sets and values to respective axes. 87 | /// 88 | /// Target quaternion. 89 | /// Value to set. 90 | /// Value to set. 91 | /// 92 | public static Quaternion WithXZ(this Quaternion quaternion, float x, float z) => With(quaternion, 0, x, 2, z); 93 | 94 | /// 95 | /// Sets components to specified axes. 96 | /// 97 | /// Target quaternion. 98 | /// Value to set. 99 | /// 100 | public static Quaternion WithXZ(this Quaternion quaternion, Vector2 values) => With(quaternion, 0, values.x, 2, values.y); 101 | 102 | /// 103 | /// Sets and values to respective axes. 104 | /// 105 | /// Target quaternion. 106 | /// Value to set. 107 | /// Value to set. 108 | /// 109 | public static Quaternion WithYZ(this Quaternion quaternion, float y, float z) => With(quaternion, 1, y, 2, z); 110 | 111 | /// 112 | /// Sets components to specified axes. 113 | /// 114 | /// Target quaternion. 115 | /// Value to set. 116 | /// 117 | public static Quaternion WithYZ(this Quaternion quaternion, Vector2 values) => With(quaternion, 1, values.x, 2, values.y); 118 | 119 | /// 120 | /// Sets and values to respective axes. 121 | /// 122 | /// Target quaternion. 123 | /// Value to set. 124 | /// Value to set. 125 | /// 126 | public static Quaternion WithXW(this Quaternion quaternion, float x, float w) => With(quaternion, 0, x, 3, w); 127 | 128 | /// 129 | /// Sets components to specified axes. 130 | /// 131 | /// Target quaternion. 132 | /// Value to set. 133 | /// 134 | public static Quaternion WithXW(this Quaternion quaternion, Vector2 values) => With(quaternion, 0, values.x, 3, values.y); 135 | 136 | /// 137 | /// Sets and values to respective axes. 138 | /// 139 | /// Target quaternion. 140 | /// Value to set. 141 | /// Value to set. 142 | /// 143 | public static Quaternion WithYW(this Quaternion quaternion, float y, float w) => With(quaternion, 1, y, 3, w); 144 | 145 | /// 146 | /// Sets components to specified axes. 147 | /// 148 | /// Target quaternion. 149 | /// Value to set. 150 | /// 151 | public static Quaternion WithYW(this Quaternion quaternion, Vector2 values) => With(quaternion, 1, values.x, 3, values.y); 152 | 153 | /// 154 | /// Sets and values to respective axes. 155 | /// 156 | /// Target quaternion. 157 | /// Value to set. 158 | /// Value to set. 159 | /// 160 | public static Quaternion WithZW(this Quaternion quaternion, float z, float w) => With(quaternion, 2, z, 3, w); 161 | 162 | /// 163 | /// Sets components to specified axes. 164 | /// 165 | /// Target quaternion. 166 | /// Value to set. 167 | /// 168 | public static Quaternion WithZW(this Quaternion quaternion, Vector2 values) => With(quaternion, 2, values.x, 3, values.y); 169 | 170 | /// 171 | /// Sets values to passed axes. 172 | /// 173 | /// Target quaternion. 174 | /// First axis to set. 175 | /// First value to set. 176 | /// Second axis to set. 177 | /// Second value to set. 178 | /// Third axis to set. 179 | /// Third value to set. 180 | /// Changed copy of the . 181 | public static Quaternion With(this Quaternion quaternion, int axis1, float value1, int axis2, float value2, int axis3, float value3) 182 | { 183 | quaternion[axis1] = value1; 184 | quaternion[axis2] = value2; 185 | quaternion[axis3] = value3; 186 | return quaternion; 187 | } 188 | 189 | /// 190 | /// Sets , and values to respective axes. 191 | /// 192 | /// Target quaternion. 193 | /// Value to set. 194 | /// Value to set. 195 | /// Value to set. 196 | /// 197 | public static Quaternion WithXYZ(this Quaternion quaternion, float x, float y, float z) => With(quaternion, 0, x, 1, y, 2, z); 198 | 199 | /// 200 | /// Sets components to specified axes. 201 | /// 202 | /// Target quaternion. 203 | /// Value to set. 204 | /// 205 | public static Quaternion WithXYZ(this Quaternion quaternion, Vector3 values) => With(quaternion, 0, values.x, 1, values.y, 2, values.z); 206 | 207 | /// 208 | /// Sets , and values to respective axes. 209 | /// 210 | /// Target quaternion. 211 | /// Value to set. 212 | /// Value to set. 213 | /// Value to set. 214 | /// 215 | public static Quaternion WithXYW(this Quaternion quaternion, float x, float y, float w) => With(quaternion, 0, x, 1, y, 3, w); 216 | 217 | /// 218 | /// Sets components to specified axes. 219 | /// 220 | /// Target quaternion. 221 | /// Value to set. 222 | /// 223 | public static Quaternion WithXYW(this Quaternion quaternion, Vector3 values) => With(quaternion, 0, values.x, 1, values.y, 3, values.z); 224 | 225 | /// 226 | /// Sets , and values to respective axes. 227 | /// 228 | /// Target quaternion. 229 | /// Value to set. 230 | /// Value to set. 231 | /// Value to set. 232 | /// 233 | public static Quaternion WithXZW(this Quaternion quaternion, float x, float z, float w) => With(quaternion, 0, x, 2, z, 3, w); 234 | 235 | /// 236 | /// Sets components to specified axes. 237 | /// 238 | /// Target quaternion. 239 | /// Value to set. 240 | /// 241 | public static Quaternion WithXZW(this Quaternion quaternion, Vector3 values) => With(quaternion, 0, values.x, 2, values.y, 3, values.z); 242 | 243 | /// 244 | /// Sets , and values to respective axes. 245 | /// 246 | /// Target quaternion. 247 | /// Value to set. 248 | /// Value to set. 249 | /// Value to set. 250 | /// 251 | public static Quaternion WithYZW(this Quaternion quaternion, float y, float z, float w) => With(quaternion, 1, y, 2, z, 3, w); 252 | 253 | /// 254 | /// Sets components to specified axes. 255 | /// 256 | /// Target quaternion. 257 | /// Value to set. 258 | /// 259 | public static Quaternion WithYZW(this Quaternion quaternion, Vector3 values) => With(quaternion, 1, values.x, 2, values.y, 3, values.z); 260 | } 261 | } -------------------------------------------------------------------------------- /Scripts/Vector3IntExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class Vector3IntExtensions 7 | { 8 | /// 9 | /// Sets value to vector's axis. 10 | /// 11 | /// Target vector. 12 | /// Axis index of the vector. 13 | /// Value to set. 14 | /// Changed copy of the vector. 15 | public static Vector3Int With(this Vector3Int vector, int axis, int value) 16 | { 17 | vector[axis] = value; 18 | return vector; 19 | } 20 | 21 | /// 22 | /// Sets value to vector's x axis. 23 | /// 24 | /// Target vector. 25 | /// Value to set. 26 | /// Changed copy of the vector. 27 | public static Vector3Int WithX(this Vector3Int vector, int x) => With(vector, 0, x); 28 | 29 | /// 30 | /// Sets value to vector's y axis. 31 | /// 32 | /// Target vector. 33 | /// Value to set. 34 | /// Changed copy of the vector. 35 | public static Vector3Int WithY(this Vector3Int vector, int y) => With(vector, 1, y); 36 | 37 | /// 38 | /// Sets value to vector's z axis. 39 | /// 40 | /// Target vector. 41 | /// Value to set. 42 | /// Changed copy of the vector. 43 | public static Vector3Int WithZ(this Vector3Int vector, int z) => With(vector, 2, z); 44 | 45 | /// 46 | /// Sets values to vector's axes. 47 | /// 48 | /// Target vector. 49 | /// First axis index of the vector. 50 | /// First value to set. 51 | /// Second axis index of the vector. 52 | /// Second value to set. 53 | /// Changed copy of the vector. 54 | public static Vector3Int With(this Vector3Int vector, int axis1, int value1, int axis2, int value2) 55 | { 56 | vector[axis1] = value1; 57 | vector[axis2] = value2; 58 | 59 | return vector; 60 | } 61 | 62 | /// 63 | /// Sets value to vector's x and y axis. 64 | /// 65 | /// Target vector. 66 | /// Value to set. 67 | /// Value to set. 68 | /// Changed copy of the vector. 69 | public static Vector3Int WithXY(this Vector3Int vector, int x, int y) => With(vector, 0, x, 1, y); 70 | 71 | /// 72 | /// Sets value to vector's x and y axis. 73 | /// 74 | /// Target vector. 75 | /// Value to set. 76 | /// Changed copy of the vector. 77 | public static Vector3 WithXY(this Vector3Int vector, Vector2Int value) => With(vector, 0, value.x, 1, value.y); 78 | 79 | /// 80 | /// Sets value to vector's x and z axis. 81 | /// 82 | /// Target vector. 83 | /// Value to set. 84 | /// Value to set. 85 | /// Changed copy of the vector. 86 | public static Vector3Int WithXZ(this Vector3Int vector, int x, int z) => With(vector, 0, x, 2, z); 87 | 88 | /// 89 | /// Sets value to vector's x and z axis. 90 | /// 91 | /// Target vector. 92 | /// Value to set. 93 | /// Changed copy of the vector. 94 | public static Vector3 WithXZ(this Vector3Int vector, Vector2Int value) => With(vector, 0, value.x, 2, value.y); 95 | 96 | /// 97 | /// Sets value to vector's y and z axis. 98 | /// 99 | /// Target vector. 100 | /// Value to set. 101 | /// Value to set. 102 | /// Changed copy of the vector. 103 | public static Vector3Int WithYZ(this Vector3Int vector, int y, int z) => With(vector, 1, y, 2, z); 104 | 105 | /// 106 | /// Sets value to vector's y and z axis. 107 | /// 108 | /// Target vector. 109 | /// Value to set. 110 | /// Changed copy of the vector. 111 | public static Vector3 WithYZ(this Vector3Int vector, Vector2Int value) => With(vector, 1, value.x, 2, value.y); 112 | 113 | /// 114 | /// Inverts value of specified axis. 115 | /// 116 | /// The vector. 117 | /// Target axis. 118 | /// Vector with inverted axis value. 119 | public static Vector3Int WithNegate(this Vector3Int vector, int axis) => vector.With(axis, -vector[axis]); 120 | 121 | /// 122 | /// Inverts x axis value. 123 | /// 124 | /// The vector. 125 | /// Vector with inverted axis value. 126 | public static Vector3Int WithNegateX(this Vector3Int vector) => WithNegate(vector, 0); 127 | 128 | /// 129 | /// Inverts y axis value. 130 | /// 131 | /// The vector. 132 | /// Vector with inverted axis value. 133 | public static Vector3Int WithNegateY(this Vector3Int vector) => WithNegate(vector, 1); 134 | 135 | /// 136 | /// Inverts z axis value. 137 | /// 138 | /// The vector. 139 | /// Vector with inverted axis value. 140 | public static Vector3Int WithNegateZ(this Vector3Int vector) => WithNegate(vector, 2); 141 | 142 | /// 143 | /// Inverts values of specified axes. 144 | /// 145 | /// The vector. 146 | /// First axis. 147 | /// Second axis. 148 | /// Vector with inverted axes values. 149 | public static Vector3Int WithNegate(this Vector3Int vector, int axis1, int axis2) 150 | { 151 | vector[axis1] = -vector[axis1]; 152 | vector[axis2] = -vector[axis2]; 153 | 154 | return vector; 155 | } 156 | 157 | /// 158 | /// Inverts x and y axes values. 159 | /// 160 | /// The vector. 161 | /// Vector with inverted axes values. 162 | public static Vector3Int WithNegateXY(this Vector3Int vector) => vector.WithNegate(0, 1); 163 | 164 | /// 165 | /// Inverts x and z axes values. 166 | /// 167 | /// The vector. 168 | /// Vector with inverted axes values. 169 | public static Vector3Int WithNegateXZ(this Vector3Int vector) => vector.WithNegate(0, 2); 170 | 171 | /// 172 | /// Inverts y and z axes values. 173 | /// 174 | /// The vector. 175 | /// Vector with inverted axes values. 176 | public static Vector3Int WithNegateYZ(this Vector3Int vector) => vector.WithNegate(1, 2); 177 | 178 | /// 179 | /// Inverts vector. 180 | /// 181 | /// The vector. 182 | /// Inverted vector. 183 | public static Vector3Int Negate(this Vector3Int vector) => new(-vector.x, -vector.y, -vector.z); 184 | 185 | /// 186 | /// Gets by axes. 187 | /// 188 | /// Target vector. 189 | /// First axis. 190 | /// Second axis. 191 | /// vector. 192 | public static Vector2Int Get(this Vector3Int vector, int axis1, int axis2) => new(vector[axis1], vector[axis2]); 193 | 194 | /// 195 | /// Gets by x and y axes. 196 | /// 197 | /// Target vector. 198 | /// vector. 199 | public static Vector2Int GetXY(this Vector3Int vector) => Get(vector, 0, 1); 200 | 201 | /// 202 | /// Gets by x and z axes. 203 | /// 204 | /// Target vector. 205 | /// vector. 206 | public static Vector2Int GetXZ(this Vector3Int vector) => Get(vector, 0, 2); 207 | 208 | /// 209 | /// Gets by y and x axes. 210 | /// 211 | /// Target vector. 212 | /// vector. 213 | public static Vector2Int GetYX(this Vector3Int vector) => Get(vector, 1, 0); 214 | 215 | /// 216 | /// Gets by y and z axes. 217 | /// 218 | /// Target vector. 219 | /// vector. 220 | public static Vector2Int GetYZ(this Vector3Int vector) => Get(vector, 1, 2); 221 | 222 | /// 223 | /// Gets by z and x axes. 224 | /// 225 | /// Target vector. 226 | /// vector. 227 | public static Vector2Int GetZX(this Vector3Int vector) => Get(vector, 2, 0); 228 | 229 | /// 230 | /// Gets by z and y axes. 231 | /// 232 | /// Target vector. 233 | /// vector. 234 | public static Vector2Int GetZY(this Vector3Int vector) => Get(vector, 2, 1); 235 | 236 | /// 237 | /// Gets vector with swapped axes. 238 | /// 239 | /// Target vector. 240 | /// First axis. 241 | /// Second axis. 242 | /// Third axis. 243 | /// vector. 244 | public static Vector3Int Get(this Vector3Int vector, int axis1, int axis2, int axis3) => new(vector[axis1], vector[axis2], vector[axis3]); 245 | 246 | /// 247 | /// Gets vector with with order XZY. 248 | /// 249 | /// Target vector. 250 | /// vector. 251 | public static Vector3Int GetXZY(this Vector3Int vector) => Get(vector, 0, 2, 1); 252 | 253 | /// 254 | /// Gets vector with with order YXZ. 255 | /// 256 | /// Target vector. 257 | /// vector. 258 | public static Vector3Int GetYXZ(this Vector3Int vector) => Get(vector, 1, 0, 2); 259 | 260 | /// 261 | /// Gets vector with with order YZX. 262 | /// 263 | /// Target vector. 264 | /// vector. 265 | public static Vector3Int GetYZX(this Vector3Int vector) => Get(vector, 1, 2, 0); 266 | 267 | /// 268 | /// Gets vector with with order ZXY. 269 | /// 270 | /// Target vector. 271 | /// vector. 272 | public static Vector3Int GetZXY(this Vector3Int vector) => Get(vector, 2, 0, 1); 273 | 274 | /// 275 | /// Gets vector with with order ZYX. 276 | /// 277 | /// Target vector. 278 | /// vector. 279 | public static Vector3Int GetZYX(this Vector3Int vector) => Get(vector, 2, 1, 0); 280 | 281 | private static void Compare(Vector3Int vector, ref int index, int compareIndex, int result) 282 | { 283 | if (vector[compareIndex].CompareTo(vector[index]) == result) 284 | index = compareIndex; 285 | } 286 | 287 | private static int CompareAllComponents(Vector3Int vector, int result) 288 | { 289 | var index = 0; 290 | 291 | Compare(vector, ref index, 1, result); 292 | Compare(vector, ref index, 2, result); 293 | 294 | return index; 295 | } 296 | 297 | /// 298 | /// Gets max component info from vector. 299 | /// 300 | /// Target vector. 301 | /// Vector's max component tuple info. 302 | public static (int index, float value) MaxComponent(this Vector3Int vector) 303 | { 304 | var index = CompareAllComponents(vector, 1); 305 | return (index, vector[index]); 306 | } 307 | 308 | /// 309 | /// Gets min component info from vector. 310 | /// 311 | /// Target vector. 312 | /// Vector's min component tuple info. 313 | public static (int index, float value) MinComponent(this Vector3Int vector) 314 | { 315 | var index = CompareAllComponents(vector, -1); 316 | return (index, vector[index]); 317 | } 318 | 319 | /// 320 | /// Creates new vector with absolute components. 321 | /// 322 | /// Target vector. 323 | /// Vector with absolute components. 324 | public static Vector3Int Abs(this Vector3Int vector) => new(Mathf.Abs(vector.x), Mathf.Abs(vector.y), Mathf.Abs(vector.z)); 325 | 326 | /// 327 | /// Creates new vector with clamped components. 328 | /// 329 | /// Target vector. 330 | /// The minimum floating value to campare agains. 331 | /// The maximum floating value to campare agains. 332 | /// Clamped vector. 333 | public static Vector3Int Clamp(this Vector3Int vector, int min, int max) 334 | { 335 | return new Vector3Int(Mathf.Clamp(vector.x, min, max), Mathf.Clamp(vector.y, min, max), Mathf.Clamp(vector.z, min, max)); 336 | } 337 | 338 | /// 339 | /// Creates and returns a vector whose components are divided by the value. 340 | /// 341 | /// Target vector. 342 | /// Vector on which divide 343 | /// Divided vector. 344 | public static Vector3Int Divide(this Vector3Int vector, Vector3Int other) 345 | { 346 | return new Vector3Int(vector.x / other.x, vector.y / other.y, vector.z / other.z); 347 | } 348 | 349 | /// 350 | /// Checks if the vector components are equals. 351 | /// 352 | /// Target vector. 353 | /// if vector's components are equals. 354 | public static bool IsUniform(this Vector3Int vector) => vector.x == vector.y && vector.y == vector.z; 355 | 356 | /// 357 | /// Gets closest point info from list. 358 | /// 359 | /// Origin point. 360 | /// Compared points. 361 | /// Closest point tuple info. 362 | public static (Vector3Int point, int index) GetClosestPoint(this Vector3Int point, params Vector3Int[] points) 363 | { 364 | return GetClosestPoint(point, (IEnumerable)points); 365 | } 366 | 367 | /// 368 | /// Gets closest point info from list. 369 | /// 370 | /// Origin point. 371 | /// Compared points. 372 | /// Closest point tuple info. 373 | public static (Vector3Int point, int index) GetClosestPoint(this Vector3Int point, IEnumerable points) 374 | { 375 | var enumerator = points.GetEnumerator(); 376 | 377 | var index = -1; 378 | var closestIndex = -1; 379 | var closestPoint = Vector3Int.zero; 380 | var closestDistance = float.MaxValue; 381 | 382 | while (enumerator.MoveNext()) 383 | { 384 | ++index; 385 | var distance = Vector3Int.Distance(point, enumerator.Current); 386 | 387 | if (distance < closestDistance) 388 | { 389 | closestIndex = index; 390 | closestDistance = distance; 391 | closestPoint = enumerator.Current; 392 | } 393 | } 394 | 395 | return (closestPoint, closestIndex); 396 | } 397 | 398 | /// 399 | /// Get the closest point on a ray. 400 | /// 401 | /// A point in space. 402 | /// Start point of ray. 403 | /// Ray direction. Must be normalized. 404 | /// Tuple which contains closest point on line and distance from to calculated point. 405 | public static (Vector3 point, float distance) GetClosestPointOnRay(this Vector3Int point, Vector3 origin, Vector3 direction) 406 | { 407 | return Vector3Extensions.GetClosestPointOnRay(point, origin, direction); 408 | } 409 | 410 | /// 411 | /// Get the closest point on a line segment. 412 | /// 413 | /// A point in space. 414 | /// Start of line segment. 415 | /// End of line segment. 416 | /// Tuple which contains closest point on line and distance from to calculated point. 417 | 418 | public static (Vector3 point, float distance) GetClosestPointOnSegment(this Vector3 point, Vector3 start, Vector3 end) 419 | { 420 | return Vector3Extensions.GetClosestPointOnSegment(point, start, end); 421 | } 422 | } 423 | } -------------------------------------------------------------------------------- /Scripts/CameraExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace Codomaster.Extensions 5 | { 6 | public static class CameraExtensions 7 | { 8 | /// 9 | /// Set red channel of camera's background color. 10 | /// 11 | /// Target camera. 12 | /// Value of the red channel. 13 | public static void SetBackgroundColorR(this Camera camera, float r) => camera.backgroundColor = camera.backgroundColor.WithR(r); 14 | 15 | /// 16 | /// Set green channel of camera's background color. 17 | /// 18 | /// Target camera. 19 | /// Value of the green channel. 20 | public static void SetBackgroundColorG(this Camera camera, float g) => camera.backgroundColor = camera.backgroundColor.WithG(g); 21 | 22 | /// 23 | /// Set blue channel of camera's background color. 24 | /// 25 | /// Target camera. 26 | /// Value of the blue channel. 27 | public static void SetBackgroundColorB(this Camera camera, float b) => camera.backgroundColor = camera.backgroundColor.WithB(b); 28 | 29 | /// 30 | /// Set alpha channel of camera's background color. 31 | /// 32 | /// Target camera. 33 | /// Value of the alpha channel. 34 | public static void SetBackgroundColorA(this Camera camera, float a) => camera.backgroundColor = camera.backgroundColor.WithA(a); 35 | 36 | /// 37 | /// Set red and green channels of camera's background color. 38 | /// 39 | /// Target camera. 40 | /// Value of the red channel. 41 | /// Value of the green channel. 42 | public static void SetBackgroundColorRG(this Camera camera, float r, float g) => camera.backgroundColor = camera.backgroundColor.WithRG(r, g); 43 | 44 | /// 45 | /// Set red and blue channels of camera's background color. 46 | /// 47 | /// Target camera. 48 | /// Value of the red channel. 49 | /// Value of the blue channel. 50 | public static void SetBackgroundColorRB(this Camera camera, float r, float b) => camera.backgroundColor = camera.backgroundColor.WithRB(r, b); 51 | 52 | /// 53 | /// Set red and alpha channels of camera's background color. 54 | /// 55 | /// Target camera. 56 | /// Value of the red channel. 57 | /// Value of the alpha channel. 58 | public static void SetBackgroundColorRA(this Camera camera, float r, float a) => camera.backgroundColor = camera.backgroundColor.WithRA(r, a); 59 | 60 | /// 61 | /// Set green and blue channels of camera's background color. 62 | /// 63 | /// Target camera. 64 | /// Value of the green channel. 65 | /// Value of the blue channel. 66 | public static void SetBackgroundColorGB(this Camera camera, float g, float b) => camera.backgroundColor = camera.backgroundColor.WithGB(g, b); 67 | 68 | /// 69 | /// Set green and alpha channels of camera's background color. 70 | /// 71 | /// Target camera. 72 | /// Value of the green channel. 73 | /// Value of the alpha channel. 74 | public static void SetBackgroundColorGA(this Camera camera, float g, float a) => camera.backgroundColor = camera.backgroundColor.WithGA(g, a); 75 | 76 | /// 77 | /// Set blue and alpha channels of camera's background color. 78 | /// 79 | /// Target camera. 80 | /// Value of the blue channel. 81 | /// Value of the alpha channel. 82 | public static void SetBackgroundColorBA(this Camera camera, float b, float a) => camera.backgroundColor = camera.backgroundColor.WithBA(b, a); 83 | 84 | /// 85 | /// Set red, green and blue channels of camera's background color. 86 | /// 87 | /// Target camera. 88 | /// Value of the red channel. 89 | /// Value of the green channel. 90 | /// Value of the blue channel. 91 | public static void SetBackgroundColorRGB(this Camera camera, float r, float g, float b) => camera.backgroundColor = camera.backgroundColor.WithRGB(r, g, b); 92 | 93 | /// 94 | /// Set red, green and alpha channels of camera's background color. 95 | /// 96 | /// Target camera. 97 | /// Value of the red channel. 98 | /// Value of the green channel. 99 | /// Value of the alpha channel. 100 | public static void SetBackgroundColorRGA(this Camera camera, float r, float g, float a) => camera.backgroundColor = camera.backgroundColor.WithRGA(r, g, a); 101 | 102 | /// 103 | /// Set red, blue and alpha channels of camera's background color. 104 | /// 105 | /// Target camera. 106 | /// Value of the red channel. 107 | /// Value of the blue channel. 108 | /// Value of the alpha channel. 109 | public static void SetBackgroundColorRBA(this Camera camera, float r, float b, float a) => camera.backgroundColor = camera.backgroundColor.WithRBA(r, b, a); 110 | 111 | /// 112 | /// Set green, blue and alpha channels of camera's background color. 113 | /// 114 | /// Target camera. 115 | /// Value of the green channel. 116 | /// Value of the blue channel. 117 | /// Value of the alpha channel. 118 | public static void SetBackgroundColorGBA(this Camera camera, float g, float b, float a) => camera.backgroundColor = camera.backgroundColor.WithGBA(g, b, a); 119 | 120 | /// 121 | /// Set x component if lens shift. 122 | /// 123 | /// Target camera. 124 | /// Value of the x component. 125 | public static void SetLensShiftX(this Camera camera, float x) => camera.lensShift = camera.lensShift.WithX(x); 126 | 127 | /// 128 | /// Set y component if lens shift. 129 | /// 130 | /// Target camera. 131 | /// Value of the y component. 132 | public static void SetLensShiftY(this Camera camera, float y) => camera.lensShift = camera.lensShift.WithY(y); 133 | 134 | /// 135 | /// Set pixel rect center of the camera. 136 | /// 137 | /// Target camera. 138 | /// Value to set. 139 | public static void SetPixelRectCenter(this Camera camera, Vector2 center) => camera.pixelRect = camera.pixelRect.WithCenter(center); 140 | 141 | /// 142 | /// Set pixel rect position of the camera. 143 | /// 144 | /// Target camera. 145 | /// Value to set. 146 | public static void SetPixelRectPosition(this Camera camera, Vector2 position) => camera.pixelRect = camera.pixelRect.WithPosition(position); 147 | 148 | /// 149 | /// Set pixel rect height of the camera. 150 | /// 151 | /// Target camera. 152 | /// Value to set. 153 | public static void SetPixelRectHeight(this Camera camera, float height) => camera.pixelRect = camera.pixelRect.WithHeight(height); 154 | 155 | /// 156 | /// Set pixel rect width of the camera. 157 | /// 158 | /// Target camera. 159 | /// Value to set. 160 | public static void SetPixelRectWidth(this Camera camera, float width) => camera.pixelRect = camera.pixelRect.WithWidth(width); 161 | 162 | /// 163 | /// Set pixel rect max point of the camera. 164 | /// 165 | /// Target camera. 166 | /// Value to set. 167 | public static void SetPixelRectMax(this Camera camera, Vector2 max) => camera.pixelRect = camera.pixelRect.WithMax(max); 168 | 169 | /// 170 | /// Set pixel rect min point of the camera. 171 | /// 172 | /// Target camera. 173 | /// Value to set. 174 | public static void SetPixelRectMin(this Camera camera, Vector2 min) => camera.pixelRect = camera.pixelRect.WithMin(min); 175 | 176 | /// 177 | /// Set pixel rect size of the camera. 178 | /// 179 | /// Target camera. 180 | /// Value to set. 181 | public static void SetPixelRectSize(this Camera camera, Vector2 size) => camera.pixelRect = camera.pixelRect.WithSize(size); 182 | 183 | /// 184 | /// Set pixel rect x value of the camera. 185 | /// 186 | /// Target camera. 187 | /// Value to set. 188 | public static void SetPixelRectX(this Camera camera, float x) => camera.pixelRect = camera.pixelRect.WithX(x); 189 | 190 | /// 191 | /// Set pixel rect y value of the camera. 192 | /// 193 | /// Target camera. 194 | /// Value to set. 195 | public static void SetPixelRectY(this Camera camera, float y) => camera.pixelRect = camera.pixelRect.WithY(y); 196 | 197 | /// 198 | /// Set pixel rect x max value of the camera. 199 | /// 200 | /// Target camera. 201 | /// Value to set. 202 | public static void SetPixelRectXMax(this Camera camera, float xMax) => camera.pixelRect = camera.pixelRect.WithXMax(xMax); 203 | 204 | /// 205 | /// Set pixel rect y max value of the camera. 206 | /// 207 | /// Target camera. 208 | /// Value to set. 209 | public static void SetPixelRectYMax(this Camera camera, float yMax) => camera.pixelRect = camera.pixelRect.WithYMax(yMax); 210 | 211 | /// 212 | /// Set pixel rect x min value of the camera. 213 | /// 214 | /// Target camera. 215 | /// Value to set. 216 | public static void SetPixelRectXMin(this Camera camera, float xMin) => camera.pixelRect = camera.pixelRect.WithXMin(xMin); 217 | 218 | /// 219 | /// Set pixel rect y min value of the camera. 220 | /// 221 | /// Target camera. 222 | /// Value to set. 223 | public static void SetPixelRectYMin(this Camera camera, float yMin) => camera.pixelRect = camera.pixelRect.WithYMin(yMin); 224 | 225 | /// 226 | /// Set rect center value of the camera. 227 | /// 228 | /// Target camera. 229 | /// Value to set. 230 | public static void SetRectCenter(this Camera camera, Vector2 center) => camera.rect = camera.rect.WithCenter(center); 231 | 232 | /// 233 | /// Set rect position value of the camera. 234 | /// 235 | /// Target camera. 236 | /// Value to set. 237 | public static void SetRectPosition(this Camera camera, Vector2 position) => camera.rect = camera.rect.WithPosition(position); 238 | 239 | /// 240 | /// Set rect height value of the camera. 241 | /// 242 | /// Target camera. 243 | /// Value to set. 244 | public static void SetRectHeight(this Camera camera, float height) => camera.rect = camera.rect.WithHeight(height); 245 | 246 | /// 247 | /// Set rect width value of the camera. 248 | /// 249 | /// Target camera. 250 | /// Value to set. 251 | public static void SetRectWidth(this Camera camera, float width) => camera.rect = camera.rect.WithWidth(width); 252 | 253 | /// 254 | /// Set rect max point value of the camera. 255 | /// 256 | /// Target camera. 257 | /// Value to set. 258 | public static void SetRectMax(this Camera camera, Vector2 max) => camera.rect = camera.rect.WithMax(max); 259 | 260 | /// 261 | /// Set rect min point value of the camera. 262 | /// 263 | /// Target camera. 264 | /// Value to set. 265 | public static void SetRectMin(this Camera camera, Vector2 min) => camera.rect = camera.rect.WithMin(min); 266 | 267 | /// 268 | /// Set rect size value of the camera. 269 | /// 270 | /// Target camera. 271 | /// Value to set. 272 | public static void SetRectSize(this Camera camera, Vector2 size) => camera.rect = camera.rect.WithSize(size); 273 | 274 | /// 275 | /// Set rect x value of the camera. 276 | /// 277 | /// Target camera. 278 | /// Value to set. 279 | public static void SetRectX(this Camera camera, float x) => camera.rect = camera.rect.WithX(x); 280 | 281 | /// 282 | /// Set rect y value of the camera. 283 | /// 284 | /// Target camera. 285 | /// Value to set. 286 | public static void SetRectY(this Camera camera, float y) => camera.rect = camera.rect.WithY(y); 287 | 288 | /// 289 | /// Set rect x max value of the camera. 290 | /// 291 | /// Target camera. 292 | /// Value to set. 293 | public static void SetRectXMax(this Camera camera, float xMax) => camera.rect = camera.rect.WithXMax(xMax); 294 | 295 | /// 296 | /// Set rect y max value of the camera. 297 | /// 298 | /// Target camera. 299 | /// Value to set. 300 | public static void SetRectYMax(this Camera camera, float yMax) => camera.rect = camera.rect.WithYMax(yMax); 301 | 302 | /// 303 | /// Set rect x min value of the camera. 304 | /// 305 | /// Target camera. 306 | /// Value to set. 307 | public static void SetRectXMin(this Camera camera, float xMin) => camera.rect = camera.rect.WithXMin(xMin); 308 | 309 | /// 310 | /// Set rect y min value of the camera. 311 | /// 312 | /// Target camera. 313 | /// Value to set. 314 | public static void SetRectYMin(this Camera camera, float yMin) => camera.rect = camera.rect.WithYMin(yMin); 315 | 316 | /// 317 | /// Set sensor size x of the camera. 318 | /// 319 | /// Target camera. 320 | /// Value to set. 321 | public static void SetSensorSizeX(this Camera camera, float x) => camera.sensorSize = camera.sensorSize.WithX(x); 322 | 323 | /// 324 | /// Set sensor size y of the camera. 325 | /// 326 | /// Target camera. 327 | /// Value to set. 328 | public static void SetSensorSizeY(this Camera camera, float y) => camera.sensorSize = camera.sensorSize.WithY(y); 329 | 330 | /// 331 | /// Set transparency sort axis x of the camera. 332 | /// 333 | /// Target camera. 334 | /// Value to set. 335 | public static void SetTransparencySortAxisX(this Camera camera, float x) => camera.transparencySortAxis = camera.transparencySortAxis.WithX(x); 336 | 337 | /// 338 | /// Set transparency sort axis y of the camera. 339 | /// 340 | /// Target camera. 341 | /// Value to set. 342 | public static void SetTransparencySortAxisY(this Camera camera, float y) => camera.transparencySortAxis = camera.transparencySortAxis.WithY(y); 343 | 344 | /// 345 | /// Set transparency sort axis z of the camera. 346 | /// 347 | /// Target camera. 348 | /// Value to set. 349 | public static void SetTransparencySortAxisZ(this Camera camera, float z) => camera.transparencySortAxis = camera.transparencySortAxis.WithZ(z); 350 | 351 | /// 352 | /// Set transparency sort x and y axes of the camera. 353 | /// 354 | /// Target camera. 355 | /// X axis value to set. 356 | /// Y axis value to set. 357 | public static void SetTransparencySortAxisXY(this Camera camera, float x, float y) => camera.transparencySortAxis = camera.transparencySortAxis.WithXY(x, y); 358 | 359 | /// 360 | /// Set transparency sort x and y axes of the camera. 361 | /// 362 | /// Target camera. 363 | /// Vector to set. 364 | public static void SetTransparencySortAxisXY(this Camera camera, Vector2 vector) => camera.transparencySortAxis = camera.transparencySortAxis.WithXY(vector.x, vector.y); 365 | 366 | /// 367 | /// Set transparency sort x and y axes of the camera. 368 | /// 369 | /// Target camera. 370 | /// X axis value to set. 371 | /// Z axis value to set. 372 | public static void SetTransparencySortAxisXZ(this Camera camera, float x, float z) => camera.transparencySortAxis = camera.transparencySortAxis.WithXZ(x, z); 373 | 374 | /// 375 | /// Set transparency sort x and z axes of the camera. 376 | /// 377 | /// Target camera. 378 | /// Vector to set. 379 | public static void SetTransparencySortAxisXZ(this Camera camera, Vector2 vector) => camera.transparencySortAxis = camera.transparencySortAxis.WithXZ(vector.x, vector.y); 380 | 381 | /// 382 | /// Set transparency sort y and z axes of the camera. 383 | /// 384 | /// Target camera. 385 | /// Y axis value to set. 386 | /// Z axis value to set. 387 | public static void SetTransparencySortAxisYZ(this Camera camera, float y, float z) => camera.transparencySortAxis = camera.transparencySortAxis.WithYZ(y, z); 388 | 389 | /// 390 | /// Set transparency sort y and z axes of the camera. 391 | /// 392 | /// Target camera. 393 | /// Vector to set. 394 | public static void SetTransparencySortAxisYZ(this Camera camera, Vector2 vector) => camera.transparencySortAxis = camera.transparencySortAxis.WithYZ(vector.x, vector.y); 395 | 396 | /// 397 | /// Convert passed world to screen space with respect to 398 | /// 399 | /// Target camera. 400 | /// Desired world position. 401 | /// Canvas scaler which will be taken into account. 402 | /// Screen space position. 403 | public static Vector3 WorldToScreenPoint(this Camera camera, Vector3 position, CanvasScaler canvasScaler) 404 | { 405 | var screenPosition = camera.WorldToScreenPoint(position); 406 | 407 | var multiplier = canvasScaler.GetScaleFactor(); 408 | screenPosition.x /= multiplier; 409 | screenPosition.y /= multiplier; 410 | 411 | return screenPosition; 412 | } 413 | } 414 | } --------------------------------------------------------------------------------