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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e6ba2d9f1366a5b48b0de31974af56cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1ea997059b193ec4f93c2ae11630ad48
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 36fb6d04b0b2d3b478161622da3f094c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ff7b234789513374cb4413a04a031a5a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8af1c5cbac5094782904447c9410b35d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 29fc0cbe08c0d4f87975cc7a62f72510
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1460e815e969b43b8a83a7caa8b48c27
timeCreated: 1464457282
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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":{}}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6cf48bb6d89824cc69e35b43f9a1aca6
timeCreated: 1512575780
licenseType: Pro
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d8b5e370f13d74ab9b7aa54226433610
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 37c108a6c38964f79a6621eccb33ddc1
timeCreated: 1457987203
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1aab6ef84d87c416f8f0b3e1ef3d77d2
timeCreated: 1457983120
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b54a75d42bc7748248ac75fe35331f9e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 66e957d58a4584a8894329531ec0b096
timeCreated: 1473758854
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9afc9fe3049ac409e886991c340e1a33
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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"));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1c04f2595983345ab86d4ef0eea06dea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ce0d8573e1b2ff42af74cb80f3e5ece
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e829cba164e3db943916a82d6c825672
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: df28596461d414a1b9f56cb406a23a3f
folderAsset: yes
timeCreated: 1459882215
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: ddef5103d5ce1401da019f7df6c472af
folderAsset: yes
timeCreated: 1459882122
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e277a78690c74451084fbfbedc0507e8
folderAsset: yes
timeCreated: 1459941651
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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());
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45a9c84618e20498993d11d2bb89946e
timeCreated: 1459667420
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 430cb8f71c23c438cb8b0ce85cc80fa6
timeCreated: 1459463931
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2de904d59497c1c47b0792de1a85faf6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c547bc1dd015a497cb998538d42d2340
folderAsset: yes
timeCreated: 1459878666
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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>.*)");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2af758247ca160446b0727c6e91632cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b497ccd4b61cb4fee8b8f0ce86302e83
timeCreated: 1459464092
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dc234ab28a32840f5adfb84a075bc023
timeCreated: 1485516445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6188b37f5f5824313b73fb964d1b269e
folderAsset: yes
timeCreated: 1459878666
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 983af1b6602bf416b9928d40b37a38bd
timeCreated: 1485516445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4842c69e8d1f0443d8f4626c65ea356a
timeCreated: 1485516445
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: eeaeb991395be4e9e9ab83197c649ad8
timeCreated: 1459944754
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
{
"name": "InkEditor",
"references": [
"Ink-Libraries"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2047ab7874eb449d78c2b459017aa506
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a26a7e3f7a600f249af24114621ba554
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 15e2b2aa92f3dff4b9aa6924a01bfd96
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 260430d96c5f0aa46a31363984dc9088
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 51bebdd29a127594b90edb5938e78b79
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 38c650d4ee11f47559699f833d29d4b9
timeCreated: 1459341699
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7db532cf76e3b4072a4e7ea2ff88d03e
folderAsset: yes
timeCreated: 1475576594
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -0,0 +1,3 @@
Hello world!
* Hello back!
Nice to hear from you!

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0487be7f554cd45a6916f94d2b6baf50
timeCreated: 1462291397
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -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:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c7ff1896f35a148d8a4c1850f1e8e13d
folderAsset: yes
timeCreated: 1459934446
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fe3507ae5d970447197e131c39ac31b6
timeCreated: 1464440328
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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() {}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7fa6f007190b6408c8aebb32050a3bbe
timeCreated: 1470299519
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 6905e53703af64a70aa6eb42f98b047c
timeCreated: 1460011343
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 09e392e872101fd4885d68e71c7ab38b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9eeba5396eb679a4fbf1e275b4da1b2c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bf969d7f2c98e470c9797844e20b20ee
timeCreated: 1459342679
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e6bbfb931dd0d104199fc4542fc5a85d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,123 @@
using UnityEditor;
using UnityEngine;
namespace Ink.UnityIntegration {
[InitializeOnLoad]
public class InkUnityIntegrationStartupWindow : EditorWindow {
const string editorPrefsKeyForVersionSeen = "Ink Unity Integration Startup Window Version Confirmed";
const int announcementVersion = 2;
Vector2 scrollPosition;
static int announcementVersionPreviouslySeen;
private static Texture2D _logoIcon;
public static Texture2D logoIcon {
get {
if(_logoIcon == null) {
_logoIcon = Resources.Load<Texture2D>("InkLogoIcon");
}
return _logoIcon;
}
}
static InkUnityIntegrationStartupWindow () {
UnityEditor.EditorApplication.delayCall += TryCreateWindow;
}
static void TryCreateWindow() {
announcementVersionPreviouslySeen = EditorPrefs.GetInt(editorPrefsKeyForVersionSeen, -1);
if(announcementVersion != announcementVersionPreviouslySeen) {
ShowWindow();
}
}
public static void ShowWindow () {
InkUnityIntegrationStartupWindow window = EditorWindow.GetWindow(typeof(InkUnityIntegrationStartupWindow), true, "Ink Update "+InkLibrary.unityIntegrationVersionCurrent.ToString(), true) as InkUnityIntegrationStartupWindow;
window.minSize = new Vector2(200, 200);
var size = new Vector2(520, 320);
window.position = new Rect((Screen.currentResolution.width-size.x) * 0.5f, (Screen.currentResolution.height-size.y) * 0.5f, size.x, size.y);
EditorPrefs.SetInt(editorPrefsKeyForVersionSeen, announcementVersion);
}
void OnGUI ()
{
EditorGUILayout.BeginVertical();
var areaSize = new Vector2(90,90);
GUILayout.BeginArea(new Rect((position.width-areaSize.x)*0.5f, 15, areaSize.x, areaSize.y));
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField(new GUIContent(logoIcon), GUILayout.Width(areaSize.x), GUILayout.Height(areaSize.x*((float)logoIcon.height/logoIcon.width)));
GUILayout.Space(5);
EditorGUILayout.LabelField("Version "+InkLibrary.unityIntegrationVersionCurrent.ToString(), EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.LabelField("Ink version "+InkLibrary.inkVersionCurrent.ToString(), EditorStyles.centeredGreyMiniLabel);
EditorGUILayout.EndVertical();
GUILayout.EndArea();
GUILayout.Space(20+areaSize.y);
if(announcementVersionPreviouslySeen == -1) {
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("New to ink?", EditorStyles.boldLabel);
EditorGUILayout.EndVertical();
}
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("About Ink")) {
Application.OpenURL("https://www.inklestudios.com/ink/");
}
if (GUILayout.Button("❤Support Us!❤️")) {
Application.OpenURL("https://www.patreon.com/inkle");
}
if (GUILayout.Button("Close")) {
Close();
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.Space();
{
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
{
// 1.0.0
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("🎉Version 1.0.0🎉:", EditorStyles.boldLabel);
EditorGUILayout.LabelField("• Update ink to 1.0.0", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Ink Editor Window: Allow resizing (some) panels", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Ink Editor Window: Named content panel ", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Ink Editor Window: Improved performance for large stories", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Allow compiling include files that don't have the .ink file extension", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Remove ability to use a custom inklecate (legacy compiler)", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Fixes settings menu on 2020+", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Improved migration from earlier versions", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Moved persistent compilation tracking code from InkLibrary into InkCompiler", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Use Unity's new ScriptableSingleton for InkLibrary, InkSettings and InkCompiler on 2020+", EditorStyles.wordWrappedLabel);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUI.skin.box);
// 0.9.71
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("Version 0.9.71:", EditorStyles.boldLabel);
EditorGUILayout.LabelField("• Resolves some compilation issues.", EditorStyles.wordWrappedLabel);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUI.skin.box);
// 0.9.60
EditorGUILayout.LabelField("Version 0.9.60:", EditorStyles.boldLabel);
EditorGUILayout.LabelField("• Moved InkLibrary and InkSettings from Assets into Library and ProjectSettings.", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField(" ‣ InkLibrary should no longer be tracked in source control.", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField(" ‣ Changes to InkSettings must be migrated manually.", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField(" ‣ The InkLibrary and InkSettings files in your project folder should be deleted.", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("• Added a divertable list of knots, stitches and other named content to the Ink Editor Window, replacing the Diverts subpanel.", EditorStyles.wordWrappedLabel);
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndScrollView();
}
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c436e11a2a780e14680d25152259eadd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ed82eefbb606deb49b637f3947d9cfb0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,121 @@
fileFormatVersion: 2
guid: 09746d3311e36764faa38d0e982f6a2d
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 2
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
- serializedVersion: 2
buildTarget: Nintendo Switch
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: da9154df703de4360bd91ca5ce4ceb2d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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