diff --git a/Assets/Code/ActController.cs b/Assets/Code/ActController.cs deleted file mode 100644 index 806d84b..0000000 --- a/Assets/Code/ActController.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.EventSystems; - - -public abstract class ActController : MonoBehaviour -{ - [Header("Settings")] - public ActSettings settings = null; - protected ActPhase phase = ActPhase.NONE; - - [Header("Results")] - public ActResults results = null; - - [Header("Objects")] - public Canvas canvas = null; - public EventSystem eventSystem = null; - - [Serializable] - public class InvalidPhaseException : Exception { - public readonly ActPhase currentPhase; - - public InvalidPhaseException(ActPhase currentPhase) { - this.currentPhase = currentPhase; - } - }; - - [Serializable] - public class MissingSettingsException : Exception {}; - - public ActPhase Phase { get; } - - /// - /// Call this to initialize the Act (GameObjects, ActSettings, etc). All interactable components should be disabled in this phase. - /// - public virtual void ActInit() { - phase = ActPhase.INIT; - - canvas = GameObject.FindGameObjectWithTag("Canvas")?.GetComponent(); - eventSystem = GameObject.FindGameObjectWithTag("EventSystem")?.GetComponent(); - - if(settings == null) { - throw new MissingSettingsException(); - } - } - - /// - /// Call this to enable all interactable components in the Act. It should be called when the player is ready to play. - /// - public virtual void ActStart() { - if(Phase != ActPhase.INIT) throw new InvalidPhaseException(phase); - phase = ActPhase.START; - } - - /// - /// Call this to disable once again all interactable components in the Act. It should be called when the Act is finished (time ran out, player reached submission limit, etc). - /// - public virtual void ActEnd() { - if(Phase != ActPhase.START) throw new InvalidPhaseException(phase); - phase = ActPhase.END; - } - - /// - /// Call this to cleanup all GameObjects created during the Init phase. - /// - public virtual void ActCleanup() { - if(Phase != ActPhase.END) { - Debug.LogWarningFormat("ActCleanup() was called during {0}", Phase); - } - phase = ActPhase.CLEANUP; - } - - protected virtual void Awake() { - - } - - protected virtual void Start() { - - } - - protected virtual void Update() { - - } - - protected virtual void OnDestroy() { - ActCleanup(); - } -} diff --git a/Assets/Code/SampleTypingAct.json.meta b/Assets/Code/Common.meta similarity index 57% rename from Assets/Code/SampleTypingAct.json.meta rename to Assets/Code/Common.meta index 1402d3b..4d3dc5c 100644 --- a/Assets/Code/SampleTypingAct.json.meta +++ b/Assets/Code/Common.meta @@ -1,6 +1,7 @@ fileFormatVersion: 2 -guid: c059168d0dc57204b9d45701d0fc25a0 -TextScriptImporter: +guid: c1b50fe5123a21e44ac5f1d6f24daef2 +folderAsset: yes +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/Assets/Code/ActPhase.cs b/Assets/Code/Common/ActPhase.cs similarity index 100% rename from Assets/Code/ActPhase.cs rename to Assets/Code/Common/ActPhase.cs diff --git a/Assets/Code/ActPhase.cs.meta b/Assets/Code/Common/ActPhase.cs.meta similarity index 100% rename from Assets/Code/ActPhase.cs.meta rename to Assets/Code/Common/ActPhase.cs.meta diff --git a/Assets/Code/ActResults.cs b/Assets/Code/Common/ActResults.cs similarity index 100% rename from Assets/Code/ActResults.cs rename to Assets/Code/Common/ActResults.cs diff --git a/Assets/Code/ActResults.cs.meta b/Assets/Code/Common/ActResults.cs.meta similarity index 100% rename from Assets/Code/ActResults.cs.meta rename to Assets/Code/Common/ActResults.cs.meta diff --git a/Assets/Code/ActSettings.cs b/Assets/Code/Common/ActSettings.cs similarity index 100% rename from Assets/Code/ActSettings.cs rename to Assets/Code/Common/ActSettings.cs diff --git a/Assets/Code/ActSettings.cs.meta b/Assets/Code/Common/ActSettings.cs.meta similarity index 100% rename from Assets/Code/ActSettings.cs.meta rename to Assets/Code/Common/ActSettings.cs.meta diff --git a/Assets/Code/Common/ConnectedPlayer.cs b/Assets/Code/Common/ConnectedPlayer.cs new file mode 100644 index 0000000..156cbcf --- /dev/null +++ b/Assets/Code/Common/ConnectedPlayer.cs @@ -0,0 +1,22 @@ +using System; + + +[Serializable] +public class ConnectedPlayerData { + public string name; + public int id; +} + +public class ConnectedPlayer { + public string name; + public int id; + + public ConnectedPlayerData Data { + get { + return new ConnectedPlayerData { + name = this.name, + id = this.id + }; + } + } +} \ No newline at end of file diff --git a/Assets/Code/Player.cs.meta b/Assets/Code/Common/ConnectedPlayer.cs.meta similarity index 100% rename from Assets/Code/Player.cs.meta rename to Assets/Code/Common/ConnectedPlayer.cs.meta diff --git a/Assets/Code/Viewer.cs.meta b/Assets/Code/Common/ConnectedViewer.cs.meta similarity index 100% rename from Assets/Code/Viewer.cs.meta rename to Assets/Code/Common/ConnectedViewer.cs.meta diff --git a/Assets/Code/DrawingResults.cs b/Assets/Code/Common/DrawingResults.cs similarity index 100% rename from Assets/Code/DrawingResults.cs rename to Assets/Code/Common/DrawingResults.cs diff --git a/Assets/Code/DrawingResults.cs.meta b/Assets/Code/Common/DrawingResults.cs.meta similarity index 100% rename from Assets/Code/DrawingResults.cs.meta rename to Assets/Code/Common/DrawingResults.cs.meta diff --git a/Assets/Code/Common/DrawingSettings.cs b/Assets/Code/Common/DrawingSettings.cs new file mode 100644 index 0000000..af1e7d8 --- /dev/null +++ b/Assets/Code/Common/DrawingSettings.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + + +[Serializable] +public class DrawingSettings : ActSettings { + public Color startingColor = Color.white; + public Color[] palette = null; + public float timeLimit = 99f; + public string actName = "Untitled"; + public string actDescription = "This Act is missing a description."; + public string destinationPool = "default"; +} \ No newline at end of file diff --git a/Assets/Code/DrawingSettings.cs.meta b/Assets/Code/Common/DrawingSettings.cs.meta similarity index 100% rename from Assets/Code/DrawingSettings.cs.meta rename to Assets/Code/Common/DrawingSettings.cs.meta diff --git a/Assets/Code/GamePhase.cs b/Assets/Code/Common/GamePhase.cs similarity index 72% rename from Assets/Code/GamePhase.cs rename to Assets/Code/Common/GamePhase.cs index e09a6cc..f289a9c 100644 --- a/Assets/Code/GamePhase.cs +++ b/Assets/Code/Common/GamePhase.cs @@ -1,7 +1,10 @@ +using System; + +[Serializable] public enum GamePhase { UNINTIALIZED, LOBBY, ACTS, RESULTS, ENDED -} \ No newline at end of file +} diff --git a/Assets/Code/GamePhase.cs.meta b/Assets/Code/Common/GamePhase.cs.meta similarity index 100% rename from Assets/Code/GamePhase.cs.meta rename to Assets/Code/Common/GamePhase.cs.meta diff --git a/Assets/Code/GameSettings.cs b/Assets/Code/Common/GameSettings.cs similarity index 84% rename from Assets/Code/GameSettings.cs rename to Assets/Code/Common/GameSettings.cs index 4171296..6f440db 100644 --- a/Assets/Code/GameSettings.cs +++ b/Assets/Code/Common/GameSettings.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; [Serializable] diff --git a/Assets/Code/GameSettings.cs.meta b/Assets/Code/Common/GameSettings.cs.meta similarity index 100% rename from Assets/Code/GameSettings.cs.meta rename to Assets/Code/Common/GameSettings.cs.meta diff --git a/Assets/Code/Common/NetMessage.cs b/Assets/Code/Common/NetMessage.cs new file mode 100644 index 0000000..6d4aaf5 --- /dev/null +++ b/Assets/Code/Common/NetMessage.cs @@ -0,0 +1,65 @@ +using Mirror; + + +namespace BetterTee.NetMsg +{ + namespace Server + { + namespace Error { + public class InvalidPassword : MessageBase {} + public class GameAlreadyStarted : MessageBase {} + } + + public class LobbyStatusChange : MessageBase { + public ConnectedPlayerData[] players; + public ConnectedViewerData[] viewers; + } + + public class LobbyEnd : MessageBase + { + public ConnectedPlayerData[] players; + } + + public class ActInit : MessageBase + { + public ActSettings settings; + } + + public class ActStart : MessageBase {} + + public class ActEnd : MessageBase {} + + public class GameEnd : MessageBase + { + public ConnectedPlayerData[] leaderboard; + } + } + + namespace Client + { + public class PlayerJoin : MessageBase + { + public string playerName; + public string gamePassword; + } + + public class ActResults : MessageBase + { + public ActResults results; + } + } + + namespace Viewer + { + public class ViewerLink : MessageBase + { + public string viewerName; + public string gamePassword; + } + + public class Settings : MessageBase + { + public GameSettings settings; + } + } +} \ No newline at end of file diff --git a/Assets/Code/NetMessage.cs.meta b/Assets/Code/Common/NetMessage.cs.meta similarity index 100% rename from Assets/Code/NetMessage.cs.meta rename to Assets/Code/Common/NetMessage.cs.meta diff --git a/Assets/Code/TypingResults.cs b/Assets/Code/Common/TypingResults.cs similarity index 85% rename from Assets/Code/TypingResults.cs rename to Assets/Code/Common/TypingResults.cs index 5b4404f..741716f 100644 --- a/Assets/Code/TypingResults.cs +++ b/Assets/Code/Common/TypingResults.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; [Serializable] diff --git a/Assets/Code/TypingResults.cs.meta b/Assets/Code/Common/TypingResults.cs.meta similarity index 100% rename from Assets/Code/TypingResults.cs.meta rename to Assets/Code/Common/TypingResults.cs.meta diff --git a/Assets/Code/Common/TypingSettings.cs b/Assets/Code/Common/TypingSettings.cs new file mode 100644 index 0000000..e99d1fb --- /dev/null +++ b/Assets/Code/Common/TypingSettings.cs @@ -0,0 +1,10 @@ +using System; + + +[Serializable] +public class TypingSettings : ActSettings { + public float timeLimit = 99f; + public string actName = "Untitled"; + public string actDescription = "This Act is missing a description."; + public string destinationPool = "default"; +} \ No newline at end of file diff --git a/Assets/Code/TypingSettings.cs.meta b/Assets/Code/Common/TypingSettings.cs.meta similarity index 100% rename from Assets/Code/TypingSettings.cs.meta rename to Assets/Code/Common/TypingSettings.cs.meta diff --git a/Assets/Code/Utils.cs b/Assets/Code/Common/Utils.cs similarity index 100% rename from Assets/Code/Utils.cs rename to Assets/Code/Common/Utils.cs diff --git a/Assets/Code/Utils.cs.meta b/Assets/Code/Common/Utils.cs.meta similarity index 100% rename from Assets/Code/Utils.cs.meta rename to Assets/Code/Common/Utils.cs.meta diff --git a/Assets/Code/DrawTool.cs b/Assets/Code/DrawTool.cs deleted file mode 100644 index d60fcb9..0000000 --- a/Assets/Code/DrawTool.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class DrawTool : MonoBehaviour -{ - protected DrawableFrame frame; - - protected virtual void Start() { - frame = GetComponent(); - } -} diff --git a/Assets/Code/DrawableFrame.cs b/Assets/Code/DrawableFrame.cs deleted file mode 100644 index f47ef52..0000000 --- a/Assets/Code/DrawableFrame.cs +++ /dev/null @@ -1,75 +0,0 @@ -using UnityEngine; - - -public class DrawableFrame : MonoBehaviour -{ - [Header("Configuration")] - public Vector2Int resolution; - public Color startingColor = Color.white; - - [Header("State")] - public bool interactable = false; - public bool hasChanged = false; - - [Header("References")] - protected Texture2D texture = null; - protected Sprite sprite = null; - protected SpriteRenderer spriteRenderer; - - public Rect Bounds { - get { - return new Rect(transform.position.x - (transform.localScale.x / 2), - transform.position.y - (transform.localScale.y / 2), - transform.localScale.x, - transform.localScale.y); - } - } - - protected void Start() - { - texture = new Texture2D(resolution.x, resolution.y); - if(resolution.x <= 128 || resolution.y <= 128) { - texture.filterMode = FilterMode.Point; - } - else { - texture.filterMode = FilterMode.Trilinear; - } - - Color[] colors = texture.GetPixels(); - for(int i = 0; i < colors.Length; i++) { - colors[i] = startingColor; - } - texture.SetPixels(colors); - texture.Apply(); - - spriteRenderer = GetComponent(); - sprite = Sprite.Create(texture, new Rect(0, 0, resolution.x, resolution.y), new Vector2(0.5f, 0.5f), resolution.x); - spriteRenderer.sprite = sprite; - } - - public Color[] GetPixels() { - return texture.GetPixels(); - } - - public void SetPixels(Color[] colors) { - if(interactable) { - texture.SetPixels(colors); - hasChanged = true; - } - } - - public byte[] ToPNG() { - return texture.EncodeToPNG(); - } - - protected void Update() { - if(hasChanged) { - texture.Apply(); - } - } - - protected void OnDrawGizmos() - { - Gizmos.DrawWireCube(transform.position, transform.localScale); - } -} diff --git a/Assets/Code/DrawingController.cs b/Assets/Code/DrawingController.cs deleted file mode 100644 index ba71826..0000000 --- a/Assets/Code/DrawingController.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - - -public class DrawingController : ActController -{ - [Header("Prefabs")] - public GameObject drawableFramePrefab; - public GameObject paletteButtonPrefab; - public GameObject radiusSliderPrefab; - public GameObject actNamePrefab; - public GameObject actDescriptionPrefab; - public GameObject actTimerPrefab; - - [Header("Objects")] - protected PencilTool pencil; - protected DrawableFrame drawableFrame; - protected List paletteButtons; - protected RadiusSlider radiusSlider; - protected Text actName; - protected Text actDescription; - protected Timer actTimer; - - public override void ActInit() { - base.ActInit(); - - //Load settings - DrawingSettings drawingSettings = settings as DrawingSettings; - - //Create drawable frame - drawableFrame = Instantiate(drawableFramePrefab, transform).GetComponent(); - drawableFrame.startingColor = drawingSettings.startingColor; - - //Init PencilTool - pencil = drawableFrame.GetComponent(); - try { - pencil.selectedColor = drawingSettings.palette[0]; - } catch(ArgumentOutOfRangeException) { - pencil.selectedColor = drawingSettings.startingColor; - } - - //Init PaletteButtons - paletteButtons = new List(); - for(int i = 0; i < drawingSettings.palette.Length; i++) { - PaletteButton button = Instantiate(paletteButtonPrefab, canvas.transform).GetComponent(); - RectTransform btnTransform = button.GetComponent(); - Image btnImage = button.GetComponent(); - button.pencil = pencil; - btnImage.color = drawingSettings.palette[i]; - btnTransform.anchoredPosition = new Vector2(-420 + i * 110, 150); - paletteButtons.Add(button); - } - - //Init RadiusSlider - radiusSlider = Instantiate(radiusSliderPrefab, canvas.transform).GetComponent(); - radiusSlider.pencil = pencil; - - //Init actName Text - actName = Instantiate(actNamePrefab, canvas.transform).GetComponent(); - actName.text = drawingSettings.actName; - - //Init actDescription Text - actDescription = Instantiate(actDescriptionPrefab, canvas.transform).GetComponent(); - actDescription.text = drawingSettings.actDescription; - - //Init actTimer - actTimer = Instantiate(actTimerPrefab, canvas.transform).GetComponent(); - actTimer.TimerSet(drawingSettings.timeLimit); - } - - public override void ActStart() { - base.ActStart(); - - //Unlock frame - drawableFrame.interactable = false; - - //Start timer - actTimer.OnTimeOut += new Action(ActEnd); - actTimer.TimerStart(); - } - - public override void ActEnd() { - base.ActEnd(); - - //Lock frame - drawableFrame.interactable = true; - - //Generate results - results = new DrawingResults(drawableFrame.ToPNG()); - } - - public override void ActCleanup() { - base.ActCleanup(); - - Destroy(drawableFrame.gameObject); - foreach(PaletteButton button in paletteButtons) { - Destroy(button.gameObject); - } - Destroy(radiusSlider.gameObject); - Destroy(actName.gameObject); - Destroy(actDescription.gameObject); - Destroy(actTimer.gameObject); - } -} diff --git a/Assets/Code/DrawingSettings.cs b/Assets/Code/DrawingSettings.cs deleted file mode 100644 index 46caeb2..0000000 --- a/Assets/Code/DrawingSettings.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - - -[Serializable] -public class DrawingSettings : ActSettings { - public Color startingColor = Color.white; - public Color[] palette = null; - public float timeLimit = 99f; - public string actName = "Untitled"; - public string actDescription = "This Act is missing a description."; - public string destinationPool = "default"; - - public DrawingSettings(Color startingColor, Color[] palette, float timeLimit, string actName, string actDescription, string destinationPool) { - this.type = "Drawing"; - this.startingColor = startingColor; - this.palette = palette; - this.timeLimit = timeLimit; - this.actName = actName; - this.actDescription = actDescription; - this.destinationPool = destinationPool; - } -} \ No newline at end of file diff --git a/Assets/Code/NetMessage.cs b/Assets/Code/NetMessage.cs deleted file mode 100644 index 435aad9..0000000 --- a/Assets/Code/NetMessage.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Mirror; - - -namespace NetMessage -{ - namespace Error - { - public class InvalidPassword : MessageBase {} - } - - namespace Connect - { - public class PlayerJoin : MessageBase - { - public string playerName; - public string gamePassword; - } - - public class PlayerJoinSuccessful : MessageBase - { - public Player player; - } - - public class ViewerLink : MessageBase - { - public string gamePassword; - } - - public class ViewerLinkSuccessful : MessageBase - { - public Viewer viewer; - } - - } - - namespace Game - { - public class Settings : MessageBase - { - public GameSettings settings; - } - - public class Start : MessageBase - { - public Player[] players; - } - - public class End : MessageBase - { - public Player[] leaderboard; - } - } - - namespace Act - { - public class Init : MessageBase - { - public ActSettings settings; - } - - public class Start : MessageBase {} - - public class Results : MessageBase - { - public ActResults results; - } - - public class End : MessageBase {} - } -} \ No newline at end of file diff --git a/Assets/Code/PaletteButton.cs b/Assets/Code/PaletteButton.cs deleted file mode 100644 index 6e15b20..0000000 --- a/Assets/Code/PaletteButton.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -public class PaletteButton : MonoBehaviour -{ - public PencilTool pencil; - - protected Image image; - - protected void Start() - { - image = GetComponent(); - } - - public void OnClick() - { - pencil.selectedColor = image.color; - } -} diff --git a/Assets/Code/PencilTool.cs b/Assets/Code/PencilTool.cs deleted file mode 100644 index 33a632d..0000000 --- a/Assets/Code/PencilTool.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -public class PencilTool : DrawTool -{ - public Color selectedColor = Color.black; - public float size = 1f; - - protected Color[] colors; - - private Vector2Int? previousPixel; - private Vector2Int? pixel; - - protected Vector2Int? GetPixelAtScreenPosition(Vector2 screenPosition) { - Vector2 worldPoint = Camera.main.ScreenToWorldPoint(screenPosition); - if(frame.Bounds.Contains(worldPoint)) { - Vector2 normalized = Rect.PointToNormalized(frame.Bounds, worldPoint); - Vector2Int result = new Vector2Int(Mathf.FloorToInt(normalized.x * frame.resolution.x), Mathf.FloorToInt(normalized.y * frame.resolution.y)); - return result; - } - return null; - } - - protected override void Start() { - base.Start(); - colors = frame.GetPixels(); - - Input.simulateMouseWithTouches = false; - } - - protected void Update() { - bool hasChanged = false; - - // Touch - foreach(Touch t in Input.touches) { - pixel = GetPixelAtScreenPosition(t.position); - previousPixel = GetPixelAtScreenPosition(t.position - t.deltaPosition); - if(pixel.HasValue) { - if(previousPixel.HasValue) { - DrawBresenhamsThickLine(pixel.Value, previousPixel.Value, size, selectedColor); - } - else { - DrawFilledCircle(pixel.Value, size, selectedColor); - } - } - hasChanged = true; - } - - // Mouse - previousPixel = pixel; - if(Input.GetMouseButton(0)) { - pixel = GetPixelAtScreenPosition(Input.mousePosition); - if(pixel.HasValue) { - if(previousPixel.HasValue) { - DrawBresenhamsThickLine(previousPixel.Value, pixel.Value, size, selectedColor); - } - else { - DrawFilledCircle(pixel.Value, size, selectedColor); - } - } - hasChanged = true; - } - else { - pixel = null; - } - - if(hasChanged) { - frame.SetPixels(colors); - } - } - - protected void DrawPixel(int x, int y, Color color) { - if(x < 0 || x >= frame.resolution.x || y < 0 || y >= frame.resolution.y) return; - colors[x + y*frame.resolution.x] = color; - } - - protected void DrawCircleEightPoints(Vector2Int center, int x_radius, int y_radius, Color color) { - DrawPixel(center.x+x_radius, center.y+y_radius, color); - DrawPixel(center.x-x_radius, center.y+y_radius, color); - DrawPixel(center.x+x_radius, center.y-y_radius, color); - DrawPixel(center.x-x_radius, center.y-y_radius, color); - DrawPixel(center.x+y_radius, center.y+x_radius, color); - DrawPixel(center.x-y_radius, center.y+x_radius, color); - DrawPixel(center.x+y_radius, center.y-x_radius, color); - DrawPixel(center.x-y_radius, center.y-x_radius, color); - } - - // No idea on how does it work - // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/ - protected void DrawBresenhamEmptyCircle(Vector2Int center, int radius, Color color) { - int x = 0; - int y = radius; - int d = 3 - 2 * radius; - DrawCircleEightPoints(center, x, y, color); - while(y >= x) { - x++; - if(d > 0) { - y--; - d = d + 4 * (x - y) + 10; - } - else { - d = d + 4 * x + 6; - } - DrawCircleEightPoints(center, x, y, color); - } - } - - protected void DrawFilledCircle(Vector2Int center, float radius, Color color) { - int x_start = Mathf.CeilToInt((float)center.x - radius); - int x_end = Mathf.CeilToInt((float)center.x + radius); - int y_start = Mathf.CeilToInt((float)center.y - radius); - int y_end = Mathf.CeilToInt((float)center.y + radius); - for(int x = x_start; x < x_end; x++) { - for(int y = y_start; y < y_end; y++) { - if(Vector2Int.Distance(new Vector2Int(x, y), center) < radius) { - DrawPixel(x, y, color); - } - } - } - } - - // http://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm - protected void DrawBresenhamsThickLine(Vector2Int start, Vector2Int end, float radius, Color color) { - int start_x = start.x, start_y = start.y, end_x = end.x, end_y = end.y; - bool steep = Mathf.Abs(end_y - start_y) > Mathf.Abs(end_x - start_x); - if (steep) { - Utils.Swap(ref start_x, ref start_y); - Utils.Swap(ref end_x, ref end_y); - } - if (start_x > end_x) { - Utils.Swap(ref start_x, ref end_x); - Utils.Swap(ref start_y, ref end_y); - } - int dX = (end_x - start_x), dY = Mathf.Abs(end_y - start_y), err = (dX / 2), ystep = (start_y < end_y ? 1 : -1), y = start_y; - - for (int x = start_x; x <= end_x; ++x) - { - if(steep) { - DrawFilledCircle(new Vector2Int(y, x), radius, color); - } - else { - DrawFilledCircle(new Vector2Int(x, y), radius, color); - } - err = err - dY; - if (err < 0) { y += ystep; err += dX; } - } - } - - protected void Apply() { - } -} diff --git a/Assets/Code/Player.cs b/Assets/Code/Player.cs deleted file mode 100644 index 011a4aa..0000000 --- a/Assets/Code/Player.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System; - -[Serializable] -public struct Player { - public string name; - public int id; -} diff --git a/Assets/Code/Player.meta b/Assets/Code/Player.meta new file mode 100644 index 0000000..86593c1 --- /dev/null +++ b/Assets/Code/Player.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 38dcaa329b85fc447b2976e3c6d8fcd9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Code/Player/ActController.cs b/Assets/Code/Player/ActController.cs new file mode 100644 index 0000000..3808a38 --- /dev/null +++ b/Assets/Code/Player/ActController.cs @@ -0,0 +1,93 @@ +using System; +using UnityEngine; +using UnityEngine.EventSystems; + + +namespace BetterTee.Player +{ + + public abstract class ActController : MonoBehaviour + { + [Header("Settings")] + public ActSettings settings = null; + protected ActPhase phase = ActPhase.NONE; + + [Header("Results")] + public ActResults results = null; + + [Header("Objects")] + public Canvas canvas = null; + public EventSystem eventSystem = null; + + [Serializable] + public class InvalidPhaseException : Exception { + public readonly ActPhase currentPhase; + + public InvalidPhaseException(ActPhase currentPhase) { + this.currentPhase = currentPhase; + } + }; + + [Serializable] + public class MissingSettingsException : Exception {}; + + public ActPhase Phase { get; } + + /// + /// Call this to initialize the Act (GameObjects, ActSettings, etc). All interactable components should be disabled in this phase. + /// + public virtual void ActInit() { + phase = ActPhase.INIT; + + canvas = GameObject.FindGameObjectWithTag("Canvas")?.GetComponent(); + eventSystem = GameObject.FindGameObjectWithTag("EventSystem")?.GetComponent(); + + if(settings == null) { + throw new MissingSettingsException(); + } + } + + /// + /// Call this to enable all interactable components in the Act. It should be called when the player is ready to play. + /// + public virtual void ActStart() { + if(Phase != ActPhase.INIT) throw new InvalidPhaseException(phase); + phase = ActPhase.START; + } + + /// + /// Call this to disable once again all interactable components in the Act. It should be called when the Act is finished (time ran out, player reached submission limit, etc). + /// + public virtual void ActEnd() { + if(Phase != ActPhase.START) throw new InvalidPhaseException(phase); + phase = ActPhase.END; + } + + /// + /// Call this to cleanup all GameObjects created during the Init phase. + /// + public virtual void ActCleanup() { + if(Phase != ActPhase.END) { + Debug.LogWarningFormat("ActCleanup() was called during {0}", Phase); + } + phase = ActPhase.CLEANUP; + } + + protected virtual void Awake() { + + } + + protected virtual void Start() { + + } + + protected virtual void Update() { + + } + + protected virtual void OnDestroy() { + ActCleanup(); + } + } + +} \ No newline at end of file diff --git a/Assets/Code/ActController.cs.meta b/Assets/Code/Player/ActController.cs.meta similarity index 83% rename from Assets/Code/ActController.cs.meta rename to Assets/Code/Player/ActController.cs.meta index bf4e940..c617b86 100644 --- a/Assets/Code/ActController.cs.meta +++ b/Assets/Code/Player/ActController.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1b7c9976c1c705342bf5b92905a0533e +guid: 0f4726b47423bf742bfc526e428363d8 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Code/Player/DrawTool.cs b/Assets/Code/Player/DrawTool.cs new file mode 100644 index 0000000..7e05af4 --- /dev/null +++ b/Assets/Code/Player/DrawTool.cs @@ -0,0 +1,16 @@ +using UnityEngine; + + +namespace BetterTee.Player +{ + + public class DrawTool : MonoBehaviour + { + protected DrawableFrame frame; + + protected virtual void Start() { + frame = GetComponent(); + } + } + +} diff --git a/Assets/Code/DrawTool.cs.meta b/Assets/Code/Player/DrawTool.cs.meta similarity index 100% rename from Assets/Code/DrawTool.cs.meta rename to Assets/Code/Player/DrawTool.cs.meta diff --git a/Assets/Code/Player/DrawableFrame.cs b/Assets/Code/Player/DrawableFrame.cs new file mode 100644 index 0000000..88674d2 --- /dev/null +++ b/Assets/Code/Player/DrawableFrame.cs @@ -0,0 +1,80 @@ +using UnityEngine; + + +namespace BetterTee.Player +{ + + public class DrawableFrame : MonoBehaviour + { + [Header("Configuration")] + public Vector2Int resolution; + public Color startingColor = Color.white; + + [Header("State")] + public bool interactable = false; + public bool hasChanged = false; + + [Header("References")] + protected Texture2D texture = null; + protected Sprite sprite = null; + protected SpriteRenderer spriteRenderer; + + public Rect Bounds { + get { + return new Rect(transform.position.x - (transform.localScale.x / 2), + transform.position.y - (transform.localScale.y / 2), + transform.localScale.x, + transform.localScale.y); + } + } + + protected void Start() + { + texture = new Texture2D(resolution.x, resolution.y); + if(resolution.x <= 128 || resolution.y <= 128) { + texture.filterMode = FilterMode.Point; + } + else { + texture.filterMode = FilterMode.Trilinear; + } + + Color[] colors = texture.GetPixels(); + for(int i = 0; i < colors.Length; i++) { + colors[i] = startingColor; + } + texture.SetPixels(colors); + texture.Apply(); + + spriteRenderer = GetComponent(); + sprite = Sprite.Create(texture, new Rect(0, 0, resolution.x, resolution.y), new Vector2(0.5f, 0.5f), resolution.x); + spriteRenderer.sprite = sprite; + } + + public Color[] GetPixels() { + return texture.GetPixels(); + } + + public void SetPixels(Color[] colors) { + if(interactable) { + texture.SetPixels(colors); + hasChanged = true; + } + } + + public byte[] ToPNG() { + return texture.EncodeToPNG(); + } + + protected void Update() { + if(hasChanged) { + texture.Apply(); + } + } + + protected void OnDrawGizmos() + { + Gizmos.DrawWireCube(transform.position, transform.localScale); + } + } + +} diff --git a/Assets/Code/DrawableFrame.cs.meta b/Assets/Code/Player/DrawableFrame.cs.meta similarity index 100% rename from Assets/Code/DrawableFrame.cs.meta rename to Assets/Code/Player/DrawableFrame.cs.meta diff --git a/Assets/Code/Player/DrawingController.cs b/Assets/Code/Player/DrawingController.cs new file mode 100644 index 0000000..aa817ef --- /dev/null +++ b/Assets/Code/Player/DrawingController.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + + +namespace BetterTee.Player +{ + + public class DrawingController : ActController + { + [Header("Prefabs")] + public GameObject drawableFramePrefab; + public GameObject paletteButtonPrefab; + public GameObject radiusSliderPrefab; + public GameObject actNamePrefab; + public GameObject actDescriptionPrefab; + public GameObject actTimerPrefab; + + [Header("Objects")] + protected PencilTool pencil; + protected DrawableFrame drawableFrame; + protected List paletteButtons; + protected RadiusSlider radiusSlider; + protected Text actName; + protected Text actDescription; + protected Timer actTimer; + + public override void ActInit() { + base.ActInit(); + + //Load settings + DrawingSettings drawingSettings = settings as DrawingSettings; + + //Create drawable frame + drawableFrame = Instantiate(drawableFramePrefab, transform).GetComponent(); + drawableFrame.startingColor = drawingSettings.startingColor; + + //Init PencilTool + pencil = drawableFrame.GetComponent(); + try { + pencil.selectedColor = drawingSettings.palette[0]; + } catch(ArgumentOutOfRangeException) { + pencil.selectedColor = drawingSettings.startingColor; + } + + //Init PaletteButtons + paletteButtons = new List(); + for(int i = 0; i < drawingSettings.palette.Length; i++) { + PaletteButton button = Instantiate(paletteButtonPrefab, canvas.transform).GetComponent(); + RectTransform btnTransform = button.GetComponent(); + Image btnImage = button.GetComponent(); + button.pencil = pencil; + btnImage.color = drawingSettings.palette[i]; + btnTransform.anchoredPosition = new Vector2(-420 + i * 110, 150); + paletteButtons.Add(button); + } + + //Init RadiusSlider + radiusSlider = Instantiate(radiusSliderPrefab, canvas.transform).GetComponent(); + radiusSlider.pencil = pencil; + + //Init actName Text + actName = Instantiate(actNamePrefab, canvas.transform).GetComponent(); + actName.text = drawingSettings.actName; + + //Init actDescription Text + actDescription = Instantiate(actDescriptionPrefab, canvas.transform).GetComponent(); + actDescription.text = drawingSettings.actDescription; + + //Init actTimer + actTimer = Instantiate(actTimerPrefab, canvas.transform).GetComponent(); + actTimer.TimerSet(drawingSettings.timeLimit); + } + + public override void ActStart() { + base.ActStart(); + + //Unlock frame + drawableFrame.interactable = false; + + //Start timer + actTimer.OnTimeOut += new Action(ActEnd); + actTimer.TimerStart(); + } + + public override void ActEnd() { + base.ActEnd(); + + //Lock frame + drawableFrame.interactable = true; + + //Generate results + results = new DrawingResults(drawableFrame.ToPNG()); + } + + public override void ActCleanup() { + base.ActCleanup(); + + Destroy(drawableFrame.gameObject); + foreach(PaletteButton button in paletteButtons) { + Destroy(button.gameObject); + } + Destroy(radiusSlider.gameObject); + Destroy(actName.gameObject); + Destroy(actDescription.gameObject); + Destroy(actTimer.gameObject); + } + } + +} \ No newline at end of file diff --git a/Assets/Code/DrawingController.cs.meta b/Assets/Code/Player/DrawingController.cs.meta similarity index 100% rename from Assets/Code/DrawingController.cs.meta rename to Assets/Code/Player/DrawingController.cs.meta diff --git a/Assets/Code/Player/PaletteButton.cs b/Assets/Code/Player/PaletteButton.cs new file mode 100644 index 0000000..5a69ddd --- /dev/null +++ b/Assets/Code/Player/PaletteButton.cs @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace BetterTee.Player { + + public class PaletteButton : MonoBehaviour + { + public PencilTool pencil; + + protected Image image; + + protected void Start() + { + image = GetComponent(); + } + + public void OnClick() + { + pencil.selectedColor = image.color; + } + } + +} diff --git a/Assets/Code/PaletteButton.cs.meta b/Assets/Code/Player/PaletteButton.cs.meta similarity index 100% rename from Assets/Code/PaletteButton.cs.meta rename to Assets/Code/Player/PaletteButton.cs.meta diff --git a/Assets/Code/Player/PencilTool.cs b/Assets/Code/Player/PencilTool.cs new file mode 100644 index 0000000..7cdb086 --- /dev/null +++ b/Assets/Code/Player/PencilTool.cs @@ -0,0 +1,158 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + + +namespace BetterTee.Player +{ + + public class PencilTool : DrawTool + { + public Color selectedColor = Color.black; + public float size = 1f; + + protected Color[] colors; + + private Vector2Int? previousPixel; + private Vector2Int? pixel; + + protected Vector2Int? GetPixelAtScreenPosition(Vector2 screenPosition) { + Vector2 worldPoint = Camera.main.ScreenToWorldPoint(screenPosition); + if(frame.Bounds.Contains(worldPoint)) { + Vector2 normalized = Rect.PointToNormalized(frame.Bounds, worldPoint); + Vector2Int result = new Vector2Int(Mathf.FloorToInt(normalized.x * frame.resolution.x), Mathf.FloorToInt(normalized.y * frame.resolution.y)); + return result; + } + return null; + } + + protected override void Start() { + base.Start(); + colors = frame.GetPixels(); + + Input.simulateMouseWithTouches = false; + } + + protected void Update() { + bool hasChanged = false; + + // Touch + foreach(Touch t in Input.touches) { + pixel = GetPixelAtScreenPosition(t.position); + previousPixel = GetPixelAtScreenPosition(t.position - t.deltaPosition); + if(pixel.HasValue) { + if(previousPixel.HasValue) { + DrawBresenhamsThickLine(pixel.Value, previousPixel.Value, size, selectedColor); + } + else { + DrawFilledCircle(pixel.Value, size, selectedColor); + } + } + hasChanged = true; + } + + // Mouse + previousPixel = pixel; + if(Input.GetMouseButton(0)) { + pixel = GetPixelAtScreenPosition(Input.mousePosition); + if(pixel.HasValue) { + if(previousPixel.HasValue) { + DrawBresenhamsThickLine(previousPixel.Value, pixel.Value, size, selectedColor); + } + else { + DrawFilledCircle(pixel.Value, size, selectedColor); + } + } + hasChanged = true; + } + else { + pixel = null; + } + + if(hasChanged) { + frame.SetPixels(colors); + } + } + + protected void DrawPixel(int x, int y, Color color) { + if(x < 0 || x >= frame.resolution.x || y < 0 || y >= frame.resolution.y) return; + colors[x + y*frame.resolution.x] = color; + } + + protected void DrawCircleEightPoints(Vector2Int center, int x_radius, int y_radius, Color color) { + DrawPixel(center.x+x_radius, center.y+y_radius, color); + DrawPixel(center.x-x_radius, center.y+y_radius, color); + DrawPixel(center.x+x_radius, center.y-y_radius, color); + DrawPixel(center.x-x_radius, center.y-y_radius, color); + DrawPixel(center.x+y_radius, center.y+x_radius, color); + DrawPixel(center.x-y_radius, center.y+x_radius, color); + DrawPixel(center.x+y_radius, center.y-x_radius, color); + DrawPixel(center.x-y_radius, center.y-x_radius, color); + } + + // No idea on how does it work + // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/ + protected void DrawBresenhamEmptyCircle(Vector2Int center, int radius, Color color) { + int x = 0; + int y = radius; + int d = 3 - 2 * radius; + DrawCircleEightPoints(center, x, y, color); + while(y >= x) { + x++; + if(d > 0) { + y--; + d = d + 4 * (x - y) + 10; + } + else { + d = d + 4 * x + 6; + } + DrawCircleEightPoints(center, x, y, color); + } + } + + protected void DrawFilledCircle(Vector2Int center, float radius, Color color) { + int x_start = Mathf.CeilToInt((float)center.x - radius); + int x_end = Mathf.CeilToInt((float)center.x + radius); + int y_start = Mathf.CeilToInt((float)center.y - radius); + int y_end = Mathf.CeilToInt((float)center.y + radius); + for(int x = x_start; x < x_end; x++) { + for(int y = y_start; y < y_end; y++) { + if(Vector2Int.Distance(new Vector2Int(x, y), center) < radius) { + DrawPixel(x, y, color); + } + } + } + } + + // http://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm + protected void DrawBresenhamsThickLine(Vector2Int start, Vector2Int end, float radius, Color color) { + int start_x = start.x, start_y = start.y, end_x = end.x, end_y = end.y; + bool steep = Mathf.Abs(end_y - start_y) > Mathf.Abs(end_x - start_x); + if (steep) { + Utils.Swap(ref start_x, ref start_y); + Utils.Swap(ref end_x, ref end_y); + } + if (start_x > end_x) { + Utils.Swap(ref start_x, ref end_x); + Utils.Swap(ref start_y, ref end_y); + } + int dX = (end_x - start_x), dY = Mathf.Abs(end_y - start_y), err = (dX / 2), ystep = (start_y < end_y ? 1 : -1), y = start_y; + + for (int x = start_x; x <= end_x; ++x) + { + if(steep) { + DrawFilledCircle(new Vector2Int(y, x), radius, color); + } + else { + DrawFilledCircle(new Vector2Int(x, y), radius, color); + } + err = err - dY; + if (err < 0) { y += ystep; err += dX; } + } + } + + protected void Apply() { + } + } + +} \ No newline at end of file diff --git a/Assets/Code/PencilTool.cs.meta b/Assets/Code/Player/PencilTool.cs.meta similarity index 100% rename from Assets/Code/PencilTool.cs.meta rename to Assets/Code/Player/PencilTool.cs.meta diff --git a/Assets/Code/Player/PlayerMainController.cs b/Assets/Code/Player/PlayerMainController.cs new file mode 100644 index 0000000..6f860f3 --- /dev/null +++ b/Assets/Code/Player/PlayerMainController.cs @@ -0,0 +1,99 @@ +using System; +using UnityEngine; +using Mirror; +using BetterTee; + +namespace BetterTee.Player +{ + + public class PlayerMainController : MonoBehaviour + { + [Header("WIP")] + public string address = "127.0.0.1"; + public string playerName = "Steffo"; + public string gamePassword = "ASDF"; + + void Start() { + ConnectToServer(address, playerName); + } + + [Header("Objects")] + public ActController currentAct = null; + + [Header("Prefabs")] + public GameObject drawingControllerPrefab; + public GameObject typingControllerPrefab; + + [Serializable] + public class InvalidActTypeException : Exception { + public readonly string actType; + + public InvalidActTypeException(string actType) { + this.actType = actType; + } + }; + + public void LoadAct(ActSettings settings) { + if(settings.type == "Drawing") { + currentAct = Instantiate(drawingControllerPrefab, transform).GetComponent(); + } + else if (settings.type == "Typing") { + currentAct = Instantiate(typingControllerPrefab, transform).GetComponent(); + } + else throw new InvalidActTypeException(settings.type); + currentAct.settings = settings; + } + + public void ConnectToServer(string address, string playerName) { + LogFilter.Debug = true; + Transport.activeTransport = GetComponent(); + NetworkClient.RegisterHandler(OnConnect); + NetworkClient.RegisterHandler(OnPlayerJoinSuccessful); + NetworkClient.RegisterHandler(OnLobbyEnd); + NetworkClient.RegisterHandler(OnGameEnd); + NetworkClient.RegisterHandler(OnActInit); + NetworkClient.RegisterHandler(OnActStart); + NetworkClient.RegisterHandler(OnActEnd); + NetworkClient.Connect(address); + } + + #region Network Events + + protected void OnConnect(NetworkConnection connection, ConnectMessage message) { + Debug.Log("Sending NetMessage.Connect.PlayerJoin"); + connection.Send(new NetMsg.Client.PlayerJoin { + playerName = playerName, + gamePassword = gamePassword + }); + } + + protected void OnPlayerJoinSuccessful(NetworkConnection connection, NetMsg.Server.PlayerJoined message) { + + } + + protected void OnLobbyEnd(NetworkConnection connection, NetMsg.Server.LobbyEnd message) {} + + protected void OnGameEnd(NetworkConnection connection, NetMsg.Server.GameEnd message) {} + + protected void OnActInit(NetworkConnection connection, NetMsg.Server.ActInit message) { + LoadAct(message.settings); + currentAct.ActInit(); + } + + protected void OnActStart(NetworkConnection connection, NetMsg.Server.ActStart message) { + currentAct.ActStart(); + } + + protected void OnActEnd(NetworkConnection connection, NetMsg.Server.ActEnd message) { + currentAct.ActEnd(); + //SEND RESULTS HERE + + //test this + Destroy(currentAct); + } + + #endregion + + } + +} \ No newline at end of file diff --git a/Assets/Code/PlayerMainController.cs.meta b/Assets/Code/Player/PlayerMainController.cs.meta similarity index 100% rename from Assets/Code/PlayerMainController.cs.meta rename to Assets/Code/Player/PlayerMainController.cs.meta diff --git a/Assets/Code/Player/RadiusSlider.cs b/Assets/Code/Player/RadiusSlider.cs new file mode 100644 index 0000000..da008ce --- /dev/null +++ b/Assets/Code/Player/RadiusSlider.cs @@ -0,0 +1,22 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace BetterTee.Player { + + public class RadiusSlider : MonoBehaviour + { + public PencilTool pencil; + + protected Slider slider; + + protected void Start() { + slider = GetComponent(); + } + + public void OnValueChange() + { + pencil.size = slider.value; + } + } + +} diff --git a/Assets/Code/RadiusSlider.cs.meta b/Assets/Code/Player/RadiusSlider.cs.meta similarity index 100% rename from Assets/Code/RadiusSlider.cs.meta rename to Assets/Code/Player/RadiusSlider.cs.meta diff --git a/Assets/Code/Player/Submit.cs b/Assets/Code/Player/Submit.cs new file mode 100644 index 0000000..1f8049f --- /dev/null +++ b/Assets/Code/Player/Submit.cs @@ -0,0 +1,27 @@ +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.EventSystems; + + +namespace BetterTee.Player +{ + + public class Submit : MonoBehaviour + { + public InputField inputField; + public TypingController typingController; + + protected EventSystem eventSystem; + + protected void Start() { + eventSystem = GameObject.FindGameObjectWithTag("EventSystem").GetComponent(); + } + + public void OnClick() { + typingController.Submit(inputField.text); + inputField.text = ""; + eventSystem.SetSelectedGameObject(inputField.gameObject); + } + } + +} \ No newline at end of file diff --git a/Assets/Code/Submit.cs.meta b/Assets/Code/Player/Submit.cs.meta similarity index 100% rename from Assets/Code/Submit.cs.meta rename to Assets/Code/Player/Submit.cs.meta diff --git a/Assets/Code/Player/Timer.cs b/Assets/Code/Player/Timer.cs new file mode 100644 index 0000000..f6fdb47 --- /dev/null +++ b/Assets/Code/Player/Timer.cs @@ -0,0 +1,56 @@ +using System; +using UnityEngine; + + +namespace BetterTee.Player +{ + + public class Timer : MonoBehaviour + { + public float startingTime = 0f; + public float time = 0f; + + private bool isTriggered = false; + private bool isRunning = false; + + protected void Update() { + if(time >= 0f) { + if(isRunning) { + time -= Time.deltaTime; + } + } + else { + if(isTriggered) { + OnTimeOut(); + time = 0f; + isTriggered = false; + isRunning = false; + } + } + } + + public void TimerSet(float startingTime) { + isTriggered = true; + isRunning = false; + this.startingTime = startingTime; + time = startingTime; + } + + public void TimerStart() { + isRunning = true; + } + + public void TimerPause() { + isRunning = false; + } + + public void TimerCancel() { + time = 0f; + isTriggered = false; + isRunning = false; + } + + public event Action OnTimeOut; + } + +} diff --git a/Assets/Code/Timer.cs.meta b/Assets/Code/Player/Timer.cs.meta similarity index 100% rename from Assets/Code/Timer.cs.meta rename to Assets/Code/Player/Timer.cs.meta diff --git a/Assets/Code/Player/TimerToText.cs b/Assets/Code/Player/TimerToText.cs new file mode 100644 index 0000000..7f2e0ab --- /dev/null +++ b/Assets/Code/Player/TimerToText.cs @@ -0,0 +1,24 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace BetterTee.Player +{ + + public class TimerToText : MonoBehaviour + { + protected Timer timer; + protected Text text; + + protected void Start() + { + timer = GetComponent(); + text = GetComponent(); + } + + public void Update() + { + text.text = Mathf.CeilToInt(timer.time).ToString(); + } + } + +} diff --git a/Assets/Code/TimerToText.cs.meta b/Assets/Code/Player/TimerToText.cs.meta similarity index 100% rename from Assets/Code/TimerToText.cs.meta rename to Assets/Code/Player/TimerToText.cs.meta diff --git a/Assets/Code/Player/TypingController.cs b/Assets/Code/Player/TypingController.cs new file mode 100644 index 0000000..47f3f2e --- /dev/null +++ b/Assets/Code/Player/TypingController.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace BetterTee.Player { + + public class TypingController : ActController + { + public List submissions; + + [Header("Prefabs")] + public GameObject actNamePrefab; + public GameObject actDescriptionPrefab; + public GameObject timerPrefab; + public GameObject submissionFieldPrefab; + public GameObject submitPrefab; + public GameObject submittedCountPrefab; + + [Header("Objects")] + protected Text actName; + protected Text actDescription; + protected Timer actTimer; + protected InputField submissionField; + protected Submit submit; + protected Text submittedCount; + + protected override void Start() { + base.Start(); + submissions = new List(); + } + + public override void ActInit() { + base.ActInit(); + + //Load settings + TypingSettings typingSettings = settings as TypingSettings; + + //Init actName Text + actName = Instantiate(actNamePrefab, canvas.transform).GetComponent(); + actName.text = typingSettings.actName; + + //Init actDescription Text + actDescription = Instantiate(actDescriptionPrefab, canvas.transform).GetComponent(); + actDescription.text = typingSettings.actDescription; + + //Init actTimer + actTimer = Instantiate(timerPrefab, canvas.transform).GetComponent(); + actTimer.TimerSet(typingSettings.timeLimit); + + //Init submissionInputField + submissionField = Instantiate(submissionFieldPrefab, canvas.transform).GetComponent(); + + //Init submit Button + submit = Instantiate(submitPrefab, canvas.transform).GetComponent(); + submit.typingController = this; + submit.inputField = submissionField; + + //Init submissionCount Text + submittedCount = Instantiate(submittedCountPrefab, canvas.transform).GetComponent(); + submittedCount.text = ""; + } + + public override void ActStart() { + base.ActStart(); + + //Enable submissionField and submit Button + submissionField.interactable = true; + submit.GetComponent