├── .gitignore ├── LICENSE.md ├── Old.meta ├── Old ├── Images.meta ├── Images │ ├── BlendTransition.gif │ ├── BlendTransition.gif.meta │ ├── Cancel.gif │ ├── Cancel.gif.meta │ ├── Cancelable.gif │ ├── Cancelable.gif.meta │ ├── Multiple.gif │ ├── Multiple.gif.meta │ ├── OWTransition.gif │ ├── OWTransition.gif.meta │ ├── Oneframe.gif │ ├── Oneframe.gif.meta │ ├── example01.PNG │ ├── example01.PNG.meta │ ├── example02.PNG │ ├── example02.PNG.meta │ ├── example03.PNG │ ├── example03.PNG.meta │ ├── example04.PNG │ ├── example04.PNG.meta │ ├── safeTransition.gif │ └── safeTransition.gif.meta ├── Old-RxStateMachine.unitypackage └── ReadMe.md ├── ReadMe.md └── StatMachine.cs /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | 29 | # Unity3D Generated File On Crash Reports 30 | sysinfo.txt 31 | 32 | # Builds 33 | *.apk 34 | 35 | # backups 36 | 37 | *.saved.bak 38 | *.cs.meta 39 | *.*.meta 40 | *.md.meta -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Made With Monster Love (pty) ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Old.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7a8f6c614ed7e34fb610663ad802fd7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Old/Images.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57a4b2fcafef4ac409707a9b28f55a5c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Old/Images/BlendTransition.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/BlendTransition.gif -------------------------------------------------------------------------------- /Old/Images/BlendTransition.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5893b8cec7665b4d9f8efc29e15f4da 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/Cancel.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/Cancel.gif -------------------------------------------------------------------------------- /Old/Images/Cancel.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 137ee4dc249c63a4ca964acfaf1f0f41 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/Cancelable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/Cancelable.gif -------------------------------------------------------------------------------- /Old/Images/Cancelable.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 538a636178f0a934a9b1e736d74e2abc 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/Multiple.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/Multiple.gif -------------------------------------------------------------------------------- /Old/Images/Multiple.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27f8b5145599a0046a592d2eb43a6d5e 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/OWTransition.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/OWTransition.gif -------------------------------------------------------------------------------- /Old/Images/OWTransition.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a3c794553984b204f8739d84689e81c7 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/Oneframe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/Oneframe.gif -------------------------------------------------------------------------------- /Old/Images/Oneframe.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 10c8b930cdb3af0419c8afdf9de61fb5 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/example01.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/example01.PNG -------------------------------------------------------------------------------- /Old/Images/example01.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6bbd882c4d7955245a50d73dd84469a4 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/example02.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/example02.PNG -------------------------------------------------------------------------------- /Old/Images/example02.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a19b62c4b828ff64189cf3a29ba94ea7 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/example03.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/example03.PNG -------------------------------------------------------------------------------- /Old/Images/example03.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 423b273dcde33914c852234132714004 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/example04.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/example04.PNG -------------------------------------------------------------------------------- /Old/Images/example04.PNG.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 703291f6fe85bec4f9343dd0a0a1e9ce 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Images/safeTransition.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Images/safeTransition.gif -------------------------------------------------------------------------------- /Old/Images/safeTransition.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f6534d938295ec4c9fcd572e89784f6 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /Old/Old-RxStateMachine.unitypackage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilpark/RxStateMachine/251ec417803aab1f35e61199609bc1fda51e17ef/Old/Old-RxStateMachine.unitypackage -------------------------------------------------------------------------------- /Old/ReadMe.md: -------------------------------------------------------------------------------- 1 | # Unity3D - RxStateMachine 2 | ![](Images/Cancelable.gif) 3 | 4 | State machine makes managing states easy, it is widely used in many games and apps. 5 | However, there are not many state machines that designed with front-end in mind. 6 | 7 | Often, integrating multiple states with UI transition can be a huge hassle and needs extra code to make simple transitions working with states. 8 | RxStateMachine is designed with "front end first" and "Reactive" in mind. 9 | 10 | RxStatemachine is built upon[ thefuntastic's finite state machine](https://github.com/thefuntastic/Unity3d-Finite-State-Machine).
11 | Basic structure is mostly same but the core logic is implemented with [Unirx](https://github.com/neuecc/UniRx) (Reactive Extension for Unity) 12 | 13 | Thanks to [thefuntastic](https://github.com/thefuntastic) and [neuecc](https://github.com/neuecc) for amazing statemachine and unirx! 14 | 15 | ## Features 16 | 17 | #### 3 Transition Modes 18 | * Safe 19 | * OverWrite 20 | * Blend 21 | #### Flexible 22 | * Support multiple statemachine instances 23 | * Support Transition as routine or single call 24 | #### Responsive 25 | * Notifies transition progress 26 | * State Transition can be canceled 27 | * no co-routine used, more reliable functionality 28 | 29 | ## Basic Usage 30 | 31 | An example project is included (Unity 2017.3) to show the RxStateMachine in action. 32 | To use the state machine you need a few simple steps 33 | 34 | ##### 1. Include the RxStateMachine package 35 | 36 | ```C# 37 | using Bebimbop.Utilities.StateMachine; 38 | 39 | public class MyStateMachineClass : MonoBehaviour { } 40 | ``` 41 | 42 | ##### 2. Define your states using an Enum 43 | 44 | ```C# 45 | public enum States 46 | { 47 | Init, 48 | Play 49 | } 50 | ``` 51 | ##### 3. Create a variable to store a reference to the State Machine 52 | 53 | ```C# 54 | public StateMachine MyStateMachine; 55 | ``` 56 | 57 | ##### 4. Get a valid state machine for your MonoBehaviour 58 | 59 | ```C# 60 | MyStateMachine = StateMachine.Initialize(this); 61 | ``` 62 | 63 | This is where all of the magic in the RxStateMachine happens: in the background, it inspects your MonoBehaviour (`this`) and looks for any methods described by the convention shown below. 64 | 65 | You can call this at any time, but generally `Awake()` is a safe choice. 66 | 67 | ##### 5. You are now ready to manage state by simply calling `ChangeState()` 68 | ```C# 69 | MyStateMachine.ChangeState(States.Init); 70 | ``` 71 | 72 | ##### 6. State callbacks are defined by underscore convention ( `StateName_Method` ) 73 | 74 | ```C# 75 | //for single frame transition 76 | private void Init_Enter() 77 | { 78 | Debug.Log("Init done!"); 79 | } 80 | 81 | //for transiton over time 82 | //float t is between 0 ~ 1 (Start ~ end) 83 | private void Play_Enter(float t) 84 | { 85 | //Ui transition so easy! 86 | canvasGroup.alpha = t; 87 | Debug.Log( "Entering State.. Progress " + t); 88 | } 89 | /* output 90 | Entering State.. Progress 0 91 | Entering State.. Progress 0.43975 92 | ... 93 | Entering State.. Progress 0.9476 94 | Entering State.. Progress 1*/ 95 | 96 | //OnCancel Method gets called when transtion interrupted 97 | //by either calling ChangeState() with overwirte or CancelTranstion() 98 | private void Play_OnCancle() 99 | { 100 | canvasGroup.alpha = 0; 101 | } 102 | 103 | void Play_Update() 104 | { 105 | Debug.Log("Game Playing"); 106 | } 107 | 108 | void Play_Exit() 109 | { 110 | Debug.Log("Game Over"); 111 | } 112 | ``` 113 | Currently supported methods are: 114 | 115 | - `Enter` 116 | - `EnterCancel` 117 | - `Exit` 118 | - `ExitCancel` 119 | - `Finally` 120 | - `FixedUpdate` 121 | - `Update` 122 | - `LateUpdate` 123 | 124 | These methods can be private or public. The methods themselves are all optional, so you only need to provide the ones you actually intend on using. 125 | 126 | Enter/Exit routines are supported by simply adding `float` parameter into Enter/Exit methods. This can be a great way to accommodate animations. Note: `FixedUpdate`, `Update` and `LateUpdate` calls won't execute while an Enter or Exit routine is running. 127 | 128 | `Finally` is a special method guaranteed to be called after a state has exited. This is a good place to perform any hygiene operations such as resetting Uis or removing event listeners. 129 | 130 | ##### Setting Transition defaults and Cancel Transition 131 | There is simple support for managing asynchronous state changes with long enter or long exit. 132 | ```C# 133 | MyStateMachine.SetDuration(enterDuration = 0.5f, exitDuration = 0.5f) 134 | ``` 135 | The default duration for enter/exit is 0.5f but you can set it to any value as you need. by calling this method will set **all transition** to set duration. 136 | 137 | ```C# 138 | MyStateMachine.SetMode(transition = StateTransition.Safe); 139 | ``` 140 | The default is `StateTransition.Safe`. This will always allow the current state to finish both it's enter and exit functions before transitioning to any new states. by calling this method will set **all transition** to set mode. 141 | 142 | ```C# 143 | MyStateMachine.SetMode(transition = StateTransition.Overwrite); 144 | ``` 145 | `StateMahcine.Overwrite` will cancel any current transitions and invoke `Cancel` methods (*more detail explained in advance usage section*), and call the next state immediately. This means any code which has yet to run in enter and exit routines will be skipped. If you need to ensure you end with a particular configuration, the finally function will always be called: 146 | 147 | ```C# 148 | void MyCurrentState_Finally() 149 | { 150 | //Reset object to desired configuration 151 | } 152 | ``` 153 | 154 | ```C# 155 | MyStateMachine.SetMode(transition = StateTransition.Blend); 156 | ``` 157 | `StateMahcine.Blend` this will call/run the current state `Exit` routine and the next state `Enter` routine at the same time. this is useful when you need crossfade transition. 158 | 159 | 160 | ```C# 161 | MyStateMachine.CancelTransition(); 162 | ``` 163 | All transitions can be canceled by calling this method, and it will invoke the current `EnterCancel` or `ExitCancel` or both depends on how far you in the transition. 164 | 165 | *e.g) if you call `CancleTransition()` beginning of exit routine, it will invoke `ExitCancel`. if you call it after entering to new state's Enter routine, it will invoke both current state's `ExitCancel` and new state's `EnterCancel` methods.* 166 | 167 | ##### Dependencies 168 | 169 | UniRx, Reactive extension for Unity. latest source code(as of 02/13/18) already included in this repository, 170 | but if you want to get a newer vision, **[Download Unirx](https://assetstore.unity.com/packages/tools/unirx-reactive-extensions-for-unity-17276)** 171 | 172 | 173 | ## Advanced Usage 174 | 175 | #### Multiple Script Setup 176 | To use RxStateMachine over multiple scripts is also simple. 177 | Here's basic example how to setup RxStateMachine in multiple scripts 178 | 179 | ##### 1. Declare StateMachine in the desired script 180 | in this example, we declare StateMachine in *GameManager.cs* and make GameManager as a singleton to call it from other scripts 181 | 182 | ```C# 183 | 184 | public class GameManager : MonoBehaviour 185 | { 186 | public StateMachine MainStateMachine; 187 | private void Awake() 188 | { 189 | //initialize statemachine in Awake() to avoid Null error in other scripts 190 | MainStateMachine = StateMachine.Initialize(this); 191 | } 192 | 193 | //define state 194 | public enum State 195 | { 196 | RED = 0,BLUE 197 | } 198 | 199 | //some singleton behaviour 200 | private static GameManager instance = null; 201 | 202 | public static GameManager Instance { ... } 203 | } 204 | ``` 205 | 206 | ##### 2. Add State Script Component to subscribe state changes with callbacks 207 | 208 | ```C# 209 | 210 | public class RedState : MonoBehaviour 211 | { 212 | private StateMachine _mainStateMachine; 213 | private void Start() 214 | { 215 | _mainStateMachine = GameManger.MainStateMachine; 216 | //add RedState as subscriber to mainStateMachine. 217 | _mainStateMachine.AddSubscriber(this); 218 | } 219 | 220 | //call backs 221 | private void RED_Enter(float t) { } 222 | private void RED_Exit(float t) { } 223 | } 224 | 225 | 226 | public class BlueState : MonoBehaviour 227 | { 228 | private StateMachine _mainStateMachine; 229 | private void Start() 230 | { 231 | _mainStateMachine = GameManger.MainStateMachine; 232 | //add BlueState as subscriber to mainStateMachine. 233 | _mainStateMachine.AddSubscriber(this); 234 | } 235 | 236 | //call backs 237 | private void BLUE_Enter(float t) { } 238 | private void BLUE_Exit(float t) { } 239 | } 240 | ``` 241 | 242 | #### Manual Transition 243 | [TODO] add description with examples... 244 | * ChangeState(T newState) 245 | * ChangeState(T newState, StateTransition transition) 246 | * ChangeState(T newState, StateTransition transition, float enterDuration, float exitDuration) 247 | 248 | ### Cancel Invocation Order & Usage 249 | [TODO] add a description with examples... 250 | * Cancel in Safe Mode 251 | * Cancel in OverWrite Mode 252 | * Cancel in Blend Mode 253 | 254 | #### [TODO] Example Usage 255 | 256 | ## Exmaples 257 | #### Multiple StateMachine Example 258 | RxStateMachine support multiple instances of StateMachine. 259 | 260 | Example Located `Assests/DemoScenes/MultipleStateMachineExample.unity` 261 | ![](Images/Multiple.gif) 262 | #### StateMachine Example 263 | This example demonstrates most functionalities on RxStateMachine 264 | Change Settings on the left side and see the difference between 3 transition modes and Test cancellation to see how it works in different modes 265 | 266 | Example Located `Assests/DemoScenes/StateMachineExample.unity` 267 | ##### Safe Mode 268 | ![](Images/safeTransition.gif) 269 | ##### OverWrite Mode 270 | ![](Images/OWTransition.gif) 271 | ##### Blend Mode 272 | ![](Images/BlendTransition.gif) 273 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Unity3D - RxStateMachine 2 | ![](Images/Cancelable.gif) 3 | 4 | RxSateMachine v2.0 is out! It is more simpler and easy to use! for old version look in to [Old](https://github.com/sendtogil/RxStateMachine/tree/master/Old) folder. 5 | 6 | State machine makes managing states easy, it is widely used in many games and apps. 7 | However, there are not many state machines that designed with front-end in mind. 8 | 9 | Often, integrating multiple states with UI transition can be a huge hassle and needs extra code to make simple transitions working with states. 10 | RxStateMachine is designed with "front end first" and "Reactive" in mind. 11 | 12 | Thanks to [neuecc](https://github.com/neuecc) for Reactive Extensions for Unity(unirx)! 13 | 14 | ##### Dependencies 15 | 16 | Unity +2018.2, UniRx, Reactive extension for Unity. latest source code(as of 02/13/18) already included in this repository, 17 | but if you want to get a newer vision, **[Download Unirx](https://assetstore.unity.com/packages/tools/unirx-reactive-extensions-for-unity-17276)** 18 | 19 | ## Features 20 | 21 | #### 2 Transition Modes 22 | * Regular 23 | * (ST1)Enter -> (ST1)Exit -> (ST2)Enter -> 24 | * Blend 25 | * (ST1)Enter -> (ST1,ST2)Exit,Enter -> (ST2,ST3)Exit,Enter -> 26 | 27 | #### Flexible 28 | * Subscribe OnEnter/Exit of State or just Sate changes 29 | * Expend OnEnter/Exit behaviour as you wanted 30 | * Support multiple state machine instances 31 | 32 | #### Responsive 33 | * State Transition can be canceled 34 | * no co-routine used, more reliable functionality 35 | 36 | ## Simple Usage (State change pub/sub) 37 | To use the state machine you need a few simple steps 38 | 39 | ##### 1. Include the RxStateMachine package 40 | 41 | ```C# 42 | using using _Scripts.RxDevKit.StateMachine; 43 | 44 | ``` 45 | 46 | ##### 2. Define your states using an Enum 47 | 48 | ```C# 49 | public enum MyState 50 | { 51 | Init,State01,State02,State03 52 | } 53 | ``` 54 | ##### 3. Create a variable to store a reference to the State Machine 55 | 56 | ```C# 57 | private StateMachine _stateMachine; 58 | ``` 59 | 60 | ##### 4. You are now ready to change(publish) state by simply calling `ChangeState()` 61 | ```C# 62 | _stateMachine.ChangeState(MyState.Init); 63 | ``` 64 | 65 | ##### 5. Subscribe StateChanges! 66 | ```C# 67 | var mainCam = Camera.main; 68 | _stateMachine.Subscribe(state => 69 | { 70 | Debug.Log($"you are in {state}"); 71 | switch (state) 72 | { 73 | case MyState.State01: 74 | mainCam.backgroundColor = Color.gray; 75 | break; 76 | case MyState.State02: 77 | mainCam.backgroundColor = Color.magenta; 78 | break; 79 | case MyState.State03: 80 | mainCam.backgroundColor = Color.white; 81 | break; 82 | default: 83 | mainCam.backgroundColor = Color.black; 84 | break; 85 | } 86 | }); 87 | ``` 88 | ## Basic Usage (OnEnter/OnExit Async Subscription) 89 | with Rx SateMachine, you can subscribe Sate's Enter and Exit. 90 | There are some points you need to pay attention to avoid confusion. 91 | 1. On Enter, On Exit only accepts `Func>` data type. 92 | ```C# 93 | _stateMachine.OnEnter(MyState.Init, () =>Observable.Timer(TimeSpan.FromSeconds(2f)).AsUnitObservable()); 94 | ``` 95 | 2. you can subscribe this OnEnter/OnExit stream as many as you can. 96 | 3. However, OnEnter/OnExit transition will be completed when the last(longest) steam is complete. 97 | 4. Which means, you can subscribe many OnEnter/OnExit on a State to handle different things. 98 | 99 | * below example using [RxFadeManager](https://github.com/sendtogil/RxFadeManager) to fade in and out on State changes. 100 | ```C# 101 | namespace Demo.StateMachine 102 | { 103 | public class Demo2State : MonoBehaviour 104 | { 105 | public CanvasGroup Panel; 106 | public MyState ThisState; 107 | private StateMachine _stateMachine; 108 | 109 | void Start () 110 | { 111 | _stateMachine = Demo02Manager.Instance.StateMachine; 112 | var duration = Demo02Manager.Instance.FadeDuration; 113 | Panel.DisableCanvasGroup(true); 114 | 115 | _stateMachine.OnEnter(ThisState, () => Panel.FadeIn(duration).AsUnitObservable()); 116 | _stateMachine.OnExit(ThisState, () => Panel.FadeOut(duration).AsUnitObservable()); 117 | 118 | if(ThisState == MyState.Init) _stateMachine.ChangeState(MyState.Init); 119 | } 120 | } 121 | } 122 | 123 | ``` 124 | 125 | ## Advanced Usage 126 | #### Multiple Script Setup 127 | To use RxStateMachine over multiple scripts is also simple. 128 | Here's basic example how to setup RxStateMachine in multiple scripts 129 | 130 | 131 | 132 | 133 | ##### 1. Declare StateMachine in the desired script 134 | in this example, we declare StateMachine in *GameManager.cs* and make GameManager as a singleton to call it from other scripts 135 | 136 | ```C# 137 | 138 | public class GameManager : MonoBehaviour 139 | { 140 | 141 | } 142 | ``` 143 | 144 | ##### 2. Add State Script Component to subscribe state changes with callbacks 145 | 146 | ```C# 147 | 148 | public class RedState : MonoBehaviour 149 | { 150 | 151 | } 152 | 153 | 154 | public class BlueState : MonoBehaviour 155 | { 156 | 157 | } 158 | ``` 159 | 160 | #### Manual Transition 161 | [TODO] add description with examples... 162 | 163 | ### Cancel Invocation Order & Usage 164 | [TODO] add a description with examples... 165 | 166 | #### [TODO] Example Usage 167 | 168 | ## Exmaples 169 | #### Multiple StateMachine Example 170 | #### StateMachine Example 171 | -------------------------------------------------------------------------------- /StatMachine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UniRx; 5 | using UnityEngine; 6 | 7 | namespace RxDevKit.StateMachine 8 | { 9 | public class StateMachine: IObservable 10 | { 11 | private readonly List> _queue = new List>(); 12 | private AsyncMessageBroker _broker = new AsyncMessageBroker(); 13 | private bool _running = false; 14 | private Enum _nextState; 15 | //debug 16 | private Enum _current; 17 | //private List _history = new List(); 18 | 19 | public bool BlendMode = false; 20 | 21 | private readonly Subject _currentState = new Subject(); 22 | private class State 23 | { 24 | public Action Enter; 25 | public Action Exit; 26 | public Enum Estate; 27 | public readonly CompositeDisposable Disposable = new CompositeDisposable(); 28 | public readonly BoolReactiveProperty HasEntered = new BoolReactiveProperty(false); 29 | public readonly BoolReactiveProperty HasExited = new BoolReactiveProperty(false); 30 | 31 | } 32 | 33 | public void ChangeState(Enum targetState) 34 | { 35 | if (_running) 36 | { 37 | Debug.Log("StateMachine: Cannot change state while transitioning"); 38 | return; 39 | } 40 | 41 | _nextState = targetState; 42 | var state = new State(); 43 | 44 | state.Enter = () => 45 | { 46 | _running = true; 47 | _broker.PublishAsync(new Tuple(targetState,true)).Subscribe(_ => 48 | { 49 | _running = false; 50 | state.HasEntered.Value = true; 51 | _currentState.OnNext(state.Estate); 52 | 53 | _current = state.Estate; 54 | //_history.Add(state.Estate); 55 | 56 | }).AddTo(state.Disposable); 57 | }; 58 | state.Exit = () => 59 | { 60 | _running = true; 61 | _broker.PublishAsync(new Tuple(targetState,false)).Subscribe(_ => 62 | { 63 | _running = false; 64 | state.HasExited.Value = true; 65 | 66 | if(!BlendMode)Next(); 67 | }).AddTo(state.Disposable); 68 | }; 69 | state.Estate = targetState; 70 | _queue.Add(state); 71 | Next(); 72 | } 73 | 74 | private void OnCancel() 75 | { 76 | var state = new State(); 77 | state.Exit = () => 78 | { 79 | _running = true; 80 | _broker.PublishAsync(new Tuple(_current,false)).Subscribe(_ => 81 | { 82 | _running = false; 83 | state.HasExited.Value = true; 84 | 85 | if(!BlendMode)Next(); 86 | }).AddTo(state.Disposable); 87 | }; 88 | state.Estate = _current; 89 | state.HasEntered.Value = true; 90 | _queue.Add(state); 91 | } 92 | 93 | private void Next() 94 | { 95 | if(_queue.Count == 0 || _running) return; 96 | var targetState = _queue.First(); 97 | if (BlendMode) 98 | { 99 | //blend mode : enter -> (exit,enter) -> 100 | if (targetState.HasEntered.Value == false) 101 | { 102 | targetState.Enter(); 103 | } 104 | else 105 | { 106 | targetState.Exit(); 107 | var nextTargetState = _queue[1]; 108 | nextTargetState.Enter(); 109 | nextTargetState.HasEntered.Where(b => b) 110 | .Subscribe(_ => _queue.RemoveAt(0)); 111 | } 112 | } 113 | else 114 | { 115 | 116 | //regular mode : enter -> exit -> enter -> 117 | var disposable = new CompositeDisposable(); 118 | if (targetState.HasEntered.Value == false) 119 | { 120 | 121 | targetState.Enter(); 122 | if (!targetState.Estate.Equals(_nextState)) 123 | { 124 | targetState.HasEntered 125 | .Where(b => b) 126 | .Subscribe(_=>Next()).AddTo(disposable); 127 | } 128 | } 129 | else 130 | { 131 | if (_hasSubscribers) 132 | { 133 | targetState.Exit(); 134 | targetState.HasExited 135 | .Where(b => b) 136 | .Subscribe(_=> 137 | { 138 | _queue.RemoveAt(0); 139 | disposable.Dispose(); 140 | }).AddTo(disposable); 141 | } 142 | else 143 | { 144 | _queue.RemoveAt(0); 145 | targetState.Exit(); 146 | disposable.Dispose(); 147 | 148 | } 149 | 150 | } 151 | } 152 | } 153 | 154 | public void Cancel() 155 | { 156 | _queue.ForEach(x =>x.Disposable.Dispose()); 157 | _queue.Clear(); 158 | _running = false; 159 | OnCancel(); 160 | } 161 | 162 | private bool _hasSubscribers = false; 163 | public IDisposable OnEnter(Enum where, Func> asyncMessageReceiver) 164 | { 165 | _hasSubscribers = true; 166 | return _broker.Subscribe>((sate) => 167 | { 168 | if (sate.Item1.Equals(where) && sate.Item2) 169 | { 170 | return asyncMessageReceiver(); 171 | } 172 | else 173 | { 174 | return Observable.ReturnUnit(); 175 | } 176 | }); 177 | } 178 | 179 | public IDisposable OnExit(Enum where, Func> asyncMessageReceiver) 180 | { 181 | _hasSubscribers = true; 182 | return _broker.Subscribe>((sate) => 183 | { 184 | if (sate.Item1.Equals(where) && !sate.Item2) 185 | { 186 | return asyncMessageReceiver(); 187 | } 188 | else 189 | { 190 | return Observable.ReturnUnit(); 191 | } 192 | }); 193 | } 194 | 195 | public IDisposable Subscribe(IObserver observer) 196 | { 197 | return _currentState.Subscribe(observer); 198 | } 199 | } 200 | } --------------------------------------------------------------------------------