Hello! Thank you for visiting my Unity Portfolio. Here I will show you samples of my Unity and C# work. Lets get to it!
Summary of Content:
- Mobile Experience
- Enemy Scripting
- Coroutines and UI
Mobile Experience

Enemy Scripting
The following is a snippet of Unity C# code from an AI patrol enemy. The goal with this system was to create an easily modifiable path of nodes for the worlds wandering NPCs. This enabled ambient ships to populate the seas to make the world feel active and alive.
void Update () { // Skip this we are not supposed ot be patroling if (!patroling) return; // Change speed to patrol speed ChangeSpeed(patrolSpeedLevel); targetSailLevel = Mathf.Clamp(targetSailLevel, 0, 3); sailLevel = Mathf.Lerp(sailLevel, targetSailLevel, 0.01f); transform.Translate(Vector2.right * speed * sailLevel / 2 * Time.deltaTime); CheckPosition(); // Check how much we still need to rotate Vector3 diff = targetPosition - transform.position; diff.Normalize(); float targetRotation = Mathf.Atan2(diff.y, diff.x); float currentRotation = Mathf.Atan2(transform.right.y, transform.right.x); if (Mathf.Abs(targetRotation - currentRotation) < 0.05) rotationDirection = 0; // Rotate towards target transform.Rotate(0, 0, turnSpeed * Time.deltaTime * rotationDirection); } void CheckPosition() { float distanceToTarget = Vector3.Magnitude(targetPosition - transform.position); // Select next target if within buffer if (distanceToTarget < targetProximityBuffer) ProceedToNextPoint(); } void ProceedToNextPoint() { // Check if we are at the end of the list if (lastPointVisited == points.Length - 1) lastPointVisited = 0; // Loop Back to the first point else ++lastPointVisited; // Move on to the next point nextPoint = lastPointVisited + 1; if (nextPoint >= points.Length) nextPoint = 0; targetPosition = points[nextPoint]; // Determine which direction to rotate Vector3 diff = targetPosition - transform.position; diff.Normalize(); float targetRotation = Mathf.Atan2(diff.y, diff.x); float currentRotation = Mathf.Atan2(transform.right.y, transform.right.x); float rotationDiff = targetRotation - currentRotation; // Dont rotate if already within target rotation if (Mathf.Abs(rotationDiff) < targetRotationBuffer) rotationDirection = 0; else rotationDirection = rotationDiff > 0 ? 1 : -1; // If we need to rotate more than 180 deg, rotate the oposite direction instead. if (Mathf.Abs(Mathf.Rad2Deg * rotationDiff) > 180) rotationDirection *= -1; }
Coroutines and UI
In this snippet I utilized coroutines to build a system that could be manipulated while executing to allow the player to skip through chunks of text. My goal on this project was to create an easy to edit dialog system that reads from a file and which enabled an exploration and story driven game.
void Update() { if (inConversation) { // End Convo Cheat if (Input.GetKeyDown(KeyCode.P)) { textLineQueue.Clear(); EndConversation(); return; } // Wait for input if (Input.GetButtonDown("Submit") || fakeSubmit) { fakeSubmit = false; if (!isTyping) { // If no more text if (textLineQueue.Count == 0) { if (waitForResponse) { if (!responseUIObject.activeSelf) // Turn on response UI if it is off responseUIObject.SetActive(true); return; // Wait } else EndConversation(); // Otherwise end the conversation } else // Next Line StartCoroutine(TextScroll(textLineQueue.Dequeue() as string)); } else if (!cancelTyping) cancelTyping = true; } } } IEnumerator TextScroll(string textLine) { if (textLine.Length == 1) // Next Line { if (textLineQueue.Count == 0) EndConversation(); else // Next Line StartCoroutine(TextScroll(textLineQueue.Dequeue() as string)); yield break; } int letter = 0; conversationText.text = ""; isTyping = true; cancelTyping = false; while (isTyping && !cancelTyping && letter < textLine.Length - 1) { conversationText.text += textLine[letter]; ++letter; yield return new WaitForSeconds(typeSpeed); } conversationText.text = textLine; isTyping = false; cancelTyping = false; } void StartConversation() { if (inConversation) return; textWindow.SetActive(true); GameManager.BroadcastAll("OnStartConversation"); StartCoroutine(TextScroll(textLineQueue.Dequeue() as string)); inConversation = true; } void EndConversation() { if (!inConversation) return; textWindow.SetActive(false); inConversation = false; GameManager.BroadcastAll("OnEndConversation"); } public void QueueTextLines(TextAsset textFile, int startLine, int endLine) { string[] textLines = textFile.text.Split('\n'); for (int i = 0; i <= endLine - startLine; i++) textLineQueue.Enqueue(textLines[startLine + i - 1]); if (inConversation == false) StartConversation(); } // Overloaded for when there is only one line public void QueueTextLines(TextAsset textFile, int startLine) { QueueTextLines(textFile, startLine, startLine); } public void QueueResponse(GameObject responseUI) { if (responseUI != null) { responseUIObject = responseUI; waitForResponse = true; } } public void ConversastionButtonPressed() { waitForResponse = false; fakeSubmit = true; responseUIObject.SetActive(false); }