Browse Source

Added Fungus library and example files

master
chrisgregan 11 years ago
parent
commit
a72dcd4016
  1. 5
      Assets/Example.meta
  2. 5
      Assets/Example/Scenes.meta
  3. BIN
      Assets/Example/Scenes/Example.unity
  4. 4
      Assets/Example/Scenes/Example.unity.meta
  5. 5
      Assets/Example/Scripts.meta
  6. 27
      Assets/Example/Scripts/MenuRoom.cs
  7. 8
      Assets/Example/Scripts/MenuRoom.cs.meta
  8. 44
      Assets/Example/Scripts/ViewRoom.cs
  9. 8
      Assets/Example/Scripts/ViewRoom.cs.meta
  10. 77
      Assets/Example/Scripts/WritingRoom.cs
  11. 8
      Assets/Example/Scripts/WritingRoom.cs.meta
  12. 5
      Assets/Fungus.meta
  13. 5
      Assets/Fungus/Editor.meta
  14. 44
      Assets/Fungus/Editor/GameEditor.cs
  15. 8
      Assets/Fungus/Editor/GameEditor.cs.meta
  16. 98
      Assets/Fungus/Editor/PageEditor.cs
  17. 8
      Assets/Fungus/Editor/PageEditor.cs.meta
  18. 16
      Assets/Fungus/Editor/RoomEditor.cs
  19. 8
      Assets/Fungus/Editor/RoomEditor.cs.meta
  20. 90
      Assets/Fungus/Editor/ViewEditor.cs
  21. 8
      Assets/Fungus/Editor/ViewEditor.cs.meta
  22. 5
      Assets/Fungus/Fonts.meta
  23. 5
      Assets/Fungus/Fonts/open-sans.meta
  24. 201
      Assets/Fungus/Fonts/open-sans/Apache License.txt
  25. 4
      Assets/Fungus/Fonts/open-sans/Apache License.txt.meta
  26. BIN
      Assets/Fungus/Fonts/open-sans/OpenSans-Regular.ttf
  27. 14
      Assets/Fungus/Fonts/open-sans/OpenSans-Regular.ttf.meta
  28. 5
      Assets/Fungus/Prefabs.meta
  29. BIN
      Assets/Fungus/Prefabs/Game.prefab
  30. 4
      Assets/Fungus/Prefabs/Game.prefab.meta
  31. BIN
      Assets/Fungus/Prefabs/Page.prefab
  32. 4
      Assets/Fungus/Prefabs/Page.prefab.meta
  33. BIN
      Assets/Fungus/Prefabs/Room.prefab
  34. 4
      Assets/Fungus/Prefabs/Room.prefab.meta
  35. BIN
      Assets/Fungus/Prefabs/View.prefab
  36. 4
      Assets/Fungus/Prefabs/View.prefab.meta
  37. 5
      Assets/Fungus/Scripts.meta
  38. 48
      Assets/Fungus/Scripts/Button.cs
  39. 8
      Assets/Fungus/Scripts/Button.cs.meta
  40. 199
      Assets/Fungus/Scripts/CameraController.cs
  41. 9
      Assets/Fungus/Scripts/CameraController.cs.meta
  42. 54
      Assets/Fungus/Scripts/CommandQueue.cs
  43. 8
      Assets/Fungus/Scripts/CommandQueue.cs.meta
  44. 463
      Assets/Fungus/Scripts/Commands.cs
  45. 8
      Assets/Fungus/Scripts/Commands.cs.meta
  46. 34
      Assets/Fungus/Scripts/FixedHeightSprite.cs
  47. 8
      Assets/Fungus/Scripts/FixedHeightSprite.cs.meta
  48. 178
      Assets/Fungus/Scripts/Game.cs
  49. 8
      Assets/Fungus/Scripts/Game.cs.meta
  50. 88
      Assets/Fungus/Scripts/GameState.cs
  51. 8
      Assets/Fungus/Scripts/GameState.cs.meta
  52. 331
      Assets/Fungus/Scripts/Page.cs
  53. 8
      Assets/Fungus/Scripts/Page.cs.meta
  54. 320
      Assets/Fungus/Scripts/Room.cs
  55. 8
      Assets/Fungus/Scripts/Room.cs.meta
  56. 20
      Assets/Fungus/Scripts/RoomTemplate.cs
  57. 8
      Assets/Fungus/Scripts/RoomTemplate.cs.meta
  58. 120
      Assets/Fungus/Scripts/SpriteController.cs
  59. 8
      Assets/Fungus/Scripts/SpriteController.cs.meta
  60. 105
      Assets/Fungus/Scripts/StringsParser.cs
  61. 8
      Assets/Fungus/Scripts/StringsParser.cs.meta
  62. 19
      Assets/Fungus/Scripts/View.cs
  63. 8
      Assets/Fungus/Scripts/View.cs.meta
  64. 5
      Assets/Fungus/Sprites.meta
  65. BIN
      Assets/Fungus/Sprites/Fungus.png
  66. 45
      Assets/Fungus/Sprites/Fungus.png.meta
  67. BIN
      Assets/Fungus/Sprites/Mushroom.png
  68. 45
      Assets/Fungus/Sprites/Mushroom.png.meta
  69. 5
      Assets/Fungus/Textures.meta
  70. BIN
      Assets/Fungus/Textures/Fade.png
  71. 45
      Assets/Fungus/Textures/Fade.png.meta
  72. BIN
      Assets/Fungus/Textures/box.png
  73. 45
      Assets/Fungus/Textures/box.png.meta
  74. 14
      Fungus.userprefs
  75. BIN
      ProjectSettings/AudioManager.asset
  76. BIN
      ProjectSettings/DynamicsManager.asset
  77. BIN
      ProjectSettings/EditorBuildSettings.asset
  78. BIN
      ProjectSettings/EditorSettings.asset
  79. BIN
      ProjectSettings/GraphicsSettings.asset
  80. BIN
      ProjectSettings/InputManager.asset
  81. BIN
      ProjectSettings/NavMeshLayers.asset
  82. BIN
      ProjectSettings/NetworkManager.asset
  83. BIN
      ProjectSettings/Physics2DSettings.asset
  84. BIN
      ProjectSettings/ProjectSettings.asset
  85. BIN
      ProjectSettings/QualitySettings.asset
  86. BIN
      ProjectSettings/TagManager.asset
  87. BIN
      ProjectSettings/TimeManager.asset

5
Assets/Example.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 19f5178ee50b34817a7cdafbda2ce166
folderAsset: yes
DefaultImporter:
userData:

5
Assets/Example/Scenes.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 695c2b87de46948719d8d25616c55ad0
folderAsset: yes
DefaultImporter:
userData:

BIN
Assets/Example/Scenes/Example.unity

Binary file not shown.

4
Assets/Example/Scenes/Example.unity.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: 5a6b6f6f9c1684498b25f6f41ef56995
DefaultImporter:
userData:

5
Assets/Example/Scripts.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 48785157e076a44009fad585c2ab2735
folderAsset: yes
DefaultImporter:
userData:

27
Assets/Example/Scripts/MenuRoom.cs

@ -0,0 +1,27 @@
using UnityEngine;
using System.Collections;
using Fungus;
public class MenuRoom : Room
{
public Room writingRoom;
public Room viewRoom;
void OnEnter()
{
AddOption("1. Writing a story with Pages", MoveToWriting);
AddOption("2. Controlling the camera with Views", MoveToViews);
Choose("Choose an example");
}
void MoveToWriting()
{
MoveToRoom(writingRoom);
}
void MoveToViews()
{
MoveToRoom(viewRoom);
}
}

8
Assets/Example/Scripts/MenuRoom.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8f3838e29c03e4ebf9a232fb00d4dffb
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

44
Assets/Example/Scripts/ViewRoom.cs

@ -0,0 +1,44 @@
using UnityEngine;
using System.Collections;
using Fungus;
public class ViewRoom : Room
{
public Room menuRoom;
public View mainView;
public View logoView;
public View toadstoolView;
void OnEnter()
{
SetView(mainView);
AddOption("Lets look at the logo", LookLogo);
AddOption("That's a nice toadstool over there", LookToadstool);
AddOption("Back to menu", MoveToMenu);
Choose("Wanna move the camera?");
}
void MoveToMenu()
{
MoveToRoom(menuRoom);
}
void LookLogo()
{
PanToView(logoView, 2f);
Wait(2);
PanToView(mainView, 2f);
Call(OnEnter);
}
void LookToadstool()
{
FadeToView(toadstoolView, 2f);
Say("Now that is a pretty mushroom");
Say("Hey - let's go look at that logo");
Call(LookLogo);
}
}

8
Assets/Example/Scripts/ViewRoom.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b17df452ec8b34e1ea67b7ff2c46579b
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

77
Assets/Example/Scripts/WritingRoom.cs

@ -0,0 +1,77 @@
using UnityEngine;
using System.Collections;
using Fungus;
public class WritingRoom : Room
{
// This is a reference to the menu room so we can transition back to the menu using MoveToRoom()
public Room menuRoom;
// The OnEnter() method is called whenever the player enters the room
// You can also use the OnLeave() method to handle when the player leaves the room.
void OnEnter()
{
// Sets the title text on the page
Title("The Mushroom");
// Each Say() command writes one line of text, followed by a continue button
Say("One day a mushroom grew in the forest");
Say("What am I doing here he wondered?");
Say("I think I will wait for a while and see if something happens.");
// Wait for a few seconds
Wait(3);
// Set the title text to the empty string to remove the page title
Title("");
Say("...");
Say("Hmmm. Nothing seems to be happening.");
// Add a couple of user options
// The first parameter is the option text
// The second parameter is the method to call if the user selects the option
// You can add as many options as you like
AddOption("Go to sleep", GoToSleep);
AddOption("Produce spores", ProduceSpores);
// Display all the previously added options, with a text prompt
Choose("Whatever will I do?");
}
void GoToSleep()
{
// Check to see if a game flag has been set
// You can also use GetCounter & GetInventory to get other types of values.
if (GetFlag("spawned"))
{
Say("I am feeling rather sleepy after all that spawning!");
Say("Yawn! Good night world!");
// Leave the current room and enter the menu room
MoveToRoom(menuRoom);
}
else
{
Say("I'm not feeling tired. I'm a fresh mushroom!");
Say("Maybe I should spawn some spores?");
// Use Call() to call another method whenever you want.
Call(ProduceSpores);
}
}
void ProduceSpores()
{
Say("Yeah! I feel like doing some sporing!");
Say("Wow - look at all these spores! COOL!");
// Sets a game flag which we check above in GoToSleep
SetFlag("spawned", true);
AddOption("So tired. I sleep now.", GoToSleep);
AddOption("No way! More spores!", ProduceSpores);
Choose("What will I do now?");
}
}

8
Assets/Example/Scripts/WritingRoom.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 79047217eeb604324b501728ce6c43b2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/Fungus.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 72452d0189a95436fb93c2ec54d83801
folderAsset: yes
DefaultImporter:
userData:

5
Assets/Fungus/Editor.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: b7cb2aa1c114f44b89b82bc527e85bab
folderAsset: yes
DefaultImporter:
userData:

44
Assets/Fungus/Editor/GameEditor.cs

@ -0,0 +1,44 @@
using UnityEditor;
using UnityEngine;
using System.Collections;
namespace Fungus
{
[CustomEditor (typeof(Game))]
public class GameEditor : Editor
{
private void OnSceneGUI()
{
GameEditor.DrawRoomNames();
}
static public void DrawRoomNames()
{
Handles.color = Color.white;
Handles.BeginGUI();
// Show labels for each room
Room[] rooms = GameObject.FindObjectsOfType<Room>();
foreach (Room room in rooms)
{
if (!room.renderer)
{
continue;
}
Bounds bounds = room.renderer.bounds;
Vector3 pos = new Vector3(bounds.min.x, bounds.max.y, 0);
GUIStyle style = new GUIStyle(GUI.skin.label);
style.normal.textColor = new Color(1,1,1);
style.fontSize /= 2;
Rect boxRect = HandleUtility.WorldPointToSizedRect(pos, new GUIContent(room.name), style);
boxRect.y -= boxRect.height * 1.5f;
GUI.Box(boxRect, room.name, style);
}
Handles.EndGUI();
}
}
}

8
Assets/Fungus/Editor/GameEditor.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5464e5745a4da462795a6f6f5b112962
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

98
Assets/Fungus/Editor/PageEditor.cs

@ -0,0 +1,98 @@
using UnityEditor;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
{
[CanEditMultipleObjects]
[CustomEditor (typeof(Page))]
public class PageEditor : Editor
{
void OnSceneGUI ()
{
Page t = target as Page;
// Render the parent view to help user position the page
Transform parent = t.transform.parent;
if (parent != null)
{
View view = parent.gameObject.GetComponent<View>();
if (view != null)
{
ViewEditor.DrawView(view);
}
}
if (t.enabled)
{
EditPageBounds();
}
if (GUI.changed)
{
EditorUtility.SetDirty(target);
}
}
void EditPageBounds()
{
Page t = target as Page;
Vector3 pos = t.transform.position;
Vector3[] verts = new Vector3[4];
verts[0] = new Vector3(pos.x + t.pageBounds.min.x, pos.y + t.pageBounds.min.y, 0);
verts[1] = new Vector3(pos.x + t.pageBounds.min.x, pos.y + t.pageBounds.max.y, 0);
verts[2] = new Vector3(pos.x + t.pageBounds.max.x, pos.y + t.pageBounds.max.y, 0);
verts[3] = new Vector3(pos.x + t.pageBounds.max.x, pos.y + t.pageBounds.min.y, 0);
Handles.DrawSolidRectangleWithOutline(verts, new Color(1,1,1,0.2f), new Color(0,0,0,1));
for(int i = 0; i < 4; ++i)
{
Vector3 vert = verts[i];
Vector3 newPos = Handles.FreeMoveHandle(vert,
Quaternion.identity,
HandleUtility.GetHandleSize(pos) * 0.1f,
Vector3.zero,
Handles.CubeCap);
newPos.z = 0;
verts[i] = newPos;
if (vert != newPos)
{
switch(i)
{
case 0:
verts[1].x = newPos.x;
verts[3].y = newPos.y;
break;
case 1:
verts[0].x = newPos.x;
verts[2].y = newPos.y;
break;
case 2:
verts[3].x = newPos.x;
verts[1].y = newPos.y;
break;
case 3:
verts[2].x = newPos.x;
verts[0].y = newPos.y;
break;
}
break;
}
}
Bounds newBounds = new Bounds(verts[0], Vector3.zero);
newBounds.Encapsulate(verts[1]);
newBounds.Encapsulate(verts[2]);
newBounds.Encapsulate(verts[3]);
t.transform.position = newBounds.center;
newBounds.center = Vector3.zero;
t.pageBounds = newBounds;
}
}
}

8
Assets/Fungus/Editor/PageEditor.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dce33924cf6804b2c94d17784a6037d1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

16
Assets/Fungus/Editor/RoomEditor.cs

@ -0,0 +1,16 @@
using UnityEditor;
using UnityEngine;
using System.Collections;
namespace Fungus
{
[CustomEditor (typeof(Room))]
[CanEditMultipleObjects]
public class RoomEditor : Editor
{
private void OnSceneGUI()
{
GameEditor.DrawRoomNames();
}
}
}

8
Assets/Fungus/Editor/RoomEditor.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0314fe408508a4b25afa76f65378a427
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

90
Assets/Fungus/Editor/ViewEditor.cs

@ -0,0 +1,90 @@
using UnityEditor;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Fungus;
[CanEditMultipleObjects]
[CustomEditor (typeof(View))]
public class ViewEditor : Editor
{
void OnSceneGUI ()
{
View t = target as View;
if (t.enabled)
{
EditViewBounds();
}
if (GUI.changed)
{
EditorUtility.SetDirty(target);
}
}
void EditViewBounds()
{
View t = target as View;
DrawView(t);
Vector3 pos = t.transform.position;
float viewSize = t.viewSize;
Vector3 newViewPos = Handles.PositionHandle(pos, Quaternion.identity);
t.transform.position = newViewPos;
Vector3[] handles = new Vector3[2];
handles[0] = pos + new Vector3(0, -viewSize, 0);
handles[1] = pos + new Vector3(0, viewSize, 0);
for (int i = 0; i < 2; ++i)
{
Vector3 newPos = Handles.FreeMoveHandle(handles[i],
Quaternion.identity,
HandleUtility.GetHandleSize(pos) * 0.1f,
Vector3.zero,
Handles.CubeCap);
if (newPos != handles[i])
{
t.viewSize = Mathf.Abs(newPos.y - pos.y);
break;
}
}
}
public static void DrawView(View view)
{
Vector3 pos = view.transform.position;
float viewSize = view.viewSize;
// Draw 2:1 aspect ratio box
{
float height = viewSize;
float width = height * (2f / 1f);
Vector3[] verts = new Vector3[4];
verts[0] = pos + new Vector3(-width, -height, 0);
verts[1] = pos + new Vector3(-width, height, 0);
verts[2] = pos + new Vector3(width, height, 0);
verts[3] = pos + new Vector3(width, -height, 0);
Handles.DrawSolidRectangleWithOutline(verts, new Color(1,1,1,0f), new Color(0,1,0,0.25f) );
}
// Draw 4:3 aspect ratio box
{
float height = viewSize;
float width = height * (4f / 3f);
Vector3[] verts = new Vector3[4];
verts[0] = pos + new Vector3(-width, -height, 0);
verts[1] = pos + new Vector3(-width, height, 0);
verts[2] = pos + new Vector3(width, height, 0);
verts[3] = pos + new Vector3(width, -height, 0);
Handles.DrawSolidRectangleWithOutline(verts, new Color(1,1,1,0f), new Color(0,1,0,1) );
}
}
}

8
Assets/Fungus/Editor/ViewEditor.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 66d37e0778b8a4bf9a5e498dc37467cf
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/Fungus/Fonts.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 9baefe3bcf2e94f17b5feaeb1c07e77e
folderAsset: yes
DefaultImporter:
userData:

5
Assets/Fungus/Fonts/open-sans.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: eb92cb8aa27394dbd87cb00161e162e8
folderAsset: yes
DefaultImporter:
userData:

201
Assets/Fungus/Fonts/open-sans/Apache License.txt

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

4
Assets/Fungus/Fonts/open-sans/Apache License.txt.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: 3e4f39b0883694bc1b7f6f8d0117fd68
TextScriptImporter:
userData:

BIN
Assets/Fungus/Fonts/open-sans/OpenSans-Regular.ttf

Binary file not shown.

14
Assets/Fungus/Fonts/open-sans/OpenSans-Regular.ttf.meta

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: a19d04f08ff4046d891ffab76afcc3b1
TrueTypeFontImporter:
serializedVersion: 2
fontSize: 16
forceTextureCase: -2
characterSpacing: 1
characterPadding: 0
includeFontData: 1
use2xBehaviour: 0
fontNames: []
customCharacters:
fontRenderingMode: 0
userData:

5
Assets/Fungus/Prefabs.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: dd60c6b3baeb0475db2ac8ac965401c4
folderAsset: yes
DefaultImporter:
userData:

BIN
Assets/Fungus/Prefabs/Game.prefab

Binary file not shown.

4
Assets/Fungus/Prefabs/Game.prefab.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: f6e5e4b8124614271beca06a1d6c67c2
NativeFormatImporter:
userData:

BIN
Assets/Fungus/Prefabs/Page.prefab

Binary file not shown.

4
Assets/Fungus/Prefabs/Page.prefab.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: ec557b5a76ab94961964394b8511fc9b
NativeFormatImporter:
userData:

BIN
Assets/Fungus/Prefabs/Room.prefab

Binary file not shown.

4
Assets/Fungus/Prefabs/Room.prefab.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: 6e8f8f59ed030466b99184bf0fb44954
NativeFormatImporter:
userData:

BIN
Assets/Fungus/Prefabs/View.prefab

Binary file not shown.

4
Assets/Fungus/Prefabs/View.prefab.meta

@ -0,0 +1,4 @@
fileFormatVersion: 2
guid: e0d427add844a4d9faf970a3afa07583
NativeFormatImporter:
userData:

5
Assets/Fungus/Scripts.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: f9ded1304c85a430bbc6c65f025cf4dc
folderAsset: yes
DefaultImporter:
userData:

48
Assets/Fungus/Scripts/Button.cs

@ -0,0 +1,48 @@
using UnityEngine;
using System.Collections;
namespace Fungus
{
// Simple button handler class.
// When the user taps on the button, the named method is called on ancestor game objects (if it exists).
[RequireComponent (typeof (SpriteController))]
[RequireComponent (typeof (Collider2D))]
public class Button : MonoBehaviour
{
public string methodName;
public bool autoDisable = true;
SpriteController spriteController;
void Start()
{
spriteController = GetComponent<SpriteController>();
}
void OnMouseUpAsButton()
{
if (methodName == "")
{
return;
}
// Ignore button press if button is not fully visible
if (!spriteController.isShown)
{
return;
}
Game game = Game.GetInstance();
game.ResetCommandQueue();
gameObject.SendMessageUpwards(methodName, SendMessageOptions.RequireReceiver);
game.ExecuteCommandQueue();
if (autoDisable)
{
gameObject.SetActive(false);
}
}
}
}

8
Assets/Fungus/Scripts/Button.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1fe346be2e3e54b0b8ec94f09bb152a4
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

199
Assets/Fungus/Scripts/CameraController.cs

@ -0,0 +1,199 @@
using UnityEngine;
using System;
using System.Collections;
using Fungus;
namespace Fungus
{
// Controller for main camera.
// Supports several types of camera transition including snap, pan & fade.
public class CameraController : MonoBehaviour
{
Action onArriveAction;
float moveDuration;
float moveTimer;
float startSize;
float endSize;
Vector3 startPos;
Vector3 endPos;
Camera mainCamera;
void Start()
{
GameObject cameraObject = GameObject.FindGameObjectWithTag("MainCamera");
if (cameraObject == null)
{
Debug.LogError("Failed to find game object with tag 'MainCamera'");
return;
}
mainCamera = cameraObject.GetComponent<Camera>();
if (mainCamera == null)
{
Debug.LogError("Failed to find camera component");
return;
}
Reset();
}
public Texture2D fadeTexture;
public float fadeAlpha = 1f;
void OnGUI()
{
int drawDepth = -1000;
if (fadeAlpha < 1f)
{
// 1 = scene fully visible
// 0 = scene fully obscured
GUI.color = new Color(1,1,1, 1f - fadeAlpha);
GUI.depth = drawDepth;
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), fadeTexture);
}
}
public void Fade(float targetAlpha, float fadeDuration, Action fadeAction)
{
StartCoroutine(FadeInternal(targetAlpha, fadeDuration, fadeAction));
}
public void FadeToView(View view, float fadeDuration, Action fadeAction)
{
// Fade out
Fade(0f, fadeDuration / 2f, delegate {
// Snap to new view
PanToView(view, 0f, null);
// Fade in
Fade(1f, fadeDuration / 2f, delegate {
if (fadeAction != null)
{
fadeAction();
}
});
});
}
IEnumerator FadeInternal(float targetAlpha, float fadeDuration, Action fadeAction)
{
float startAlpha = fadeAlpha;
float timer = 0;
while (timer < fadeDuration)
{
float t = timer / fadeDuration;
timer += Time.deltaTime;
t = Mathf.Clamp01(t);
fadeAlpha = Mathf.Lerp(startAlpha, targetAlpha, t);
yield return null;
}
fadeAlpha = targetAlpha;
if (fadeAction != null)
{
fadeAction();
}
}
void Reset()
{
moveDuration = 0;
moveTimer = 0;
startSize = 0;
endSize = 0;
startPos = Vector3.zero;
endPos = Vector3.zero;
onArriveAction = null;
}
public void SnapToView(View view)
{
PanToView(view, 0, null);
}
public void PanToView(View view, float duration, Action arriveAction)
{
Reset();
if (duration == 0f)
{
// Move immediately
mainCamera.orthographicSize = view.viewSize;
mainCamera.transform.position = view.transform.position;
SetCameraZ();
if (arriveAction != null)
{
arriveAction();
}
}
else
{
moveDuration = duration;
onArriveAction = arriveAction;
moveTimer = 0;
startSize = mainCamera.orthographicSize;
endSize = view.viewSize;
startPos = mainCamera.transform.position;
endPos = view.transform.position;
}
}
// Position camera so sprite is centered and fills the screen
public void CenterOnSprite(SpriteRenderer spriteRenderer)
{
Sprite sprite = spriteRenderer.sprite;
Vector3 extents = sprite.bounds.extents;
float localScaleY = spriteRenderer.transform.localScale.y;
mainCamera.orthographicSize = extents.y * localScaleY;
Vector3 pos = spriteRenderer.transform.position;
mainCamera.transform.position = new Vector3(pos.x, pos.y, 0);
SetCameraZ();
}
void Update ()
{
if (moveDuration == 0f)
{
return;
}
moveTimer += Time.deltaTime;
bool arrived = false;
if (moveTimer > moveDuration)
{
moveTimer = moveDuration;
arrived = true;
}
float t = moveTimer / moveDuration;
mainCamera.orthographicSize = Mathf.Lerp(startSize, endSize, Mathf.SmoothStep(0f, 1f, t));
mainCamera.transform.position = Vector3.Lerp(startPos, endPos, Mathf.SmoothStep(0f, 1f, t));
SetCameraZ();
if (arrived)
{
if (onArriveAction != null)
{
onArriveAction();
}
Reset();
}
}
void SetCameraZ()
{
mainCamera.transform.position = new Vector3(mainCamera.transform.position.x, mainCamera.transform.position.y, -10f);
}
}
}

9
Assets/Fungus/Scripts/CameraController.cs.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: efb7bb24722d4469bbd789bd2e01db19
MonoImporter:
serializedVersion: 2
defaultReferences:
- fadeTexture: {fileID: 2800000, guid: f6c7b1f3a78a24703b70c746d8b9c768, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:

54
Assets/Fungus/Scripts/CommandQueue.cs

@ -0,0 +1,54 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
{
// Manages a sequential list of commands.
// When a command completes, the next command is popped from the queue and exectuted.
public class CommandQueue : MonoBehaviour
{
[HideInInspector]
public CameraController cameraController;
public void Start()
{
cameraController = Game.GetInstance().GetComponent<CameraController>();
}
// Base class for commands used with the CommandQueue
public abstract class Command
{
public abstract void Execute(CommandQueue commandQueue, Action onComplete);
}
List<Command> commandList = new List<Command>();
public void AddCommand(Command command)
{
commandList.Add(command);
}
public void Reset()
{
StopAllCoroutines();
commandList.Clear();
}
public void Execute()
{
if (commandList.Count == 0)
{
return;
}
Command command = commandList[0];
command.Execute(this, delegate {
commandList.RemoveAt(0);
Execute();
});
}
}
}

8
Assets/Fungus/Scripts/CommandQueue.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6727650fe2095478c9d180eac7ba0d2f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

463
Assets/Fungus/Scripts/Commands.cs

@ -0,0 +1,463 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
{
// Call a delegate method on execution.
// This command can be used to schedule arbitrary script code.
public class CallCommand : CommandQueue.Command
{
Action callAction;
public CallCommand(Action _callAction)
{
if (_callAction == null)
{
Debug.LogError("Action must not be null.");
return;
}
callAction = _callAction;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
if (callAction != null)
{
callAction();
}
onComplete();
}
}
// Wait for a period of time
public class WaitCommand : CommandQueue.Command
{
float duration;
public WaitCommand(float _duration)
{
duration = _duration;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
commandQueue.StartCoroutine(WaitCoroutine(duration, onComplete));
}
IEnumerator WaitCoroutine(float duration, Action onComplete)
{
yield return new WaitForSeconds(duration);
if (onComplete != null)
{
onComplete();
}
}
}
// Sets the currently active view immediately.
// The main camera snaps to the active view.
public class SetViewCommand : CommandQueue.Command
{
View view;
public SetViewCommand(View _view)
{
if (_view == null)
{
Debug.LogError("View must not be null");
}
view = _view;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
commandQueue.cameraController.SnapToView(view);
Game.GetInstance().activeView = view;
// Set the first page component found (if any) as the active page
Page page = view.gameObject.GetComponentInChildren<Page>();
if (page != null)
{
Game.GetInstance().activePage = page;
}
if (onComplete != null)
{
onComplete();
}
}
}
// Sets the currently active page for text rendering
public class SetPageCommand : CommandQueue.Command
{
Page page;
public SetPageCommand(Page _page)
{
page = _page;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Game.GetInstance().activePage = page;
if (onComplete != null)
{
onComplete();
}
}
}
// Sets the title text displayed at the top of the active page
public class TitleCommand : CommandQueue.Command
{
string titleText;
public TitleCommand(string _titleText)
{
titleText = _titleText;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Page page = Game.GetInstance().activePage;
if (page == null)
{
Debug.LogError("Active page must not be null");
}
else
{
page.SetTitle(titleText);
}
if (onComplete != null)
{
onComplete();
}
}
}
// Writes story text to the currently active page.
// A 'continue' button is displayed when the text has fully appeared.
public class SayCommand : CommandQueue.Command
{
string storyText;
public SayCommand(string _storyText)
{
storyText = _storyText;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Page page = Game.GetInstance().activePage;
if (page == null)
{
Debug.LogError("Active page must not be null");
}
else
{
page.Say(storyText, onComplete);
}
}
}
// Adds an option button to the current list of options.
// Use the Choose command to display added options.
public class AddOptionCommand : CommandQueue.Command
{
string optionText;
Action optionAction;
public AddOptionCommand(string _optionText, Action _optionAction)
{
optionText = _optionText;
optionAction = _optionAction;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Page page = Game.GetInstance().activePage;
if (page == null)
{
Debug.LogError("Active page must not be null");
}
else
{
page.AddOption(optionText, optionAction);
}
if (onComplete != null)
{
onComplete();
}
}
}
// Displays all previously added options.
public class ChooseCommand : CommandQueue.Command
{
string chooseText;
public ChooseCommand(string _chooseText)
{
chooseText = _chooseText;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Page page = Game.GetInstance().activePage;
if (page == null)
{
Debug.LogError("Active page must not be null");
}
else
{
page.Choose(chooseText);
}
// Choose always clears commandQueue, so no need to call onComplete()
}
}
// Changes the active room to a different room
public class MoveToRoomCommand : CommandQueue.Command
{
Room room;
public MoveToRoomCommand(Room _room)
{
if (_room == null)
{
Debug.LogError("Room must not be null.");
return;
}
room = _room;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Game.GetInstance().MoveToRoom(room);
// MoveToRoom always resets the command queue so no need to call onComplete
}
}
// Sets a global boolean flag value
public class SetFlagCommand : CommandQueue.Command
{
string key;
bool value;
public SetFlagCommand(string _key, bool _value)
{
key = _key;
value = _value;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Game.GetInstance().SetFlag(key, value);
if (onComplete != null)
{
onComplete();
}
}
}
// Sets a global integer counter value
public class SetCounterCommand : CommandQueue.Command
{
string key;
int value;
public SetCounterCommand(string _key, int _value)
{
key = _key;
value = _value;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Game.GetInstance().SetCounter(key, value);
if (onComplete != null)
{
onComplete();
}
}
}
// Sets a global inventory count value
public class SetInventoryCommand : CommandQueue.Command
{
string key;
int value;
public SetInventoryCommand(string _key, int _value)
{
key = _key;
value = _value;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
Game.GetInstance().SetInventory(key, value);
if (onComplete != null)
{
onComplete();
}
}
}
// Fades a sprite to a given alpha value over a period of time
public class FadeSpriteCommand : CommandQueue.Command
{
SpriteController spriteController;
float targetAlpha;
float fadeDuration;
Vector2 slideOffset = Vector2.zero;
public FadeSpriteCommand(SpriteController _spriteController,
float _targetAlpha,
float _fadeDuration,
Vector2 _slideOffset)
{
if (_spriteController == null)
{
Debug.LogError("Sprite controller must not be null.");
return;
}
spriteController = _spriteController;
targetAlpha = _targetAlpha;
fadeDuration = _fadeDuration;
slideOffset = _slideOffset;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
spriteController.SlideFade(targetAlpha, fadeDuration, slideOffset);
if (onComplete != null)
{
onComplete();
}
}
}
// Plays the named animation on a object with a SpriteController component
public class PlayAnimationCommand : CommandQueue.Command
{
SpriteController spriteController;
string animationName;
public PlayAnimationCommand(SpriteController _spriteController,
string _animationName)
{
if (_spriteController == null)
{
Debug.LogError("Sprite controller must not be null.");
return;
}
spriteController = _spriteController;
animationName = _animationName;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
spriteController.PlayAnimation(animationName);
if (onComplete != null)
{
onComplete();
}
}
}
// Pans the camera to a view over a period of time.
public class PanToViewCommand : CommandQueue.Command
{
View view;
float duration;
public PanToViewCommand(View _view,
float _duration)
{
if (_view == null)
{
Debug.LogError("View must not be null.");
return;
}
view = _view;
duration = _duration;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
commandQueue.cameraController.PanToView(view, duration, delegate {
Game game = Game.GetInstance();
game.activeView = view;
// Try to find a page that is a child of the active view.
// If there are multiple child pages then it is the client's responsibility
// to set the correct active page in the room script.
Page defaultPage = view.gameObject.GetComponentInChildren<Page>();
if (defaultPage)
{
game.activePage = defaultPage;
}
if (onComplete != null)
{
onComplete();
}
});
}
}
// Fades the camera to a view over a period of time.
public class FadeToViewCommand : CommandQueue.Command
{
View view;
float duration;
public FadeToViewCommand(View _view,
float _duration)
{
if (_view == null)
{
Debug.LogError("View must not be null.");
return;
}
view = _view;
duration = _duration;
}
public override void Execute(CommandQueue commandQueue, Action onComplete)
{
commandQueue.cameraController.FadeToView(view, duration, delegate {
Game game = Game.GetInstance();
game.activeView = view;
// Try to find a page that is a child of the active view.
// If there are multiple child pages then it is the client's responsibility
// to set the correct active page in the room script.
Page defaultPage = view.gameObject.GetComponentInChildren<Page>();
if (defaultPage)
{
game.activePage = defaultPage;
}
if (onComplete != null)
{
onComplete();
}
});
}
}
}

8
Assets/Fungus/Scripts/Commands.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b221bfbeec06a47aab4bce90937db5e8
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

34
Assets/Fungus/Scripts/FixedHeightSprite.cs

@ -0,0 +1,34 @@
using UnityEngine;
using System.Collections;
namespace Fungus
{
// Adjusts the scale of a sprite to fit into a fixed number of vertical world units
// This helps to keep room sprites neatly organised in the editor.
[ExecuteInEditMode]
public class FixedHeightSprite : MonoBehaviour
{
public float height = 2f;
public void Update()
{
if (!Application.isPlaying)
{
SpriteRenderer spriteRenderer = renderer as SpriteRenderer;
if (!spriteRenderer || !spriteRenderer.sprite)
{
return;
}
transform.position = new Vector3(transform.position.x, transform.position.y, 0);
transform.rotation = Quaternion.identity;
float spriteHeight = spriteRenderer.sprite.bounds.extents.y * 2;
float scale = height / spriteHeight;
transform.localScale = new Vector3(scale, scale, 1f);
}
}
}
}

8
Assets/Fungus/Scripts/FixedHeightSprite.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 09bfb0dc7847247568d08205da364d93
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

178
Assets/Fungus/Scripts/Game.cs

@ -0,0 +1,178 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
{
// Manages movement between rooms and global game state
[RequireComponent (typeof (CommandQueue))]
[RequireComponent (typeof (CameraController))]
public class Game : MonoBehaviour
{
public bool showLinks = true;
public Room activeRoom;
[HideInInspector]
public View activeView;
[HideInInspector]
public Page activePage;
public GameState state = new GameState();
protected Dictionary<string, string> stringTable = new Dictionary<string, string>();
private static Game instance;
CameraController cameraController;
CommandQueue commandQueue;
public float fadeDuration = 1f;
public string continueText = "Continue";
public int charactersPerSecond = 60;
public static Game GetInstance()
{
if (!instance)
{
instance = GameObject.FindObjectOfType(typeof(Game)) as Game;
if (!instance)
{
Debug.LogError("There must be one active Game object in your scene.");
}
}
return instance;
}
public virtual void Start()
{
cameraController = GetComponent<CameraController>();
commandQueue = GetComponent<CommandQueue>();
if (activeRoom == null)
{
// Pick first room found if none is specified
activeRoom = GameObject.FindObjectOfType(typeof(Room)) as Room;
}
if (activeRoom != null)
{
MoveToRoom(activeRoom);
}
}
public Room GetCurrentRoom()
{
return GetInstance().activeRoom;
}
public void ResetCommandQueue()
{
commandQueue.Reset();
}
public void ExecuteCommandQueue()
{
commandQueue.Execute();
}
public void MoveToRoom(Room room)
{
if (room == null)
{
Debug.LogError("Failed to move to room. Room must not be null.");
return;
}
// Fade out screen
cameraController.Fade(0f, fadeDuration / 2f, delegate {
if (activeRoom != null)
{
activeRoom.Leave();
}
activeRoom = room;
activeRoom.Enter();
// Fade in screen
cameraController.Fade(1f, fadeDuration / 2f, null);
});
}
public void Restart()
{
// TODO: Reload scene
}
public void ClearFlags()
{
state.ClearFlags();
}
public bool GetFlag(string key)
{
return state.GetFlag(key);
}
public void SetFlag(string key, bool value)
{
state.SetFlag(key, value);
}
public void ClearCounters()
{
state.ClearCounters();
}
public int GetCounter(string key)
{
return state.GetCounter(key);
}
public void SetCounter(string key, int value)
{
state.SetCounter(key, value);
}
public void ClearInventory()
{
state.ClearInventory();
}
public int GetInventory(string key)
{
return state.GetInventory(key);
}
public void SetInventory(string key, int value)
{
state.SetInventory(key, value);
}
public void ClearStringTable()
{
stringTable.Clear();
}
public string GetString(string key)
{
if (stringTable.ContainsKey(key))
{
return stringTable[key];
}
return "";
}
public void SetString(string key, string value)
{
stringTable[key] = value;
}
}
}

8
Assets/Fungus/Scripts/Game.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 05e21cf853d714e3ab419e2573b64951
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

88
Assets/Fungus/Scripts/GameState.cs

@ -0,0 +1,88 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Fungus
{
// Manages the global state information for the game
// This is implemented as a separate class to support saving and loading game state easily.
public class GameState
{
protected Dictionary<string, bool> flags = new Dictionary<string, bool>();
protected Dictionary<string, int> counters = new Dictionary<string, int>();
protected Dictionary<string, int> inventory = new Dictionary<string, int>();
public GameState DeepClone()
{
GameState clone = new GameState();
foreach (string key in flags.Keys)
clone.flags[key] = flags[key];
foreach (string key in counters.Keys)
clone.counters[key] = counters[key];
foreach (string key in inventory.Keys)
clone.inventory[key] = inventory[key];
return clone;
}
public void ClearFlags()
{
flags.Clear();
}
public bool GetFlag(string key)
{
if (flags.ContainsKey(key))
{
return flags[key];
}
return false;
}
public void SetFlag(string key, bool value)
{
flags[key] = value;
}
public void ClearCounters()
{
counters.Clear();
}
public int GetCounter(string key)
{
if (counters.ContainsKey(key))
{
return counters[key];
}
return 0;
}
public void SetCounter(string key, int value)
{
counters[key] = value;
}
public void ClearInventory()
{
inventory.Clear();
}
public int GetInventory(string key)
{
if (inventory.ContainsKey(key))
{
return inventory[key];
}
return 0;
}
public void SetInventory(string key, int value)
{
inventory[key] = value;
}
}
}

8
Assets/Fungus/Scripts/GameState.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2420b605a4ce1443bba29d71d694429c
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

331
Assets/Fungus/Scripts/Page.cs

@ -0,0 +1,331 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Fungus
{
// A rectangular screen area for rendering story text.
// Rooms may contain any number of Pages.
// If a Page is a child of a View, then transitiong to that View will automatically activate the Page.
[ExecuteInEditMode]
public class Page : MonoBehaviour
{
public Bounds pageBounds = new Bounds(Vector3.zero, new Vector3(0.25f, 0.25f, 0f));
// The font size for title, say and option text is calculated by dividing the screen height
// by the number of allowed rows for each type of text. This gives a consistent font size
// regardless of the device resolution.
public int titleRows = 20;
public int sayRows = 25;
public int optionRows = 25;
public GUIStyle titleStyle;
public GUIStyle sayStyle;
public GUIStyle optionStyle;
public GUIStyle boxStyle;
string titleText = "";
string originalStoryText = "";
string displayedStoryText = "";
Action deferredAction;
public enum Mode
{
Idle,
Say,
Choose
};
Mode mode = Mode.Idle;
class Option
{
public string optionText;
public Action optionAction;
public Option(string _optionText, Action _optionAction)
{
optionText = _optionText;
optionAction = _optionAction;
}
}
List<Option> options = new List<Option>();
public void SetTitle(string _titleText)
{
titleText = _titleText;
}
public void Say(string sayText, Action sayAction)
{
mode = Mode.Say;
string subbedText = SubstituteStrings(sayText);
WriteStory(subbedText, sayAction);
}
public void AddOption(string optionText, Action optionAction)
{
string subbedText = FormatLinkText(SubstituteStrings(optionText));
options.Add(new Option(subbedText, optionAction));
}
public void Choose(string _chooseText)
{
mode = Mode.Choose;
string subbedText = SubstituteStrings(_chooseText);
WriteStory(subbedText, null);
}
void WriteStory(string storyText, Action writeAction)
{
originalStoryText = storyText;
// Add continue option
if (writeAction != null)
{
options.Clear();
options.Add(new Option(Game.GetInstance().continueText, writeAction));
}
// Hack to avoid displaying partial color tag text
if (storyText.Contains("<"))
{
displayedStoryText = storyText;
}
else
{
// Use a coroutine to write the text out over time
StartCoroutine(WriteStoryInternal());
}
}
IEnumerator WriteStoryInternal()
{
float writeDelay = 1f / (float)Game.GetInstance().charactersPerSecond;
displayedStoryText = "";
while (displayedStoryText.Length < originalStoryText.Length)
{
displayedStoryText += originalStoryText.Substring(displayedStoryText.Length, 1);
yield return new WaitForSeconds(writeDelay);
}
displayedStoryText = originalStoryText;
}
public virtual void OnGUI()
{
if (mode == Mode.Idle)
{
return;
}
Rect pageRect = GetScreenRect();
Rect outerRect = pageRect;
Rect innerRect = CalcInnerRect(outerRect);
// Calculate height of each section
float titleHeight = CalcTitleHeight(innerRect.width);
float storyHeight = CalcStoryHeight(innerRect.width);
float optionsHeight = CalcOptionsHeight(innerRect.width);
float contentHeight = titleHeight + storyHeight + optionsHeight;
// Adjust inner and outer rect to center around original page middle
outerRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom);
outerRect.y = pageRect.center.y - outerRect.height / 2;
innerRect = CalcInnerRect(outerRect);
// Override the font size to compensate for varying device resolution
titleStyle.fontSize = Screen.height / titleRows;
sayStyle.fontSize = Screen.height / sayRows;
optionStyle.fontSize = Screen.height / optionRows;
// Draw box
Rect boxRect = outerRect;
boxRect.height = contentHeight + (boxStyle.padding.top + boxStyle.padding.bottom);
GUI.Box(boxRect, "", boxStyle);
// Draw title label
Rect titleRect = innerRect;
titleRect.height = titleHeight;
GUI.Label(titleRect, titleText, titleStyle);
// Draw say label
Rect storyRect = innerRect;
storyRect.y += titleHeight;
storyRect.height = storyHeight;
GUI.Label(storyRect, displayedStoryText, sayStyle);
// Draw option buttons
bool finishedWriting = (displayedStoryText.Length == originalStoryText.Length);
if (finishedWriting)
{
Rect buttonRect = innerRect;
buttonRect.y += titleHeight + storyHeight;
foreach (Option option in options)
{
GUIContent buttonContent = new GUIContent(option.optionText);
buttonRect.height = optionStyle.CalcHeight(buttonContent, innerRect.width);
if (GUI.Button(buttonRect, buttonContent, optionStyle))
{
if (option.optionAction != null)
{
// We can't execute the option action yet because OnGUI
// may be called multiple times during a frame, and it's
// not permitted to modify GUI elements within a frame.
// We defer executing the action until OnGUI has completed.
deferredAction = option.optionAction;
break;
}
}
buttonRect.y += buttonRect.height;
}
}
if (Event.current.type == EventType.Repaint)
{
if (deferredAction != null)
{
Action tempAction = deferredAction;
options.Clear();
displayedStoryText = "";
originalStoryText = "";
deferredAction = null;
if (mode == Mode.Choose)
{
// Reset to idle, but calling action may set this again
mode = Mode.Idle;
Game.GetInstance().ResetCommandQueue();
tempAction();
Game.GetInstance().ExecuteCommandQueue();
}
else if (mode == Mode.Say)
{
// Reset to idle, but calling action may set this again
mode = Mode.Idle;
// Execute next command
tempAction();
}
}
}
}
float CalcTitleHeight(float boxWidth)
{
if (mode == Mode.Idle ||
titleText.Length == 0)
{
return 0;
}
GUIContent titleContent = new GUIContent(titleText);
return titleStyle.CalcHeight(titleContent, boxWidth);
}
float CalcStoryHeight(float boxWidth)
{
if (mode == Mode.Idle ||
originalStoryText.Length == 0)
{
return 0;
}
GUIContent storyContent = new GUIContent(originalStoryText + "\n");
return sayStyle.CalcHeight(storyContent, boxWidth);
}
float CalcOptionsHeight(float boxWidth)
{
if (mode == Mode.Idle ||
options.Count == 0)
{
return 0;
}
float totalHeight = 0;
foreach (Option option in options)
{
GUIContent optionContent = new GUIContent(option.optionText);
float optionHeight = optionStyle.CalcHeight(optionContent, boxWidth);
totalHeight += optionHeight;
}
return totalHeight;
}
// Returns smaller internal box rect with padding style applied
Rect CalcInnerRect(Rect outerRect)
{
return new Rect(outerRect.x + boxStyle.padding.left,
outerRect.y + boxStyle.padding.top,
outerRect.width - (boxStyle.padding.left + boxStyle.padding.right),
outerRect.height - (boxStyle.padding.top + boxStyle.padding.bottom));
}
private string SubstituteStrings(string text)
{
string subbedText = text;
// Instantiate the regular expression object.
Regex r = new Regex("{.*?}");
// Match the regular expression pattern against a text string.
var results = r.Matches(text);
foreach (Match match in results)
{
string stringKey = match.Value.Substring(1, match.Value.Length - 2);
string stringValue = Game.GetInstance().GetString(stringKey);
subbedText = subbedText.Replace(match.Value, stringValue);
}
return subbedText;
}
private string FormatLinkText(string text)
{
string trimmed;
if (text.Contains("\n"))
{
trimmed = text.Substring(0, text.IndexOf("\n"));
}
else
{
trimmed = text;
}
return trimmed;
}
Rect GetScreenRect()
{
// Y decreases up the screen in GUI space, so top left is rect origin
Vector3 topLeft = transform.position + pageBounds.center;
topLeft.x -= pageBounds.extents.x;
topLeft.y += pageBounds.extents.y;
Vector3 bottomRight = transform.position + pageBounds.center;
bottomRight.x += pageBounds.extents.x;
bottomRight.y -= pageBounds.extents.y;
Camera mainCamera = GameObject.FindGameObjectWithTag("MainCamera").camera;
Vector2 tl = mainCamera.WorldToScreenPoint(topLeft);
Vector2 br = mainCamera.WorldToScreenPoint(bottomRight);
return new Rect(tl.x, Screen.height - tl.y, br.x - tl.x, tl.y - br.y);
}
}
}

8
Assets/Fungus/Scripts/Page.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2154cd49b43b3450fb92da231e24e065
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

320
Assets/Fungus/Scripts/Room.cs

@ -0,0 +1,320 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Fungus;
namespace Fungus
{
// This is the main scripting interface for Fungus games.
// Each room in your game should have a script which inherits from Room.
// The OnEnter() method is called when the player enters the room.
// The OnLeave() method is called when the player moves to a different room.
// Convenience methods are provided for accessing all features of the library.
public abstract class Room : MonoBehaviour
{
public int visitCount;
Game game;
CommandQueue commandQueue;
CameraController cameraController;
void Awake()
{
game = Game.GetInstance();
cameraController = game.gameObject.GetComponent<CameraController>();
commandQueue = game.gameObject.GetComponent<CommandQueue>();
}
void OnDrawGizmos()
{
const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
FieldInfo[] fields = this.GetType().GetFields(flags);
foreach (FieldInfo fieldInfo in fields)
{
Room room = fieldInfo.GetValue(this) as Room;
if (room != null)
{
DrawLinkToRoom(room);
}
}
}
void DrawLinkToRoom(Room room)
{
if (!room)
{
Gizmos.color = Color.red;
Gizmos.DrawWireCube(transform.position, renderer.bounds.size * 1.1f);
return;
}
if (!Game.GetInstance().showLinks)
{
return;
}
Gizmos.color = Color.green;
Vector3 posA = transform.position;
Vector3 posB = room.transform.position;
Ray toA = new Ray(posB, posA - posB);
Ray toB = new Ray(posA, posB - posA);
float tA = 0;
if (renderer)
{
if (renderer.bounds.IntersectRay(toA, out tA))
{
posA = toA.GetPoint(tA * 0.95f);
}
}
float tB = 0;
if (room.gameObject.renderer)
{
if (room.gameObject.renderer.bounds.IntersectRay(toB, out tB))
{
posB = toB.GetPoint(tB * 0.95f);
}
}
Gizmos.DrawLine(posA, posB);
float arrowHeadSize = 0.25f;
Vector3 arrowPosA = posB;
Vector3 arrowPosB = arrowPosA;
Vector3 arrowPosC = arrowPosA;
arrowPosB.x += toB.direction.y * arrowHeadSize;
arrowPosB.y -= toB.direction.x * arrowHeadSize;
arrowPosB -= toB.direction * arrowHeadSize;
Gizmos.DrawLine(arrowPosA, arrowPosB);
arrowPosC.x -= toB.direction.y * arrowHeadSize;
arrowPosC.y += toB.direction.x * arrowHeadSize;
arrowPosC -= toB.direction * arrowHeadSize;
Gizmos.DrawLine(arrowPosA, arrowPosC);
}
// Internal use only! Called by Game when changing room
public void Enter()
{
// Pick first view found in the room and snap to camera to this view.
// It is allowed for a room to not have any views.
// In this case game.activeView will be null, and the camera will attempt
// to snap to the room sprite.
View view = gameObject.GetComponentInChildren<View>();
if (view == null)
{
// No view defined for this room, try to center on room sprite
SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
{
cameraController.CenterOnSprite(spriteRenderer);
}
else
{
Debug.LogError("Failed to set camera view when entering room.");
}
}
else
{
// Snap to new view
cameraController.SnapToView(view);
game.activeView = view;
}
// Pick first page found in room
// It is allowed for a room to not have any pages. In this case game.activePage will be null
game.activePage = gameObject.GetComponentInChildren<Page>();
// Rooms may have multiple child views and page. It is the responsibility of the client
// room script to set the appropriate view & page in its OnEnter method.
game.ResetCommandQueue();
SendMessage("OnEnter", SendMessageOptions.DontRequireReceiver);
game.ExecuteCommandQueue();
visitCount++;
}
// Internal use only! Called by Game when changing room
public void Leave()
{
SendMessage("OnLeave", SendMessageOptions.DontRequireReceiver);
}
// Public convenience methods
// These methods all execute immediately
// Returns true if this is the first time the player has visited this room
public bool IsFirstVisit()
{
return (visitCount == 0);
}
// Return true if the boolean flag for the key has been set to true
public bool GetFlag(string key)
{
return game.GetFlag(key);
}
// Returns the count value for the key
// Returns zero if no value has been set.
public int GetCounter(string key)
{
return game.GetCounter(key);
}
// Returns the inventory count value for the key
// Returns zero if no inventory count has been set.
public int GetInventory(string key)
{
return game.GetInventory(key);
}
// Returns true if the inventory count for the key is greater than zero
public bool HasInventory(string key)
{
return (game.GetInventory(key) > 0);
}
// Public command methods
// These methods all queue commands for later execution in serial order
// Wait for a period of time before executing the next command
public void Wait(float duration)
{
commandQueue.AddCommand(new WaitCommand(duration));
}
// Call a delegate method provided by the client
// Used to queue the execution of arbitrary code.
public void Call(Action callAction)
{
commandQueue.AddCommand(new CallCommand(callAction));
}
// Sets the currently active view immediately.
// The main camera snaps to the active view.
public void SetView(View view)
{
commandQueue.AddCommand(new SetViewCommand(view));
}
// Sets the currently active page for text rendering
public void SetPage(Page page)
{
commandQueue.AddCommand(new SetPageCommand(page));
}
// Sets the title text displayed at the top of the active page
public void Title(string titleText)
{
commandQueue.AddCommand(new TitleCommand(titleText));
}
// Writes story text to the currently active page.
// A 'continue' button is displayed when the text has fully appeared.
public void Say(string storyText)
{
commandQueue.AddCommand(new SayCommand(storyText));
}
// Adds an option button to the current list of options.
// Use the Choose command to display added options.
public void AddOption(string optionText, Action optionAction)
{
commandQueue.AddCommand(new AddOptionCommand(optionText, optionAction));
}
// Displays a text prompt, followed by all previously added options as buttons.
public void Choose(string chooseText)
{
commandQueue.AddCommand(new ChooseCommand(chooseText));
}
// Changes the active room to a different room
public void MoveToRoom(Room room)
{
commandQueue.AddCommand(new MoveToRoomCommand(room));
}
// Sets a global boolean flag value
public void SetFlag(string key, bool value)
{
commandQueue.AddCommand(new SetFlagCommand(key, value));
}
// Sets a global integer counter value
public void SetCounter(string key, int value)
{
commandQueue.AddCommand(new SetCounterCommand(key, value));
}
// Sets a global inventory count value
// Assumes that the count value is 1 (common case)
public void SetInventory(string key)
{
commandQueue.AddCommand(new SetInventoryCommand(key, 1));
}
// Sets a global inventory count value
public void SetInventory(string key, int value)
{
commandQueue.AddCommand(new SetInventoryCommand(key, value));
}
// Sets sprite alpha to 0 immediately
public void HideSprite(SpriteController spriteController)
{
commandQueue.AddCommand(new FadeSpriteCommand(spriteController, 0f, 0f, Vector2.zero));
}
// Sets sprite alpha to 1 immediately
public void ShowSprite(SpriteController spriteController)
{
commandQueue.AddCommand(new FadeSpriteCommand(spriteController, 1f, 0f, Vector2.zero));
}
// Fades a sprite to a given alpha value over a period of time
public void FadeSprite(SpriteController spriteController, float targetAlpha, float duration)
{
commandQueue.AddCommand(new FadeSpriteCommand(spriteController, targetAlpha, duration, Vector2.zero));
}
// Fades a sprite to a given alpha value over a period of time, and applies a sliding motion to the sprite transform
public void FadeSprite(SpriteController spriteController, float targetAlpha, float duration, Vector2 slideOffset)
{
commandQueue.AddCommand(new FadeSpriteCommand(spriteController, targetAlpha, duration, slideOffset));
}
// Plays the named animation on a object with a SpriteController component
public void PlayAnimation(SpriteController spriteController, string animationName)
{
commandQueue.AddCommand(new PlayAnimationCommand(spriteController, animationName));
}
// Pans the camera to the target view of a period of time
public void PanToView(View targetView, float duration)
{
commandQueue.AddCommand(new PanToViewCommand(targetView, duration));
}
// Snaps the camera to the target view immediately
public void SnapToView(View targetView)
{
commandQueue.AddCommand(new PanToViewCommand(targetView, 0f));
}
// Fades out the current camera view, and fades in again using the target view.
public void FadeToView(View targetView, float duration)
{
commandQueue.AddCommand(new FadeToViewCommand(targetView, duration));
}
}
}

8
Assets/Fungus/Scripts/Room.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0f9670668ba24460ab0f64b121ec7d51
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

20
Assets/Fungus/Scripts/RoomTemplate.cs

@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections;
using Fungus;
// An empty template room class to use as a starting point for your own room scripts.
// Copy this script to your game folder, rename it and add it to your room object.
public class RoomTemplate : Room
{
// Properties go here
// Called when the player enters the room
void OnEnter()
{
}
// Called when the player leaves the room
void OnLeave()
{
}
}

8
Assets/Fungus/Scripts/RoomTemplate.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4c04fb21e6b82447da36d145d0c35c18
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

120
Assets/Fungus/Scripts/SpriteController.cs

@ -0,0 +1,120 @@
using UnityEngine;
using System.Collections;
namespace Fungus
{
// Extends sprite functionality with support for fading and playing simple animations
[RequireComponent (typeof (SpriteRenderer))]
public class SpriteController : MonoBehaviour
{
[HideInInspector]
public bool isShown;
private float spriteAlpha;
private float fadeDuration;
private float fadeTimer;
private float startAlpha;
private float endAlpha;
private Vector3 startPosition;
private Vector3 startSlideOffset;
void Start()
{
SpriteRenderer spriteRenderer = renderer as SpriteRenderer;
spriteAlpha = spriteRenderer.color.a;
}
void Update()
{
if (fadeDuration > 0f)
{
fadeTimer += Time.deltaTime;
if (fadeTimer > fadeDuration)
{
spriteAlpha = endAlpha;
fadeDuration = 0;
}
else
{
float t = Mathf.SmoothStep(0, 1, fadeTimer / fadeDuration);
spriteAlpha = Mathf.Lerp(startAlpha, endAlpha, t);
transform.position = Vector3.Lerp(startPosition + startSlideOffset, startPosition, t);
}
}
UpdateSpriteColor();
}
void UpdateSpriteColor()
{
isShown = (spriteAlpha == 1f);
SpriteRenderer spriteRenderer = renderer as SpriteRenderer;
Color color = spriteRenderer.material.color;
color.a = spriteAlpha;
spriteRenderer.material.color = color;
SpriteRenderer[] children = gameObject.GetComponentsInChildren<SpriteRenderer>();
foreach (SpriteRenderer child in children)
{
Color childColor = child.material.color;
childColor.a = spriteAlpha;
child.material.color = childColor;
}
}
public void Fade(float targetAlpha, float duration)
{
if (duration == 0f)
{
spriteAlpha = targetAlpha;
return;
}
fadeDuration = duration;
fadeTimer = 0;
startAlpha = spriteAlpha;
endAlpha = targetAlpha;
startPosition = transform.position;
startSlideOffset = Vector3.zero;
SpriteController[] children = gameObject.GetComponentsInChildren<SpriteController>();
foreach (SpriteController child in children)
{
if (child == this)
{
continue;
}
child.Fade(targetAlpha, duration);
}
}
public void SlideFade(float targetAlpha, float duration, Vector2 slideOffset)
{
Fade(targetAlpha, duration);
if (duration > 0)
{
startSlideOffset = slideOffset;
}
}
public void PlayAnimation(string animationName)
{
Animator anim = GetComponent<Animator>();
if (anim == null)
{
Debug.LogError("Failed to find animator component when playing animation " + animationName);
return;
}
anim.Play(animationName);
}
}
}

8
Assets/Fungus/Scripts/SpriteController.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fc308840c2cad4e02af85d79616861fd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

105
Assets/Fungus/Scripts/StringsParser.cs

@ -0,0 +1,105 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Fungus
{
// Parses a text file in a simple format and adds string values to the global string table.
// The format is:
// $FirstString
// The first string text goes here
// $SecondString
// The second string text goes here
// # This is a comment line and will be ignored by the parser
public class StringsParser : MonoBehaviour
{
public TextAsset stringsFile;
private enum ParseMode
{
Idle,
Text,
};
void Start()
{
StringsParser.ProcessText(stringsFile.text);
}
static public void ProcessText(string text)
{
// Split text into lines. Add a newline at end to ensure last command is always parsed
string[] lines = Regex.Split(text + "\n", "(?<=\n)");
string blockBuffer = "";
ParseMode mode = ParseMode.Idle;
string blockTag = "";
for (int i = 0; i < lines.Length; ++i)
{
string line = lines[i];
bool newBlock = line.StartsWith("$");
if (mode == ParseMode.Idle && !newBlock)
{
// Ignore any text not preceded by a label tag
continue;
}
string newBlockTag = "";
if (newBlock)
{
newBlockTag = line.Replace ("\n", "");
}
bool endOfFile = (i == lines.Length-1);
bool storeBlock = false;
if (newBlock)
{
storeBlock = true;
}
else if (mode == ParseMode.Text && endOfFile)
{
storeBlock = true;
if (!line.StartsWith("#"))
{
blockBuffer += line;
}
}
else
{
if (!line.StartsWith("#"))
{
blockBuffer += line;
}
}
if (storeBlock)
{
if (blockTag.Length > 0 && blockBuffer.Length > 0)
{
// Trim off last newline
blockBuffer = blockBuffer.TrimEnd( '\r', '\n', ' ', '\t');
Game.GetInstance().SetString(blockTag, blockBuffer);
}
// Prepare to parse next block
mode = ParseMode.Idle;
if (newBlock)
{
mode = ParseMode.Text;
blockTag = newBlockTag;
}
blockBuffer = "";
}
}
}
}
}

8
Assets/Fungus/Scripts/StringsParser.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0f02aedc631824200a4abe95774a44f5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

19
Assets/Fungus/Scripts/View.cs

@ -0,0 +1,19 @@
using UnityEngine;
using System.Collections;
namespace Fungus
{
// Defines a camera view point.
// The position and rotation are specified using the game object's transform, so this class
// only specifies the ortographic view size.
[ExecuteInEditMode]
public class View : MonoBehaviour
{
public float viewSize = 0.5f;
void Start()
{
// An empty Start() method is needed to display enable checkbox in editor
}
}
}

8
Assets/Fungus/Scripts/View.cs.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 95c387d3e32404bcc91c60318d766bb1
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

5
Assets/Fungus/Sprites.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: 46997c16617ca413c9b5d94fd22aeb52
folderAsset: yes
DefaultImporter:
userData:

BIN
Assets/Fungus/Sprites/Fungus.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

45
Assets/Fungus/Sprites/Fungus.png.meta

@ -0,0 +1,45 @@
fileFormatVersion: 2
guid: 773b12a7efad440aeaaed4ef18989818
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 0
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: .5, y: .5}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 8
buildTargetSettings: []
spriteSheet:
sprites: []
spritePackingTag:
userData:

BIN
Assets/Fungus/Sprites/Mushroom.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

45
Assets/Fungus/Sprites/Mushroom.png.meta

@ -0,0 +1,45 @@
fileFormatVersion: 2
guid: b1f86eb0dd1bd4f6f972269140a7d425
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 0
linearTexture: 0
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -3
maxTextureSize: 1024
textureSettings:
filterMode: 0
aniso: 1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: .5, y: .5}
spritePixelsToUnits: 100
alphaIsTransparency: 1
textureType: 8
buildTargetSettings: []
spriteSheet:
sprites: []
spritePackingTag:
userData:

5
Assets/Fungus/Textures.meta

@ -0,0 +1,5 @@
fileFormatVersion: 2
guid: cf85925068af94b348277e4f112490c1
folderAsset: yes
DefaultImporter:
userData:

BIN
Assets/Fungus/Textures/Fade.png

Binary file not shown.

45
Assets/Fungus/Textures/Fade.png.meta

@ -0,0 +1,45 @@
fileFormatVersion: 2
guid: f6c7b1f3a78a24703b70c746d8b9c768
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 1
linearTexture: 0
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: .5, y: .5}
spritePixelsToUnits: 100
alphaIsTransparency: 0
textureType: -1
buildTargetSettings: []
spriteSheet:
sprites: []
spritePackingTag:
userData:

BIN
Assets/Fungus/Textures/box.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

45
Assets/Fungus/Textures/box.png.meta

@ -0,0 +1,45 @@
fileFormatVersion: 2
guid: 9590a0e80747c47c5a37f3a19e751e4c
TextureImporter:
serializedVersion: 2
mipmaps:
mipMapMode: 0
enableMipMap: 1
linearTexture: 0
correctGamma: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: .25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 1024
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: -1
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: .5, y: .5}
spritePixelsToUnits: 100
alphaIsTransparency: 0
textureType: -1
buildTargetSettings: []
spriteSheet:
sprites: []
spritePackingTag:
userData:

14
Fungus.userprefs

@ -0,0 +1,14 @@
<Properties>
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.Workbench ActiveDocument="Assets/Example/Scripts/WritingRoom.cs">
<Files>
<File FileName="Assets/Example/Scripts/MenuRoom.cs" Line="18" Column="1" />
<File FileName="Assets/Example/Scripts/WritingRoom.cs" Line="54" Column="35" />
<File FileName="Assets/Fungus/Scripts/RoomTemplate.cs" Line="1" Column="1" />
</Files>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints>
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
</Properties>

BIN
ProjectSettings/AudioManager.asset

Binary file not shown.

BIN
ProjectSettings/DynamicsManager.asset

Binary file not shown.

BIN
ProjectSettings/EditorBuildSettings.asset

Binary file not shown.

BIN
ProjectSettings/EditorSettings.asset

Binary file not shown.

BIN
ProjectSettings/GraphicsSettings.asset

Binary file not shown.

BIN
ProjectSettings/InputManager.asset

Binary file not shown.

BIN
ProjectSettings/NavMeshLayers.asset

Binary file not shown.

BIN
ProjectSettings/NetworkManager.asset

Binary file not shown.

BIN
ProjectSettings/Physics2DSettings.asset

Binary file not shown.

BIN
ProjectSettings/ProjectSettings.asset

Binary file not shown.

BIN
ProjectSettings/QualitySettings.asset

Binary file not shown.

BIN
ProjectSettings/TagManager.asset

Binary file not shown.

BIN
ProjectSettings/TimeManager.asset

Binary file not shown.
Loading…
Cancel
Save