Committed everything

This commit is contained in:
2021-06-30 21:39:19 +10:00
commit fcfa8e7213
525 changed files with 49440 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
[Ll]ibrary/
[Tt]emp/
[Oo]bj/
[Bb]uild/
[Bb]uilds/
Assets/AssetStoreTools*
# Visual Studio 2015 cache directory
/.vs/
# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
# Unity3D Generated File On Crash Reports
sysinfo.txt
# Builds
*.apk
*.unitypackage
#steam
steam_sdk/
#switch
SwitchIL2CPPCache/
SwitchIL2CPPStats/
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e6ba2d9f1366a5b48b0de31974af56cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1ea997059b193ec4f93c2ae11630ad48
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 36fb6d04b0b2d3b478161622da3f094c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ff7b234789513374cb4413a04a031a5a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,744 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 3
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 0
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 10
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 0
m_CompAOExponentDirect: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 1024
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringMode: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ShowResolutionOverlay: 1
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &1104190021
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1104190022}
- component: {fileID: 1104190024}
- component: {fileID: 1104190023}
- component: {fileID: 1104190025}
m_Layer: 5
m_Name: Help
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1104190022
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1104190021}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1908123727}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 291.5, y: -308}
m_SizeDelta: {x: 346, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1104190023
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1104190021}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 18
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Check the readme file for more information!
--- !u!222 &1104190024
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1104190021}
m_CullTransparentMesh: 0
--- !u!114 &1104190025
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1104190021}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &1300920510
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1300920511}
- component: {fileID: 1300920513}
- component: {fileID: 1300920512}
- component: {fileID: 1300920514}
m_Layer: 5
m_Name: Edit the story!
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1300920511
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1300920510}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1908123727}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 291.5, y: -298}
m_SizeDelta: {x: 583, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1300920512
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1300920510}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 18
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "When you're done, try editing the story.ink to change the story; and the\r
BasicInkExample script to change what Unity does with it!"
--- !u!222 &1300920513
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1300920510}
m_CullTransparentMesh: 0
--- !u!114 &1300920514
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1300920510}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &1482195891
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1482195896}
- component: {fileID: 1482195895}
- component: {fileID: 1482195893}
- component: {fileID: 1482195892}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1482195892
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1482195891}
m_Enabled: 1
--- !u!124 &1482195893
Behaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1482195891}
m_Enabled: 1
--- !u!20 &1482195895
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1482195891}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844}
m_projectionMatrixMode: 1
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_GateFitMode: 2
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1482195896
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1482195891}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: -456, y: -470, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 2009679605}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1767420452
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1767420453}
- component: {fileID: 1767420455}
- component: {fileID: 1767420454}
- component: {fileID: 1767420456}
m_Layer: 5
m_Name: Press Play
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1767420453
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1767420452}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1908123727}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 291.5, y: -288}
m_SizeDelta: {x: 365, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1767420454
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1767420452}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 18
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Press the Play button at the top of the screen!
--- !u!222 &1767420455
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1767420452}
m_CullTransparentMesh: 0
--- !u!114 &1767420456
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1767420452}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &1908123722
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1908123727}
- component: {fileID: 1908123726}
- component: {fileID: 1908123725}
- component: {fileID: 1908123723}
- component: {fileID: 1908123724}
- component: {fileID: 1908123728}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1908123723
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1908123722}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1297475563, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 4
m_Spacing: 10
m_ChildForceExpandWidth: 0
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 1
m_ChildControlHeight: 0
--- !u!114 &1908123724
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1908123722}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7ce0d8573e1b2ff42af74cb80f3e5ece, type: 3}
m_Name:
m_EditorClassIdentifier:
key: 27
--- !u!114 &1908123725
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1908123722}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 66e957d58a4584a8894329531ec0b096, type: 3}
m_Name:
m_EditorClassIdentifier:
inkJSONAsset: {fileID: 4900000, guid: 6cf48bb6d89824cc69e35b43f9a1aca6, type: 3}
canvas: {fileID: 1908123726}
textPrefab: {fileID: 11456674, guid: 1aab6ef84d87c416f8f0b3e1ef3d77d2, type: 3}
buttonPrefab: {fileID: 11455116, guid: 37c108a6c38964f79a6621eccb33ddc1, type: 3}
--- !u!223 &1908123726
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1908123722}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 1
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 25
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &1908123727
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1908123722}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 1767420453}
- {fileID: 1300920511}
- {fileID: 1104190022}
m_Father: {fileID: 2009679605}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!114 &1908123728
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1908123722}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!1 &1949950323
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1949950326}
- component: {fileID: 1949950325}
- component: {fileID: 1949950324}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1949950324
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1949950323}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &1949950325
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1949950323}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &1949950326
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1949950323}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2009679603
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2009679605}
- component: {fileID: 2009679604}
- component: {fileID: 2009679606}
m_Layer: 0
m_Name: Scene Controller
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2009679604
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009679603}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 66e957d58a4584a8894329531ec0b096, type: 3}
m_Name:
m_EditorClassIdentifier:
inkJSONAsset: {fileID: 4900000, guid: 6cf48bb6d89824cc69e35b43f9a1aca6, type: 3}
canvas: {fileID: 1908123726}
textPrefab: {fileID: 11456674, guid: 1aab6ef84d87c416f8f0b3e1ef3d77d2, type: 3}
buttonPrefab: {fileID: 11455116, guid: 37c108a6c38964f79a6621eccb33ddc1, type: 3}
--- !u!4 &2009679605
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009679603}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 456, y: 470, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1482195896}
- {fileID: 1908123727}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2009679606
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2009679603}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7ce0d8573e1b2ff42af74cb80f3e5ece, type: 3}
m_Name:
m_EditorClassIdentifier:
key: 27
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8af1c5cbac5094782904447c9410b35d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 29fc0cbe08c0d4f87975cc7a62f72510
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,19 @@
- I looked at Monsieur Fogg
* ... and I could contain myself no longer.
'What is the purpose of our journey, Monsieur?'
'A wager,' he replied.
* * 'A wager!'[] I returned.
He nodded.
* * * 'But surely that is foolishness!'
* * * 'A most serious matter then!'
- - - He nodded again.
* * * 'But can we win?'
'That is what we will endeavour to find out,' he answered.
* * * 'A modest wager, I trust?'
'Twenty thousand pounds,' he replied, quite flatly.
* * * I asked nothing further of him then[.], and after a final, polite cough, he offered nothing more to me. <>
* * 'Ah[.'],' I replied, uncertain what I thought.
- - After that, <>
* ... but I said nothing[] and <>
- we passed the day in silence.
- -> END
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1460e815e969b43b8a83a7caa8b48c27
timeCreated: 1464457282
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1 @@
{"inkVersion":20,"root":[[["^I looked at Monsieur Fogg","\n",["ev",{"^->":"0.g-0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg":18},{"s":["^... and I could contain myself no longer.",{"->":"$r","var":true},null]}],["ev",{"^->":"0.g-0.3.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-1","flg":18},{"s":["^... but I said nothing",{"->":"$r","var":true},null]}],{"c-0":["ev",{"^->":"0.g-0.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.2.s"},[{"#n":"$r2"}],"\n","^'What is the purpose of our journey, Monsieur?'","\n","^'A wager,' he replied.","\n",[["ev",{"^->":"0.g-0.c-0.11.0.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg":18},{"s":["^'A wager!'",{"->":"$r","var":true},null]}],["ev",{"^->":"0.g-0.c-0.11.1.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","str","^.'","/str","/ev",{"*":".^.^.c-1","flg":22},{"s":["^'Ah",{"->":"$r","var":true},null]}],{"c-0":["ev",{"^->":"0.g-0.c-0.11.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.0.s"},[{"#n":"$r2"}],"^ I returned.","\n","^He nodded.","\n",[["ev",{"^->":"0.g-0.c-0.11.c-0.10.0.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-0","flg":18},{"s":["^'But surely that is foolishness!'",{"->":"$r","var":true},null]}],["ev",{"^->":"0.g-0.c-0.11.c-0.10.1.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-1","flg":18},{"s":["^'A most serious matter then!'",{"->":"$r","var":true},null]}],{"c-0":["ev",{"^->":"0.g-0.c-0.11.c-0.10.c-0.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.0.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},{"#f":5}],"c-1":["ev",{"^->":"0.g-0.c-0.11.c-0.10.c-1.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.1.s"},[{"#n":"$r2"}],"\n",{"->":".^.^.g-0"},{"#f":5}],"g-0":["^He nodded again.","\n",["ev",{"^->":"0.g-0.c-0.11.c-0.10.g-0.2.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-2","flg":18},{"s":["^'But can we win?'",{"->":"$r","var":true},null]}],["ev",{"^->":"0.g-0.c-0.11.c-0.10.g-0.3.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","/ev",{"*":".^.^.c-3","flg":18},{"s":["^'A modest wager, I trust?'",{"->":"$r","var":true},null]}],["ev",{"^->":"0.g-0.c-0.11.c-0.10.g-0.4.$r1"},{"temp=":"$r"},"str",{"->":".^.s"},[{"#n":"$r1"}],"/str","str","^.","/str","/ev",{"*":".^.^.c-4","flg":22},{"s":["^I asked nothing further of him then",{"->":"$r","var":true},null]}],{"c-2":["ev",{"^->":"0.g-0.c-0.11.c-0.10.g-0.c-2.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.2.s"},[{"#n":"$r2"}],"\n","^'That is what we will endeavour to find out,' he answered.","\n",{"->":".^.^.^.^.^.g-0"},{"#f":5}],"c-3":["ev",{"^->":"0.g-0.c-0.11.c-0.10.g-0.c-3.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.3.s"},[{"#n":"$r2"}],"\n","^'Twenty thousand pounds,' he replied, quite flatly.","\n",{"->":".^.^.^.^.^.g-0"},{"#f":5}],"c-4":["ev",{"^->":"0.g-0.c-0.11.c-0.10.g-0.c-4.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.4.s"},[{"#n":"$r2"}],"^, and after a final, polite cough, he offered nothing more to me. ","<>","\n",{"->":".^.^.^.^.^.g-0"},{"#f":5}],"#f":5}]}],{"#f":5}],"c-1":["ev",{"^->":"0.g-0.c-0.11.c-1.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.1.s"},[{"#n":"$r2"}],"^,' I replied, uncertain what I thought.","\n",{"->":".^.^.g-0"},{"#f":5}],"g-0":["^After that, ","<>","\n",{"->":"0.g-1"},{"#f":5}]}],{"#f":5}],"c-1":["ev",{"^->":"0.g-0.c-1.$r2"},"/ev",{"temp=":"$r"},{"->":".^.^.3.s"},[{"#n":"$r2"}],"^ and ","<>","\n",{"->":"0.g-1"},{"#f":5}],"#f":5,"#n":"g-0"}],{"g-1":["^we passed the day in silence.","\n",["end",["done",{"#f":5,"#n":"g-3"}],{"#f":5,"#n":"g-2"}],{"#f":5}]}],"done",{"#f":1}],"listDefs":{}}
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6cf48bb6d89824cc69e35b43f9a1aca6
timeCreated: 1512575780
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d8b5e370f13d74ab9b7aa54226433610
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,265 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &105558
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 224: {fileID: 22491254}
- 222: {fileID: 22256872}
- 114: {fileID: 11418596}
- 114: {fileID: 11455116}
- 114: {fileID: 11420252}
- 114: {fileID: 11438922}
m_Layer: 5
m_Name: Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &134058
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 224: {fileID: 22447082}
- 222: {fileID: 22289712}
- 114: {fileID: 11421544}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &11418596
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105558}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &11420252
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105558}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_VerticalFit: 2
--- !u!114 &11421544
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 134058}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Button
--- !u!114 &11438922
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105558}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -405508275, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 5
m_Right: 5
m_Top: 5
m_Bottom: 5
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
--- !u!114 &11455116
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105558}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1392445389, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 11418596}
m_OnClick:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!222 &22256872
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105558}
--- !u!222 &22289712
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 134058}
--- !u!224 &22447082
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 134058}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children: []
m_Father: {fileID: 22491254}
m_RootOrder: 0
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &22491254
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 105558}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 22447082}
m_Father: {fileID: 0}
m_RootOrder: 0
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 0}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_HorizontalFit
value: 2
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_VerticalFit
value: 2
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_Padding.m_Left
value: 5
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_Padding.m_Right
value: 5
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_Padding.m_Top
value: 5
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_Padding.m_Bottom
value: 5
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_Spacing
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 105558}
m_IsPrefabParent: 1
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 37c108a6c38964f79a6621eccb33ddc1
timeCreated: 1457987203
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,118 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &162960
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 22481992}
- component: {fileID: 22265584}
- component: {fileID: 11456674}
- component: {fileID: 11422042}
- component: {fileID: 11400932}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &22481992
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 162960}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &22265584
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 162960}
m_CullTransparentMesh: 0
--- !u!114 &11456674
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 162960}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 20
m_FontStyle: 1
m_BestFit: 0
m_MinSize: 0
m_MaxSize: 40
m_Alignment: 1
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text:
--- !u!114 &11422042
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 162960}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -405508275, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Right: 0
m_Top: 0
m_Bottom: 0
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 1
m_ChildForceExpandHeight: 1
m_ChildControlWidth: 1
m_ChildControlHeight: 1
--- !u!114 &11400932
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 162960}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1aab6ef84d87c416f8f0b3e1ef3d77d2
timeCreated: 1457983120
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b54a75d42bc7748248ac75fe35331f9e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,110 @@
using UnityEngine;
using UnityEngine.UI;
using System;
using Ink.Runtime;
// This is a super bare bones example of how to play and display a ink story in Unity.
public class BasicInkExample : MonoBehaviour {
public static event Action<Story> OnCreateStory;
void Awake () {
// Remove the default message
RemoveChildren();
StartStory();
}
// Creates a new Story object with the compiled story which we can then play!
void StartStory () {
story = new Story (inkJSONAsset.text);
if(OnCreateStory != null) OnCreateStory(story);
RefreshView();
}
// This is the main function called every time the story changes. It does a few things:
// Destroys all the old content and choices.
// Continues over all the lines of text, then displays all the choices. If there are no choices, the story is finished!
void RefreshView () {
// Remove all the UI on screen
RemoveChildren ();
// Read all the content until we can't continue any more
while (story.canContinue) {
// Continue gets the next line of the story
string text = story.Continue ();
// This removes any white space from the text.
text = text.Trim();
// Display the text on screen!
CreateContentView(text);
}
// Display all the choices, if there are any!
if(story.currentChoices.Count > 0) {
for (int i = 0; i < story.currentChoices.Count; i++) {
Choice choice = story.currentChoices [i];
Button button = CreateChoiceView (choice.text.Trim ());
// Tell the button what to do when we press it
button.onClick.AddListener (delegate {
OnClickChoiceButton (choice);
});
}
}
// If we've read all the content and there's no choices, the story is finished!
else {
Button choice = CreateChoiceView("End of story.\nRestart?");
choice.onClick.AddListener(delegate{
StartStory();
});
}
}
// When we click the choice button, tell the story to choose that choice!
void OnClickChoiceButton (Choice choice) {
story.ChooseChoiceIndex (choice.index);
RefreshView();
}
// Creates a textbox showing the the line of text
void CreateContentView (string text) {
Text storyText = Instantiate (textPrefab) as Text;
storyText.text = text;
storyText.transform.SetParent (canvas.transform, false);
}
// Creates a button showing the choice text
Button CreateChoiceView (string text) {
// Creates the button from a prefab
Button choice = Instantiate (buttonPrefab) as Button;
choice.transform.SetParent (canvas.transform, false);
// Gets the text from the button prefab
Text choiceText = choice.GetComponentInChildren<Text> ();
choiceText.text = text;
// Make the button expand to fit the text
HorizontalLayoutGroup layoutGroup = choice.GetComponent <HorizontalLayoutGroup> ();
layoutGroup.childForceExpandHeight = false;
return choice;
}
// Destroys all the children of this gameobject (all the UI)
void RemoveChildren () {
int childCount = canvas.transform.childCount;
for (int i = childCount - 1; i >= 0; --i) {
GameObject.Destroy (canvas.transform.GetChild (i).gameObject);
}
}
[SerializeField]
private TextAsset inkJSONAsset = null;
public Story story;
[SerializeField]
private Canvas canvas = null;
// UI Prefabs
[SerializeField]
private Text textPrefab = null;
[SerializeField]
private Button buttonPrefab = null;
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 66e957d58a4584a8894329531ec0b096
timeCreated: 1473758854
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9afc9fe3049ac409e886991c340e1a33
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,28 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Ink.UnityIntegration;
using Ink.Runtime;
[CustomEditor(typeof(BasicInkExample))]
[InitializeOnLoad]
public class BasicInkExampleEditor : Editor {
static BasicInkExampleEditor () {
BasicInkExample.OnCreateStory += OnCreateStory;
}
static void OnCreateStory (Story story) {
// If you'd like NOT to automatically show the window and attach (your teammates may appreciate it!) then replace "true" with "false" here.
InkPlayerWindow window = InkPlayerWindow.GetWindow(true);
if(window != null) InkPlayerWindow.Attach(story);
}
public override void OnInspectorGUI () {
Repaint();
base.OnInspectorGUI ();
var realTarget = target as BasicInkExample;
var story = realTarget.story;
InkPlayerWindow.DrawStoryPropertyField(story, new GUIContent("Story"));
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1c04f2595983345ab86d4ef0eea06dea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using UnityEngine;
using System.Collections;
public class QuitGameOnKeypress : MonoBehaviour {
public KeyCode key = KeyCode.Escape;
void Update () {
if(Input.GetKeyDown(key)) Application.Quit();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ce0d8573e1b2ff42af74cb80f3e5ece
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e829cba164e3db943916a82d6c825672
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: df28596461d414a1b9f56cb406a23a3f
folderAsset: yes
timeCreated: 1459882215
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ddef5103d5ce1401da019f7df6c472af
folderAsset: yes
timeCreated: 1459882122
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e277a78690c74451084fbfbedc0507e8
folderAsset: yes
timeCreated: 1459941651
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,178 @@
// Automatically creates JSON files from an ink placed within the Assets/Ink folder.
using UnityEngine;
using UnityEditor;
using System.IO;
using Debug = UnityEngine.Debug;
using System.Collections.Generic;
using System.Linq;
namespace Ink.UnityIntegration {
class InkPostProcessor : AssetPostprocessor {
// Several assets moved at the same time can cause unity to call OnPostprocessAllAssets several times as a result of moving additional files, or simply due to minor time differences.
// This queue tells the compiler which files to recompile after moves have completed.
// Not a perfect solution - If Unity doesn't move all the files in the same attempt you can expect some error messages to appear on compile.
private static List<string> queuedMovedAssets = new List<string>();
public static bool disabled = false;
// Recompiles any ink files as a result of an ink file (re)import
private static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) {
if(disabled) return;
if(deletedAssets.Length > 0) {
OnDeleteAssets(deletedAssets);
}
if(movedAssets.Length > 0) {
OnMoveAssets(movedAssets.Except(importedAssets).ToArray());
}
if(importedAssets.Length > 0) {
OnImportAssets(importedAssets);
}
#if !UNITY_2020_1_OR_NEWER
if(InkLibrary.created)
#endif
InkLibrary.Clean();
}
private static void OnDeleteAssets (string[] deletedAssets) {
bool deletedInk = false;
foreach (var deletedAssetPath in deletedAssets) {
if(InkEditorUtils.IsInkFile(deletedAssetPath)) {
deletedInk = true;
break;
}
}
if(!deletedInk)
return;
// bool alsoDeleteJSON = false;
// alsoDeleteJSON = EditorUtility.DisplayDialog("Deleting .ink file", "Also delete the JSON file associated with the deleted .ink file?", "Yes", "No"));
List<InkFile> masterFilesAffected = new List<InkFile>();
for (int i = InkLibrary.instance.inkLibrary.Count - 1; i >= 0; i--) {
if(InkLibrary.instance.inkLibrary [i].inkAsset == null) {
if(!InkLibrary.instance.inkLibrary[i].isMaster) {
foreach(var masterInkFile in InkLibrary.instance.inkLibrary[i].masterInkFiles) {
if(!masterFilesAffected.Contains(masterInkFile))
masterFilesAffected.Add(masterInkFile);
}
}
if(InkSettings.instance.handleJSONFilesAutomatically) {
var assetPath = AssetDatabase.GetAssetPath(InkLibrary.instance.inkLibrary[i].jsonAsset);
if(assetPath != null && assetPath != string.Empty) {
AssetDatabase.DeleteAsset(assetPath);
}
}
InkLibrary.RemoveAt(i);
}
}
// After deleting files, we might have broken some include references, so we rebuild them. There's probably a faster way to do this, or we could probably just remove any null references, but this is a bit more robust.
foreach(InkFile inkFile in InkLibrary.instance.inkLibrary) {
inkFile.FindIncludedFiles();
}
foreach(InkFile masterFile in masterFilesAffected) {
if(InkSettings.instance.compileAutomatically || masterFile.compileAutomatically) {
InkCompiler.CompileInk(masterFile);
}
}
}
private static void OnMoveAssets (string[] movedAssets) {
if (!InkSettings.instance.handleJSONFilesAutomatically)
return;
List<string> validMovedAssets = new List<string>();
for (var i = 0; i < movedAssets.Length; i++) {
if(!InkEditorUtils.IsInkFile(movedAssets[i]))
continue;
validMovedAssets.Add(movedAssets[i]);
queuedMovedAssets.Add(movedAssets[i]);
}
// Move compiled JSON files.
// This can cause Unity to postprocess assets again.
bool assetMoved = false;
foreach(var inkFilePath in validMovedAssets) {
InkFile inkFile = InkLibrary.GetInkFileWithPath(inkFilePath);
if(inkFile == null) continue;
if(inkFile.jsonAsset == null) continue;
string jsonAssetPath = AssetDatabase.GetAssetPath(inkFile.jsonAsset);
string movedAssetDir = Path.GetDirectoryName(inkFilePath);
string movedAssetFile = Path.GetFileName(inkFilePath);
string newPath = InkEditorUtils.CombinePaths(movedAssetDir, Path.GetFileNameWithoutExtension(movedAssetFile)) + ".json";
AssetDatabase.MoveAsset(jsonAssetPath, newPath);
assetMoved = true;
}
// Check if no JSON assets were moved (as a result of none needing to move, or this function being called as a result of JSON files being moved)
if(!assetMoved && queuedMovedAssets.Count > 0) {
List<InkFile> filesToCompile = new List<InkFile>();
// Add the old master file to the files to be recompiled
foreach(var inkFilePath in queuedMovedAssets) {
InkFile inkFile = InkLibrary.GetInkFileWithPath(inkFilePath);
if(inkFile == null) continue;
foreach(var masterInkFile in inkFile.masterInkFilesIncludingSelf) {
if(!filesToCompile.Contains(inkFile))
filesToCompile.Add(inkFile);
}
}
InkLibrary.RebuildInkFileConnections();
// Add the new file to be recompiled
foreach(var inkFilePath in queuedMovedAssets) {
InkFile inkFile = InkLibrary.GetInkFileWithPath(inkFilePath);
if(inkFile == null) continue;
foreach(var masterInkFile in inkFile.masterInkFilesIncludingSelf) {
if(!filesToCompile.Contains(inkFile))
filesToCompile.Add(inkFile);
}
}
queuedMovedAssets.Clear();
// Compile any ink files that are deemed master files a rebuild
foreach(var inkFile in filesToCompile) {
if(inkFile.isMaster) {
if(InkSettings.instance.compileAutomatically || inkFile.compileAutomatically) {
InkCompiler.CompileInk(inkFile);
}
}
}
}
}
private static void OnImportAssets (string[] importedAssets) {
List<string> importedInkAssets = new List<string>();
string inklecateFileLocation = null;
foreach (var importedAssetPath in importedAssets) {
if(InkEditorUtils.IsInkFile(importedAssetPath))
importedInkAssets.Add(importedAssetPath);
else if (Path.GetFileName(importedAssetPath) == "inklecate" && Path.GetExtension(importedAssetPath) == "")
inklecateFileLocation = importedAssetPath;
}
if(importedInkAssets.Count > 0)
PostprocessInkFiles(importedInkAssets);
if(inklecateFileLocation != null)
PostprocessInklecate(inklecateFileLocation);
}
private static void PostprocessInklecate (string inklecateFileLocation) {
// This should probably only recompile files marked to compile automatically, but it's such a rare case, and one where you probably do want to compile.
// To fix, one day!
Debug.Log("Inklecate updated. Recompiling all Ink files...");
InkEditorUtils.RecompileAll();
}
private static void PostprocessInkFiles (List<string> importedInkAssets) {
if(EditorApplication.isPlaying && InkSettings.instance.delayInPlayMode) {
foreach(var fileToImport in importedInkAssets) {
InkCompiler.AddToPendingCompilationStack(fileToImport);
}
} else {
InkLibrary.CreateOrReadUpdatedInkFiles (importedInkAssets);
InkCompiler.CompileInk(InkCompiler.GetUniqueMasterInkFilesToCompile (importedInkAssets).ToArray());
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45a9c84618e20498993d11d2bb89946e
timeCreated: 1459667420
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,684 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditorInternal;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;
using Debug = UnityEngine.Debug;
namespace Ink.UnityIntegration {
#if UNITY_2020_1_OR_NEWER
[FilePath("Library/InkCompiler.asset", FilePathAttribute.Location.ProjectFolder)]
public class InkCompiler : ScriptableSingleton<InkCompiler> {
#else
public class InkCompiler : ScriptableObject {
#endif
#if !UNITY_2020_1_OR_NEWER
public static bool created {
get {
return (_instance != (UnityEngine.Object) null);
}
}
private static InkCompiler _instance;
public static InkCompiler instance {
get {
if(!created)
LoadOrCreateInstance();
return _instance;
} private set {
if(_instance == value) return;
_instance = value;
}
}
static string absoluteSavePath {
get {
return System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),"Library","InkCompiler.asset"));
}
}
public static void LoadOrCreateInstance () {
InternalEditorUtility.LoadSerializedFileAndForget(absoluteSavePath);
if(created) {
if(InkEditorUtils.isFirstCompile) {
ClearCompilationStacks();
}
} else {
instance = ScriptableObject.CreateInstance<InkCompiler>();
instance.hideFlags = HideFlags.HideAndDontSave;
}
}
public void Save (bool saveAsText) {
InternalEditorUtility.SaveToSerializedFileAndForget((UnityEngine.Object[]) new InkCompiler[1] {this}, absoluteSavePath, saveAsText);
}
protected InkCompiler () {
if (created)
Debug.LogError((object) "ScriptableSingleton already exists. Did you query the singleton in a constructor?");
else {
instance = this;
}
}
#endif
public class AssetSaver : UnityEditor.AssetModificationProcessor {
static string[] OnWillSaveAssets(string[] paths) {
InkCompiler.instance.Save(true);
return paths;
}
}
public static void SaveStatic (bool saveAsText) {
#if !UNITY_2020_1_OR_NEWER
if(!created) return;
#endif
instance.Save(saveAsText);
}
public static bool compiling {
get {
return instance.compilationStack.Count > 0;
}
}
public static bool buildBlocked = false;
static bool playModeBlocked = false;
public delegate void OnCompileInkEvent (InkFile inkFile);
public static event OnCompileInkEvent OnCompileInk;
// Track if we've currently locked compilation of Unity C# Scripts
public static bool hasLockedUnityCompilation = false;
private static List<Action> onCompleteActions = new List<Action>();
// If InkSettings' delayInPlayMode option is true, dirty files are added here when they're changed in play mode
// This ensures they're remembered when you exit play mode and can be compiled
public List<string> pendingCompilationStack = new List<string>();
// The state of files currently being compiled.
public List<InkCompiler.CompilationStackItem> compilationStack = new List<InkCompiler.CompilationStackItem>();
[Serializable]
public class CompilationStackItem {
public enum State {
// Default state, item is about to be queued for compilation
Queued,
// Item is now owned by the thread pool and being compiled
Compiling,
// Compilation has finished, item to be processed for errors and result handled
Complete,
}
public State state = State.Queued;
public bool immediate;
public InkFile inkFile;
public string compiledJson;
public string inkAbsoluteFilePath;
public string jsonAbsoluteFilePath;
public List<InkCompilerLog> logOutput = new List<InkCompilerLog>();
public List<string> unhandledErrorOutput = new List<string>();
public DateTime startTime;
public DateTime endTime;
public float timeTaken {
get {
if(state == State.Complete) return (float)(endTime - startTime).TotalSeconds;
else return (float)(DateTime.Now - startTime).TotalSeconds;
}
}
public CompilationStackItem () {}
}
// This always runs after the InkEditorUtils constructor
[InitializeOnLoadMethod]
static void OnProjectLoadedInEditor() {
#if UNITY_2017_1_OR_NEWER
EditorApplication.playModeStateChanged += OnPlayModeChange;
#else
EditorApplication.playmodeStateChanged += LegacyOnPlayModeChange;
#endif
EditorApplication.update += Update;
// I really don't know if this can fire, since it assumes that it compiled so can't have been locked. But safety first!
EditorApplication.UnlockReloadAssemblies();
#if UNITY_2019_4_OR_NEWER
// This one, on the other hand, seems to actually occur sometimes - presumably because c# compiles at the same time as the ink.
if(InkEditorUtils.disallowedAutoRefresh) {
InkEditorUtils.disallowedAutoRefresh = false;
try {
AssetDatabase.AllowAutoRefresh();
} catch (Exception e) {
Debug.LogWarning("Failed AllowAutoRefresh "+e);
}
}
#endif
}
private static void Update () {
#if UNITY_2020_1_OR_NEWER
// If we're not compiling but have locked C# compilation then now is the time to reset
if (!compiling && hasLockedUnityCompilation) {
hasLockedUnityCompilation = false;
EditorApplication.UnlockReloadAssemblies();
}
#else
// If we're not compiling but have locked C# compilation then now is the time to reset
if ((!InkLibrary.created || !compiling) && hasLockedUnityCompilation) {
hasLockedUnityCompilation = false;
EditorApplication.UnlockReloadAssemblies();
}
if(!InkLibrary.created)
return;
#endif
if(compiling) {
// Check for timeouts, in case of an unhandled bug with this system/the ink compiler!
for (int i = instance.compilationStack.Count - 1; i >= 0; i--) {
var compilingFile = instance.compilationStack [i];
if (compilingFile.state == CompilationStackItem.State.Compiling) {
if (compilingFile.timeTaken > InkSettings.instance.compileTimeout) {
// TODO - Cancel the thread if it's still going. Not critical, since its kinda fine if it compiles a bit later, but it's not clear.
RemoveCompilingFile(i);
Debug.LogError("Ink Compiler timed out for "+compilingFile.inkAbsoluteFilePath+".\nCompilation should never take more than a few seconds, but for large projects or slow computers you may want to increase the timeout time in the InkSettings file.\nIf this persists there may be another issue; or else check an ink file exists at this path and try Assets/Recompile Ink, else please report as a bug with the following error log at this address: https://github.com/inkle/ink/issues\nError log:\n"+string.Join("\n",compilingFile.unhandledErrorOutput.ToArray()));
TryCompileNextFileInStack();
}
}
}
// When all files have compiled, run the complete function.
if(NumFilesInCompilingStackInState(CompilationStackItem.State.Compiling) == 0) {
if(NumFilesInCompilingStackInState(CompilationStackItem.State.Queued) == 0) {
DelayedComplete();
} else {
// We used to avoid calling this here in favour of calling it CompileInkThreaded but it seems that it doesn't run when called there, for some reason.
// If someone can make this work please let me know!
TryCompileNextFileInStack();
}
}
}
// If we're not showing a progress bar in Linux this whole step is superfluous
#if !UNITY_EDITOR_LINUX
UpdateProgressBar();
#endif
}
static void RemoveCompilingFile (int index) {
instance.compilationStack.RemoveAt(index);
instance.Save(true);
// Progress bar prevents delayCall callback from firing in Linux Editor, locking the
// compilation until it times out. Let's just not show progress bars in Linux Editor
#if !UNITY_EDITOR_LINUX
if (instance.compilationStack.Count == 0) EditorUtility.ClearProgressBar();
#endif
}
static void UpdateProgressBar () {
if(instance.compilationStack.Count == 0) return;
int numCompiling = NumFilesInCompilingStackInState(CompilationStackItem.State.Compiling);
string message = "Compiling .Ink File "+(instance.compilationStack.Count-numCompiling)+" of "+instance.compilationStack.Count+".";
if(playModeBlocked) message += " Will enter play mode when complete.";
if(buildBlocked || playModeBlocked || EditorApplication.isPlaying) EditorUtility.DisplayProgressBar("Compiling Ink...", message, GetEstimatedCompilationProgress());
else EditorUtility.ClearProgressBar();
}
public static float GetEstimatedCompilationProgress () {
if(!compiling) return 1;
float progress = 0;
foreach (var compilingFile in instance.compilationStack) {
if (compilingFile.state == CompilationStackItem.State.Compiling)
progress += compilingFile.timeTaken / InkSettings.instance.compileTimeout;
if (compilingFile.state == CompilationStackItem.State.Complete)
progress += 1;
}
progress /= instance.compilationStack.Count;
return progress;
}
#if UNITY_2017_1_OR_NEWER
static void OnPlayModeChange (PlayModeStateChange mode) {
if(mode == PlayModeStateChange.EnteredEditMode && instance.pendingCompilationStack.Count > 0)
CompilePendingFiles();
if(mode == PlayModeStateChange.ExitingEditMode && compiling)
BlockPlayMode();
if(mode == PlayModeStateChange.EnteredPlayMode && compiling)
EnteredPlayModeWhenCompiling();
}
#else
static void LegacyOnPlayModeChange () {
if(!EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying && instance.pendingCompilationStack.Count > 0)
CompilePendingFiles();
if(EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying && compiling)
BlockPlayMode();
if(EditorApplication.isPlayingOrWillChangePlaymode && EditorApplication.isPlaying && compiling)
EnteredPlayModeWhenCompiling();
}
#endif
static void CompilePendingFiles () {
InkLibrary.CreateOrReadUpdatedInkFiles (instance.pendingCompilationStack);
foreach (var pendingMasterFile in GetUniqueMasterInkFilesToCompile(instance.pendingCompilationStack))
InkCompiler.CompileInk(pendingMasterFile);
}
static void BlockPlayMode () {
EditorApplication.isPlaying = false;
var percentage = String.Format("{0:P0}.", GetEstimatedCompilationProgress());
Debug.LogWarning("Delayed entering play mode because Ink is still compiling ("+percentage+"). Will enter play mode on completion.");
playModeBlocked = true;
}
static void EnteredPlayModeWhenCompiling () {
Debug.LogError("Entered Play Mode while Ink was still compiling! Your story will not be up to date. Recommend exiting and re-entering play mode.\nWe normally delay entering play mode when compiling, so you've found an edge case!");
}
public static void CompileInk (params InkFile[] inkFiles) {
CompileInk(inkFiles, false, null);
}
public static void CompileInk (InkFile[] inkFiles, bool immediate, Action onComplete) {
#if UNITY_2019_4_OR_NEWER
if(!InkEditorUtils.disallowedAutoRefresh) {
InkEditorUtils.disallowedAutoRefresh = true;
try {
AssetDatabase.DisallowAutoRefresh();
} catch (Exception e) {
Debug.LogWarning("Failed DisallowAutoRefresh "+e);
}
}
#endif
InkLibrary.Validate();
if(onComplete != null) onCompleteActions.Add(onComplete);
StringBuilder filesCompiledLog = new StringBuilder("Files compiled:");
foreach (var inkFile in inkFiles) filesCompiledLog.AppendLine().Append(inkFile.filePath);
StringBuilder outputLog = new StringBuilder ();
outputLog.Append ("Ink compilation started at ");
outputLog.AppendLine (DateTime.Now.ToLongTimeString ());
outputLog.Append (filesCompiledLog.ToString());
Debug.Log(outputLog);
foreach(var inkFile in inkFiles) {
CompileInkInternal (inkFile, immediate);
}
}
/// <summary>
/// Starts a System.Process that compiles a master ink file, creating a playable JSON file that can be parsed by the Ink.Story class
/// </summary>
/// <param name="inkFile">Ink file.</param>
private static void CompileInkInternal (InkFile inkFile, bool immediate) {
if(inkFile == null) {
Debug.LogError("Tried to compile ink file but input was null.");
return;
}
if(!inkFile.isMaster)
Debug.LogWarning("Compiling InkFile which is an include. Any file created is likely to be invalid. Did you mean to call CompileInk on inkFile.master?");
// If we've not yet locked C# compilation do so now
if (!hasLockedUnityCompilation)
{
hasLockedUnityCompilation = true;
EditorApplication.LockReloadAssemblies();
}
RemoveFromPendingCompilationStack(inkFile);
if(GetCompilationStackItem(inkFile) != null) {
UnityEngine.Debug.LogWarning("Tried compiling ink file, but file is already compiling. "+inkFile.filePath);
return;
}
string inputPath = InkEditorUtils.CombinePaths(inkFile.absoluteFolderPath, Path.GetFileName(inkFile.filePath));
Debug.Assert(inkFile.absoluteFilePath == inputPath);
CompilationStackItem pendingFile = new CompilationStackItem
{
inkFile = InkLibrary.GetInkFileWithAbsolutePath(inputPath),
inkAbsoluteFilePath = inputPath,
jsonAbsoluteFilePath = inkFile.absoluteJSONPath,
state = CompilationStackItem.State.Queued,
immediate = immediate
};
AddToCompilationStack(pendingFile);
TryCompileNextFileInStack();
}
private static void TryCompileNextFileInStack () {
if(!compiling) return;
InkCompiler.CompilationStackItem fileToCompile = null;
foreach(var x in instance.compilationStack) {
if(x.state == CompilationStackItem.State.Compiling) return;
if(x.state == CompilationStackItem.State.Queued) {
fileToCompile = x;
break;
}
}
if(fileToCompile != null) {
if(fileToCompile.immediate) {
CompileInkThreaded(fileToCompile);
} else {
if(EditorApplication.isCompiling) Debug.LogWarning("Was compiling scripts when ink compilation started! This seems to cause the thread to cancel and complete, but the work isn't done. It may cause a timeout.");
ThreadPool.QueueUserWorkItem(CompileInkThreaded, fileToCompile);
}
} else {
}
}
private static void BeginCompilingFile(CompilationStackItem item) {
if(item.state != CompilationStackItem.State.Queued) return;
item.state = CompilationStackItem.State.Compiling;
item.startTime = DateTime.Now;
}
private static void CompleteCompilingFile(CompilationStackItem item) {
if(item.state != CompilationStackItem.State.Compiling) return;
item.state = CompilationStackItem.State.Complete;
item.endTime = DateTime.Now;
if (item.timeTaken > InkSettings.instance.compileTimeout * 0.6f)
Debug.LogWarning ("Compilation for "+Path.GetFileName(item.inkFile.filePath)+" took over 60% of the time required to timeout the compiler. Consider increasing the compile timeout on the InkSettings file.");
}
private static void CompileInkThreaded(object itemObj) {
CompilationStackItem item = (CompilationStackItem) itemObj;
if(item.state == CompilationStackItem.State.Compiling) {
Debug.LogWarning("CompileInkThreaded was called on a file that is already compiling! This is most likely a threading bug. Please report this!");
return;
}
BeginCompilingFile(item);
var inputString = File.ReadAllText(item.inkAbsoluteFilePath);
var compiler = new Compiler(inputString, new Compiler.Options
{
countAllVisits = true,
fileHandler = new UnityInkFileHandler(Path.GetDirectoryName(item.inkAbsoluteFilePath)),
errorHandler = (string message, ErrorType type) => {
InkCompilerLog log;
if(InkCompilerLog.TryParse(message, out log)) {
if(string.IsNullOrEmpty(log.fileName)) log.fileName = Path.GetFileName(item.inkAbsoluteFilePath);
item.logOutput.Add(log);
} else {
Debug.LogWarning("Couldn't parse log "+message);
}
}
});
try
{
var compiledStory = compiler.Compile();
if (compiledStory != null)
item.compiledJson = compiledStory.ToJson();
}
catch (SystemException e)
{
item.unhandledErrorOutput.Add(string.Format(
"Ink Compiler threw exception \nError: {0}\n---- Trace ----\n{1}\n--------\n", e.Message,
e.StackTrace));
}
CompleteCompilingFile(item);
// This doesn't seem to execute when called in a thread, and I apparently don't have a bloody clue how threads work.
// If someone can make this work, I'd rather that TryCompileNextFileInStack ran directly after CompileInkThreaded finishes.
// I couldn't make it work, so I've put TryCompileNextFileInStack in Update instead. Bleh!
// TryCompileNextFileInStack();
}
// When all files in stack have been compiled. This is called via update because Process events run in another thread.
private static void DelayedComplete () {
if(NumFilesInCompilingStackInState(CompilationStackItem.State.Compiling) > 0) {
Debug.LogWarning("Delayed, but a file is now compiling! You can ignore this warning.");
return;
}
bool errorsFound = false;
StringBuilder filesCompiledLog = new StringBuilder("Files compiled:");
// Create and import compiled files
AssetDatabase.StartAssetEditing();
foreach (var compilingFile in instance.compilationStack) {
// Complete status is also set when an error occured, in these cases 'compiledJson' will be null so there's no import to process
if (compilingFile.compiledJson == null) continue;
// Write new compiled data to the file system
File.WriteAllText(compilingFile.jsonAbsoluteFilePath, compilingFile.compiledJson, Encoding.UTF8);
AssetDatabase.ImportAsset(compilingFile.inkFile.jsonPath);
}
AssetDatabase.StopAssetEditing();
foreach (var compilingFile in instance.compilationStack) {
// Load and store a reference to the compiled file
compilingFile.inkFile.FindCompiledJSONAsset();
filesCompiledLog.AppendLine().Append(compilingFile.inkFile.filePath);
filesCompiledLog.Append(string.Format(" ({0}s)", compilingFile.timeTaken));
if(compilingFile.unhandledErrorOutput.Count > 0) {
filesCompiledLog.Append(" (With unhandled error)");
StringBuilder errorLog = new StringBuilder ();
errorLog.Append ("Unhandled error(s) occurred compiling Ink file ");
errorLog.Append ("'");
errorLog.Append (compilingFile.inkFile.filePath);
errorLog.Append ("'");
errorLog.AppendLine ("! Please report following error(s) as a bug:");
foreach (var error in compilingFile.unhandledErrorOutput)
errorLog.AppendLine (error);
Debug.LogError(errorLog);
compilingFile.inkFile.unhandledCompileErrors = compilingFile.unhandledErrorOutput;
errorsFound = true;
} else {
SetOutputLog(compilingFile);
bool errorsInEntireStory = false;
bool warningsInEntireStory = false;
foreach(var inkFile in compilingFile.inkFile.inkFilesInIncludeHierarchy) {
if(inkFile.hasErrors) {
errorsInEntireStory = true;
}
if(inkFile.hasWarnings) {
warningsInEntireStory = true;
}
}
if(errorsInEntireStory) {
filesCompiledLog.Append(" (With error)");
errorsFound = true;
}
if(warningsInEntireStory) {
filesCompiledLog.Append(" (With warning)");
}
}
}
foreach (var compilingFile in instance.compilationStack) {
if (OnCompileInk != null) {
OnCompileInk (compilingFile.inkFile);
}
}
StringBuilder outputLog = new StringBuilder ();
if(errorsFound) {
outputLog.Append ("Ink compilation completed with errors at ");
outputLog.AppendLine (DateTime.Now.ToLongTimeString ());
outputLog.Append (filesCompiledLog.ToString());
Debug.LogError(outputLog);
} else {
outputLog.Append ("Ink compilation completed at ");
outputLog.AppendLine (DateTime.Now.ToLongTimeString ());
outputLog.Append (filesCompiledLog.ToString());
Debug.Log(outputLog);
}
ClearCompilationStack();
#if !UNITY_EDITOR_LINUX
EditorUtility.ClearProgressBar();
#endif
#if UNITY_2019_4_OR_NEWER
if(InkEditorUtils.disallowedAutoRefresh) {
InkEditorUtils.disallowedAutoRefresh = false;
try {
AssetDatabase.AllowAutoRefresh();
} catch (Exception e) {
Debug.LogWarning("Failed AllowAutoRefresh "+e);
}
}
#endif
// This is now allowed, if compiled manually. I've left this code commented out because at some point we might want to track what caused a file to compile.
// if(EditorApplication.isPlayingOrWillChangePlaymode && InkSettings.instance.delayInPlayMode) {
// Debug.LogError("Ink just finished recompiling while in play mode. This should never happen when InkSettings.instance.delayInPlayMode is true!");
// }
buildBlocked = false;
if(playModeBlocked) {
playModeBlocked = false;
if(!errorsFound) {
// Delaying gives the editor a frame to clear the progress bar.
EditorApplication.delayCall += () => {
Debug.Log("Compilation completed, entering play mode.");
EditorApplication.isPlaying = true;
};
} else {
Debug.LogWarning("Play mode not entered after ink compilation because ink had errors.");
}
}
foreach(var onCompleteAction in onCompleteActions) {
if(onCompleteAction != null) onCompleteAction();
}
onCompleteActions.Clear();
}
private static void SetOutputLog (CompilationStackItem pendingFile) {
pendingFile.inkFile.errors.Clear();
pendingFile.inkFile.warnings.Clear();
pendingFile.inkFile.todos.Clear();
foreach(var childInkFile in pendingFile.inkFile.inkFilesInIncludeHierarchy) {
childInkFile.unhandledCompileErrors.Clear();
childInkFile.errors.Clear();
childInkFile.warnings.Clear();
childInkFile.todos.Clear();
}
foreach(var output in pendingFile.logOutput) {
if(output.type == ErrorType.Error) {
pendingFile.inkFile.errors.Add(output);
Debug.LogError("Ink "+output.type+": "+output.content + " (at "+output.fileName+":"+output.lineNumber+")", pendingFile.inkFile.inkAsset);
} else if (output.type == ErrorType.Warning) {
pendingFile.inkFile.warnings.Add(output);
Debug.LogWarning("Ink "+output.type+": "+output.content + " (at "+output.fileName+" "+output.lineNumber+")", pendingFile.inkFile.inkAsset);
} else if (output.type == ErrorType.Author) {
pendingFile.inkFile.todos.Add(output);
if(InkSettings.instance.printInkLogsInConsoleOnCompile)
Debug.Log("Ink Log: "+output.content + " (at "+output.fileName+" "+output.lineNumber+")", pendingFile.inkFile.inkAsset);
}
}
}
public static List<InkFile> GetUniqueMasterInkFilesToCompile (List<string> importedInkAssets) {
List<InkFile> masterInkFiles = new List<InkFile>();
foreach (var importedAssetPath in importedInkAssets) {
foreach(var masterInkFile in GetMasterFilesIncludingInkAssetPath(importedAssetPath)) {
if (!masterInkFiles.Contains(masterInkFile) && (InkSettings.instance.compileAutomatically || masterInkFile.compileAutomatically)) {
masterInkFiles.Add(masterInkFile);
}
}
}
return masterInkFiles;
}
// An ink file might actually have several owners! This should be reflected here.
public static IEnumerable<InkFile> GetMasterFilesIncludingInkAssetPath (string importedAssetPath) {
InkFile inkFile = InkLibrary.GetInkFileWithPath(importedAssetPath);
// Trying to catch a rare (and not especially important) bug that seems to happen occasionally when opening a project
// It's probably this - I've noticed it before in another context.
Debug.Assert(InkSettings.instance != null, "No ink settings file. This is a bug. For now you should be able to fix this via Assets > Rebuild Ink Library");
// I've caught it here before
Debug.Assert(inkFile != null, "No internal InkFile reference at path "+importedAssetPath+". This is a bug. For now you can fix this via Assets > Rebuild Ink Library");
Debug.Assert(inkFile != null);
return inkFile.masterInkFilesIncludingSelf;
}
public static void AddToCompilationStack (InkCompiler.CompilationStackItem compilationStackItem) {
if(!instance.compilationStack.Contains(compilationStackItem)) {
instance.compilationStack.Add(compilationStackItem);
instance.Save(true);
}
}
public static void ClearCompilationStack () {
if(instance.compilationStack.Count != 0) {
instance.compilationStack.Clear();
instance.Save(true);
}
}
public static void AddToPendingCompilationStack (string filePath) {
if(!instance.pendingCompilationStack.Contains(filePath)) {
instance.pendingCompilationStack.Add(filePath);
instance.Save(true);
}
}
public static void RemoveFromPendingCompilationStack (InkFile inkFile) {
bool anyChange = false;
anyChange = instance.pendingCompilationStack.Remove(inkFile.filePath) || anyChange;
foreach(var includeFile in inkFile.inkFilesInIncludeHierarchy) {
anyChange = instance.pendingCompilationStack.Remove(includeFile.filePath) || anyChange;
}
if(anyChange)
instance.Save(true);
}
public static void ClearCompilationStacks () {
instance.compilationStack.Clear();
instance.pendingCompilationStack.Clear();
instance.Save(true);
}
public static int NumFilesInCompilingStackInState (InkCompiler.CompilationStackItem.State state) {
int count = 0;
foreach(var x in instance.compilationStack) {
if(x.state == state)
count++;
}
return count;
}
public static List<InkCompiler.CompilationStackItem> FilesInCompilingStackInState (InkCompiler.CompilationStackItem.State state) {
List<InkCompiler.CompilationStackItem> items = new List<InkCompiler.CompilationStackItem>();
foreach(var x in instance.compilationStack) {
if(x.state == state)
items.Add(x);
}
return items;
}
public static InkCompiler.CompilationStackItem GetCompilationStackItem (InkFile inkFile) {
foreach(var x in instance.compilationStack) {
if(x.inkFile == inkFile)
return x;
}
return null;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 430cb8f71c23c438cb8b0ce85cc80fa6
timeCreated: 1459463931
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
using Ink;
using System.IO;
// Utility class for the ink compiler, used to work out how to find include files and their contents
public class UnityInkFileHandler : IFileHandler {
private readonly string rootDirectory;
public UnityInkFileHandler(string rootDirectory)
{
this.rootDirectory = rootDirectory;
}
public string ResolveInkFilename(string includeName)
{
// Convert to Unix style, and then use FileInfo.FullName to parse any ..\
return new FileInfo(Path.Combine(rootDirectory, includeName).Replace('\\', '/')).FullName;
}
public string LoadInkFileContents(string fullFilename)
{
return File.ReadAllText(fullFilename);
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2de904d59497c1c47b0792de1a85faf6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c547bc1dd015a497cb998538d42d2340
folderAsset: yes
timeCreated: 1459878666
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,58 @@
using System.Text.RegularExpressions;
using Debug = UnityEngine.Debug;
namespace Ink.UnityIntegration
{
[System.Serializable]
public class InkCompilerLog {
public Ink.ErrorType type;
public string content;
public string fileName;
public int lineNumber;
public InkCompilerLog (Ink.ErrorType type, string content, string fileName, int lineNumber = -1) {
this.type = type;
this.content = content;
this.fileName = fileName;
this.lineNumber = lineNumber;
}
public static bool TryParse (string rawLog, out InkCompilerLog log) {
var match = _errorRegex.Match(rawLog);
if (match.Success) {
Ink.ErrorType errorType = Ink.ErrorType.Author;
string filename = null;
int lineNo = -1;
string message = null;
var errorTypeCapture = match.Groups["errorType"];
if( errorTypeCapture != null ) {
var errorTypeStr = errorTypeCapture.Value;
if(errorTypeStr == "AUTHOR" || errorTypeStr == "TODO") errorType = Ink.ErrorType.Author;
else if(errorTypeStr == "WARNING") errorType = Ink.ErrorType.Warning;
else if(errorTypeStr == "ERROR") errorType = Ink.ErrorType.Error;
else Debug.LogWarning("Could not parse error type from "+errorTypeStr);
}
var filenameCapture = match.Groups["filename"];
if (filenameCapture != null)
filename = filenameCapture.Value;
var lineNoCapture = match.Groups["lineNo"];
if (lineNoCapture != null)
lineNo = int.Parse (lineNoCapture.Value);
var messageCapture = match.Groups["message"];
if (messageCapture != null)
message = messageCapture.Value.Trim();
log = new InkCompilerLog(errorType, message, filename, lineNo);
return true;
} else {
Debug.LogWarning("Could not parse InkFileLog from log: "+rawLog);
log = null;
return false;
}
}
private static Regex _errorRegex = new Regex(@"(?<errorType>ERROR|WARNING|TODO):(?:\s(?:'(?<filename>[^']*)'\s)?line (?<lineNo>\d+):)?(?<message>.*)");
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2af758247ca160446b0727c6e91632cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,371 @@
using UnityEngine;
using UnityEditor;
using System.IO;
using Debug = UnityEngine.Debug;
using System.Collections.Generic;
using System;
using System.Text;
using System.Text.RegularExpressions;
namespace Ink.UnityIntegration {
// Helper class for ink files that maintains INCLUDE connections between ink files
[System.Serializable]
public class InkFile {
public bool compileAutomatically = false;
// A reference to the ink file
public DefaultAsset inkAsset;
//specify json destination folder (if None, default to same folder as ink file)
public DefaultAsset jsonAssetDirectory;
// The compiled json file. Use this to start a story.
public TextAsset jsonAsset;
// The file path relative to the Assets folder (Assets/Ink/Story.ink)
public string filePath {
get {
if(inkAsset == null)
return null;
return InkEditorUtils.SanitizePathString(AssetDatabase.GetAssetPath(inkAsset));
}
}
// The full file path (C:/Users/Inkle/HeavensVault/Assets/Ink/Story.ink)
public string absoluteFilePath {
get {
if(inkAsset == null)
return null;
return InkEditorUtils.UnityRelativeToAbsolutePath(filePath);
}
}
public string absoluteFolderPath {
get {
return InkEditorUtils.SanitizePathString(Path.GetDirectoryName(absoluteFilePath));
}
}
// The path of any compiled json file. Relative to assets folder.
public string jsonPath {
get {
var _filePath = filePath;
Debug.Assert(_filePath != null, "File path for ink file is null! The ink library requires rebuilding.");
DefaultAsset jsonFolder = jsonAssetDirectory;
if (jsonFolder == null) // no path specified for this specific file
{
if(InkSettings.instance.defaultJsonAssetPath != null)
{
// use default path in InkSettings
jsonFolder = InkSettings.instance.defaultJsonAssetPath;
}
if (jsonFolder == null)
{
//fallback to same folder as .ink file
jsonFolder = AssetDatabase.LoadAssetAtPath<DefaultAsset>(Path.GetDirectoryName(_filePath));
}
}
Debug.Assert(jsonFolder != null, "JSON folder not found for ink file at path "+_filePath);
string jsonPath = AssetDatabase.GetAssetPath(jsonFolder);
string strJsonAssetPath = InkEditorUtils.CombinePaths(jsonPath, Path.GetFileNameWithoutExtension(_filePath)) + ".json";
return strJsonAssetPath;
}
}
public string absoluteJSONPath {
get {
if(inkAsset == null)
return null;
return InkEditorUtils.UnityRelativeToAbsolutePath(jsonPath);
}
}
// Fatal unhandled errors that should be reported as compiler bugs.
public List<string> unhandledCompileErrors = new List<string>();
public bool hasUnhandledCompileErrors {
get {
return unhandledCompileErrors.Count > 0;
}
}
// Fatal errors caused by errors in the user's ink script.
public List<InkCompilerLog> errors = new List<InkCompilerLog>();
public bool hasErrors {
get {
return errors.Count > 0;
}
}
public List<InkCompilerLog> warnings = new List<InkCompilerLog>();
public bool hasWarnings {
get {
return warnings.Count > 0;
}
}
public List<InkCompilerLog> todos = new List<InkCompilerLog>();
public bool hasTodos {
get {
return todos.Count > 0;
}
}
public bool requiresCompile {
get {
if(!isMaster) return false;
return jsonAsset == null || lastEditDate > lastCompileDate || hasUnhandledCompileErrors;
}
}
/// <summary>
/// Gets the last compile date of the story.
/// </summary>
/// <value>The last compile date of the story.</value>
public DateTime lastCompileDate {
get {
if(isMaster) {
string fullJSONFilePath = InkEditorUtils.UnityRelativeToAbsolutePath(AssetDatabase.GetAssetPath(jsonAsset));
return File.GetLastWriteTime(fullJSONFilePath);
} else {
return default(DateTime);
}
}
}
/// <summary>
/// Gets the last edit date of the file.
/// </summary>
/// <value>The last edit date of the file.</value>
public DateTime lastEditDate {
get {
return File.GetLastWriteTime(absoluteFilePath);
}
}
// File that contains this file as an include, if one exists.
public List<DefaultAsset> parents;
public IEnumerable<InkFile> parentInkFiles {
get {
if(parents != null && parents.Count != 0) {
foreach(var parentInkAsset in parents) {
yield return InkLibrary.GetInkFileWithFile(parentInkAsset);
}
}
}
}
// Is this ink file a parent file?
public bool isParent {
get {
return includes.Count > 0;
}
}
public List<DefaultAsset> masterInkAssets;
public IEnumerable<InkFile> masterInkFiles {
get {
if(masterInkAssets != null && masterInkAssets.Count != 0) {
foreach(var masterInkAsset in masterInkAssets) {
yield return InkLibrary.GetInkFileWithFile(masterInkAsset);
}
}
}
}
public IEnumerable<InkFile> masterInkFilesIncludingSelf {
get {
if(isMaster) yield return this;
else {
foreach(var masterInkFile in masterInkFiles) {
yield return masterInkFile;
}
}
}
}
public DefaultAsset masterInkAsset;
// Is this ink file a master file?
public bool isMaster {
get {
return masterInkAssets == null || masterInkAssets.Count == 0;
}
}
// The files included by this file
// We cache the paths of the files to be included for performance, giving us more freedom to refresh the actual includes list without needing to parse all the text.
public List<string> includePaths = new List<string>();
public List<DefaultAsset> includes = new List<DefaultAsset>();
// The InkFiles of the includes of this file
public List<InkFile> includesInkFiles {
get {
List<InkFile> _includesInkFiles = new List<InkFile>();
foreach(var child in includes) {
if(child == null) {
Debug.LogError("Error compiling ink: Ink file include in "+filePath+" is null.", inkAsset);
continue;
}
_includesInkFiles.Add(InkLibrary.GetInkFileWithFile(child));
}
return _includesInkFiles;
}
}
// The InkFiles in the include hierarchy of this file.
public List<InkFile> inkFilesInIncludeHierarchy {
get {
List<InkFile> _inkFilesInIncludeHierarchy = new List<InkFile>();
_inkFilesInIncludeHierarchy.Add(this);
foreach(var child in includesInkFiles) {
if (child == null)
return null;
_inkFilesInIncludeHierarchy.AddRange(child.inkFilesInIncludeHierarchy);
}
return _inkFilesInIncludeHierarchy;
}
}
public InkFile (DefaultAsset inkAsset) {
Debug.Assert(inkAsset != null);
this.inkAsset = inkAsset;
ParseContent();
}
public void FindCompiledJSONAsset () {
Debug.Assert(inkAsset != null);
jsonAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(jsonPath);
}
// public string content;
// The contents of the .ink file
public string GetFileContents () {
if(inkAsset == null) {
Debug.LogWarning("Ink file asset is null! Rebuild library using Assets > Rebuild Ink Library");
return "";
}
return File.ReadAllText(absoluteFilePath);
}
public void ParseContent () {
includePaths.Clear();
includePaths.AddRange(InkIncludeParser.ParseIncludes(GetFileContents()));
}
public void FindIncludedFiles (bool addMissing = false) {
includes.Clear();
foreach(string includePath in includePaths) {
string localIncludePath = InkEditorUtils.CombinePaths(Path.GetDirectoryName(filePath), includePath);
// This enables parsing ..\ and the like. Can we use Path.GetFullPath instead?
var fullIncludePath = new FileInfo(localIncludePath).FullName;
localIncludePath = InkEditorUtils.AbsoluteToUnityRelativePath(fullIncludePath);
DefaultAsset includedInkFileAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(localIncludePath);
if(includedInkFileAsset == null) {
Debug.LogError(filePath+ " expected child .ink asset at '"+localIncludePath+"' but file was not found.", inkAsset);
} else {
InkFile includedInkFile = InkLibrary.GetInkFileWithFile(includedInkFileAsset, addMissing);
if(includedInkFile == null) {
Debug.LogError(filePath+ " expected child InkFile from .ink asset at '"+localIncludePath+"' but file was not found.", inkAsset);
} else if (includedInkFile.includes.Contains(inkAsset)) {
Debug.LogError("Circular INCLUDE reference between '"+filePath+"' and '"+includedInkFile.filePath+"'.", inkAsset);
} else
includes.Add(includedInkFileAsset);
}
}
}
public static class InkIncludeParser {
static Regex _includeRegex;
static Regex includeRegex {
get {
if(_includeRegex == null) {
_includeRegex = new Regex (@"^\s*INCLUDE\s+([^\r\n]+)\r*$", RegexOptions.Multiline);
}
return _includeRegex;
}
}
public static IEnumerable<string> ParseIncludes (string inkContents) {
return FindIncludes (EliminateComments(inkContents));
}
static string EliminateComments(string inkStr) {
var sb = new StringBuilder ();
int idx = 0;
while(idx < inkStr.Length) {
var commentStarterIdx = inkStr.IndexOf ('/', idx);
// Final string?
if (commentStarterIdx == -1 || commentStarterIdx >= inkStr.Length-2 ) {
sb.Append (inkStr.Substring (idx, inkStr.Length - idx));
break;
}
sb.Append (inkStr.Substring (idx, commentStarterIdx - idx));
var commentStarter = inkStr.Substring (commentStarterIdx, 2);
if (commentStarter == "//" || commentStarter == "/*") {
int endOfCommentIdx = -1;
// Single line comments
if (commentStarter == "//") {
endOfCommentIdx = inkStr.IndexOf ('\n', commentStarterIdx);
if (endOfCommentIdx == -1)
endOfCommentIdx = inkStr.Length;
else if (inkStr [endOfCommentIdx - 1] == '\r')
endOfCommentIdx = endOfCommentIdx - 1;
}
// Block comments
else if (commentStarter == "/*") {
endOfCommentIdx = inkStr.IndexOf ("*/", idx);
if (endOfCommentIdx == -1)
endOfCommentIdx = inkStr.Length;
else
endOfCommentIdx += 2;
// If there are *any* newlines, we should add one in here,
// so that lines are spit up correctly
if (inkStr.IndexOf ('\n', commentStarterIdx, endOfCommentIdx - commentStarterIdx) != -1)
sb.Append ("\n");
}
// Skip over comment
if (endOfCommentIdx > -1)
idx = endOfCommentIdx;
}
// Normal slash we need, not a comment
else {
sb.Append ("/");
idx = commentStarterIdx + 1;
}
}
return sb.ToString ();
}
static IEnumerable<string> FindIncludes(string str) {
MatchCollection matches = includeRegex.Matches(str);
foreach (Match match in matches)
{
var capture = match.Groups [1].Captures [0];
yield return capture.Value;
}
}
}
public override string ToString () {
return string.Format ("[InkFile: filePath={0}]", filePath);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b497ccd4b61cb4fee8b8f0ce86302e83
timeCreated: 1459464092
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,475 @@
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
/// <summary>
/// Holds a reference to an InkFile object for every .ink file detected in the Assets folder.
/// Provides helper functions to easily obtain these files.
/// </summary>
namespace Ink.UnityIntegration {
#if UNITY_2020_1_OR_NEWER
[FilePath("Library/InkLibrary.asset", FilePathAttribute.Location.ProjectFolder)]
public class InkLibrary : ScriptableSingleton<InkLibrary>, IEnumerable<InkFile> {
#else
public class InkLibrary : ScriptableObject, IEnumerable<InkFile> {
#endif
//
public static System.Version inkVersionCurrent = new System.Version(1,0,0);
public static System.Version unityIntegrationVersionCurrent = new System.Version(1,0,0);
static string absoluteSavePath {
get {
return System.IO.Path.GetFullPath(System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(),"Library","InkLibrary.asset"));
}
}
#if !UNITY_2020_1_OR_NEWER
public static bool created {
get {
// If it's null, there's no InkLibrary loaded
return (_instance != (Object) null);
}
}
private static InkLibrary _instance;
public static InkLibrary instance {
get {
if(!created)
LoadOrCreateInstance();
return _instance;
} private set {
if(_instance == value) return;
_instance = value;
}
}
// This occurs on recompile, creation and load (note that data has not necessarily been loaded at this point!)
protected InkLibrary () {
if (created)
Debug.LogError((object) "ScriptableSingleton already exists. Did you query the singleton in a constructor?");
else {
instance = this;
}
}
public static void LoadOrCreateInstance () {
InternalEditorUtility.LoadSerializedFileAndForget(absoluteSavePath);
if(created) {
if(InkEditorUtils.isFirstCompile) {
Validate();
}
} else {
instance = ScriptableObject.CreateInstance<InkLibrary>();
instance.hideFlags = HideFlags.HideAndDontSave;
Rebuild();
instance.Save(true);
}
}
public void Save (bool saveAsText) {
if(!created) return;
InternalEditorUtility.SaveToSerializedFileAndForget((Object[]) new InkLibrary[1] {instance}, absoluteSavePath, saveAsText);
}
static void EnsureCreated () {
if(!created) LoadOrCreateInstance();
}
#endif
public class AssetSaver : UnityEditor.AssetModificationProcessor {
static string[] OnWillSaveAssets(string[] paths) {
instance.Save(true);
return paths;
}
}
public List<InkFile> inkLibrary = new List<InkFile>();
Dictionary<DefaultAsset, InkFile> inkLibraryDictionary;
public int Count {
get {
return inkLibrary.Count;
}
}
public InkFile this[int key] {
get {
return inkLibrary[key];
} set {
inkLibrary[key] = value;
}
}
IEnumerator<InkFile> IEnumerable<InkFile>.GetEnumerator() {
return inkLibrary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return inkLibrary.GetEnumerator();
}
void OnValidate () {
BuildLookupDictionary();
Validate();
}
// After recompile, the data associated with the object is fetched (or whatever happens to it) by this point.
void OnEnable () {
// Deletes the persistent version of this asset that we used to use prior to 0.9.71
if(!Application.isPlaying && EditorUtility.IsPersistent(this)) {
var path = AssetDatabase.GetAssetPath(this);
if(!string.IsNullOrEmpty(path)) {
#if !UNITY_2020_1_OR_NEWER
if(_instance == this) _instance = null;
#endif
AssetDatabase.DeleteAsset(path);
AssetDatabase.Refresh();
return;
}
}
}
static void BuildLookupDictionary () {
if(instance.inkLibraryDictionary == null) instance.inkLibraryDictionary = new Dictionary<DefaultAsset, InkFile>();
else instance.inkLibraryDictionary.Clear();
foreach(var inkFile in instance.inkLibrary) {
instance.inkLibraryDictionary.Add(inkFile.inkAsset, inkFile);
}
}
/// <summary>
/// Checks if the library is corrupt and rebuilds if necessary. Returns true if the library was valid
/// </summary>
public static bool Validate () {
if(RequiresRebuild()) {
Rebuild();
Debug.LogWarning("InkLibrary was invalid and has been rebuilt. This can occur if files are moved/deleted while the editor is closed. You can ignore this warning.");
return false;
} else {
return true;
}
}
/// <summary>
/// Checks if the library is corrupt and requires a Rebuild.
/// This can happen when asset IDs change, causing the wrong file to be referenced.
/// This occassionally occurs from source control.
/// This is a fairly performant check.
/// </summary>
static bool RequiresRebuild () {
#if !UNITY_2020_1_OR_NEWER
EnsureCreated();
#endif
foreach(var inkFile in instance.inkLibrary) {
if(inkFile == null) {
return true;
}
if(inkFile.inkAsset == null) {
return true;
}
if(!instance.inkLibraryDictionary.ContainsKey(inkFile.inkAsset)) {
return true;
}
if(inkFile.inkAsset == null) {
return true;
}
foreach(var include in inkFile.includes) {
if(include == null) {
return true;
}
if(!instance.inkLibraryDictionary.ContainsKey(include)) {
return true;
}
}
}
return false;
}
/// <summary>
/// Removes and null references in the library
/// </summary>
public static bool Clean () {
bool wasDirty = false;
for (int i = instance.Count - 1; i >= 0; i--) {
InkFile inkFile = InkLibrary.instance[i];
if (inkFile.inkAsset == null) {
InkLibrary.RemoveAt(i);
wasDirty = true;
}
}
return wasDirty;
}
public static void Add (InkFile inkFile) {
instance.inkLibrary.Add(inkFile);
SortInkLibrary();
instance.inkLibraryDictionary.Add(inkFile.inkAsset, inkFile);
}
public static void RemoveAt (int index) {
var inkFile = instance.inkLibrary[index];
instance.inkLibrary.RemoveAt(index);
instance.inkLibraryDictionary.Remove(inkFile.inkAsset);
}
static void SortInkLibrary () {
instance.inkLibrary = instance.inkLibrary.OrderBy(x => x.filePath).ToList();
}
/// <summary>
/// Updates the ink library. Executed whenever an ink file is changed by InkToJSONPostProcessor
/// Can be called manually, but incurs a performance cost.
/// </summary>
public static void Rebuild () {
// Disable the asset post processor in case any assetdatabase functions called as a result of this would cause further operations.
InkPostProcessor.disabled = true;
// Remove any old file connections
Clean();
// Reset the asset name
instance.name = "Ink Library "+unityIntegrationVersionCurrent.ToString();
// Add any new file connections (if any are found it replaces the old library entirely)
string[] inkFilePaths = GetAllInkFilePaths();
bool inkLibraryChanged = false;
List<InkFile> newInkLibrary = new List<InkFile>(inkFilePaths.Length);
for (int i = 0; i < inkFilePaths.Length; i++) {
InkFile inkFile = GetInkFileWithAbsolutePath(inkFilePaths [i]);
// If the ink library doesn't have a representation for this file, then make one
if(inkFile == null) {
inkLibraryChanged = true;
string localAssetPath = InkEditorUtils.AbsoluteToUnityRelativePath(inkFilePaths [i]);
DefaultAsset inkFileAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(localAssetPath);
// If the ink file can't be found, it might not yet have been imported. We try to manually import it to fix this.
if(inkFileAsset == null) {
AssetDatabase.ImportAsset(localAssetPath);
inkFileAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(localAssetPath);
if(inkFileAsset == null) {
Debug.LogWarning("Ink File Asset not found at "+localAssetPath+". This can occur if the .meta file has not yet been created. This issue should resolve itself, but if unexpected errors occur, rebuild Ink Library using Assets > Recompile Ink");
continue;
}
}
inkFile = new InkFile(inkFileAsset);
}
newInkLibrary.Add(inkFile);
}
if(inkLibraryChanged) {
instance.inkLibrary = newInkLibrary;
SortInkLibrary();
}
BuildLookupDictionary();
RebuildInkFileConnections();
foreach (InkFile inkFile in instance.inkLibrary) inkFile.FindCompiledJSONAsset();
instance.Save(true);
// Re-enable the ink asset post processor
InkPostProcessor.disabled = false;
Debug.Log("Ink Library was rebuilt.");
}
public static void CreateOrReadUpdatedInkFiles (List<string> importedInkAssets) {
foreach (var importedAssetPath in importedInkAssets) {
InkFile inkFile = InkLibrary.GetInkFileWithPath(importedAssetPath);
if(inkFile == null) {
DefaultAsset asset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(importedAssetPath);
inkFile = new InkFile(asset);
Add(inkFile);
} else {
inkFile.ParseContent();
}
}
// Now we've updated all the include paths for the ink library we can create master/child references between them.
RebuildInkFileConnections();
}
// Finds absolute file paths of all the ink files in Application.dataPath
private static string[] GetAllInkFilePaths () {
string[] inkFilePaths = Directory.GetFiles(Application.dataPath, "*.ink", SearchOption.AllDirectories);
for (int i = 0; i < inkFilePaths.Length; i++) {
inkFilePaths [i] = InkEditorUtils.SanitizePathString(inkFilePaths [i]);
}
return inkFilePaths;
}
// All the master files
public static IEnumerable<InkFile> GetMasterInkFiles () {
if(instance.inkLibrary == null) yield break;
foreach (InkFile inkFile in instance.inkLibrary) {
if(inkFile.isMaster)
yield return inkFile;
}
}
// All the master files which are dirty and are set to compile
public static IEnumerable<InkFile> GetFilesRequiringRecompile () {
foreach(InkFile inkFile in InkLibrary.GetMasterInkFiles ()) {
if(inkFile.requiresCompile && (InkSettings.instance.compileAutomatically || inkFile.compileAutomatically))
yield return inkFile;
}
}
// All the master files which are set to compile
public static IEnumerable<InkFile> FilesCompiledByRecompileAll () {
foreach(InkFile inkFile in InkLibrary.GetMasterInkFiles ()) {
if(InkSettings.instance.compileAutomatically || inkFile.compileAutomatically)
yield return inkFile;
}
}
/// <summary>
/// Gets the ink file from the .ink file reference.
/// </summary>
/// <returns>The ink file with path.</returns>
/// <param name="file">File asset.</param>
/// <param name="addIfMissing">Adds the file if missing from inkLibrary.</param>
public static InkFile GetInkFileWithFile (DefaultAsset file, bool addIfMissing = false) {
if(instance.inkLibrary == null) return null;
if (!file) {
Debug.LogError("Can't add null file.");
return null;
}
if(instance.inkLibraryDictionary == null) {
Debug.LogWarning("GetInkFileWithFile: inkLibraryDictionary was null! This should never occur, but is handled following a user reported bug. If this has never been seen long after 12/08/2020, it can be safely removed");
BuildLookupDictionary();
}
foreach(InkFile inkFile in instance.inkLibrary) {
if(inkFile.inkAsset == file) {
return inkFile;
}
}
if (addIfMissing) {
InkFile newFile = new InkFile(file);
instance.inkLibrary.Add(newFile);
Debug.Log(file + " missing from ink library. Adding it now.");
return newFile;
}
System.Text.StringBuilder listOfFiles = new System.Text.StringBuilder();
foreach(InkFile inkFile in instance.inkLibrary) {
listOfFiles.AppendLine(inkFile.ToString());
}
Debug.LogWarning (file + " missing from ink library. Please rebuild.\n"+listOfFiles);
return null;
}
/// <summary>
/// Gets the ink file with path relative to Assets folder, for example: "Assets/Ink/myStory.ink".
/// </summary>
/// <returns>The ink file with path.</returns>
/// <param name="path">Path.</param>
public static InkFile GetInkFileWithPath (string path) {
if(instance.inkLibrary == null) return null;
foreach(InkFile inkFile in instance.inkLibrary) {
if(inkFile.filePath == path) {
return inkFile;
}
}
return null;
}
/// <summary>
/// Gets the ink file with absolute path.
/// </summary>
/// <returns>The ink file with path.</returns>
/// <param name="path">Path.</param>
public static InkFile GetInkFileWithAbsolutePath (string absolutePath) {
if(instance.inkLibrary == null) return null;
foreach(InkFile inkFile in instance.inkLibrary) {
if(inkFile.absoluteFilePath == absolutePath) {
return inkFile;
}
}
return null;
}
/// <summary>
/// Rebuilds which files are master files and the connections between the files.
/// </summary>
public static void RebuildInkFileConnections () {
Queue<InkFile> inkFileQueue = new Queue<InkFile>(instance.inkLibrary);
while (inkFileQueue.Count > 0) {
InkFile inkFile = inkFileQueue.Dequeue();
inkFile.parents = new List<DefaultAsset>();
inkFile.masterInkAssets = new List<DefaultAsset>();
inkFile.ParseContent();
inkFile.FindIncludedFiles(true);
foreach (InkFile includedInkFile in inkFile.includesInkFiles) {
if (!inkFileQueue.Contains(includedInkFile)) {
inkFileQueue.Enqueue(includedInkFile);
}
}
}
// We now set the master file for ink files. As a file can be in an include hierarchy, we need to do this in two passes.
// First, we set the master file to the file that includes an ink file.
foreach (InkFile inkFile in instance.inkLibrary) {
if(inkFile.includes.Count == 0)
continue;
foreach (InkFile otherInkFile in instance.inkLibrary) {
if(inkFile == otherInkFile)
continue;
if(inkFile.includes.Contains(otherInkFile.inkAsset)) {
if(!otherInkFile.parents.Contains(inkFile.inkAsset)) {
otherInkFile.parents.Add(inkFile.inkAsset);
}
}
}
}
// Next, we create a list of all the files owned by the actual master file, which we obtain by travelling up the parent tree from each file.
Dictionary<InkFile, List<InkFile>> masterChildRelationships = new Dictionary<InkFile, List<InkFile>>();
foreach (InkFile inkFile in instance.inkLibrary) {
foreach(var parentInkFile in inkFile.parentInkFiles) {
InkFile lastMasterInkFile = parentInkFile;
InkFile masterInkFile = parentInkFile;
while (masterInkFile.parents.Count != 0) {
// This shouldn't just pick first, but iterate the whole lot!
// I didn't feel like writing a recursive algorithm until it's actually needed though - a file included by several parents is already a rare enough case!
masterInkFile = masterInkFile.parentInkFiles.First();
lastMasterInkFile = masterInkFile;
}
if(lastMasterInkFile.parents.Count > 1) {
Debug.LogError("The ink ownership tree has another master file that is not discovered! This is an oversight of the current implementation. If you requres this feature, please take a look at the comment in the code above - if you solve it let us know and we'll merge it in!");
}
if(!masterChildRelationships.ContainsKey(masterInkFile)) {
masterChildRelationships.Add(masterInkFile, new List<InkFile>());
}
masterChildRelationships[masterInkFile].Add(inkFile);
}
// if(inkFile.parent == null)
// continue;
// InkFile parent = inkFile.parentInkFile;
// while (parent.metaInfo.parent != null) {
// parent = parent.metaInfo.parentInkFile;
// }
// if(!masterChildRelationships.ContainsKey(parent)) {
// masterChildRelationships.Add(parent, new List<InkFile>());
// }
// masterChildRelationships[parent].Add(inkFile);
}
// Finally, we set the master file of the children
foreach (var inkFileRelationship in masterChildRelationships) {
foreach(InkFile childInkFile in inkFileRelationship.Value) {
if(!childInkFile.masterInkAssets.Contains(inkFileRelationship.Key.inkAsset)) {
childInkFile.masterInkAssets.Add(inkFileRelationship.Key.inkAsset);
} else {
Debug.LogWarning("Child file already contained master file reference! This is weird!");
}
if(InkSettings.instance.handleJSONFilesAutomatically && childInkFile.jsonAsset != null) {
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(childInkFile.jsonAsset));
childInkFile.jsonAsset = null;
}
}
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dc234ab28a32840f5adfb84a075bc023
timeCreated: 1485516445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6188b37f5f5824313b73fb964d1b269e
folderAsset: yes
timeCreated: 1459878666
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,114 @@
using UnityEngine;
using UnityEditor;
using Debug = UnityEngine.Debug;
/// <summary>
/// Holds a reference to an InkFile object for every .ink file detected in the Assets folder.
/// Provides helper functions to easily obtain these files.
/// </summary>
namespace Ink.UnityIntegration {
#if UNITY_2020_1_OR_NEWER
[FilePath("ProjectSettings/InkSettings.asset", FilePathAttribute.Location.ProjectFolder)]
public class InkSettings : ScriptableSingleton<InkSettings> {
#else
public class InkSettings : ScriptableObject {
#endif
#if !UNITY_2020_1_OR_NEWER
public static bool created {
get {
// If it's null, there's just no InkSettings asset in the project
return _instance != null;
}
}
static string absoluteSavePath {
get {
return System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath,"..","ProjectSettings","InkSettings.asset"));
}
}
public static void SaveStatic (bool saveAsText) {
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new[] { instance }, absoluteSavePath, saveAsText);
}
public void Save (bool saveAsText) {
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget((UnityEngine.Object[]) new InkSettings[1] {this}, absoluteSavePath, saveAsText);
}
private static InkSettings _instance;
public static InkSettings instance {
get {
if(_instance == null) {
Object[] objects = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(absoluteSavePath);
if (objects != null && objects.Length > 0) {
instance = objects[0] as InkSettings;
} else {
instance = ScriptableObject.CreateInstance<InkSettings>();
instance.Save(true);
}
}
return _instance;
} private set {
if(_instance == value) return;
_instance = value;
}
}
#else
public static void SaveStatic (bool saveAsText) {
instance.Save(saveAsText);
}
#endif
public class AssetSaver : UnityEditor.AssetModificationProcessor {
static string[] OnWillSaveAssets(string[] paths) {
InkSettings.instance.Save(true);
return paths;
}
}
public TextAsset templateFile;
public string templateFilePath {
get {
if(templateFile == null) return "";
else return AssetDatabase.GetAssetPath(templateFile);
}
}
public DefaultAsset defaultJsonAssetPath;
public bool compileAutomatically = true;
public bool delayInPlayMode = true;
public bool handleJSONFilesAutomatically = true;
public int compileTimeout = 30;
public bool printInkLogsInConsoleOnCompile;
#if UNITY_EDITOR && !UNITY_2018_1_OR_NEWER
[MenuItem("Edit/Project Settings/Ink", false, 500)]
public static void SelectFromProjectSettings() {
Selection.activeObject = instance;
}
#elif UNITY_EDITOR && UNITY_2018_1_OR_NEWER
public static SerializedObject GetSerializedSettings() {
return new SerializedObject(instance);
}
#endif
// Deletes the persistent version of this asset that we used to use prior to 0.9.71
void OnEnable () {
if(!Application.isPlaying && EditorUtility.IsPersistent(this)) {
var path = AssetDatabase.GetAssetPath(this);
if(!string.IsNullOrEmpty(path)) {
#if !UNITY_2020_1_OR_NEWER
if(_instance == this) _instance = null;
#endif
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(this));
AssetDatabase.Refresh();
return;
}
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 983af1b6602bf416b9928d40b37a38bd
timeCreated: 1485516445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,103 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace Ink.UnityIntegration {
[CustomEditor(typeof(InkSettings))]
public class InkSettingsEditor : Editor {
#pragma warning disable
protected InkSettings data;
public void OnEnable() {
data = (InkSettings) target;
}
public override void OnInspectorGUI() {
serializedObject.Update();
DrawSettings(serializedObject);
if(GUI.changed && target != null)
EditorUtility.SetDirty(target);
serializedObject.ApplyModifiedProperties();
}
#if UNITY_2018_1_OR_NEWER
[SettingsProvider]
public static SettingsProvider CreateInkSettingsProvider() {
// First parameter is the path in the Settings window.
// Second parameter is the scope of this setting: it only appears in the Project Settings window.
var provider = new SettingsProvider("Project/Ink", SettingsScope.Project) {
// By default the last token of the path is used as display name if no label is provided.
label = "Ink",
// Create the SettingsProvider and initialize its drawing (IMGUI) function in place:
guiHandler = (searchContext) => {
// Drawing the SO makes them disabled, and I have no idea why. Drawing manually until fixed.
// var settings = InkSettings.GetSerializedSettings();
DrawSettings(InkSettings.instance);
},
// Populate the search keywords to enable smart search filtering and label highlighting:
// keywords = new HashSet<string>(new[] { "Number", "Some String" })
};
return provider;
}
#endif
static string versionLabel => string.Format("Ink Unity Integration version "+InkLibrary.unityIntegrationVersionCurrent+"\nInk version "+InkLibrary.inkVersionCurrent+"\nInk story format version "+Ink.Runtime.Story.inkVersionCurrent+"\nInk save format version "+Ink.Runtime.StoryState.kInkSaveStateVersion);
static void DrawSettings (InkSettings settings) {
var cachedLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 260;
EditorGUILayout.HelpBox(versionLabel, MessageType.Info);
if(settings.templateFile == null) {
EditorGUILayout.HelpBox("Template not found. Ink files created via Assets > Create > Ink will be blank.", MessageType.Info);
}
settings.templateFile = (TextAsset)EditorGUILayout.ObjectField(new GUIContent("Ink Template", "Optional. The default content of files created via Assets > Create > Ink."), settings.templateFile, typeof(TextAsset));
settings.defaultJsonAssetPath = (DefaultAsset)EditorGUILayout.ObjectField(new GUIContent("New JSON Path", "By default, story JSON files are placed next to the ink. Drag a folder here to place new JSON files there instead."), settings.defaultJsonAssetPath, typeof(DefaultAsset));
settings.compileAutomatically = EditorGUILayout.Toggle(new GUIContent("Compile All Ink Automatically", "When disabled, automatic compilation can be enabled on a per-story basis via the inspector for a master story file. This can be helpful when you have several stories in a single project."), settings.compileAutomatically);
settings.delayInPlayMode = EditorGUILayout.Toggle(new GUIContent("Delay compilation if in Play Mode", "When enabled, ink compilation is delayed if in play mode. Files will be compiled on re-entering edit mode."), settings.delayInPlayMode);
settings.printInkLogsInConsoleOnCompile = EditorGUILayout.Toggle(new GUIContent("Print ink TODOs in console on compile", "When enabled, ink lines starting with TODO are printed in the console."), settings.printInkLogsInConsoleOnCompile);
settings.handleJSONFilesAutomatically = EditorGUILayout.Toggle(new GUIContent("Handle JSON Automatically", "Whether JSON files are moved, renamed and deleted along with their ink files."), settings.handleJSONFilesAutomatically);
settings.compileTimeout = EditorGUILayout.IntField(new GUIContent("Compile Timeout", "The max time the compiler will attempt to compile for in case of unhanded errors. You may need to increase this for very large ink projects."), settings.compileTimeout);
EditorGUIUtility.labelWidth = cachedLabelWidth;
EditorGUILayout.Separator();
if(GUILayout.Button("Show changelog")) {
InkUnityIntegrationStartupWindow.ShowWindow();
}
}
static void DrawSettings (SerializedObject settings) {
var cachedLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 260;
EditorGUI.BeginChangeCheck();
EditorGUILayout.HelpBox(versionLabel, MessageType.Info);
if(settings.FindProperty("templateFile").objectReferenceValue == null) {
EditorGUILayout.HelpBox("Template not found. Ink files created via Assets > Create > Ink will be blank.", MessageType.Info);
}
EditorGUILayout.PropertyField(settings.FindProperty("templateFile"), new GUIContent("Ink Template", "Optional. The default content of files created via Assets > Create > Ink."));
EditorGUILayout.PropertyField(settings.FindProperty("defaultJsonAssetPath"), new GUIContent("New JSON Path", "By default, story JSON files are placed next to the ink. Drag a folder here to place new JSON files there instead."));
EditorGUILayout.PropertyField(settings.FindProperty("compileAutomatically"), new GUIContent("Compile All Ink Automatically", "When disabled, automatic compilation can be enabled on a per-story basis via the inspector for a master story file. This can be helpful when you have several stories in a single project."));
EditorGUILayout.PropertyField(settings.FindProperty("delayInPlayMode"), new GUIContent("Delay compilation if in Play Mode", "When enabled, ink compilation is delayed if in play mode. Files will be compiled on re-entering edit mode."));
EditorGUILayout.PropertyField(settings.FindProperty("printInkLogsInConsoleOnCompile"), new GUIContent("Print ink TODOs in console on compile", "When enabled, ink lines starting with TODO are printed in the console."));
EditorGUILayout.PropertyField(settings.FindProperty("handleJSONFilesAutomatically"), new GUIContent("Handle JSON Automatically", "Whether JSON files are moved, renamed and deleted along with their ink files."));
EditorGUILayout.PropertyField(settings.FindProperty("compileTimeout"), new GUIContent("Compile Timeout", "The max time the compiler will attempt to compile for in case of unhanded errors. You may need to increase this for very large ink projects."));
if(EditorGUI.EndChangeCheck()) {
settings.ApplyModifiedProperties();
}
EditorGUIUtility.labelWidth = cachedLabelWidth;
EditorGUILayout.Separator();
if(GUILayout.Button("Show changelog")) {
InkUnityIntegrationStartupWindow.ShowWindow();
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4842c69e8d1f0443d8f4626c65ea356a
timeCreated: 1485516445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,294 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
using Ink.Runtime;
using UnityEditor.ProjectWindowCallback;
using UnityEditor.Callbacks;
using Path = System.IO.Path;
namespace Ink.UnityIntegration {
class CreateInkAssetAction : EndNameEditAction {
public override void Action(int instanceId, string pathName, string resourceFile) {
var text = "";
if(File.Exists(resourceFile)) {
StreamReader streamReader = new StreamReader(resourceFile);
text = streamReader.ReadToEnd();
streamReader.Close();
}
UnityEngine.Object asset = CreateScriptAsset(pathName, text);
ProjectWindowUtil.ShowCreatedAsset(asset);
}
internal static UnityEngine.Object CreateScriptAsset(string pathName, string text) {
string fullPath = Path.GetFullPath(pathName);
UTF8Encoding encoding = new UTF8Encoding(true, false);
bool append = false;
StreamWriter streamWriter = new StreamWriter(fullPath, append, encoding);
streamWriter.Write(text);
streamWriter.Close();
AssetDatabase.ImportAsset(pathName);
return AssetDatabase.LoadAssetAtPath(pathName, typeof(DefaultAsset));
}
}
[InitializeOnLoad]
public static class InkEditorUtils {
public const string inkFileExtension = ".ink";
const string lastCompileTimeKey = "InkIntegrationLastCompileTime";
// When compiling we call AssetDatabase.DisallowAutoRefresh.
// We NEED to remember to re-allow it or unity stops registering file changes!
// The issue is that you need to pair calls perfectly, and you can't even use a try-catch to get around it.
// So - we cache if we've disabled auto refresh here, since this persists across plays.
// This does have one issue - this setting is saved even when unity re-opens, but the internal asset refresh state isn't.
// We need this to reset on launching the editor.
// We currently fix this by setting it false on InkEditorUtils.OnOpenUnityEditor
// A potentially better approach is to use playerprefs for this, since it's really nothing to do with the library.
public static bool disallowedAutoRefresh {
get {
if(EditorPrefs.HasKey("InkLibraryDisallowedAutoRefresh"))
return EditorPrefs.GetBool("InkLibraryDisallowedAutoRefresh");
return false;
} set {
EditorPrefs.SetBool("InkLibraryDisallowedAutoRefresh", value);
}
}
// This should run before any of the other ink integration scripts.
static InkEditorUtils () {
EnsureFirstLaunchHandled();
EditorApplication.wantsToQuit += WantsToQuit;
}
// Save the current EditorApplication.timeSinceStartup so OnOpenUnityEditor is sure to run next time the editor opens.
static bool WantsToQuit () {
LoadAndSaveLastCompileTime();
return true;
}
public static bool isFirstCompile;
static void EnsureFirstLaunchHandled () {
float lastCompileTime = LoadAndSaveLastCompileTime();
isFirstCompile = EditorApplication.timeSinceStartup < lastCompileTime;
if(isFirstCompile)
OnOpenUnityEditor();
}
static float LoadAndSaveLastCompileTime () {
float lastCompileTime = 0;
if(EditorPrefs.HasKey(lastCompileTimeKey))
lastCompileTime = EditorPrefs.GetFloat(lastCompileTimeKey);
EditorPrefs.SetFloat(lastCompileTimeKey, (float)EditorApplication.timeSinceStartup);
return lastCompileTime;
}
static void OnOpenUnityEditor () {
disallowedAutoRefresh = false;
}
[MenuItem("Assets/Rebuild Ink Library", false, 200)]
public static void RebuildLibrary() {
InkLibrary.Rebuild();
}
[MenuItem("Assets/Recompile Ink", false, 201)]
public static void RecompileAll() {
var filesToRecompile = InkLibrary.FilesCompiledByRecompileAll().ToArray();
string logString = filesToRecompile.Any() ?
"Recompile All will compile "+string.Join(", ", filesToRecompile.Select(x => Path.GetFileName(x.filePath)).ToArray()) :
"No valid ink found. Note that only files with 'Compile Automatic' checked are compiled if not set to compile all files automatically in InkSettings file.";
Debug.Log(logString);
InkCompiler.CompileInk(filesToRecompile);
}
public static void RecompileAllImmediately() {
var filesToRecompile = InkLibrary.FilesCompiledByRecompileAll().ToArray();
string logString = filesToRecompile.Any() ?
"Recompile All Immediately will compile "+string.Join(", ", filesToRecompile.Select(x => Path.GetFileName(x.filePath)).ToArray()) :
"No valid ink found. Note that only files with 'Compile Automatic' checked are compiled if not set to compile all files automatically in InkSettings file.";
Debug.Log(logString);
InkCompiler.CompileInk(filesToRecompile, true, null);
}
[MenuItem("Assets/Create/Ink", false, 120)]
public static void CreateNewInkFile () {
string fileName = "New Ink.ink";
string filePath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(GetSelectedPathOrFallback(), fileName));
CreateNewInkFile(filePath, InkSettings.instance.templateFilePath);
}
public static void CreateNewInkFile (string filePath, string templateFileLocation) {
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<CreateInkAssetAction>(), filePath, InkBrowserIcons.inkFileIcon, templateFileLocation);
}
private static string GetSelectedPathOrFallback() {
string path = "Assets";
foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) {
path = AssetDatabase.GetAssetPath(obj);
if (!string.IsNullOrEmpty(path) && File.Exists(path)) {
path = Path.GetDirectoryName(path);
break;
}
}
return path;
}
[MenuItem("Help/Ink/About")]
public static void OpenAbout() {
Application.OpenURL("https://github.com/inkle/ink#ink");
}
[MenuItem("Help/Ink/Writing Tutorial...")]
public static void OpenWritingDocumentation() {
Application.OpenURL("https://github.com/inkle/ink/blob/master/Documentation/WritingWithInk.md");
}
[MenuItem("Help/Ink/API Documentation...")]
public static void OpenAPIDocumentation() {
Application.OpenURL("https://github.com/inkle/ink/blob/master/Documentation/RunningYourInk.md");
}
[MenuItem("Help/Ink/Donate...")]
public static void Donate() {
Application.OpenURL("https://www.patreon.com/inkle");
}
[PostProcessBuildAttribute(-1)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
if(!Debug.isDebugBuild) {
var color = EditorGUIUtility.isProSkin ? "#3498db" : "blue";
Debug.Log("<color="+color+">Thanks for using ink, and best of luck with your release!\nIf you're doing well, please help fund the project via Patreon https://www.patreon.com/inkle</color>");
}
}
public static TextAsset CreateStoryStateTextFile (string jsonStoryState, string defaultPath = "Assets/Ink", string defaultName = "storyState") {
string name = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(defaultPath, defaultName+".json")).Substring(defaultPath.Length+1);
string fullPathName = EditorUtility.SaveFilePanel("Save Story State", defaultPath, name, "json");
if(fullPathName == "")
return null;
using (StreamWriter outfile = new StreamWriter(fullPathName)) {
outfile.Write(jsonStoryState);
}
string relativePath = AbsoluteToUnityRelativePath(fullPathName);
AssetDatabase.ImportAsset(relativePath);
TextAsset textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(relativePath);
return textAsset;
}
public static bool StoryContainsVariables (Story story) {
return story.variablesState.GetEnumerator().MoveNext();
}
public static bool CheckStoryIsValid (string storyJSON, out Exception exception) {
try {
new Story(storyJSON);
} catch (Exception ex) {
exception = ex;
return false;
}
exception = null;
return true;
}
public static bool CheckStoryIsValid (string storyJSON, out Story story) {
try {
story = new Story(storyJSON);
} catch {
story = null;
return false;
}
return true;
}
public static bool CheckStoryIsValid (string storyJSON, out Exception exception, out Story story) {
try {
story = new Story(storyJSON);
} catch (Exception ex) {
exception = ex;
story = null;
return false;
}
exception = null;
return true;
}
public static bool CheckStoryStateIsValid (string storyJSON, string storyStateJSON) {
Story story;
if(CheckStoryIsValid(storyJSON, out story)) {
try {
story.state.LoadJson(storyStateJSON);
} catch {
return false;
}
}
return true;
}
// Returns a sanitized version of the supplied string by:
// - swapping MS Windows-style file separators with Unix/Mac style file separators.
// If null is provided, null is returned.
public static string SanitizePathString(string path) {
if (path == null) {
return null;
}
return path.Replace('\\', '/');
}
// Combines two file paths and returns that path. Unlike C#'s native Paths.Combine, regardless of operating
// system this method will always return a path which uses forward slashes ('/' characters) exclusively to ensure
// equality checks on path strings return equalities as expected.
public static string CombinePaths(string firstPath, string secondPath) {
Debug.Assert(firstPath != null);
Debug.Assert(secondPath != null);
return SanitizePathString(Path.Combine(firstPath, secondPath));
}
public static string AbsoluteToUnityRelativePath(string fullPath) {
return SanitizePathString(fullPath.Substring(Application.dataPath.Length-6));
}
public static string UnityRelativeToAbsolutePath(string filePath) {
return InkEditorUtils.CombinePaths(Application.dataPath, filePath.Substring(7));
}
/// <summary>
/// Draws a property field for a story using GUILayout, allowing you to attach stories to the player window for debugging.
/// </summary>
/// <param name="story">Story.</param>
/// <param name="label">Label.</param>
public static void DrawStoryPropertyField (Story story, GUIContent label) {
Debug.LogWarning("DrawStoryPropertyField has been moved from InkEditorUtils to InkPlayerWindow");
}
/// <summary>
/// Draws a property field for a story using GUI, allowing you to attach stories to the player window for debugging.
/// </summary>
/// <param name="position">Position.</param>
/// <param name="story">Story.</param>
/// <param name="label">Label.</param>
public static void DrawStoryPropertyField (Rect position, Story story, GUIContent label) {
Debug.LogWarning("DrawStoryPropertyField has been moved from InkEditorUtils to InkPlayerWindow");
}
/// <summary>
/// Checks to see if the given path is an ink file or not, regardless of extension.
/// </summary>
/// <param name="path">The path to check.</param>
/// <returns>True if it's an ink file, otherwise false.</returns>
public static bool IsInkFile(string path) {
string extension = Path.GetExtension(path);
if (extension == InkEditorUtils.inkFileExtension) {
return true;
}
return String.IsNullOrEmpty(extension) && InkLibrary.instance.inkLibrary.Exists(f => f.filePath == path);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: eeaeb991395be4e9e9ab83197c649ad8
timeCreated: 1459944754
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,16 @@
{
"name": "InkEditor",
"references": [
"Ink-Libraries"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2047ab7874eb449d78c2b459017aa506
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a26a7e3f7a600f249af24114621ba554
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 15e2b2aa92f3dff4b9aa6924a01bfd96
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,66 @@
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using System.Text;
using Ink.UnityIntegration;
using System.Linq;
#if UNITY_2018_1_OR_NEWER
using UnityEditor.Build.Reporting;
#endif
class InkPreBuildValidationCheck :
#if UNITY_2018_1_OR_NEWER
IPreprocessBuildWithReport
#else
IPreprocessBuild
#endif
{
public int callbackOrder { get { return 0; } }
#if UNITY_2018_1_OR_NEWER
public void OnPreprocessBuild(BuildReport report) {
PreprocessValidationStep();
}
#else
public void OnPreprocessBuild(BuildTarget target, string path) {
PreprocessValidationStep();
}
#endif
static void PreprocessValidationStep () {
AssertNotCompiling();
CheckForInvalidFiles();
}
static void AssertNotCompiling () {
if(InkCompiler.compiling) {
StringBuilder sb = new StringBuilder("Ink is currently compiling!");
var errorString = sb.ToString();
InkCompiler.buildBlocked = true;
if(UnityEditor.EditorUtility.DisplayDialog("Ink Build Error!", errorString, "Ok")) {
Debug.LogError(errorString);
}
}
}
// When syncronous compilation is allowed we should try to replace this error with a compile.
static void CheckForInvalidFiles () {
var filesToRecompile = InkLibrary.GetFilesRequiringRecompile();
if(filesToRecompile.Any()) {
StringBuilder sb = new StringBuilder();
sb.AppendLine("There are Ink files which should be compiled, but appear not to be. You can resolve this by either:");
sb.AppendLine(" - Compiling your files via 'Assets/Recompile Ink'");
var resolveStep = " - Disabling 'Compile Automatically' "+(InkSettings.instance.compileAutomatically ? "in your Ink Settings file" : "for each of the files listed below");
sb.AppendLine(resolveStep);
sb.AppendLine();
sb.AppendLine("Files:");
var filesAsString = string.Join(", ", filesToRecompile.Select(x => x.filePath).ToArray());
sb.AppendLine(filesAsString);
var errorString = sb.ToString();
if(!UnityEditor.EditorUtility.DisplayDialog("Ink Build Error!", errorString, "Build anyway", "Cancel build")) {
Debug.LogError(errorString);
} else {
Debug.LogWarning(errorString);
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 260430d96c5f0aa46a31363984dc9088
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51bebdd29a127594b90edb5938e78b79
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,184 @@
using System.IO;
using UnityEditor;
using UnityEngine;
/*
* This script allows you to set custom icons for folders in project browser.
* Recommended icon sizes - small: 16x16 px, large: 64x64 px;
*/
namespace Ink.UnityIntegration {
[InitializeOnLoad]
public class InkBrowserIcons {
private static bool isRetina {
get {
float unityVersion = float.Parse(Application.unityVersion.Substring (0, 3));
return Application.platform == RuntimePlatform.OSXEditor && unityVersion >= 5.4f;
}
}
private const float largeIconSize = 64f;
private static Texture2D _inkFileIcon;
public static Texture2D inkFileIcon {
get {
if(_inkFileIcon == null) {
if(isRetina) {
_inkFileIcon = Resources.Load<Texture2D>("InkFileIcon-retina");
} else {
_inkFileIcon = Resources.Load<Texture2D>("InkFileIcon");
}
}
return _inkFileIcon;
}
}
private static Texture2D _inkFileIconLarge;
public static Texture2D inkFileIconLarge {
get {
if(_inkFileIconLarge == null) {
_inkFileIconLarge = Resources.Load<Texture2D>("InkFileIcon-large");
}
return _inkFileIconLarge;
}
}
private static Texture2D _errorIcon;
public static Texture2D errorIcon {
get {
if(_errorIcon == null) {
_errorIcon = Resources.Load<Texture2D>("InkErrorIcon");
}
return _errorIcon;
}
}
private static Texture2D _warningIcon;
public static Texture2D warningIcon {
get {
if(_warningIcon == null) {
_warningIcon = Resources.Load<Texture2D>("InkWarningIcon");
}
return _warningIcon;
}
}
private static Texture2D _todoIcon;
public static Texture2D todoIcon {
get {
if(_todoIcon == null) {
_todoIcon = Resources.Load<Texture2D>("InkTodoIcon");
}
return _todoIcon;
}
}
private static Texture2D _manualIcon;
public static Texture2D manualIcon {
get {
if(_manualIcon == null) {
_manualIcon = Resources.Load<Texture2D>("InkCompileManualIcon");
}
return _manualIcon;
}
}
private static Texture2D _childIcon;
public static Texture2D childIcon {
get {
if(_childIcon == null) {
_childIcon = Resources.Load<Texture2D>("InkChildIcon");
}
return _childIcon;
}
}
private static Texture2D _childIconLarge;
public static Texture2D childIconLarge {
get {
if(_childIconLarge == null) {
_childIconLarge = Resources.Load<Texture2D>("InkChildIcon-Large");
}
return _childIconLarge;
}
}
private static Texture2D _unknownFileIcon;
public static Texture2D unknownFileIcon {
get {
if(_unknownFileIcon == null) {
_unknownFileIcon = Resources.Load<Texture2D>("InkUnknownFileIcon");
}
return _unknownFileIcon;
}
}
static InkBrowserIcons() {
EditorApplication.projectWindowItemOnGUI += OnDrawProjectWindowItem;
}
static void OnDrawProjectWindowItem(string guid, Rect rect) {
string path = AssetDatabase.GUIDToAssetPath(guid);
if (InkEditorUtils.IsInkFile(path)) {
DefaultAsset asset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(path);
DrawInkFile(InkLibrary.GetInkFileWithFile(asset), rect);
}
}
static void DrawInkFile (InkFile inkFile, Rect rect) {
bool isSmall = rect.width > rect.height;
if (isSmall) {
rect.width = rect.height;
} else {
rect.height = rect.width;
}
if (rect.width >= largeIconSize) {
DrawLarge(inkFile, rect);
} else {
DrawSmall(inkFile, rect);
}
}
static void DrawLarge (InkFile inkFile, Rect rect) {
var offset = (rect.width - largeIconSize) * 0.5f;
rect = new Rect(rect.x + offset, rect.y + offset, largeIconSize, largeIconSize);
if(inkFileIconLarge != null)
GUI.DrawTexture(rect, inkFileIconLarge);
Rect miniRect = new Rect(rect.center, rect.size * 0.5f);
if(inkFile == null) {
if(unknownFileIcon != null) {
GUI.DrawTexture(miniRect, unknownFileIcon);
}
} else {
if(inkFile.hasErrors && errorIcon != null) {
GUI.DrawTexture(miniRect, errorIcon);
} else if(inkFile.hasWarnings && warningIcon != null) {
GUI.DrawTexture(miniRect, warningIcon);
} else if(inkFile.hasTodos && todoIcon != null) {
GUI.DrawTexture(miniRect, todoIcon);
}
if(!inkFile.isMaster && childIcon != null) {
GUI.DrawTexture(new Rect(rect.x, rect.y, rect.width * 0.5f, rect.height * 0.5f), childIconLarge);
}
}
}
static void DrawSmall (InkFile inkFile, Rect rect) {
if(inkFileIcon != null)
GUI.DrawTexture(rect, inkFileIcon);
if(inkFile == null) {
if(unknownFileIcon != null) {
GUI.DrawTexture(new Rect(rect.x, rect.y, unknownFileIcon.width, unknownFileIcon.height), unknownFileIcon);
}
} else {
if(!InkSettings.instance.compileAutomatically && !inkFile.compileAutomatically && inkFile.isMaster)
GUI.DrawTexture(new Rect(rect.x, rect.y + rect.size.y * 0.5f, rect.size.x * 0.5f, rect.size.y * 0.5f), manualIcon);
Rect miniRect = new Rect(rect.center, rect.size * 0.5f);
if(inkFile.hasErrors && errorIcon != null) {
GUI.DrawTexture(miniRect, errorIcon);
} else if(inkFile.hasWarnings && warningIcon != null) {
GUI.DrawTexture(miniRect, warningIcon);
} else if(inkFile.hasTodos && todoIcon != null) {
GUI.DrawTexture(miniRect, todoIcon);
}
if(!inkFile.isMaster && childIcon != null) {
GUI.DrawTexture(new Rect(rect.x, rect.y, childIcon.width, childIcon.height), childIcon);
}
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 38c650d4ee11f47559699f833d29d4b9
timeCreated: 1459341699
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7db532cf76e3b4072a4e7ea2ff88d03e
folderAsset: yes
timeCreated: 1475576594
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: f4e541342c07c476094e04dc118fed7b
timeCreated: 1463742861
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: 53256257fd17e4dfda5f08016551019e
timeCreated: 1461958426
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,84 @@
fileFormatVersion: 2
guid: 1e91fdbfb2b154a18b675257bc4d43d9
timeCreated: 1485360612
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 1
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: iPhone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,3 @@
Hello world!
* Hello back!
Nice to hear from you!
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0487be7f554cd45a6916f94d2b6baf50
timeCreated: 1462291397
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: ab12885a47a21456596113fc9233946c
timeCreated: 1461099630
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: 957c8ea47888d42349ae208cffe69c4b
timeCreated: 1463734461
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 16
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: bd3c497264be941e3a935055a433bbb9
timeCreated: 1459953147
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: 8e6b218461abe4192baeeabfbe7a9ced
timeCreated: 1459341708
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 16
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,84 @@
fileFormatVersion: 2
guid: 73b0b2e787c654227845ff231c5eab5d
timeCreated: 1485360612
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 1
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: iPhone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: b26518ba7d72a4fd3bc42599f621c839
timeCreated: 1462526037
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,57 @@
fileFormatVersion: 2
guid: efc1324f6160840a9a4c26231cc2d304
timeCreated: 1461099630
licenseType: Store
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 1
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
cubemapConvolution: 0
cubemapConvolutionSteps: 7
cubemapConvolutionExponent: 1.5
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 2048
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
rGBM: 0
compressionQuality: 50
allowsAlphaSplitting: 0
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 2
buildTargetSettings: []
spriteSheet:
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c7ff1896f35a148d8a4c1850f1e8e13d
folderAsset: yes
timeCreated: 1459934446
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,60 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Ink.UnityIntegration {
[CustomEditor(typeof(DefaultAsset), true)]
public class DefaultAssetEditor : Editor {
private DefaultAssetInspector inspector;
private void OnEnable () {
inspector = FindObjectInspector ();
if(inspector != null) {
inspector.editor = this;
inspector.serializedObject = serializedObject;
inspector.target = target;
inspector.OnEnable();
}
}
private void OnDisable () {
if(inspector != null)
inspector.OnDisable();
}
protected override void OnHeaderGUI () {
if(inspector != null) {
inspector.OnHeaderGUI();
}
else
base.OnHeaderGUI();
}
public override void OnInspectorGUI () {
if(inspector != null) {
GUI.enabled = true;
inspector.OnInspectorGUI();
}
else
base.OnInspectorGUI();
}
private DefaultAssetInspector FindObjectInspector () {
var assembly = Assembly.GetExecutingAssembly();
var assetPath = AssetDatabase.GetAssetPath(target);
foreach(var type in assembly.GetTypes()) {
if(type.IsSubclassOf(typeof(DefaultAssetInspector))) {
DefaultAssetInspector objectInspector = (DefaultAssetInspector)Activator.CreateInstance(type);
if(objectInspector.IsValid(assetPath)) {
objectInspector.target = target;
return objectInspector;
}
}
}
return null;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fe3507ae5d970447197e131c39ac31b6
timeCreated: 1464440328
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,19 @@
using UnityEngine;
using UnityEditor;
namespace Ink.UnityIntegration {
public abstract class DefaultAssetInspector {
// Reference to the actual editor we draw to
public Editor editor;
// Shortcut to the target object
public Object target;
// Shortcut to the serializedObject
public SerializedObject serializedObject;
public abstract bool IsValid(string assetPath);
public virtual void OnEnable () {}
public virtual void OnDisable () {}
public virtual void OnHeaderGUI () {}
public virtual void OnInspectorGUI() {}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7fa6f007190b6408c8aebb32050a3bbe
timeCreated: 1470299519
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,418 @@
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEditorInternal;
using Object = UnityEngine.Object;
namespace Ink.UnityIntegration {
public class InkInspector : DefaultAssetInspector {
private InkFile inkFile;
private ReorderableList includesFileList;
private ReorderableList mastersFileList;
private ReorderableList errorList;
private ReorderableList warningList;
private ReorderableList todosList;
private string cachedTrimmedFileContents;
private const int maxCharacters = 16000;
public override bool IsValid(string assetPath) {
return Path.GetExtension(assetPath) == InkEditorUtils.inkFileExtension;
}
public override void OnHeaderGUI () {
GUILayout.BeginHorizontal();
GUILayout.Space(38f);
GUILayout.BeginVertical();
GUILayout.Space(19f);
GUILayout.BeginHorizontal();
GUILayoutUtility.GetRect(10f, 10f, 16f, 16f, EditorStyles.layerMaskField);
GUILayout.FlexibleSpace();
EditorGUI.BeginDisabledGroup(inkFile == null);
if (GUILayout.Button("Open", EditorStyles.miniButton)) {
AssetDatabase.OpenAsset(inkFile.inkAsset, 3);
GUIUtility.ExitGUI();
}
EditorGUI.EndDisabledGroup();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndHorizontal();
Rect lastRect = GUILayoutUtility.GetLastRect();
Rect rect = new Rect(lastRect.x, lastRect.y, lastRect.width, lastRect.height);
Rect iconRect = new Rect(rect.x + 6f, rect.y + 6f, 32f, 32f);
GUI.DrawTexture(iconRect, InkBrowserIcons.inkFileIconLarge);
Rect childIconRect = new Rect(iconRect.x, iconRect.y, 16f, 16f);
if(inkFile == null) {
GUI.DrawTexture(childIconRect, InkBrowserIcons.unknownFileIcon, ScaleMode.ScaleToFit);
} else if(!inkFile.isMaster) {
GUI.DrawTexture(childIconRect, InkBrowserIcons.childIconLarge, ScaleMode.ScaleToFit);
}
Rect titleRect = new Rect(rect.x + 44f, rect.y + 6f, rect.width - 44f - 38f - 4f, 16f);
titleRect.yMin -= 2f;
titleRect.yMax += 2f;
GUI.Label(titleRect, editor.target.name, EditorStyles.largeLabel);
}
public override void OnEnable () {
Rebuild();
InkCompiler.OnCompileInk += OnCompileInk;
}
public override void OnDisable () {
InkCompiler.OnCompileInk -= OnCompileInk;
}
void OnCompileInk (InkFile inkFile) {
Rebuild();
}
void Rebuild () {
cachedTrimmedFileContents = "";
string assetPath = AssetDatabase.GetAssetPath(target);
inkFile = InkLibrary.GetInkFileWithPath(assetPath);
if(inkFile == null)
return;
if (inkFile.includes.Count > 0) CreateIncludeList ();
else includesFileList = null;
if (inkFile.masterInkAssets.Count > 0) CreateMastersList ();
else mastersFileList = null;
CreateErrorList();
CreateWarningList();
CreateTodoList();
cachedTrimmedFileContents = inkFile.GetFileContents();
cachedTrimmedFileContents = cachedTrimmedFileContents.Substring(0, Mathf.Min(cachedTrimmedFileContents.Length, maxCharacters));
if(cachedTrimmedFileContents.Length >= maxCharacters)
cachedTrimmedFileContents += "...\n\n<...etc...>";
}
void CreateIncludeList () {
List<DefaultAsset> includeTextAssets = inkFile.includes;
includesFileList = new ReorderableList(includeTextAssets, typeof(DefaultAsset), false, false, false, false);
includesFileList.drawHeaderCallback = (Rect rect) => {
EditorGUI.LabelField(rect, "Included Files");
};
includesFileList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
DefaultAsset childAssetFile = ((List<DefaultAsset>)includesFileList.list)[index];
if(childAssetFile == null) {
Debug.LogError("Ink file in include list is null. This should never occur. Use Assets > Recompile Ink to fix this issue.");
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File in include list is null. Use Assets > Recompile Ink to fix this issue."));
return;
}
InkFile childInkFile = InkLibrary.GetInkFileWithFile(childAssetFile);
if(childInkFile == null) {
Debug.LogError("Ink File for included file "+childAssetFile+" not found. This should never occur. Use Assets > Recompile Ink to fix this issue.");
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File for included file "+childAssetFile+" not found. Use Assets > Recompile Ink to fix this issue."));
return;
}
Rect iconRect = new Rect(rect.x, rect.y, 0, 16);
if(childInkFile.hasErrors || childInkFile.hasWarnings) {
iconRect.width = 20;
}
Rect objectFieldRect = new Rect(iconRect.xMax, rect.y, rect.width - iconRect.width - 80, 16);
Rect selectRect = new Rect(objectFieldRect.xMax, rect.y, 80, 16);
if(childInkFile.hasErrors) {
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.errorIcon));
} else if(childInkFile.hasWarnings) {
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.warningIcon));
}
EditorGUI.BeginDisabledGroup(true);
EditorGUI.ObjectField(objectFieldRect, childAssetFile, typeof(Object), false);
EditorGUI.EndDisabledGroup();
if(GUI.Button(selectRect, "Select")) {
Selection.activeObject = childAssetFile;
}
};
}
void CreateMastersList () {
List<DefaultAsset> mastersTextAssets = inkFile.masterInkAssets;
mastersFileList = new ReorderableList(mastersTextAssets, typeof(DefaultAsset), false, false, false, false);
mastersFileList.drawHeaderCallback = (Rect rect) => {
EditorGUI.LabelField(rect, "Master Files");
};
mastersFileList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
DefaultAsset masterAssetFile = ((List<DefaultAsset>)mastersFileList.list)[index];
if(masterAssetFile == null) {
Debug.LogError("Ink file in masters list is null. This should never occur. Use Assets > Recompile Ink to fix this issue.");
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File in masters list is null. Use Assets > Recompile Ink to fix this issue."));
return;
}
InkFile masterInkFile = InkLibrary.GetInkFileWithFile(masterAssetFile);
if(masterInkFile == null) {
Debug.LogError("Ink File for master file "+masterAssetFile+" not found. This should never occur. Use Assets > Recompile Ink to fix this issue.");
EditorGUI.LabelField(rect, new GUIContent("Warning: Ink File for master file "+masterAssetFile+" not found. Use Assets > Recompile Ink to fix this issue."));
return;
}
Rect iconRect = new Rect(rect.x, rect.y, 0, 16);
if(masterInkFile.hasErrors || masterInkFile.hasWarnings) {
iconRect.width = 20;
}
Rect objectFieldRect = new Rect(iconRect.xMax, rect.y, rect.width - iconRect.width - 80, 16);
Rect selectRect = new Rect(objectFieldRect.xMax, rect.y, 80, 16);
if(masterInkFile.hasErrors) {
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.errorIcon));
} else if(masterInkFile.hasWarnings) {
EditorGUI.LabelField(iconRect, new GUIContent(InkBrowserIcons.warningIcon));
}
EditorGUI.BeginDisabledGroup(true);
EditorGUI.ObjectField(objectFieldRect, masterAssetFile, typeof(Object), false);
EditorGUI.EndDisabledGroup();
if(GUI.Button(selectRect, "Select")) {
Selection.activeObject = masterAssetFile;
}
// foreach(var masterInkFile in inkFile.masterInkFiles) {
// EditorGUILayout.BeginHorizontal();
// if(masterInkFile.hasErrors) {
// GUILayout.Label(new GUIContent(InkBrowserIcons.errorIcon), GUILayout.Width(20));
// } else if(masterInkFile.hasWarnings) {
// GUILayout.Label(new GUIContent(InkBrowserIcons.warningIcon), GUILayout.Width(20));
// }
// EditorGUI.BeginDisabledGroup(true);
// EditorGUILayout.ObjectField("Master Ink File", masterInkFile.inkAsset, typeof(Object), false);
// EditorGUI.EndDisabledGroup();
// if(GUILayout.Button("Select", GUILayout.Width(80))) {
// Selection.activeObject = masterInkFile.inkAsset;
// }
// EditorGUILayout.EndHorizontal();
// }
};
}
void CreateErrorList () {
errorList = new ReorderableList(inkFile.errors, typeof(string), false, false, false, false);
errorList.elementHeight = 18;
errorList.drawHeaderCallback = (Rect rect) => {
EditorGUI.LabelField(rect, new GUIContent(InkBrowserIcons.errorIcon), new GUIContent("Errors"));
};
errorList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
Rect buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height-2);
InkCompilerLog log = ((List<InkCompilerLog>)errorList.list)[index];
string label = log.content;
GUI.Label(labelRect, label);
string openLabel = "Open"+ (log.lineNumber == -1 ? "" : " ("+log.lineNumber+")");
if(GUI.Button(buttonRect, openLabel)) {
OpenInEditor(inkFile.filePath, log.lineNumber);
}
};
}
void CreateWarningList () {
warningList = new ReorderableList(inkFile.warnings, typeof(string), false, false, false, false);
warningList.elementHeight = 18;
warningList.drawHeaderCallback = (Rect rect) => {
EditorGUI.LabelField(rect, new GUIContent(InkBrowserIcons.warningIcon), new GUIContent("Warnings"));
};
warningList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
Rect buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height-2);
InkCompilerLog log = ((List<InkCompilerLog>)warningList.list)[index];
string label = log.content;
GUI.Label(labelRect, label);
string openLabel = "Open"+ (log.lineNumber == -1 ? "" : " ("+log.lineNumber+")");
if(GUI.Button(buttonRect, openLabel)) {
OpenInEditor(inkFile.filePath, log.lineNumber);
}
};
}
void CreateTodoList () {
todosList = new ReorderableList(inkFile.todos, typeof(string), false, false, false, false);
todosList.elementHeight = 18;
todosList.drawHeaderCallback = (Rect rect) => {
EditorGUI.LabelField(rect, "To do");
};
todosList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
Rect labelRect = new Rect(rect.x, rect.y, rect.width - 80, rect.height);
Rect buttonRect = new Rect(labelRect.xMax, rect.y, 80, rect.height-2);
InkCompilerLog log = ((List<InkCompilerLog>)todosList.list)[index];
string label = log.content;
GUI.Label(labelRect, label);
string openLabel = "Open"+ (log.lineNumber == -1 ? "" : " ("+log.lineNumber+")");
if(GUI.Button(buttonRect, openLabel)) {
OpenInEditor(inkFile.filePath, log.lineNumber);
}
};
}
static void OpenInEditor (string filePath, int lineNumber) {
#if UNITY_2019_1_OR_NEWER
// This function replaces OpenFileAtLineExternal, but I guess it's totally internal and can't be accessed.
// CodeEditorUtility.Editor.Current.OpenProject(filePath, lineNumber);
#pragma warning disable
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(filePath, lineNumber);
#pragma warning restore
#else
UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(filePath, lineNumber);
#endif
}
public override void OnInspectorGUI () {
editor.Repaint();
serializedObject.Update();
if(inkFile == null) {
EditorGUILayout.HelpBox("Ink File is not in library.", MessageType.Warning);
if(GUILayout.Button("Rebuild Library")) {
InkLibrary.Rebuild();
Rebuild();
}
return;
}
if(InkCompiler.GetCompilationStackItem(inkFile) != null) {
EditorGUILayout.HelpBox("File is compiling...", MessageType.Info);
return;
}
if(inkFile.isMaster) {
DrawMasterFileHeader();
DrawEditAndCompileDates(inkFile);
if(inkFile.hasUnhandledCompileErrors) {
EditorGUILayout.HelpBox("Last compiled failed", MessageType.Error);
} if(inkFile.hasErrors) {
EditorGUILayout.HelpBox("Last compiled had errors", MessageType.Error);
} else if(inkFile.hasWarnings) {
EditorGUILayout.HelpBox("Last compile had warnings", MessageType.Warning);
} else if(inkFile.jsonAsset == null) {
EditorGUILayout.HelpBox("Ink file has not been compiled", MessageType.Warning);
}
if(inkFile.requiresCompile && GUILayout.Button("Compile")) {
InkCompiler.CompileInk(inkFile);
}
DrawIncludedFiles();
DrawCompileErrors();
DrawErrors();
DrawWarnings();
DrawTODOList();
} else {
DrawSubFileHeader();
}
DrawFileContents ();
serializedObject.ApplyModifiedProperties();
}
void DrawMasterFileHeader () {
EditorGUILayout.LabelField("Master File", EditorStyles.boldLabel);
if(!InkSettings.instance.compileAutomatically) {
inkFile.compileAutomatically = EditorGUILayout.Toggle("Compile Automatially", inkFile.compileAutomatically);
EditorApplication.RepaintProjectWindow();
}
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.ObjectField("JSON Asset", inkFile.jsonAsset, typeof(TextAsset), false);
EditorGUI.EndDisabledGroup();
if(inkFile.jsonAsset != null && inkFile.errors.Count == 0 && GUILayout.Button("Play")) {
InkPlayerWindow.LoadAndPlay(inkFile.jsonAsset);
}
// if(!checkedStoryForErrors) {
// if(GUILayout.Button("Check for errors")) {
// GetStoryErrors();
// }
// } else {
// if(exception != null) {
// EditorGUILayout.HelpBox("Story is invalid\n"+exception.ToString(), MessageType.Error);
// } else {
// EditorGUILayout.HelpBox("Story is valid", MessageType.Info);
// }
// }
}
void DrawSubFileHeader() {
EditorGUILayout.LabelField("Include File", EditorStyles.boldLabel);
if(mastersFileList != null && mastersFileList.count > 0) {
mastersFileList.DoLayoutList();
}
}
void DrawEditAndCompileDates (InkFile masterInkFile) {
string editAndCompileDateString = "";
DateTime lastEditDate = inkFile.lastEditDate;
editAndCompileDateString += "Last edit date "+lastEditDate.ToString();
if(masterInkFile.jsonAsset != null) {
DateTime lastCompileDate = masterInkFile.lastCompileDate;
editAndCompileDateString += "\nLast compile date "+lastCompileDate.ToString();
if(lastEditDate > lastCompileDate) {
if(EditorApplication.isPlaying && InkSettings.instance.delayInPlayMode) {
editAndCompileDateString += "\nWill compile on exiting play mode";
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.Info);
} else {
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.Warning);
}
} else {
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.None);
}
} else {
EditorGUILayout.HelpBox(editAndCompileDateString, MessageType.None);
}
}
void DrawIncludedFiles () {
if(includesFileList != null && includesFileList.count > 0) {
includesFileList.DoLayoutList();
}
}
void DrawCompileErrors () {
if(inkFile.unhandledCompileErrors.Count == 0)
return;
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.HelpBox("Compiler bug prevented compilation of JSON file. Please help us fix it by reporting this as a bug.", MessageType.Error);
EditorGUILayout.BeginHorizontal();
if(GUILayout.Button("Report via Github")) {
Application.OpenURL("https://github.com/inkle/ink-unity-integration/issues/new");
}
if(GUILayout.Button("Report via Email")) {
Application.OpenURL("mailto:info@inklestudios.com");
}
EditorGUILayout.EndHorizontal();
foreach(string compileError in inkFile.unhandledCompileErrors) {
GUILayout.TextArea(compileError);
}
EditorGUILayout.EndVertical();
}
void DrawErrors () {
if(errorList != null && errorList.count > 0) {
errorList.DoLayoutList();
}
}
void DrawWarnings () {
if(warningList != null && warningList.count > 0) {
warningList.DoLayoutList();
}
}
void DrawTODOList () {
if(todosList != null && todosList.count > 0) {
todosList.DoLayoutList();
}
}
void DrawFileContents () {
float width = EditorGUIUtility.currentViewWidth-50;
float height = EditorStyles.wordWrappedLabel.CalcHeight(new GUIContent(cachedTrimmedFileContents), width);
EditorGUILayout.BeginVertical(EditorStyles.textArea);
EditorGUILayout.SelectableLabel(cachedTrimmedFileContents, EditorStyles.wordWrappedLabel, GUILayout.ExpandHeight(true), GUILayout.Width(width), GUILayout.Height(height));
EditorGUILayout.EndVertical();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6905e53703af64a70aa6eb42f98b047c
timeCreated: 1460011343
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 09e392e872101fd4885d68e71c7ab38b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using Ink.Runtime;
using UnityEngine;
namespace Ink.UnityIntegration.Debugging {
[System.Serializable]
public class InkHistoryContentItem {
public enum ContentType {
PresentedContent,
ChooseChoice,
PresentedChoice,
EvaluateFunction,
CompleteEvaluateFunction,
ChoosePathString,
Warning,
Error,
DebugNote
}
public string content;
public List<string> tags;
public ContentType contentType;
[SerializeField]
JsonDateTime _time;
public DateTime time {
get {
return _time;
} private set {
_time = value;
}
}
InkHistoryContentItem (string text, ContentType contentType) {
this.content = text;
this.contentType = contentType;
this.time = DateTime.Now;
}
InkHistoryContentItem (string text, List<string> tags, ContentType contentType) {
this.content = text;
this.tags = tags;
this.contentType = contentType;
this.time = DateTime.Now;
}
public static InkHistoryContentItem CreateForContent (string choiceText, List<string> tags) {
return new InkHistoryContentItem(choiceText, tags, InkHistoryContentItem.ContentType.PresentedContent);
}
public static InkHistoryContentItem CreateForPresentChoice (Choice choice) {
return new InkHistoryContentItem(choice.text.Trim(), InkHistoryContentItem.ContentType.PresentedChoice);
}
public static InkHistoryContentItem CreateForMakeChoice (Choice choice) {
return new InkHistoryContentItem(choice.text.Trim(), InkHistoryContentItem.ContentType.ChooseChoice);
}
public static InkHistoryContentItem CreateForEvaluateFunction (string choiceText) {
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.EvaluateFunction);
}
public static InkHistoryContentItem CreateForCompleteEvaluateFunction (string choiceText) {
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.CompleteEvaluateFunction);
}
public static InkHistoryContentItem CreateForChoosePathString (string choiceText) {
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.ChoosePathString);
}
public static InkHistoryContentItem CreateForWarning (string choiceText) {
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.Warning);
}
public static InkHistoryContentItem CreateForError (string choiceText) {
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.Error);
}
public static InkHistoryContentItem CreateForDebugNote (string choiceText) {
return new InkHistoryContentItem(choiceText, InkHistoryContentItem.ContentType.DebugNote);
}
struct JsonDateTime {
public long value;
public static implicit operator DateTime(JsonDateTime jdt) {
return DateTime.FromFileTime(jdt.value);
}
public static implicit operator JsonDateTime(DateTime dt) {
JsonDateTime jdt = new JsonDateTime();
jdt.value = dt.ToFileTime();
return jdt;
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9eeba5396eb679a4fbf1e275b4da1b2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More