├── .github └── FUNDING.yml ├── .gitignore ├── Assets ├── SweatyChair.meta └── SweatyChair │ ├── Tutorials.meta │ └── Tutorials │ ├── Animations.meta │ ├── Animations │ ├── HandClick.anim │ ├── HandClick.anim.meta │ ├── HandDrag.anim │ ├── HandDrag.anim.meta │ ├── HandDragDouble.anim │ ├── HandDragDouble.anim.meta │ ├── HandPinch.anim │ └── HandPinch.anim.meta │ ├── Demo.meta │ ├── Demo │ ├── Demo.unity │ ├── Demo.unity.meta │ ├── DemoTutorial.prefab │ ├── DemoTutorial.prefab.meta │ ├── DemoTutorialValidator.cs │ └── DemoTutorialValidator.cs.meta │ ├── Resources.example.meta │ ├── Resources.example │ ├── TutorialPanel.prefab │ └── TutorialPanel.prefab.meta │ ├── Scripts.meta │ ├── Scripts │ ├── Editor.meta │ ├── Editor │ │ ├── TutorialActivateTaskEditor.cs │ │ ├── TutorialActivateTaskEditor.cs.meta │ │ ├── TutorialAnimateHandTaskEditor.cs │ │ ├── TutorialAnimateHandTaskEditor.cs.meta │ │ ├── TutorialAnimateTaskEditor.cs │ │ ├── TutorialAnimateTaskEditor.cs.meta │ │ ├── TutorialClickButtonTaskEditor.cs │ │ ├── TutorialClickButtonTaskEditor.cs.meta │ │ ├── TutorialDebugger.cs │ │ ├── TutorialDebugger.cs.meta │ │ ├── TutorialDragDoubleTaskEditor.cs │ │ ├── TutorialDragDoubleTaskEditor.cs.meta │ │ ├── TutorialDragTaskEditor.cs │ │ ├── TutorialDragTaskEditor.cs.meta │ │ ├── TutorialEventCompleteTaskEditor.cs │ │ ├── TutorialEventCompleteTaskEditor.cs.meta │ │ ├── TutorialHighlightTaskEditor.cs │ │ ├── TutorialHighlightTaskEditor.cs.meta │ │ ├── TutorialInstantiateTaskEditor.cs │ │ ├── TutorialInstantiateTaskEditor.cs.meta │ │ ├── TutorialOverrideClickButtonTaskEvent.cs │ │ ├── TutorialOverrideClickButtonTaskEvent.cs.meta │ │ ├── TutorialPinchTaskEditor.cs │ │ ├── TutorialPinchTaskEditor.cs.meta │ │ ├── TutorialSettingsEditor.cs │ │ ├── TutorialSettingsEditor.cs.meta │ │ ├── TutorialShowPanelTaskEditor.cs │ │ ├── TutorialShowPanelTaskEditor.cs.meta │ │ ├── TutorialShowTargetPanelTaskEditor.cs │ │ ├── TutorialShowTargetPanelTaskEditor.cs.meta │ │ ├── TutorialTaskEditor.cs │ │ ├── TutorialTaskEditor.cs.meta │ │ ├── TutorialWaitForActiveTaskEditor.cs │ │ └── TutorialWaitForActiveTaskEditor.cs.meta │ ├── Helpers.meta │ ├── Helpers │ │ ├── TimeScaleEnabler.cs │ │ ├── TimeScaleEnabler.cs.meta │ │ ├── TransformPathObtainer.cs │ │ ├── TransformPathObtainer.cs.meta │ │ ├── TutorialCompleteStepTrigger.cs │ │ ├── TutorialCompleteStepTrigger.cs.meta │ │ ├── TutorialDialogueEventHandler.cs │ │ └── TutorialDialogueEventHandler.cs.meta │ ├── Tasks.meta │ ├── Tasks │ │ ├── TutorialActivateTask.cs │ │ ├── TutorialActivateTask.cs.meta │ │ ├── TutorialAnimateHandTask.cs │ │ ├── TutorialAnimateHandTask.cs.meta │ │ ├── TutorialAnimateTask.cs │ │ ├── TutorialAnimateTask.cs.meta │ │ ├── TutorialClickButtonTask.cs │ │ ├── TutorialClickButtonTask.cs.meta │ │ ├── TutorialDialogueTask.cs │ │ ├── TutorialDialogueTask.cs.meta │ │ ├── TutorialDragDoubleTask.cs │ │ ├── TutorialDragDoubleTask.cs.meta │ │ ├── TutorialDragTask.cs │ │ ├── TutorialDragTask.cs.meta │ │ ├── TutorialEventCompleteTask.cs │ │ ├── TutorialEventCompleteTask.cs.meta │ │ ├── TutorialHighlightTask.cs │ │ ├── TutorialHighlightTask.cs.meta │ │ ├── TutorialInstantiateTask.cs │ │ ├── TutorialInstantiateTask.cs.meta │ │ ├── TutorialOverrideClickButtonTask.cs │ │ ├── TutorialOverrideClickButtonTask.cs.meta │ │ ├── TutorialPinchTask.cs │ │ ├── TutorialPinchTask.cs.meta │ │ ├── TutorialShowPanelTask.cs │ │ ├── TutorialShowPanelTask.cs.meta │ │ ├── TutorialShowTargetPanelTask.cs │ │ ├── TutorialShowTargetPanelTask.cs.meta │ │ ├── TutorialTask.cs │ │ ├── TutorialTask.cs.meta │ │ ├── TutorialWaitForActiveTask.cs │ │ └── TutorialWaitForActiveTask.cs.meta │ ├── Tutorial.cs │ ├── Tutorial.cs.meta │ ├── TutorialInitializer.cs │ ├── TutorialInitializer.cs.meta │ ├── TutorialManager.cs │ ├── TutorialManager.cs.meta │ ├── TutorialPanel.cs │ ├── TutorialPanel.cs.meta │ ├── TutorialSettings.cs │ ├── TutorialSettings.cs.meta │ ├── TutorialStep.cs │ ├── TutorialStep.cs.meta │ ├── TutorialValidator.cs │ └── TutorialValidator.cs.meta │ ├── Textures.meta │ ├── Textures │ ├── Character_Render_Texture.renderTexture │ ├── Character_Render_Texture.renderTexture.meta │ ├── blank_pixels.png │ ├── blank_pixels.png.meta │ ├── character_example.png │ ├── character_example.png.meta │ ├── speech_bubble.png │ ├── speech_bubble.png.meta │ ├── tutorial_arrow.png │ ├── tutorial_arrow.png.meta │ ├── tutorial_hand_impact.png │ ├── tutorial_hand_impact.png.meta │ ├── tutorial_hand_pinch.png │ ├── tutorial_hand_pinch.png.meta │ ├── tutorial_hand_pinch_out.png │ ├── tutorial_hand_pinch_out.png.meta │ ├── tutorial_hand_pressed.png │ ├── tutorial_hand_pressed.png.meta │ ├── tutorial_hand_pressed_double.png │ ├── tutorial_hand_pressed_double.png.meta │ ├── tutorial_hand_simple.png │ ├── tutorial_hand_simple.png.meta │ ├── tutorial_hand_slap.png │ ├── tutorial_hand_slap.png.meta │ ├── tutorial_hand_unpressed.png │ ├── tutorial_hand_unpressed.png.meta │ ├── tutorial_spotlight.psd │ └── tutorial_spotlight.psd.meta │ ├── TutorialInitializer.prefab │ └── TutorialInitializer.prefab.meta ├── Documents ├── 01_tutorial_manager.png ├── 02_tutorial_prefab.png └── 03_tutorial_steps.png ├── LICENSE └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: sweatyc, furic 4 | custom: ['https://PayPal.Me/liwenzou1', 'https://PayPal.Me/furic'] 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | 7 | /Assets/AssetStoreTools* 8 | # /Assets/Plugins/GitHub.meta 9 | # /Assets/Plugins/GitHub/ 10 | 11 | # Visual Studio 2015 cache directory 12 | /.vs/ 13 | 14 | # Autogenerated VS/MD/Consulo solution and project files 15 | ExportedObj/ 16 | .consulo/ 17 | *.csproj 18 | *.unityproj 19 | *.sln 20 | *.suo 21 | *.tmp 22 | *.user 23 | *.userprefs 24 | *.pidb 25 | *.booproj 26 | *.svd 27 | *.pdb 28 | 29 | 30 | # Unity3D generated meta files 31 | *.pidb.meta 32 | 33 | # Unity3D Generated File On Crash Reports 34 | sysinfo.txt 35 | 36 | # Builds 37 | *.apk 38 | *.unitypackage 39 | 40 | # Plugin folders 41 | /TPS_cache/ 42 | /UnityPackageManager/ 43 | Assets/Plugins/iOS/Heyzap/libHeyzapAds.a 44 | *.a 45 | *.exr 46 | 47 | # Ignore ProjectSettings and Packages, for open-source plugins only 48 | /Packages/ 49 | /ProjectSettings/ -------------------------------------------------------------------------------- /Assets/SweatyChair.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb5c42062768e48629b69b6fd1d0d5b2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0226cbc7b7e6d43d693041750121429a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Animations.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 229ff225ffd754513886c5d5597dd919 3 | folderAsset: yes 4 | timeCreated: 1521097143 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Animations/HandClick.anim: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!74 &7400000 4 | AnimationClip: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: HandClick 10 | serializedVersion: 6 11 | m_Legacy: 1 12 | m_Compressed: 0 13 | m_UseHighQualityCurve: 1 14 | m_RotationCurves: [] 15 | m_CompressedRotationCurves: [] 16 | m_EulerCurves: [] 17 | m_PositionCurves: [] 18 | m_ScaleCurves: [] 19 | m_FloatCurves: 20 | - curve: 21 | serializedVersion: 2 22 | m_Curve: 23 | - serializedVersion: 3 24 | time: 0 25 | value: 1 26 | inSlope: Infinity 27 | outSlope: Infinity 28 | tangentMode: 103 29 | weightedMode: 0 30 | inWeight: 0.33333334 31 | outWeight: 0.33333334 32 | - serializedVersion: 3 33 | time: 0.5 34 | value: 0 35 | inSlope: Infinity 36 | outSlope: Infinity 37 | tangentMode: 103 38 | weightedMode: 0 39 | inWeight: 0.33333334 40 | outWeight: 0.33333334 41 | - serializedVersion: 3 42 | time: 1 43 | value: 1 44 | inSlope: Infinity 45 | outSlope: Infinity 46 | tangentMode: 103 47 | weightedMode: 0 48 | inWeight: 0.33333334 49 | outWeight: 0.33333334 50 | m_PreInfinity: 2 51 | m_PostInfinity: 2 52 | m_RotationOrder: 4 53 | attribute: m_IsActive 54 | path: HandTexture/HandPressed 55 | classID: 1 56 | script: {fileID: 0} 57 | - curve: 58 | serializedVersion: 2 59 | m_Curve: 60 | - serializedVersion: 3 61 | time: 0 62 | value: 0 63 | inSlope: Infinity 64 | outSlope: Infinity 65 | tangentMode: 103 66 | weightedMode: 0 67 | inWeight: 0.33333334 68 | outWeight: 0.33333334 69 | - serializedVersion: 3 70 | time: 0.5 71 | value: 1 72 | inSlope: Infinity 73 | outSlope: Infinity 74 | tangentMode: 103 75 | weightedMode: 0 76 | inWeight: 0.33333334 77 | outWeight: 0.33333334 78 | - serializedVersion: 3 79 | time: 1 80 | value: 0 81 | inSlope: Infinity 82 | outSlope: Infinity 83 | tangentMode: 103 84 | weightedMode: 0 85 | inWeight: 0.33333334 86 | outWeight: 0.33333334 87 | m_PreInfinity: 2 88 | m_PostInfinity: 2 89 | m_RotationOrder: 4 90 | attribute: m_IsActive 91 | path: HandTexture/HandUnpressed 92 | classID: 1 93 | script: {fileID: 0} 94 | - curve: 95 | serializedVersion: 2 96 | m_Curve: 97 | - serializedVersion: 3 98 | time: 0 99 | value: 0 100 | inSlope: 0 101 | outSlope: 0 102 | tangentMode: 136 103 | weightedMode: 0 104 | inWeight: 0 105 | outWeight: 0 106 | m_PreInfinity: 2 107 | m_PostInfinity: 2 108 | m_RotationOrder: 4 109 | attribute: m_LocalPosition.x 110 | path: 111 | classID: 224 112 | script: {fileID: 0} 113 | - curve: 114 | serializedVersion: 2 115 | m_Curve: 116 | - serializedVersion: 3 117 | time: 0 118 | value: 0 119 | inSlope: 0 120 | outSlope: 0 121 | tangentMode: 136 122 | weightedMode: 0 123 | inWeight: 0 124 | outWeight: 0 125 | m_PreInfinity: 2 126 | m_PostInfinity: 2 127 | m_RotationOrder: 4 128 | attribute: m_LocalPosition.y 129 | path: 130 | classID: 224 131 | script: {fileID: 0} 132 | - curve: 133 | serializedVersion: 2 134 | m_Curve: 135 | - serializedVersion: 3 136 | time: 0 137 | value: 0 138 | inSlope: 0 139 | outSlope: 0 140 | tangentMode: 136 141 | weightedMode: 0 142 | inWeight: 0 143 | outWeight: 0 144 | m_PreInfinity: 2 145 | m_PostInfinity: 2 146 | m_RotationOrder: 4 147 | attribute: m_LocalPosition.z 148 | path: 149 | classID: 224 150 | script: {fileID: 0} 151 | m_PPtrCurves: [] 152 | m_SampleRate: 20 153 | m_WrapMode: 2 154 | m_Bounds: 155 | m_Center: {x: 0, y: 0, z: 0} 156 | m_Extent: {x: 0, y: 0, z: 0} 157 | m_ClipBindingConstant: 158 | genericBindings: [] 159 | pptrCurveMapping: [] 160 | m_AnimationClipSettings: 161 | serializedVersion: 2 162 | m_AdditiveReferencePoseClip: {fileID: 0} 163 | m_AdditiveReferencePoseTime: 0 164 | m_StartTime: 0 165 | m_StopTime: 1 166 | m_OrientationOffsetY: 0 167 | m_Level: 0 168 | m_CycleOffset: 0 169 | m_HasAdditiveReferencePose: 0 170 | m_LoopTime: 0 171 | m_LoopBlend: 0 172 | m_LoopBlendOrientation: 0 173 | m_LoopBlendPositionY: 0 174 | m_LoopBlendPositionXZ: 0 175 | m_KeepOriginalOrientation: 0 176 | m_KeepOriginalPositionY: 1 177 | m_KeepOriginalPositionXZ: 0 178 | m_HeightFromFeet: 0 179 | m_Mirror: 0 180 | m_EditorCurves: 181 | - curve: 182 | serializedVersion: 2 183 | m_Curve: 184 | - serializedVersion: 3 185 | time: 0 186 | value: 1 187 | inSlope: Infinity 188 | outSlope: Infinity 189 | tangentMode: 103 190 | weightedMode: 0 191 | inWeight: 0.33333334 192 | outWeight: 0.33333334 193 | - serializedVersion: 3 194 | time: 0.5 195 | value: 0 196 | inSlope: Infinity 197 | outSlope: Infinity 198 | tangentMode: 103 199 | weightedMode: 0 200 | inWeight: 0.33333334 201 | outWeight: 0.33333334 202 | - serializedVersion: 3 203 | time: 1 204 | value: 1 205 | inSlope: Infinity 206 | outSlope: Infinity 207 | tangentMode: 103 208 | weightedMode: 0 209 | inWeight: 0.33333334 210 | outWeight: 0.33333334 211 | m_PreInfinity: 2 212 | m_PostInfinity: 2 213 | m_RotationOrder: 4 214 | attribute: m_IsActive 215 | path: HandTexture/HandPressed 216 | classID: 1 217 | script: {fileID: 0} 218 | - curve: 219 | serializedVersion: 2 220 | m_Curve: 221 | - serializedVersion: 3 222 | time: 0 223 | value: 0 224 | inSlope: Infinity 225 | outSlope: Infinity 226 | tangentMode: 103 227 | weightedMode: 0 228 | inWeight: 0.33333334 229 | outWeight: 0.33333334 230 | - serializedVersion: 3 231 | time: 0.5 232 | value: 1 233 | inSlope: Infinity 234 | outSlope: Infinity 235 | tangentMode: 103 236 | weightedMode: 0 237 | inWeight: 0.33333334 238 | outWeight: 0.33333334 239 | - serializedVersion: 3 240 | time: 1 241 | value: 0 242 | inSlope: Infinity 243 | outSlope: Infinity 244 | tangentMode: 103 245 | weightedMode: 0 246 | inWeight: 0.33333334 247 | outWeight: 0.33333334 248 | m_PreInfinity: 2 249 | m_PostInfinity: 2 250 | m_RotationOrder: 4 251 | attribute: m_IsActive 252 | path: HandTexture/HandUnpressed 253 | classID: 1 254 | script: {fileID: 0} 255 | - curve: 256 | serializedVersion: 2 257 | m_Curve: 258 | - serializedVersion: 3 259 | time: 0 260 | value: 0 261 | inSlope: 0 262 | outSlope: 0 263 | tangentMode: 136 264 | weightedMode: 0 265 | inWeight: 0 266 | outWeight: 0 267 | m_PreInfinity: 2 268 | m_PostInfinity: 2 269 | m_RotationOrder: 4 270 | attribute: m_LocalPosition.x 271 | path: 272 | classID: 224 273 | script: {fileID: 0} 274 | - curve: 275 | serializedVersion: 2 276 | m_Curve: 277 | - serializedVersion: 3 278 | time: 0 279 | value: 0 280 | inSlope: 0 281 | outSlope: 0 282 | tangentMode: 136 283 | weightedMode: 0 284 | inWeight: 0 285 | outWeight: 0 286 | m_PreInfinity: 2 287 | m_PostInfinity: 2 288 | m_RotationOrder: 4 289 | attribute: m_LocalPosition.y 290 | path: 291 | classID: 224 292 | script: {fileID: 0} 293 | - curve: 294 | serializedVersion: 2 295 | m_Curve: 296 | - serializedVersion: 3 297 | time: 0 298 | value: 0 299 | inSlope: 0 300 | outSlope: 0 301 | tangentMode: 136 302 | weightedMode: 0 303 | inWeight: 0 304 | outWeight: 0 305 | m_PreInfinity: 2 306 | m_PostInfinity: 2 307 | m_RotationOrder: 4 308 | attribute: m_LocalPosition.z 309 | path: 310 | classID: 224 311 | script: {fileID: 0} 312 | m_EulerEditorCurves: [] 313 | m_HasGenericRootTransform: 0 314 | m_HasMotionFloatCurves: 0 315 | m_Events: [] 316 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Animations/HandClick.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a7d8648d87ea145be8e174ad29965e56 3 | timeCreated: 1465365368 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: -1 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Animations/HandDrag.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dca7617d8238d4597ba9aeaa2eb4f394 3 | timeCreated: 1465365368 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Animations/HandDragDouble.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38f5bc9d316e54edfa714e0865e54e29 3 | timeCreated: 1465365368 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Animations/HandPinch.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da18cffb762d84a66aa93c2365e01898 3 | timeCreated: 1516594966 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | mainObjectFileID: -1 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Demo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83efcd39f86e94bccacbb151c6f7649a 3 | folderAsset: yes 4 | timeCreated: 1521097143 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Demo/Demo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86461e93612684e87ba641cf074c9900 3 | timeCreated: 1445882094 4 | licenseType: Store 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Demo/DemoTutorial.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34fce780ea41b46d1936472dc9a6994b 3 | timeCreated: 1473654755 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Demo/DemoTutorialValidator.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace SweatyChair 4 | { 5 | 6 | // This is a demo tutorial validator, a validator has custom logic on 7 | // checking if a tutorial should be execute, as well as what to do when 8 | // tutorial start and complete 9 | public class DemoTutorialValidator : TutorialValidator 10 | { 11 | 12 | public override bool IsValidated() 13 | { 14 | // If true, execute the tutorial, put logic here such as player reach level 2 15 | return true; 16 | } 17 | 18 | public override void OnTutorialStart() 19 | { 20 | Debug.Log("Demo tutorial started."); 21 | // Do anything here, such as give player some items that they cau use in the tutorial 22 | } 23 | 24 | public override void OnTutorialComplete() 25 | { 26 | Debug.Log("Demo tutorial completed."); 27 | // Do anything here, such as reward the player for completing the tutorial 28 | } 29 | 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Demo/DemoTutorialValidator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc4e75bb642cb44d2b3e8e296230e5a2 3 | timeCreated: 1465352139 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Resources.example.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae0a21e2289e54184af576e06eb7694f 3 | folderAsset: yes 4 | timeCreated: 1521097143 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Resources.example/TutorialPanel.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b52cd0ff07fe34a7c822bb6d43774a85 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec9b56b02dbb34fcf8f9c9d305bb299c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50f643074524446bab6b94d43f93120c 3 | folderAsset: yes 4 | timeCreated: 1521097143 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialActivateTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace SweatyChair 5 | { 6 | 7 | [CustomEditor(typeof(TutorialActivateTask))] 8 | public class TutorialActivateTaskEditor : TutorialTaskEditor 9 | { 10 | 11 | private TutorialActivateTask _tat => target as TutorialActivateTask; 12 | 13 | protected override void OnPreviewSettingGUI() 14 | { 15 | Transform targetTF = TransformUtils.GetTransformByPath(_tat.targetPath); 16 | string targetPath = (EditorGUILayout.ObjectField(new GUIContent("Target in Scene", "The target transform in current scene, this will be converted and saved as path string."), targetTF, typeof(Transform), true) as Transform).ToPath(); 17 | if (targetTF == null && !string.IsNullOrEmpty(_tat.targetPath)) 18 | GUI.contentColor = Color.red; 19 | string customTargetPath = EditorGUILayout.TextField(new GUIContent(string.IsNullOrEmpty(_tat.targetPath) ? "Enter Manually" : (targetTF == null ? "Not Found" : " "), "Manually set the target path, use this for dynamically-loaded prefab."), _tat.targetPath); 20 | if (customTargetPath != _tat.targetPath) { 21 | EditorUtility.SetDirty(_tat); 22 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Custom Target Path"); 23 | _tat.targetPath = customTargetPath; 24 | targetPath = customTargetPath; 25 | } 26 | if (targetTF == null && !string.IsNullOrEmpty(_tat.targetPath)) 27 | GUI.contentColor = Color.white; 28 | if ((string.IsNullOrEmpty(_tat.targetPath) || targetTF != null) && targetPath != _tat.targetPath) { 29 | EditorUtility.SetDirty(_tat); 30 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Target Path"); 31 | _tat.targetPath = targetPath; 32 | } 33 | 34 | bool isActivate = EditorGUILayout.Toggle(new GUIContent("Is Activate", "Set the target GameObject to be active or not."), _tat.isActivate); 35 | if (isActivate != _tat.isActivate) { 36 | EditorUtility.SetDirty(_tat); 37 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Is Activate"); 38 | _tat.isActivate = isActivate; 39 | } 40 | 41 | bool checkOnUpdate = EditorGUILayout.Toggle(new GUIContent("Check On Update", "Set the active status in Update, set this for if target GameObject's active status also controlled by another script."), _tat.checkOnUpdate); 42 | if (checkOnUpdate != _tat.checkOnUpdate) { 43 | EditorUtility.SetDirty(_tat); 44 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Check On Update"); 45 | _tat.checkOnUpdate = checkOnUpdate; 46 | } 47 | } 48 | 49 | protected override void OnOtherSettingGUI() 50 | { 51 | bool deactivateOnComplete = EditorGUILayout.Toggle(new GUIContent("Set Prev Activation On Complete", "Set the active status back after this tutorial step complete."), _tat.setPrevActivationOnComplete); 52 | if (deactivateOnComplete != _tat.setPrevActivationOnComplete) { 53 | EditorUtility.SetDirty(_tat); 54 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Set Prev Activation On Complete"); 55 | _tat.setPrevActivationOnComplete = deactivateOnComplete; 56 | } 57 | } 58 | 59 | #region Preview 60 | 61 | protected override bool isPreviewShown => _tat.targetGO != null && _tat.targetGO.activeSelf == _tat.isActivate; 62 | 63 | protected override bool canShowPreview => TransformUtils.GetTransformByPath(_tat.targetPath) != null; 64 | 65 | protected override string cannotShowPreviewWarning => "Assign target to enable Preview"; 66 | 67 | protected override void OnRemovePreviewClick() 68 | { 69 | _tat.targetGO.SetActive(false); 70 | } 71 | 72 | protected override void OnAddPreviewClick() 73 | { 74 | _tat.Init(); 75 | } 76 | 77 | #endregion 78 | 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialActivateTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6647b6c5def3450fb503dc06d6e09ae 3 | timeCreated: 1508321027 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialAnimateHandTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using UnityEditor; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [CustomEditor(typeof(TutorialAnimateHandTask))] 9 | public class TutorialAnimateHandTaskEditor : TutorialShowPanelTaskEditor 10 | { 11 | private TutorialAnimateHandTask _taht { 12 | get { return target as TutorialAnimateHandTask; } 13 | } 14 | 15 | protected override void OnPreviewSettingGUI() 16 | { 17 | string handAnim = EditorGUILayout.TextField("Hand animation to use", _taht.handAnim); 18 | if (handAnim != _taht.handAnim) { 19 | EditorUtility.SetDirty(_taht); 20 | Undo.RegisterCompleteObjectUndo(_taht, "Reassign Hand Anim"); 21 | _taht.handAnim = handAnim; 22 | } 23 | 24 | EditorGUI.indentLevel++; 25 | 26 | base.OnPreviewSettingGUI(); 27 | } 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialAnimateHandTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60ccd8d0ea086634296288fd343f4409 3 | timeCreated: 1517360992 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialAnimateTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace SweatyChair 5 | { 6 | 7 | [CustomEditor(typeof(TutorialAnimateTask))] 8 | public class TutorialAnimateTaskEditor : TutorialHighlightTaskEditor 9 | { 10 | 11 | private TutorialAnimateTask _tat => target as TutorialAnimateTask; 12 | 13 | protected override bool isCompletedTriggerEditable { get { return false; } } 14 | 15 | protected override TutoriaCompletelTrigger forceCompleteTrigger { get { return TutoriaCompletelTrigger.Auto; } } 16 | 17 | protected override void OnOtherSettingGUI() 18 | { 19 | AnimationClip addAnimationClip = EditorGUILayout.ObjectField("Add Animation Clip", _tat.animationClip, typeof(AnimationClip), false) as AnimationClip; 20 | if (addAnimationClip != _tat.animationClip) { 21 | EditorUtility.SetDirty(_tat); 22 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Add Animation Clip"); 23 | _tat.animationClip = addAnimationClip; 24 | } 25 | 26 | if (addAnimationClip != null) { 27 | Transform animationTF = TransformUtils.GetTransformByPath(_tat.animationPath); 28 | string animationPath = TransformUtils.ToPath(EditorGUILayout.ObjectField("Animation Transform in Scene", animationTF, typeof(Transform), true) as Transform); 29 | if (!string.IsNullOrEmpty(_tat.animationPath) && animationTF == null) { // Set but targetTF not found, this may be because in wrong scene 30 | GUI.contentColor = Color.red; 31 | string customAnimationPath = EditorGUILayout.TextField("Not Found!", _tat.animationPath); 32 | if (customAnimationPath != _tat.animationPath) { 33 | EditorUtility.SetDirty(_tat); 34 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Custom Animation Path"); 35 | _tat.animationPath = customAnimationPath; 36 | } 37 | GUI.contentColor = Color.white; 38 | } 39 | if (animationTF != null) { 40 | GUI.contentColor = Color.green; 41 | if (animationTF.GetComponent() == null) 42 | GUILayout.Label("An Animation component will be added in runtime"); 43 | else 44 | GUILayout.Label("The animation clip will be added to Animation in runtime"); 45 | GUI.contentColor = Color.white; 46 | } 47 | if (!string.IsNullOrEmpty(animationPath) && animationPath != _tat.animationPath) { 48 | EditorUtility.SetDirty(_tat); 49 | Undo.RegisterCompleteObjectUndo(_tat, "Reassign Animation Path"); 50 | _tat.animationPath = animationPath; 51 | } 52 | } 53 | 54 | OnDisableButtonsSettingGUI(); 55 | OnDoNotResetOnCompleteSettingGUI(); 56 | } 57 | 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialAnimateTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7ce112d4be344118b02464818e51753 3 | timeCreated: 1508320968 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialClickButtonTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | 3 | namespace SweatyChair 4 | { 5 | 6 | [CustomEditor(typeof(TutorialClickButtonTask))] 7 | public class TutorialClickButtonTaskEditor : TutorialHighlightTaskEditor 8 | { 9 | 10 | private TutorialClickButtonTask _tcbt => target as TutorialClickButtonTask; 11 | 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialClickButtonTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b18b67562899471caa18d53519ae574 3 | timeCreated: 1508321325 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialDebugger.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace SweatyChair 5 | { 6 | 7 | public static class TutorialDebugger 8 | { 9 | 10 | [MenuItem("Debug/Tutorial/Complete All Tutorials")] 11 | public static void CompleteAllTutorials() 12 | { 13 | ToggleAllTutorialsComplete(true); 14 | } 15 | 16 | [MenuItem("Debug/Tutorial/Reset All Tutorials")] 17 | public static void ResetAllTutorials() 18 | { 19 | ToggleAllTutorialsComplete(false); 20 | } 21 | 22 | private static void ToggleAllTutorialsComplete(bool isCompleted) 23 | { 24 | GameObject tmGO = GameObject.Find("TutorialManager"); 25 | bool isInScene = true; 26 | 27 | if (tmGO == null) { 28 | tmGO = AssetDatabase.LoadAssetAtPath("Assets/SweatyChair/Essentials/Tutorials/TutorialManager.prefab"); 29 | isInScene = false; 30 | } 31 | 32 | foreach (Tutorial t in TutorialSettings.current.tutorials) 33 | t.isCompleted = isCompleted; 34 | 35 | Selection.activeObject = tmGO; 36 | 37 | if (isInScene) 38 | Debug.Log("All tutorials marked as " + (isCompleted ? "" : "not ") + "completed, please apply and save the TutorialManager prefab."); 39 | else 40 | Debug.Log("All tutorials marked as " + (isCompleted ? "" : "not ") + "completed in TutorialManager prefab, make sure you check it out."); 41 | } 42 | 43 | [MenuItem("Debug/Tutorial/Start First Tutorial")] 44 | public static void StartFirstTutorial() 45 | { 46 | TutorialManager.StartTutorial(1); 47 | } 48 | 49 | [MenuItem("Debug/Tutorial/Print Parameters")] 50 | public static void PrintParameters() 51 | { 52 | Debug.Log("TutorialManager.currentTutorial=" + TutorialManager.currentTutorial); 53 | Debug.Log("TutorialManager.isFirstTutorialCompleted=" + TutorialManager.isFirstTutorialCompleted); 54 | Debug.Log("TutorialManager.areCoreTutorialsCompleted=" + TutorialManager.areCoreTutorialsCompleted); 55 | Debug.Log("TutorialManager.totalCoreTutorials=" + TutorialManager.totalCoreTutorials); 56 | Debug.Log("TutorialManager.totalCoreTutorialsCompleted=" + TutorialManager.totalCoreTutorialsCompleted); 57 | Debug.Log("TutorialManager.isAllTutorialsCompleted=" + TutorialManager.areAllTutorialsCompleted); 58 | } 59 | 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialDebugger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c47819e52ea254c45932ed3faf83145b 3 | timeCreated: 1466229069 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialDragDoubleTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [System.Serializable] 9 | [CustomEditor(typeof(TutorialDragDoubleTaskEditor), true)] 10 | public class TutorialDragDoubleTaskEditor : TutorialDragTaskEditor 11 | { 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialDragDoubleTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 96d5e7d2482d8451d90fdab44f68b241 3 | timeCreated: 1508321325 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialDragTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [System.Serializable] 9 | [CustomEditor(typeof(TutorialDragTask), true)] 10 | public class TutorialDragTaskEditor : TutorialHighlightTaskEditor 11 | { 12 | 13 | private TutorialDragTask _tod { 14 | get { return target as TutorialDragTask; } 15 | } 16 | 17 | protected override bool isCompletedTriggerEditable { get { return false; } } 18 | 19 | protected override TutoriaCompletelTrigger forceCompleteTrigger { get { return TutoriaCompletelTrigger.Auto; } } 20 | 21 | protected override void OnOtherSettingGUI() 22 | { 23 | bool constraintDirection = EditorGUILayout.Toggle(new GUIContent("Constraint Direction", "Constraint direction, can drag toward anywhere if false."), _tod.constraintDirection); 24 | if (constraintDirection != _tod.constraintDirection) { 25 | EditorUtility.SetDirty(_tod); 26 | Undo.RegisterCompleteObjectUndo(_tod, "Reassign Constraint Direction"); 27 | _tod.constraintDirection = constraintDirection; 28 | } 29 | 30 | if (constraintDirection) { 31 | 32 | float dragDirectionAngle = EditorGUILayout.FloatField(new GUIContent("Drag Direction Angle", "Angle direction to drag, e.g. 135 is toward top-left."), _tod.dragDirectionAngle); 33 | if (dragDirectionAngle != _tod.dragDirectionAngle) { 34 | EditorUtility.SetDirty(_tod); 35 | Undo.RegisterCompleteObjectUndo(_tod, "Reassign Drag Direction Angle"); 36 | _tod.dragDirectionAngle = dragDirectionAngle; 37 | } 38 | 39 | bool inverseDirection = EditorGUILayout.Toggle(new GUIContent("Inverse Direction", "Also include for inverse direction or not."), _tod.inverseDirection); 40 | if (inverseDirection != _tod.inverseDirection) { 41 | EditorUtility.SetDirty(_tod); 42 | Undo.RegisterCompleteObjectUndo(_tod, "Reassign Inverse Direction"); 43 | _tod.inverseDirection = inverseDirection; 44 | } 45 | 46 | } 47 | 48 | if (_tod.scaleDistanceWithScreenWidth && _tod.dragDistance >= 1) 49 | EditorGUILayout.HelpBox("Drag distance should be less than 1 when scaling with screen width.", MessageType.Error); 50 | else if (!_tod.scaleDistanceWithScreenWidth && _tod.dragDistance < 1) 51 | EditorGUILayout.HelpBox("Drag distance should be more than 1 when not scaling with screen width.", MessageType.Error); 52 | 53 | float dragDistance = EditorGUILayout.FloatField(new GUIContent("Drag Distance", "Drag distance, either absolute screen pixels or percentage to screen width."), _tod.dragDistance); 54 | if (dragDistance != _tod.dragDistance) { 55 | EditorUtility.SetDirty(_tod); 56 | Undo.RegisterCompleteObjectUndo(_tod, "Reassign Drag Distance"); 57 | _tod.dragDistance = dragDistance; 58 | } 59 | 60 | bool scaleDistanceWithScreenWidth = EditorGUILayout.Toggle(new GUIContent("Scale Distance With Screen Width", "Drag distance is absolute screen pixel if false, otherwise dragDistance is a percentage in [0,1]."), _tod.scaleDistanceWithScreenWidth); 61 | if (scaleDistanceWithScreenWidth != _tod.scaleDistanceWithScreenWidth) { 62 | EditorUtility.SetDirty(_tod); 63 | Undo.RegisterCompleteObjectUndo(_tod, "Reassign Scale Distance With Screen Width"); 64 | _tod.scaleDistanceWithScreenWidth = scaleDistanceWithScreenWidth; 65 | } 66 | 67 | bool accumulateDistance = EditorGUILayout.Toggle(new GUIContent("Accumlate Distance", "Player must finish in ONE drag, or can be completed in few drags (with accumulated distance)"), _tod.accumulateDistance); 68 | if (accumulateDistance != _tod.accumulateDistance) { 69 | EditorUtility.SetDirty(_tod); 70 | Undo.RegisterCompleteObjectUndo(_tod, "Reassign Accumulate Distance"); 71 | _tod.accumulateDistance = accumulateDistance; 72 | } 73 | 74 | OnDisableButtonsSettingGUI(); 75 | OnDoNotResetOnCompleteSettingGUI(); 76 | } 77 | 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialDragTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 18567ea04ed844dae84783f46620b515 3 | timeCreated: 1508321325 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialEventCompleteTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Reflection; 7 | 8 | namespace SweatyChair 9 | { 10 | 11 | [CustomEditor(typeof(TutorialEventCompleteTask))] 12 | public class TutorialEventCompleteTaskEditor : TutorialTaskEditor 13 | { 14 | 15 | protected bool showTargetSetting = true; 16 | 17 | private TutorialEventCompleteTask _tect { 18 | get { return target as TutorialEventCompleteTask; } 19 | } 20 | 21 | protected override bool isCompletedTriggerEditable { get { return false; } } 22 | 23 | protected override TutoriaCompletelTrigger forceCompleteTrigger { get { return TutoriaCompletelTrigger.Auto; } } 24 | 25 | protected override void OnOtherSettingGUI() 26 | { 27 | Transform targetTF = TransformUtils.GetTransformByPath(_tect.targetPath); 28 | string targetPath = (EditorGUILayout.ObjectField(new GUIContent("Target in Scene", "The target transform in current scene, this will be converted and saved as path string."), targetTF, typeof(Transform), true) as Transform).ToPath(); 29 | if (targetTF == null && !string.IsNullOrEmpty(_tect.targetPath)) 30 | GUI.contentColor = Color.red; 31 | string customTargetPath = EditorGUILayout.TextField(string.IsNullOrEmpty(_tect.targetPath) ? "Enter Manually" : (targetTF == null ? "Not Found" : " "), _tect.targetPath); 32 | if (customTargetPath != _tect.targetPath) { 33 | EditorUtility.SetDirty(_tect); 34 | Undo.RegisterCompleteObjectUndo(_tect, "Reassign Custom Target Path"); 35 | _tect.targetPath = customTargetPath; 36 | targetPath = customTargetPath; 37 | } 38 | if (targetTF == null && !string.IsNullOrEmpty(_tect.targetPath)) 39 | GUI.contentColor = Color.white; 40 | if ((string.IsNullOrEmpty(_tect.targetPath) || targetTF != null) && targetPath != _tect.targetPath) { 41 | EditorUtility.SetDirty(_tect); 42 | Undo.RegisterCompleteObjectUndo(_tect, "Reassign Target Path"); 43 | _tect.targetPath = targetPath; 44 | } 45 | 46 | if (targetTF != null) { 47 | 48 | Component[] components = targetTF.GetComponents(); 49 | int savedComponentIndex = -1; 50 | GUIContent[] componentContents = new GUIContent[components.Length]; 51 | for (int i = 0, imax = components.Length; i < imax; i++) { 52 | componentContents[i] = new GUIContent(components[i].GetType().ToString(), ""); 53 | if (components[i].GetType().ToString() == _tect.targetComponentName) 54 | savedComponentIndex = i; 55 | } 56 | 57 | int selectedComponentIndex = EditorGUILayout.Popup(new GUIContent("Component", "The script that contain the variable."), savedComponentIndex, componentContents); 58 | if (selectedComponentIndex != savedComponentIndex) { 59 | EditorUtility.SetDirty(_tect); 60 | Undo.RegisterCompleteObjectUndo(_tect, "Reassign Component"); 61 | _tect.targetComponentName = components[selectedComponentIndex].GetType().ToString(); 62 | } 63 | 64 | if (!string.IsNullOrEmpty(_tect.targetComponentName)) { 65 | 66 | if (selectedComponentIndex >= components.Length) 67 | selectedComponentIndex = components.Length - 1; 68 | Component c = components.Length > 0 ? components[selectedComponentIndex] : null; 69 | FieldInfo[] fieldInfos = components[selectedComponentIndex].GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); 70 | 71 | int savedFieldIndex = 0; 72 | GUIContent[] fieldContents = new GUIContent[fieldInfos.Length + 1]; // First null 73 | fieldContents[0] = new GUIContent("", ""); 74 | for (int i = 0, imax = fieldInfos.Length; i < imax; i++) { 75 | fieldContents[i + 1] = new GUIContent(fieldInfos[i].Name, ""); 76 | if (fieldInfos[i].Name == _tect.fieldName) 77 | savedFieldIndex = i + 1; 78 | } 79 | 80 | int selectedObjectIndex = EditorGUILayout.Popup(new GUIContent("Field Object", "The variable field name."), savedFieldIndex, fieldContents); 81 | if (selectedObjectIndex != savedFieldIndex) { 82 | EditorUtility.SetDirty(_tect); 83 | Undo.RegisterCompleteObjectUndo(_tect, "Reassign Field Object"); 84 | _tect.fieldName = fieldInfos[selectedObjectIndex].Name; 85 | } 86 | 87 | EventInfo[] eventInfos; 88 | if (string.IsNullOrEmpty(_tect.fieldName) || c == null) { 89 | eventInfos = c.GetType().GetEvents(BindingFlags.Public | BindingFlags.Instance); 90 | } else { 91 | object obj = (object)c.GetType().GetField(_tect.fieldName, BindingFlags.Public | BindingFlags.Instance).GetValue(c); 92 | eventInfos = obj.GetType().GetEvents(BindingFlags.Public | BindingFlags.Instance); 93 | } 94 | 95 | if (eventInfos.Length == 0) { 96 | GUI.contentColor = Color.red; 97 | EditorGUILayout.LabelField("Event", "Not Found"); 98 | GUI.contentColor = Color.white; 99 | } else { 100 | int savedEventIndex = -1; 101 | GUIContent[] actionsContents = new GUIContent[eventInfos.Length]; 102 | for (int i = 0, imax = eventInfos.Length; i < imax; i++) { 103 | actionsContents[i] = new GUIContent(eventInfos[i].Name, ""); 104 | if (eventInfos[i].Name == _tect.eventName) 105 | savedEventIndex = i; 106 | } 107 | 108 | int selectedActionIndex = EditorGUILayout.Popup(new GUIContent("Event", "The event field name."), savedEventIndex, actionsContents); 109 | if (selectedActionIndex != savedEventIndex) { 110 | EditorUtility.SetDirty(_tect); 111 | Undo.RegisterCompleteObjectUndo(_tect, "Reassign Event"); 112 | _tect.eventName = eventInfos[selectedActionIndex].Name; 113 | } 114 | } 115 | 116 | } 117 | 118 | } 119 | } 120 | 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialEventCompleteTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce701b42adf514dd5901dc3ba5a103aa 3 | timeCreated: 1508321326 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialHighlightTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 508e32975c37a434facabc0a3eb3d190 3 | timeCreated: 1508321325 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialInstantiateTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [CustomEditor(typeof(TutorialInstantiateTask))] 9 | public class TutorialInstantiateTaskEditor : TutorialTaskEditor 10 | { 11 | 12 | private TutorialInstantiateTask _tit { 13 | get { return target as TutorialInstantiateTask; } 14 | } 15 | 16 | protected override void OnPreviewSettingGUI() 17 | { 18 | GUILayout.Label("Object", EditorStyles.boldLabel); 19 | 20 | GameObject prefab = EditorGUILayout.ObjectField(new GUIContent("Prefab", "The prefab to be instantiate."), _tit.prefab, typeof(GameObject), false) as GameObject; 21 | if (prefab != _tit.prefab) { 22 | EditorUtility.SetDirty(_tit); 23 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Prefab"); 24 | _tit.prefab = prefab; 25 | } 26 | 27 | if (_tit.prefab != null) { 28 | Transform parentTF = TransformUtils.GetTransformByPath(_tit.parentPath); 29 | string parentPath = (EditorGUILayout.ObjectField(new GUIContent("Parent in Scene", "The parent transform in current scene, this will be converted and saved as path string."), parentTF, typeof(Transform), true) as Transform).ToPath(); 30 | if (parentTF == null && !string.IsNullOrEmpty(_tit.parentPath)) 31 | GUI.contentColor = Color.red; 32 | string customTargetPath = EditorGUILayout.TextField(new GUIContent(string.IsNullOrEmpty(_tit.parentPath) ? "Enter Manually" : (parentTF == null ? "Not Found" : " "), "Manually set the target path, use this for dynamically-loaded prefab."), _tit.parentPath); 33 | if (customTargetPath != _tit.parentPath) { 34 | EditorUtility.SetDirty(_tit); 35 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Custom Parent Path"); 36 | _tit.parentPath = customTargetPath; 37 | parentPath = customTargetPath; 38 | } 39 | if (parentTF == null && !string.IsNullOrEmpty(_tit.parentPath)) 40 | GUI.contentColor = Color.white; 41 | if ((string.IsNullOrEmpty(_tit.parentPath) || parentTF != null) && parentPath != _tit.parentPath) { 42 | EditorUtility.SetDirty(_tit); 43 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Parent Path"); 44 | _tit.parentPath = parentPath; 45 | } 46 | 47 | Vector3 localPosition = EditorGUILayout.Vector3Field(new GUIContent("Local Position", "Local position of the instantiated prefab."), _tit.localPosition); 48 | if (localPosition != _tit.localPosition) { 49 | EditorUtility.SetDirty(_tit); 50 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Local Position"); 51 | _tit.localPosition = localPosition; 52 | UpdatePreview(); 53 | } 54 | 55 | Vector3 localRotation = EditorGUILayout.Vector3Field(new GUIContent("Local Rotation", "Local rotation of the instantiated prefab."), _tit.localRotation); 56 | 57 | if (localRotation != _tit.localRotation) { 58 | EditorUtility.SetDirty(_tit); 59 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Local Rotation"); 60 | _tit.localRotation = localRotation; 61 | UpdatePreview(); 62 | } 63 | } 64 | } 65 | 66 | protected override void OnOtherSettingGUI() 67 | { 68 | float completeWaitSeconds = EditorGUILayout.FloatField(new GUIContent("Complete Wait Seconds", "Added waiting seconds before this tutorial step complete."), _tit.completeWaitSeconds); 69 | if (completeWaitSeconds != _tit.completeWaitSeconds) { 70 | EditorUtility.SetDirty(_tit); 71 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Complete Wait Seconds"); 72 | _tit.completeWaitSeconds = completeWaitSeconds; 73 | } 74 | 75 | bool destroyOnComplete = EditorGUILayout.Toggle(new GUIContent("Destroy On Complete", "Destroy the instantiated prefab after this tutorial step complete."), _tit.destroyOnComplete); 76 | if (destroyOnComplete != _tit.destroyOnComplete) { 77 | EditorUtility.SetDirty(_tit); 78 | Undo.RegisterCompleteObjectUndo(_tit, "Reassign Destroy On Complete"); 79 | _tit.destroyOnComplete = destroyOnComplete; 80 | } 81 | } 82 | 83 | #region Preview 84 | 85 | protected override bool isPreviewShown { 86 | get { return _tit.objectGO != null; } 87 | } 88 | 89 | protected override bool canShowPreview { 90 | get { return _tit.prefab != null; } 91 | } 92 | 93 | protected override string cannotShowPreviewWarning { 94 | get { return "Assign prefab to enable Preview"; } 95 | } 96 | 97 | protected override void OnRemovePreviewClick() 98 | { 99 | _tit.DestroyObject(); 100 | } 101 | 102 | protected override void OnAddPreviewClick() 103 | { 104 | _tit.Init(); 105 | _tit.DoInstantiate(); 106 | UpdatePreview(); 107 | } 108 | 109 | protected override void UpdatePreview() 110 | { 111 | if (_tit.objectGO != null) 112 | _tit.SetObjectTransform(); 113 | } 114 | 115 | #endregion 116 | 117 | } 118 | 119 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialInstantiateTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 876c08dc8d7e948f5a7ba3cbf6430902 3 | timeCreated: 1508321326 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialOverrideClickButtonTaskEvent.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace SweatyChair 5 | { 6 | 7 | [CustomEditor(typeof(TutorialOverrideClickButtonTask))] 8 | public class TutorialOverrideClickButtonTaskEditor : TutorialHighlightTaskEditor 9 | { 10 | #region Variables 11 | 12 | private SerializedProperty _buttonEventProp; 13 | 14 | private TutorialOverrideClickButtonTask _tocbt { 15 | get { return target as TutorialOverrideClickButtonTask; } 16 | } 17 | 18 | #endregion 19 | 20 | #region OnEnable / Disable 21 | 22 | protected void OnEnable() 23 | { 24 | _buttonEventProp = serializedObject.FindProperty("onButtonClickOverride"); 25 | } 26 | 27 | #endregion 28 | 29 | #region Override Editor Drawing 30 | 31 | public override void OnInspectorGUI() 32 | { 33 | serializedObject.Update(); 34 | 35 | EditorUtils.DrawScriptField(_tocbt); 36 | base.OnInspectorGUI(); 37 | OnButtonOverrideSettingGUI(); 38 | 39 | serializedObject.ApplyModifiedProperties(); 40 | } 41 | 42 | protected virtual void OnButtonOverrideSettingGUI() 43 | { 44 | EditorUtils.HorizontalLine(Color.grey); 45 | GUILayout.Label("On Button Click Override"); 46 | EditorGUI.indentLevel++; 47 | EditorGUILayout.PropertyField(_buttonEventProp, true); 48 | EditorGUI.indentLevel--; 49 | } 50 | 51 | #endregion 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialOverrideClickButtonTaskEvent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfd26449c32517248b3de2a9c4f4965a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialPinchTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [System.Serializable] 9 | [CustomEditor(typeof(TutorialPinchTask), true)] 10 | public class TutorialPinchTaskEditor : TutorialShowPanelTaskEditor 11 | { 12 | 13 | private TutorialPinchTask _topt { 14 | get { return target as TutorialPinchTask; } 15 | } 16 | 17 | protected override bool isCompletedTriggerEditable { get { return false; } } 18 | 19 | protected override TutoriaCompletelTrigger forceCompleteTrigger { get { return TutoriaCompletelTrigger.Auto; } } 20 | 21 | protected override void OnOtherSettingGUI() 22 | { 23 | TutorialPinchTask.PinchAction checkPinchAction = (TutorialPinchTask.PinchAction)EditorGUILayout.EnumPopup(new GUIContent("Check Pinch Action", "Which pinch action to complete this tutorial step."), _topt.checkPinchAction); 24 | if (checkPinchAction != _topt.checkPinchAction) { 25 | EditorUtility.SetDirty(_topt); 26 | Undo.RegisterCompleteObjectUndo(_topt, "Reassign Check Pinch Action"); 27 | _topt.checkPinchAction = checkPinchAction; 28 | } 29 | 30 | if (_topt.scaleDistanceWithScreenWidth && _topt.pinchDistance >= 1) 31 | EditorGUILayout.HelpBox("Pinch distance should be less than 1 when scaling with screen width.", MessageType.Error); 32 | else if (!_topt.scaleDistanceWithScreenWidth && _topt.pinchDistance < 1) 33 | EditorGUILayout.HelpBox("Pinch distance should be more than 1 when not scaling with screen width.", MessageType.Error); 34 | 35 | float pinchDistance = EditorGUILayout.FloatField(new GUIContent("Pinch Distance", "Pinch distance, either absolute screen pixels or percentage to screen width."), _topt.pinchDistance); 36 | if (pinchDistance != _topt.pinchDistance) { 37 | EditorUtility.SetDirty(_topt); 38 | Undo.RegisterCompleteObjectUndo(_topt, "Reassign Pinch Distance"); 39 | _topt.pinchDistance = pinchDistance; 40 | } 41 | 42 | bool scaleDistanceWithScreenWidth = EditorGUILayout.Toggle(new GUIContent("Scale Distance With Screen Width", "Pinch distance is absolute screen pixel if false, otherwise dragDistance is a percentage in [0,1]."), _topt.scaleDistanceWithScreenWidth); 43 | if (scaleDistanceWithScreenWidth != _topt.scaleDistanceWithScreenWidth) { 44 | EditorUtility.SetDirty(_topt); 45 | Undo.RegisterCompleteObjectUndo(_topt, "Reassign Scale Distance With Screen Width"); 46 | _topt.scaleDistanceWithScreenWidth = scaleDistanceWithScreenWidth; 47 | } 48 | 49 | bool accumulateDistance = EditorGUILayout.Toggle(new GUIContent("Accumlate Distance", "Player must finish in ONE pinch, or can be completed in few pinches (with accumulated distance)"), _topt.accumulateDistance); 50 | if (accumulateDistance != _topt.accumulateDistance) { 51 | EditorUtility.SetDirty(_topt); 52 | Undo.RegisterCompleteObjectUndo(_topt, "Reassign Accumulate Distance"); 53 | _topt.accumulateDistance = accumulateDistance; 54 | } 55 | 56 | OnDoNotResetOnCompleteSettingGUI(); 57 | } 58 | 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialPinchTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e17ca627e3f7e41bdb5227aaf02c3456 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialSettingsEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ac028adb5a9c4cfe9b926a78a117fcb 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialShowPanelTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [CustomEditor(typeof(TutorialShowPanelTask))] 9 | public class TutorialShowPanelTaskEditor : TutorialTaskEditor 10 | { 11 | 12 | protected bool showHandSetting = true; 13 | protected bool showTextSetting = true; 14 | protected bool showBackgroundSetting = true; 15 | 16 | private TutorialShowPanelTask _tspt { 17 | get { return target as TutorialShowPanelTask; } 18 | } 19 | 20 | // Force complete trigger to be call 21 | protected override bool isCompletedTriggerEditable { get { return false; } } 22 | 23 | protected override TutoriaCompletelTrigger forceCompleteTrigger { get { return TutoriaCompletelTrigger.Auto; } } 24 | 25 | protected override void OnPreviewSettingGUI() 26 | { 27 | OnHandSettingGUI(); 28 | OnTextSettingGUI(); 29 | OnBackgroundMaskSettingGUI(); 30 | } 31 | 32 | protected virtual void OnHandSettingGUI() 33 | { 34 | showHandSetting = EditorGUILayout.Foldout(showHandSetting, "Hand"); 35 | EditorGUI.indentLevel++; 36 | 37 | if (showHandSetting) { 38 | 39 | bool showHand = EditorGUILayout.Toggle(new GUIContent("Show Hand", "Show the hand or not."), _tspt.showHand); 40 | if (showHand != _tspt.showHand) { 41 | EditorUtility.SetDirty(_tspt); 42 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Show Hand"); 43 | _tspt.showHand = showHand; 44 | UpdatePreview(); 45 | } 46 | 47 | if (_tspt.showHand) { 48 | 49 | Vector3 handLocalPosition = EditorGUILayout.Vector3Field(new GUIContent("Local Position", "Local position of the hand."), _tspt.handLocalPosition); 50 | if (handLocalPosition != _tspt.handLocalPosition) { 51 | EditorUtility.SetDirty(_tspt); 52 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Hand Local Position"); 53 | _tspt.handLocalPosition = handLocalPosition; 54 | UpdatePreview(); 55 | } 56 | 57 | Vector3 handLocalRotation = EditorGUILayout.Vector3Field(new GUIContent("Local Rotation", "Local rotation of the hand."), _tspt.handLocalRotation); 58 | if (handLocalRotation != _tspt.handLocalRotation) { 59 | EditorUtility.SetDirty(_tspt); 60 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Hand Local Rotation"); 61 | _tspt.handLocalRotation = handLocalRotation; 62 | UpdatePreview(); 63 | } 64 | 65 | Vector3 handLocalScale = EditorGUILayout.Vector3Field(new GUIContent("Local Scale", "Local scale of the hand."), _tspt.handLocalScale); 66 | if (handLocalScale != _tspt.handLocalScale) { 67 | EditorUtility.SetDirty(_tspt); 68 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Hand Local Scale"); 69 | _tspt.handLocalScale = handLocalScale; 70 | UpdatePreview(); 71 | } 72 | 73 | } 74 | 75 | } 76 | 77 | EditorGUI.indentLevel--; 78 | } 79 | 80 | protected virtual void OnTextSettingGUI() 81 | { 82 | showTextSetting = EditorGUILayout.Foldout(showTextSetting, "Text"); 83 | EditorGUI.indentLevel++; 84 | 85 | if (showTextSetting) { 86 | 87 | bool showText = EditorGUILayout.Toggle(new GUIContent("Show Text", "Show text of not."), !string.IsNullOrEmpty(_tspt.text)); 88 | if (showText == string.IsNullOrEmpty(_tspt.text)) { 89 | EditorUtility.SetDirty(_tspt); 90 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Show Text"); 91 | _tspt.text = showText ? "Tutorial text" : ""; 92 | UpdatePreview(); 93 | } 94 | 95 | if (showText) { 96 | 97 | Vector3 textLocalPosition = EditorGUILayout.Vector3Field(new GUIContent("Local Position", "Local position of the text."), _tspt.textLocalPosition); 98 | if (textLocalPosition != _tspt.textLocalPosition) { 99 | EditorUtility.SetDirty(_tspt); 100 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Text Local Position"); 101 | _tspt.textLocalPosition = textLocalPosition; 102 | UpdatePreview(); 103 | } 104 | 105 | Vector3 textLocalRotation = EditorGUILayout.Vector3Field(new GUIContent("Local Rotation", "Local rotation of the text."), _tspt.textLocalRotation); 106 | if (textLocalRotation != _tspt.textLocalRotation) { 107 | EditorUtility.SetDirty(_tspt); 108 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Text Local Rotation"); 109 | _tspt.textLocalRotation = textLocalRotation; 110 | UpdatePreview(); 111 | } 112 | 113 | Vector2 textSize = EditorGUILayout.Vector2Field(new GUIContent("Size", "Font size of the text."), _tspt.textSize); 114 | if (textSize != _tspt.textSize) { 115 | EditorUtility.SetDirty(_tspt); 116 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Text Size"); 117 | _tspt.textSize = textSize; 118 | UpdatePreview(); 119 | } 120 | 121 | string text = EditorGUILayout.TextField(new GUIContent("Text", "Text string of the text."), _tspt.text); 122 | if (text != _tspt.text) { 123 | EditorUtility.SetDirty(_tspt); 124 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Text String"); 125 | _tspt.text = text; 126 | UpdatePreview(); 127 | } 128 | 129 | Color textColor = EditorGUILayout.ColorField(new GUIContent("Text Color", "Text color of the text."), _tspt.textColor); 130 | if (textColor != _tspt.textColor) { 131 | EditorUtility.SetDirty(_tspt); 132 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Text Color"); 133 | _tspt.textColor = textColor; 134 | UpdatePreview(); 135 | } 136 | 137 | int fontSize = EditorGUILayout.IntField(new GUIContent("Font Size", "Font size of the text."), _tspt.fontSize); 138 | if (fontSize != _tspt.fontSize) { 139 | EditorUtility.SetDirty(_tspt); 140 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Font Size"); 141 | _tspt.fontSize = fontSize; 142 | UpdatePreview(); 143 | } 144 | 145 | TextAnchor alignment = (TextAnchor)EditorGUILayout.EnumPopup(new GUIContent("Alignment", "Alignment of the text."), _tspt.alignment); 146 | if (alignment != _tspt.alignment) { 147 | EditorUtility.SetDirty(_tspt); 148 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Text Alignment"); 149 | _tspt.alignment = alignment; 150 | UpdatePreview(); 151 | } 152 | 153 | } 154 | 155 | } 156 | 157 | EditorGUI.indentLevel--; 158 | } 159 | 160 | protected virtual void OnBackgroundMaskSettingGUI() 161 | { 162 | showBackgroundSetting = EditorGUILayout.Foldout(showBackgroundSetting, "Background Mask"); 163 | EditorGUI.indentLevel++; 164 | 165 | if (showBackgroundSetting) { 166 | 167 | bool showBackgroundMask = EditorGUILayout.Toggle(new GUIContent("Show Background Mask", "Show background mask or not."), _tspt.showBackgroundMask); 168 | if (showBackgroundMask != _tspt.showBackgroundMask) { 169 | EditorUtility.SetDirty(_tspt); 170 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Show Background Mask"); 171 | _tspt.showBackgroundMask = showBackgroundMask; 172 | UpdatePreview(); 173 | } 174 | 175 | if (showBackgroundMask) { 176 | int alpha = (int)EditorGUILayout.Slider(new GUIContent("Alpha", "Background mask color alpha."), _tspt.alpha, 0, 255); 177 | if (alpha != _tspt.alpha) { 178 | EditorUtility.SetDirty(_tspt); 179 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Background Mask Alpha"); 180 | _tspt.alpha = alpha; 181 | UpdatePreview(); 182 | } 183 | bool clickToComplete = EditorGUILayout.Toggle(new GUIContent("Click To Complete", "Click the background mask to complete the tutorial step or not."), _tspt.clickToComplete); 184 | if (clickToComplete != _tspt.clickToComplete) { 185 | EditorUtility.SetDirty(_tspt); 186 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Show Background Click To Complete"); 187 | _tspt.clickToComplete = clickToComplete; 188 | } 189 | 190 | if (clickToComplete) { 191 | float timeBeforeClickable = EditorGUILayout.FloatField(new GUIContent("Time Before Clickable", "Seconds disallow clicking background mask after OnEnable."), _tspt.timeBeforeClickable); 192 | if (timeBeforeClickable != _tspt.timeBeforeClickable) { 193 | EditorUtility.SetDirty(_tspt); 194 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Show Background Time Before Clickable"); 195 | _tspt.timeBeforeClickable = timeBeforeClickable; 196 | } 197 | } 198 | } 199 | } 200 | 201 | EditorGUI.indentLevel--; 202 | } 203 | 204 | protected override void OnOtherSettingGUI() 205 | { 206 | OnDoNotResetOnCompleteSettingGUI(); 207 | } 208 | 209 | protected virtual void OnDoNotResetOnCompleteSettingGUI() 210 | { 211 | bool doNotResetPanelOnComplete = EditorGUILayout.Toggle(new GUIContent("Do Not Hide Panel On Complete", "Do not reset and hide the panel after tutorial step complete. This is mainly used when next tutorial step also use the tutorial panel, so avoid flicker of the tutorial panel."), _tspt.doNotHidePanelOnComplete); 212 | if (doNotResetPanelOnComplete != _tspt.doNotHidePanelOnComplete) { 213 | EditorUtility.SetDirty(_tspt); 214 | Undo.RegisterCompleteObjectUndo(_tspt, "Reassign Do Not Reset Panel On Complete"); 215 | _tspt.doNotHidePanelOnComplete = doNotResetPanelOnComplete; 216 | } 217 | } 218 | 219 | #region Preview 220 | 221 | protected override bool isPreviewShown { 222 | get { return _tspt.tutorialPanel != null; } 223 | } 224 | 225 | protected override void OnRemovePreviewClick() 226 | { 227 | _tspt.ResetBackgroundMask(); 228 | _tspt.DestroyTutorialPanel(); 229 | } 230 | 231 | protected override void OnAddPreviewClick() 232 | { 233 | _tspt.Init(); 234 | UpdatePreview(); 235 | } 236 | 237 | protected override void UpdatePreview() 238 | { 239 | if (_tspt.tutorialPanel != null) 240 | _tspt.SetupTutorialPanel(); 241 | } 242 | 243 | #endregion 244 | 245 | } 246 | 247 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialShowPanelTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd39e0be371c04fc0b8fa056cda00b65 3 | timeCreated: 1508321326 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialShowTargetPanelTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using SweatyChair.UI; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [CustomEditor(typeof(TutorialShowTargetPanelTask))] 9 | public class TutorialShowTargetPanelTaskEditor : TutorialTaskEditor 10 | { 11 | 12 | private TutorialShowTargetPanelTask _tstpt { 13 | get { return target as TutorialShowTargetPanelTask; } 14 | } 15 | 16 | protected override void OnPreviewSettingGUI() 17 | { 18 | GUILayout.Label("UI", EditorStyles.boldLabel); 19 | 20 | Panel targetPanel = TransformUtils.GetComponentByPath(_tstpt.targetPath); 21 | string targetPath = (EditorGUILayout.ObjectField(new GUIContent("Panel in Scene", "The target panel in current scene, this will be converted and saved as path string."), targetPanel, typeof(Panel), true) as Panel).ToPath(); 22 | if (targetPanel == null && !string.IsNullOrEmpty(_tstpt.targetPath)) 23 | GUI.contentColor = Color.red; 24 | string customTargetPath = EditorGUILayout.TextField(new GUIContent(string.IsNullOrEmpty(_tstpt.targetPath) ? "Enter Manually" : (targetPanel == null ? "Not Found" : " "), "Manually set the target path, use this for dynamically-loaded prefab."), _tstpt.targetPath); 25 | if (customTargetPath != _tstpt.targetPath) { 26 | EditorUtility.SetDirty(_tstpt); 27 | Undo.RegisterCompleteObjectUndo(_tstpt, "Reassign Custom Target Path"); 28 | _tstpt.targetPath = customTargetPath; 29 | targetPath = customTargetPath; 30 | } 31 | if (targetPanel == null && !string.IsNullOrEmpty(_tstpt.targetPath)) 32 | GUI.contentColor = Color.white; 33 | if ((string.IsNullOrEmpty(_tstpt.targetPath) || targetPanel != null) && targetPath != _tstpt.targetPath) { 34 | EditorUtility.SetDirty(_tstpt); 35 | Undo.RegisterCompleteObjectUndo(_tstpt, "Reassign Target Path"); 36 | _tstpt.targetPath = targetPath; 37 | } 38 | } 39 | 40 | protected override void OnOtherSettingGUI() 41 | { 42 | bool hideOnComplete = EditorGUILayout.Toggle(new GUIContent("Hide On Complete", "Hide the panel after this tutorial step complete."), _tstpt.hideOnComplete); 43 | if (hideOnComplete != _tstpt.hideOnComplete) { 44 | EditorUtility.SetDirty(_tstpt); 45 | Undo.RegisterCompleteObjectUndo(_tstpt, "Reassign Hide On Complete"); 46 | _tstpt.hideOnComplete = hideOnComplete; 47 | } 48 | } 49 | 50 | #region Preview 51 | 52 | protected override bool isPreviewShown { 53 | get { return _tstpt.targetPanel != null; } 54 | } 55 | 56 | protected override bool canShowPreview { 57 | get { return !string.IsNullOrEmpty(_tstpt.targetPath) && TransformUtils.GetTransformByPath(_tstpt.targetPath) != null; } 58 | } 59 | 60 | protected override string cannotShowPreviewWarning { 61 | get { return "Assign target to enable Preview"; } 62 | } 63 | 64 | protected override void OnRemovePreviewClick() 65 | { 66 | _tstpt.Reset(); 67 | } 68 | 69 | protected override void OnAddPreviewClick() 70 | { 71 | _tstpt.Init(); 72 | _tstpt.targetPanel.Show(); 73 | } 74 | 75 | #endregion 76 | 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialShowTargetPanelTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32e2cbf1f8dd5134ba2541a370ec52f4 3 | timeCreated: 1508321326 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | using SweatyChair.StateManagement; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | [CustomEditor(typeof(TutorialTask))] 9 | public class TutorialTaskEditor : Editor 10 | { 11 | 12 | private TutorialTask _tt => target as TutorialTask; 13 | 14 | private bool hasPreviewSection { 15 | get { 16 | if (!GetType().IsSubclassOf(typeof(TutorialTaskEditor))) 17 | return false; 18 | var mi = GetType().GetMethod("OnPreviewSettingGUI"); 19 | return mi == null || mi.DeclaringType == GetType(); 20 | } 21 | } 22 | 23 | private bool hasOtherSettingSection { 24 | get { 25 | if (!GetType().IsSubclassOf(typeof(TutorialTaskEditor))) 26 | return false; 27 | var mi = GetType().GetMethod("OnOtherSettingGUI"); 28 | return mi == null || mi.DeclaringType == GetType(); 29 | } 30 | } 31 | 32 | public override void OnInspectorGUI() 33 | { 34 | OnTriggerSettingGUI(); 35 | 36 | if (hasPreviewSection) { 37 | EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); 38 | OnPreviewSettingGUI(); 39 | OnPreviewGUI(); 40 | } 41 | 42 | if (hasOtherSettingSection) { 43 | EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); 44 | OnOtherSettingGUI(); 45 | } 46 | 47 | serializedObject.Update(); 48 | } 49 | 50 | #region Settings 51 | 52 | protected virtual bool isCompletedTriggerEditable => true; 53 | 54 | protected virtual TutoriaCompletelTrigger forceCompleteTrigger => TutoriaCompletelTrigger.Auto; 55 | 56 | protected void OnTriggerSettingGUI() 57 | { 58 | State skipState = (State)EditorGUILayout.EnumPopup(new GUIContent("Skip State", "Skip this task for specfic states"), _tt.skipState); 59 | if (skipState != _tt.skipState) { 60 | EditorUtility.SetDirty(_tt); 61 | Undo.RegisterCompleteObjectUndo(_tt, "Reassign skip state"); 62 | _tt.skipState = skipState; 63 | } 64 | 65 | if (isCompletedTriggerEditable) { 66 | TutoriaCompletelTrigger completeTrigger = (TutoriaCompletelTrigger)EditorGUILayout.EnumPopup(new GUIContent("Complete Trigger", "How this be triggered to complete"), _tt.completeTrigger); 67 | if (completeTrigger != _tt.completeTrigger) { 68 | EditorUtility.SetDirty(_tt); 69 | Undo.RegisterCompleteObjectUndo(_tt, "Reassign complete trigger"); 70 | _tt.completeTrigger = completeTrigger; 71 | } 72 | } else { 73 | EditorGUI.BeginDisabledGroup(true); 74 | EditorGUILayout.EnumPopup(new GUIContent("Complete Trigger", string.Format("How this be triggered to complete, not editable for {0}.", target.GetType())), _tt.completeTrigger); 75 | _tt.completeTrigger = forceCompleteTrigger; 76 | EditorGUI.EndDisabledGroup(); 77 | } 78 | 79 | float timeoutSeconds = EditorGUILayout.FloatField(new GUIContent("Timeout Seconds", "A timeout seconds to force complete this step, if complete trigger is not fired."), _tt.timeoutSeconds); 80 | if (timeoutSeconds != _tt.timeoutSeconds) { 81 | EditorUtility.SetDirty(_tt); 82 | Undo.RegisterCompleteObjectUndo(_tt, "Reassign Timeout Seconds"); 83 | _tt.timeoutSeconds = timeoutSeconds; 84 | } 85 | 86 | if (_tt.timeoutSeconds > 0) { 87 | bool completeTutorialIfTimeout = EditorGUILayout.Toggle(new GUIContent("Complete Tutorial If Timeout", "Complete the whole tutorial if this step timeout."), _tt.completeTutorialIfTimeout); 88 | if (completeTutorialIfTimeout != _tt.completeTutorialIfTimeout) { 89 | EditorUtility.SetDirty(_tt); 90 | Undo.RegisterCompleteObjectUndo(_tt, "Reassign Complete Tutorial If Timeout"); 91 | _tt.completeTutorialIfTimeout = completeTutorialIfTimeout; 92 | } 93 | } 94 | 95 | float minEnabledSeconds = EditorGUILayout.FloatField(new GUIContent("Min Enabled Seconds", "A minimum seconds between start and complete, use this to avoid flicker."), _tt.minEnabledSeconds); 96 | if (minEnabledSeconds != _tt.minEnabledSeconds) { 97 | EditorUtility.SetDirty(_tt); 98 | Undo.RegisterCompleteObjectUndo(_tt, "Reassign Min Enabled Seconds"); 99 | _tt.minEnabledSeconds = minEnabledSeconds; 100 | } 101 | } 102 | 103 | protected virtual void OnPreviewSettingGUI() 104 | { 105 | } 106 | 107 | protected virtual void OnOtherSettingGUI() 108 | { 109 | } 110 | 111 | #endregion 112 | 113 | #region Preview 114 | 115 | protected virtual bool isPreviewShown { 116 | get { return false; } 117 | } 118 | 119 | protected virtual bool canShowPreview { 120 | get { return true; } 121 | } 122 | 123 | protected virtual string cannotShowPreviewWarning { 124 | get { return string.Empty; } 125 | } 126 | 127 | protected virtual void OnPreviewGUI() 128 | { 129 | if (isPreviewShown) { 130 | GUI.backgroundColor = Color.red; 131 | if (GUILayout.Button("Remove Preview")) 132 | OnRemovePreviewClick(); 133 | GUI.backgroundColor = Color.white; 134 | } else { 135 | if (canShowPreview) { 136 | GUI.backgroundColor = Color.green; 137 | if (GUILayout.Button("Preview")) 138 | OnAddPreviewClick(); 139 | GUI.backgroundColor = Color.white; 140 | } else { 141 | GUI.contentColor = Color.red; 142 | GUILayout.Label(cannotShowPreviewWarning); 143 | GUI.contentColor = Color.white; 144 | } 145 | } 146 | } 147 | 148 | protected virtual void OnRemovePreviewClick() 149 | { 150 | } 151 | 152 | protected virtual void OnAddPreviewClick() 153 | { 154 | } 155 | 156 | protected virtual void UpdatePreview() 157 | { 158 | } 159 | 160 | #endregion 161 | 162 | } 163 | 164 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff42e25274586454998b6469922723fd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialWaitForActiveTaskEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | namespace SweatyChair 5 | { 6 | 7 | [CustomEditor(typeof(TutorialWaitForActiveTask))] 8 | public class TutorialWaitForActiveTaskEditor : TutorialTaskEditor 9 | { 10 | 11 | private TutorialWaitForActiveTask _twfat => target as TutorialWaitForActiveTask; 12 | 13 | protected override void OnPreviewSettingGUI() 14 | { 15 | Transform targetTF = TransformUtils.GetTransformByPath(_twfat.targetPath); 16 | string targetPath = (EditorGUILayout.ObjectField(new GUIContent("Target in Scene", "The target transform in current scene, this will be converted and saved as path string."), targetTF, typeof(Transform), true) as Transform).ToPath(); 17 | if (targetTF == null && !string.IsNullOrEmpty(_twfat.targetPath)) 18 | GUI.contentColor = Color.red; 19 | string customTargetPath = EditorGUILayout.TextField(new GUIContent(string.IsNullOrEmpty(_twfat.targetPath) ? "Enter Manually" : (targetTF == null ? "Not Found" : " "), "Manually set the target path, use this for dynamically-loaded prefab."), _twfat.targetPath); 20 | if (customTargetPath != _twfat.targetPath) { 21 | EditorUtility.SetDirty(_twfat); 22 | Undo.RegisterCompleteObjectUndo(_twfat, "Reassign Custom Target Path"); 23 | _twfat.targetPath = customTargetPath; 24 | targetPath = customTargetPath; 25 | } 26 | if (targetTF == null && !string.IsNullOrEmpty(_twfat.targetPath)) 27 | GUI.contentColor = Color.white; 28 | if ((string.IsNullOrEmpty(_twfat.targetPath) || targetTF != null) && targetPath != _twfat.targetPath) { 29 | EditorUtility.SetDirty(_twfat); 30 | Undo.RegisterCompleteObjectUndo(_twfat, "Reassign Target Path"); 31 | _twfat.targetPath = targetPath; 32 | } 33 | 34 | bool isActive = EditorGUILayout.Toggle(new GUIContent("Is Active", "Check if the target GameObject to be active for true, or inactive for false."), _twfat.isActive); 35 | if (isActive != _twfat.isActive) { 36 | EditorUtility.SetDirty(_twfat); 37 | Undo.RegisterCompleteObjectUndo(_twfat, "Reassign Is Activate"); 38 | _twfat.isActive = isActive; 39 | } 40 | } 41 | 42 | #region Preview 43 | 44 | protected override bool canShowPreview => false; 45 | 46 | protected override void OnRemovePreviewClick() 47 | { 48 | _twfat.targetGO.SetActive(false); 49 | } 50 | 51 | protected override void OnAddPreviewClick() 52 | { 53 | _twfat.Init(); 54 | } 55 | 56 | #endregion 57 | 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Editor/TutorialWaitForActiveTaskEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf2d02f957de244a8a02795fbcee08ba 3 | timeCreated: 1508321027 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e8b6990177414922be3d87ca7fea710 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TimeScaleEnabler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SweatyChair 6 | { 7 | 8 | public class TimeScaleEnabler : MonoBehaviour 9 | { 10 | 11 | private float _lastTimeScale = 0; 12 | 13 | private void OnEnable() 14 | { 15 | _lastTimeScale = Time.timeScale; 16 | Time.timeScale = 1; 17 | } 18 | 19 | private void OnDisable() 20 | { 21 | Time.timeScale = _lastTimeScale; 22 | } 23 | 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TimeScaleEnabler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2942652a4f116b4397201be2860a2d0 3 | timeCreated: 1521097143 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TransformPathObtainer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using SweatyChair; 3 | 4 | public class TransformPathObtainer : MonoBehaviour 5 | { 6 | 7 | #if UNITY_EDITOR 8 | 9 | [UnityEditor.MenuItem("Sweaty Chair/Utilities/Copy Path")] 10 | private static void CopyActiveObjectPath() 11 | { 12 | if (UnityEditor.Selection.activeObject == null || !(UnityEditor.Selection.activeObject is GameObject)) { 13 | Debug.LogError("Please select a object in scene first."); 14 | } else { 15 | GameObject gameObject = (GameObject)UnityEditor.Selection.activeObject; 16 | if (gameObject != null) { 17 | CopyTransformPath(gameObject.transform); 18 | } 19 | } 20 | } 21 | 22 | [UnityEditor.MenuItem("CONTEXT/Transform/Copy Path")] 23 | private static void CopyTransformPath(UnityEditor.MenuCommand menuCommand) 24 | { 25 | CopyTransformPath(menuCommand.context as Transform); 26 | } 27 | 28 | [UnityEditor.MenuItem("CONTEXT/GameObject/Copy Path")] 29 | private static void CopyGameObjectPath(UnityEditor.MenuCommand menuCommand) 30 | { 31 | CopyTransformPath((menuCommand.context as GameObject).transform); 32 | } 33 | 34 | #endif 35 | 36 | private static void CopyTransformPath(Transform transform) 37 | { 38 | string path = transform.ToPath(); 39 | Debug.LogFormat("Copied '{0}' to clipboard", path); 40 | TextEditor te = new TextEditor { 41 | text = path 42 | }; 43 | te.SelectAll(); 44 | te.Copy(); 45 | } 46 | 47 | [ContextMenu("Copy Path")] 48 | private void CopyPath() 49 | { 50 | CopyTransformPath(transform); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TransformPathObtainer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63a79608b3b7e45238f7a0f82146aa03 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TutorialCompleteStepTrigger.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace SweatyChair 4 | { 5 | 6 | /// 7 | /// Call to TutorialAssistant when satifying a condition. 8 | /// 9 | public class TutorialCompleteStepTrigger : EventTrigger 10 | { 11 | 12 | protected override void CallEvent() 13 | { 14 | TutorialManager.CompleteManualSteps(); 15 | } 16 | 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TutorialCompleteStepTrigger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0a035fb24b82045c99b25636a6885916 3 | timeCreated: 1521097143 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TutorialDialogueEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Events; 5 | 6 | namespace SweatyChair 7 | { 8 | 9 | public class TutorialDialogueEventHandler : MonoBehaviour 10 | { 11 | 12 | [System.Serializable] 13 | public class TutorialDialogueEvent 14 | { 15 | [SerializeField] private string _triggerText; 16 | [SerializeField] private UnityEvent _action; 17 | 18 | public bool Compare(string triggerText) 19 | { 20 | return _triggerText == triggerText; 21 | } 22 | 23 | public void Invoke() 24 | { 25 | if (_action != null) 26 | _action.Invoke(); 27 | } 28 | } 29 | 30 | [SerializeField] private List tutorialDialogueEventList = new List(); 31 | 32 | private void Awake() 33 | { 34 | TutorialDialogueTask.dialogueShown += DialogueCheck; 35 | } 36 | 37 | private void OnDestroy() 38 | { 39 | TutorialDialogueTask.dialogueShown -= DialogueCheck; 40 | } 41 | 42 | private void DialogueCheck(string dialogue) 43 | { 44 | foreach (TutorialDialogueEvent dialogueEvent in tutorialDialogueEventList) { 45 | if (dialogueEvent.Compare(dialogue)) { 46 | dialogueEvent.Invoke(); 47 | break; 48 | } 49 | } 50 | } 51 | 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Helpers/TutorialDialogueEventHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d86a3f6123c64aa39216f738d573b80 3 | timeCreated: 1521097143 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b9d18d3534c554f809c3baca93d854f3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialActivateTask.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace SweatyChair 4 | { 5 | 6 | /// 7 | /// Activate a game object in current scene. 8 | /// 9 | public class TutorialActivateTask : TutorialTask 10 | { 11 | 12 | public string targetPath; 13 | 14 | public bool isActivate = true; 15 | public bool checkOnUpdate = false; 16 | 17 | public bool setPrevActivationOnComplete = false; 18 | 19 | public GameObject targetGO; 20 | 21 | private bool _prevActivation = false; 22 | 23 | public override bool Init() 24 | { 25 | if (string.IsNullOrEmpty(targetPath)) { 26 | Debug.LogErrorFormat("{0}:{1}:Init - Target object not set, targetPath={2}", name, GetType(), targetPath); 27 | return false; 28 | } 29 | 30 | Transform targetTF = TransformUtils.GetTransformByPath(targetPath); 31 | if (targetTF == null) { 32 | Debug.LogErrorFormat("{0}:{1}:Init - Target transform not found, targetPath={2}", name, GetType(), targetPath); 33 | return false; 34 | } 35 | 36 | targetGO = targetTF.gameObject; 37 | 38 | return true; 39 | } 40 | 41 | public override bool DoStart() 42 | { 43 | if (!base.DoStart()) 44 | return false; 45 | 46 | if (completeTrigger == TutoriaCompletelTrigger.Auto) // Set complete on beginning 47 | DoComplete(); 48 | 49 | _prevActivation = targetGO.activeSelf; 50 | targetGO.SetActive(isActivate); 51 | 52 | return true; 53 | } 54 | 55 | protected override void DoUpdate() 56 | { 57 | if (checkOnUpdate) 58 | targetGO.SetActive(isActivate); 59 | } 60 | 61 | public override void Reset() 62 | { 63 | if (setPrevActivationOnComplete) 64 | targetGO.SetActive(_prevActivation); 65 | } 66 | 67 | #if UNITY_EDITOR 68 | 69 | public override bool IsValidate() 70 | { 71 | if (!string.IsNullOrEmpty(targetPath) && TransformUtils.GetTransformByPath(targetPath) == null) 72 | return false; 73 | return true; 74 | } 75 | 76 | #endif 77 | 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialActivateTask.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 913285c9a717b4bc69e9bb2d47d2296d 3 | timeCreated: 1521097143 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialAnimateHandTask.cs: -------------------------------------------------------------------------------- 1 | namespace SweatyChair 2 | { 3 | 4 | /// 5 | /// Tutorial to set hand animation manually. 6 | /// 7 | public class TutorialAnimateHandTask : TutorialShowPanelTask 8 | { 9 | public string handAnim = "HandClick"; 10 | 11 | public override void SetupTutorialPanel() 12 | { 13 | base.SetupTutorialPanel(); 14 | tutorialPanel.SetHandAnimation(handAnim); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialAnimateHandTask.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d78de99a372a664f822424518585db4 3 | timeCreated: 1521097143 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialAnimateTask.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace SweatyChair 4 | { 5 | 6 | /// 7 | /// Works like TutorialHighlight, plus animate the higlighted UI object. 8 | /// 9 | public class TutorialAnimateTask : TutorialHighlightTask 10 | { 11 | 12 | public AnimationClip animationClip; 13 | public string animationPath; 14 | 15 | private Animation _addedAnimation; 16 | 17 | public override bool Init() 18 | { 19 | if (!base.Init()) 20 | return false; 21 | if (targetTF.gameObject.layer != LayerMask.NameToLayer("UI")) { 22 | Debug.LogError(string.Format("{0}:{1}:Init - Target object is not an UI, targetPath={2}", name, GetType(), targetPath)); 23 | return false; 24 | } 25 | return true; 26 | } 27 | 28 | public override void SetupTutorialPanel() 29 | { 30 | base.SetupTutorialPanel(); 31 | if (Application.isPlaying) // Skip in editor 32 | PlayAnimation(); 33 | } 34 | 35 | private void PlayAnimation() 36 | { 37 | if (animationClip == null) 38 | return; 39 | 40 | Transform animationTF = targetTF; 41 | if (!string.IsNullOrEmpty(animationPath)) 42 | animationTF = TransformUtils.GetTransformByPath(animationPath); 43 | 44 | if (animationTF == null) 45 | return; 46 | 47 | Animation animation = animationTF.GetComponent(); 48 | 49 | if (animation != null) { // There's already animation component attached 50 | 51 | bool containClip = false; 52 | animation.clip = animationClip; 53 | animation.Play(); 54 | 55 | } else { 56 | 57 | if (_addedAnimation != null) 58 | Destroy(_addedAnimation); 59 | 60 | _addedAnimation = animationTF.gameObject.AddComponent(); 61 | _addedAnimation.clip = animationClip; 62 | _addedAnimation.playAutomatically = true; 63 | 64 | // Re-active the animation 65 | animationTF.gameObject.SetActive(false); 66 | animationTF.gameObject.SetActive(true); 67 | 68 | } 69 | } 70 | 71 | public override void Reset() 72 | { 73 | base.Reset(); 74 | 75 | if (_addedAnimation != null) 76 | Destroy(_addedAnimation); 77 | } 78 | 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialAnimateTask.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51e0fd04e2e5f410f9c5a3e5994d4a6a 3 | timeCreated: 1521097143 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/SweatyChair/Tutorials/Scripts/Tasks/TutorialClickButtonTask.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace SweatyChair 5 | { 6 | 7 | /// 8 | /// Works like TutorialShowPanel, plus highlight and follow an in-game UI/world object. 9 | /// 10 | public class TutorialClickButtonTask : TutorialHighlightTask 11 | { 12 | 13 | protected Button _targetButton; 14 | 15 | private bool _isHandAnimationPlaying = false; 16 | 17 | public override bool Init() 18 | { 19 | bool tmp = base.Init(); 20 | 21 | if (!tmp) 22 | return false; 23 | 24 | _targetButton = targetTF.GetComponent