Neon Breakline
Full code for the Character Controller in Neon Breakline (Careful its around 700 lines long)
using System.Collections;
using Unity.Cinemachine;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
//RULE: the player ALWAYS moves forward
//There is NO input that stops or reverses movement
public static PlayerController Instance;
[Header("Player Stats")]
public bool advance = true;
public bool levelFinished = false;
public int maxHealth = 3;
public int currentHealth;
[HideInInspector] public enum SpeedTier { Base, Lv1, Lv2, Lv3 }
public SpeedTier speedTier = SpeedTier.Base;
public bool playerDied = false;
[Header("Forward Movement Settings")]
public float baseSpeed = 5f;
public float lv1Speed = 7f;
public float lv2Speed = 9f;
public float lv3Speed = 12f;
public float baseAnimSpeed = .8f;
public float lv1AnimSpeed = 1f;
public float lv2AnimSpeed = 1.1f;
public float lv3AnimSpeed = 1.2f;
[Header("Jump Settings")]
public float jumpForce = 8f;
public Transform groundCheck;
[SerializeField] private float groundCheckY = 0.2f;
[SerializeField] private float groundCheckX = 0.5f;
public LayerMask groundLayer;
public bool isGrounded;
[Header("Jump Assist")]
[SerializeField] private float coyoteTime = 0.1f;
[SerializeField] private float jumpBufferTime = 0.1f;
private float coyoteTimeCounter;
private float jumpBufferCounter;
[Header("Slide Settings")]
public float slideDuration = 1f;
[Header("Attack Settings")]
public GameObject attackHitbox;
public float attackCooldown = 0.25f;
private float lastAttackTime;
public GameObject slashFX;
[SerializeField] private float attackBufferTime = .1f;
private float attackBufferCounter;
[Header("Parry Settings")]
public GameObject parryHitbox;
public float parryAnimDuration = 0.12f;
public float parrySpeedMultiplier = 0.5f;
[Header("Pushback Settings")]
public float pushbackForce = 6f;
public float pushbackDuration = 0.2f;
private Coroutine pushbackCoroutine;
[Header("Hitstop Settings")]
public float hitstopDuration = 0.07f;
public float parryHitstopDuration = 0.1f;
public bool isInHitstop = false;
[Header("Screen Shake Settings")]
public CinemachineImpulseSource wallHitImpulseSource;
public CinemachineImpulseSource parryImpulseSource;
public CinemachineImpulseSource attackImpulseSource;
[Header("Camera Settings")]
public float baseFOV = 40f;
public float lv1FOV = 41f;
public float lv2FOV = 43f;
public float lv3FOV = 45f;
[Header("Particles")]
public ParticleSystem parryParticles;
public ParticleSystem jumpParticles;
public ParticleSystem bloodParticles;
#region Input Actions
private PlayerInput playerInput;
private InputAction jumpAction;
private InputAction attackAction;
private InputAction parryAction;
private InputAction crouchAction;
#endregion
#region Input Bools
public bool JumpJustPressed { get; private set; }
public bool JumpBeingHeld { get; private set; }
public bool JumpReleased { get; private set; }
public bool AttackInput { get; private set; }
public bool ParryInput { get; private set; }
public bool CrouchInput { get; private set; }
#endregion
[HideInInspector] public Rigidbody2D rb;
[HideInInspector] public Animator anim;
[HideInInspector] public AudioSource audsrc;
[HideInInspector] public PlayerStates pState;
[HideInInspector] public AudioManager audioManager;
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
}
else
{
Instance = this;
}
playerInput = GetComponent();
SetupInputActions();
rb = GetComponent();
anim = GetComponent();
audsrc = GetComponent();
pState = GetComponent();
}
void Start()
{
ToggleCursorOff();
audioManager = AudioManager.Instance;
currentHealth = maxHealth;
PlayerHUDManager.Instance.UpdateHealthUI();
PlayerHUDManager.Instance.UpdateSpeedTierUI();
}
private void SetupInputActions()
{
jumpAction = playerInput.actions["Jump"];
attackAction = playerInput.actions["Attack"];
parryAction = playerInput.actions["Parry"];
crouchAction = playerInput.actions["Crouch"];
}
public void GetInputs()
{
AttackInput = attackAction.WasPressedThisFrame();
ParryInput = parryAction.WasPressedThisFrame();
CrouchInput = crouchAction.IsPressed();
JumpJustPressed = jumpAction.WasPressedThisFrame();
JumpBeingHeld = jumpAction.IsPressed();
JumpReleased = jumpAction.WasReleasedThisFrame();
}
void Update()
{
if (GameManager.Instance.gameIsPaused || levelFinished || playerDied) return;
CheckGround();
GetInputs();
HandleJump();
Slide();
HandleAttack();
Parry();
}
void FixedUpdate()
{
if (GameManager.Instance.gameIsPaused || levelFinished) return;
if (advance && !playerDied)
{
rb.linearVelocity = new Vector2(GetSpeedFromTier(), rb.linearVelocityY);
}
}
private void Jump()
{
if (!pState.jumping && !pState.sliding && !pState.parrying)
{
pState.jumping = true;
anim.SetBool("Jumping", true);
jumpParticles.Play();
audioManager.PlayRandomJumpSound();
rb.linearVelocity = new Vector2(rb.linearVelocityX, jumpForce);
}
}
private void HandleJump()
{
UpdateCoyoteTime();
UpdateJumpBuffer();
TryJump();
}
private void UpdateCoyoteTime()
{
if (isGrounded)
{
coyoteTimeCounter = coyoteTime;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
}
private void UpdateJumpBuffer()
{
if (JumpJustPressed)
jumpBufferCounter = jumpBufferTime;
else
jumpBufferCounter -= Time.deltaTime;
}
private void TryJump()
{
if (jumpBufferCounter > 0f && coyoteTimeCounter > 0f)
{
Jump();
jumpBufferCounter = 0f;
coyoteTimeCounter = 0f;
}
}
private void Slide()
{
if (CrouchInput && isGrounded && !pState.sliding && !pState.attacking && !pState.parrying)
{
StartCoroutine(PerformSlide());
}
}
private IEnumerator PerformSlide()
{
pState.sliding = true;
anim.SetTrigger("Slide");
audioManager.PlaySFX(audioManager.slideSound);
yield return new WaitForSeconds(slideDuration);
pState.sliding = false;
}
private void HandleAttack()
{
UpdateAttackBuffer();
TryAttack();
}
private bool Attack()
{
if (Time.time >= lastAttackTime + attackCooldown && !pState.attacking && !pState.sliding && !pState.parrying)
{
pState.attacking = true;
anim.SetTrigger("Attack");
audioManager.PlayRandomAttackSound();
lastAttackTime = Time.time;
return true;
}
return false;
}
private void UpdateAttackBuffer()
{
if (AttackInput)
attackBufferCounter = attackBufferTime;
else
attackBufferCounter -= Time.deltaTime;
}
private void TryAttack()
{
if (attackBufferCounter > 0f)
{
if (Attack())
{
attackBufferCounter = 0f;
}
}
}
private void Parry()
{
if (ParryInput && !pState.parrying && !pState.attacking && !pState.sliding && !pState.beingPushedBack)
{
StartCoroutine(ParryRoutine());
}
}
private IEnumerator ParryRoutine()
{
if (pState.beingPushedBack)
yield break;
pState.parrying = true;
anim.SetTrigger("Parry");
audioManager.PlaySFX(audioManager.parrySound);
float originalSpeed = GetSpeedFromTier();
advance = false;
rb.linearVelocity = new Vector2(originalSpeed * parrySpeedMultiplier, rb.linearVelocityY);
yield return new WaitForSeconds(parryAnimDuration);
if (CanAdvance())
{
advance = true;
}
pState.parrying = false;
}
public void OnSuccessfulParry()
{
pState.parrying = false;
anim.SetTrigger("ParrySuccess");
parryParticles.Play();
audioManager.PlayRandomParriedSound();
StartCoroutine(TemporaryInvincibility(0.05f)); // Set Based on animation
GainSpeedTier();
StartCoroutine(Hitstop(parryHitstopDuration));
StartCoroutine(SmallSpeedBoost());
parryImpulseSource.GenerateImpulse();
}
public IEnumerator TemporaryInvincibility(float duration)
{
pState.invincible = true;
yield return new WaitForSeconds(duration);
pState.invincible = false;
}
public IEnumerator SmallSpeedBoost()
{
float originalSpeed = GetSpeedFromTier();
advance = false;
rb.linearVelocity = new Vector2(originalSpeed * 1.5f, rb.linearVelocityY);
yield return new WaitForSeconds(0.2f);
if (CanAdvance())
{
advance = true;
}
}
public float GetSpeedFromTier()
{
switch (speedTier)
{
case SpeedTier.Lv1:
return lv1Speed;
case SpeedTier.Lv2:
return lv2Speed;
case SpeedTier.Lv3:
return lv3Speed;
default:
return baseSpeed;
}
}
private void CheckGround()
{
isGrounded = Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckY, groundLayer)
|| Physics2D.Raycast(groundCheck.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, groundLayer)
|| Physics2D.Raycast(groundCheck.position + new Vector3(-groundCheckX, 0, 0), Vector2.down, groundCheckY, groundLayer);
if (isGrounded && rb.linearVelocityY <= 0)
{
pState.jumping = false;
anim.SetBool("Jumping", false);
anim.SetBool("Falling", false);
}
else if (!isGrounded)
{
anim.SetBool("Falling", true);
}
}
private void OnDrawGizmos()
{
if (groundCheck == null) return;
// Draw the three raycast lines in the Scene view
Gizmos.color = Color.yellow;
Vector3 center = groundCheck.position;
Vector3 right = center + new Vector3(groundCheckX, 0, 0);
Vector3 left = center + new Vector3(-groundCheckX, 0, 0);
Gizmos.DrawLine(center, center + Vector3.down * groundCheckY);
Gizmos.DrawLine(right, right + Vector3.down * groundCheckY);
Gizmos.DrawLine(left, left + Vector3.down * groundCheckY);
}
public void GainSpeedTier()
{
if (playerDied) return;
if (speedTier < SpeedTier.Lv3)
{
speedTier++;
PlayerHUDManager.Instance.UpdateSpeedTierUI();
audioManager.PlayTierUpPitched(speedTier);
}
}
public void LoseSpeedTier()
{
if (playerDied) return;
if (speedTier > SpeedTier.Base)
{
if (pState.invincible) return;
audioManager.PlayTierDownPitched(speedTier);
speedTier--;
PlayerHUDManager.Instance.UpdateSpeedTierUI();
}
}
public void TakeDamage(int damage)
{
if (pState.invincible || playerDied) return;
currentHealth -= damage;
PlayerHUDManager.Instance.UpdateHealthUI();
if (currentHealth <= 0)
{
Die();
}
}
private void Die()
{
if (playerDied) return;
StartCoroutine(DeathRoutine());
}
private IEnumerator DeathRoutine()
{
audioManager.PlayRandomDeathSound();
advance = false;
playerDied = true;
rb.linearVelocity = new Vector2(0,0);
anim.Play("PlayerDeath");
yield return new WaitForSeconds(2f);
GameManager.Instance.RestartLevelAfterFade();
}
public void ApplyPushback()
{
if (pState.invincible) return;
audioManager.PlaySFX(audioManager.hitWallSound);
pState.beingPushedBack = true;
anim.SetTrigger("Hit");
rb.linearVelocity = Vector2.zero;
rb.AddForce(new Vector2(-pushbackForce, pushbackForce * 0.5f), ForceMode2D.Impulse);
LoseSpeedTier();
wallHitImpulseSource.GenerateImpulse();
StartCoroutine(Hitstop(hitstopDuration));
if (pushbackCoroutine != null)
{
StopCoroutine(pushbackCoroutine);
}
pushbackCoroutine = StartCoroutine(ContinueAfterPushback(pushbackDuration));
}
public IEnumerator ContinueAfterPushback(float delay)
{
advance = false;
yield return new WaitForSeconds(delay);
advance = true;
pState.beingPushedBack = false;
}
IEnumerator Hitstop(float time)
{
if (isInHitstop)
yield break;
isInHitstop = true;
//float originalTimeScale = Time.timeScale;
Time.timeScale = 0f;
yield return new WaitForSecondsRealtime(time);
if (!GameManager.Instance.gameIsPaused)
{
Time.timeScale = /*originalTimeScale*/ 1f;
}
isInHitstop = false;
}
public void DoHitStop(float time)
{
StartCoroutine(Hitstop(time));
}
public void DoAttackScreenShake()
{
attackImpulseSource.GenerateImpulse();
}
public void SpawnSlashFX()
{
float randomDir = Random.Range(-4,4);
Quaternion rotation = Quaternion.Euler(0, 0, randomDir);
Vector3 spawnPos = transform.position;
spawnPos.y += Random.Range(-.15f, .15f);
GameObject slash = Instantiate(slashFX, spawnPos, rotation);
float randomScale = Random.Range(.9f, 1.1f);
slash.transform.localScale *= randomScale;
}
public void SpawnBloodFX(Vector3 position)
{
ParticleSystem particles = Instantiate(bloodParticles, position, Quaternion.identity);
Destroy(particles.gameObject, particles.main.duration + particles.main.startLifetime.constantMax);
}
public void ChangeCameraFov()
{
baseFOV = CameraManager.Instance.normalCameraFov;
switch (speedTier)
{
case SpeedTier.Lv1:
CameraManager.Instance.currentCamera.Lens.FieldOfView = lv1FOV;
anim.SetFloat("RunSpeed", lv1AnimSpeed);
break;
case SpeedTier.Lv2:
CameraManager.Instance.currentCamera.Lens.FieldOfView = lv2FOV;
anim.SetFloat("RunSpeed", lv2AnimSpeed);
break;
case SpeedTier.Lv3:
CameraManager.Instance.currentCamera.Lens.FieldOfView = lv3FOV;
anim.SetFloat("RunSpeed", lv3AnimSpeed);
break;
default:
CameraManager.Instance.currentCamera.Lens.FieldOfView = baseFOV;
anim.SetFloat("RunSpeed", baseAnimSpeed);
break;
}
}
public void EnableAttackHitbox()
{
attackHitbox.SetActive(true);
}
public void DisableAttackHitbox()
{
pState.attacking = false;
attackHitbox.SetActive(false);
}
public void EnableParryHitbox()
{
parryHitbox.SetActive(true);
}
public void DisableParryHitbox()
{
pState.parrying = false;
parryHitbox.SetActive(false);
}
public bool CanAdvance()
{
return !pState.beingPushedBack; // Add anythyng needed
}
public void PlayFootStepSound()
{
audioManager.PlayRandomFootStepSound();
}
/// UTILITIES
public void ToggleCursorOn()
{
if (playerInput.currentControlScheme == "Controller") return;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
public void ToggleCursorOff()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
Neon Breakline
Handles game states and scene changes.
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
[SerializeField] private GameObject pauseMenu;
[SerializeField] private Button pauseMenuButton;
public bool gameIsPaused;
private PlayerInput playerInput;
private InputAction pauseAction;
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
}
else
{
Instance = this;
}
Time.timeScale = 1f;
playerInput = FindFirstObjectByType();
pauseAction = playerInput.actions["Pause"];
}
private void Update()
{
if (pauseAction.WasPressedThisFrame())
{
TogglePause();
}
}
public void TogglePause()
{
if (PlayerController.Instance.pState.inTutorial || PlayerController.Instance.levelFinished) return;
if (gameIsPaused)
ResumeGame();
else
PauseGame();
}
public void PauseGame()
{
Time.timeScale = 0f;
gameIsPaused = true;
pauseMenu.SetActive(true);
pauseMenuButton.Select();
}
public void ResumeGame()
{
Time.timeScale = 1f;
gameIsPaused = false;
pauseMenu.SetActive(false);
}
public void ExitToMainMenu()
{
Time.timeScale = 1f;
SceneManager.LoadScene("MainMenu");
}
public void RestartLevel()
{
Time.timeScale = 1f;
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
Neon Breakline
Helped encrypt the save data for Neon Breakline so it couldn't be easily editable.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
public static class EncryptionUtility
{
private static readonly string key = "ProjectForwardWallaceKey"; //24 chars
private static readonly string iv = "ProjectForwardIV"; //16 chars
public static string Encrypt(string plainText)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key.Substring(0, 24));
aes.IV = Encoding.UTF8.GetBytes(iv.Substring(0, 16));
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(plainText);
sw.Close();
return Convert.ToBase64String(ms.ToArray());
}
}
}
public static string Decrypt(string cipherText)
{
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key.Substring(0, 24));
aes.IV = Encoding.UTF8.GetBytes(iv.Substring(0, 16));
byte[] buffer = Convert.FromBase64String(cipherText);
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(cipherText)))
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read))
using (StreamReader sr = new StreamReader(cs))
{
return sr.ReadToEnd();
}
}
}
}
Thousand Paths (Metroidvania)
Handled Dialogue Scenes in my Metroidvania Project.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.UI;
public class CutsceneSystem : MonoBehaviour
{
[Header("Core")]
public static CutsceneSystem instance;
public AudioSource audioSource;
[Header("Dialogue")]
public bool isInDialogue;
public DialogueLines[] lines;
public int currentLine;
public float ogTextSpeed;
public float textSpeed;
[SerializeField][TextArea] private string[] textInfo;
[Header("UI")]
public GameObject dialogueBox;
public TMP_Text currentText;
public TMP_Text currentNameText;
public Image characterImage;
public Image indicator;
[HideInInspector] public Animator indicatorAnim;
[Header("CharacterCheck")]
public bool solveigTalking;
public bool asaTalking;
public bool kurohaTalking;
public bool ichikaTalking;
public bool kingTalking;
public bool mayukaTalking;
public bool mikaelTalking;
private Queue dialogueQueue;
private bool isScrolling;
private void Awake()
{
if (instance != null && instance != this)
{
Destroy(gameObject);
}
else
{
instance = this;
}
dialogueQueue = new Queue();
ogTextSpeed = textSpeed;
indicatorAnim = indicator.GetComponent();
this.gameObject.SetActive(false);
}
public void Update()
{
if (!isInDialogue) return;
if (textSpeed > ogTextSpeed)
{
textSpeed = ogTextSpeed;
}
if (Input.GetButtonDown("Submit") || Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.Mouse0))
{
DisplayNextLine();
if (isScrolling)
{
textSpeed /= 7;
}
}
else if (Input.GetButtonUp("Submit") || Input.GetKeyUp(KeyCode.Space) || Input.GetKeyUp(KeyCode.Mouse0))
{
textSpeed *= 7;
}
}
public void StartDialogue(DialogueLines[] lines)
{
if (isInDialogue) return;
textSpeed = ogTextSpeed;
dialogueQueue.Clear();
foreach (var line in lines)
{
if (!PlayerController.Instance.playedDialogueIds.Contains(line.id))
{
dialogueQueue.Enqueue(line);
if (line.deleteAfterPlay)
{
PlayerController.Instance.playedDialogueIds.Add(line.id);
}
}
}
isInDialogue = true;
PlayerController.Instance.pState.cantControl = true;
PlayerController.Instance.rb.velocity = new Vector3(0, 0, 0);
PlayerController.Instance.ReturnToIdle();
dialogueBox.SetActive(true);
DisplayNextLine();
}
public void DisplayNextLine()
{
if (isScrolling) return;
indicatorAnim.SetBool("End", false);
if (dialogueQueue.Count == 0)
{
EndDialogue();
return;
}
if (dialogueQueue.Count == 1)
{
indicatorAnim.SetBool("End",true);
}
var currentLine = dialogueQueue.Dequeue();
UpdateUI(currentLine);
PlayDialogueSound(currentLine);
StartCoroutine(ScrollText(currentLine.dialogueText));
if (currentLine.action.GetPersistentEventCount() > 0)
{
currentLine.action.Invoke();
}
}
private void UpdateUI(DialogueLines line)
{
if (line.character.ToString() == "NONE")
{
currentNameText.text = "";
characterImage.sprite = line.GetCharacterPortrait();
}
else
{
currentNameText.text = line.character.ToString();
characterImage.sprite = line.GetCharacterPortrait();
}
}
private IEnumerator ScrollText(string text)
{
indicatorAnim.SetTrigger("Scrolling");
isScrolling = true;
currentText.text = "";
foreach (char c in text)
{
currentText.text += c;
yield return new WaitForSeconds(textSpeed);
}
isScrolling = false;
if (indicatorAnim.GetBool("End") == false)
{
indicatorAnim.SetTrigger("Next");
}
}
private void PlayDialogueSound(DialogueLines line)
{
if (audioSource == null) return;
AudioClip clip = line.GetSoundEffect();
if (clip != null)
{
audioSource.PlayOneShot(clip);
}
}
public void EndDialogue()
{
dialogueBox.SetActive(false);
isInDialogue = false;
PlayerController.Instance.pState.cantControl = false;
this.gameObject.SetActive(false);
}
}
Thousand Paths (Metroidvania)
Handled health UI and some other things like the economy HUD.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class HealthController : MonoBehaviour
{
PlayerController player;
private GameObject[] sakuraContainer;
private Image[] sakuraFilled;
public Transform sakuraParent;
public GameObject sakuraContainerPrefab;
public TextMeshProUGUI riceText;
public TextMeshProUGUI coinsText;
[SerializeField] public Animator riceCounter;
[SerializeField] public Animator coinsCounter;
public bool riceCollected;
public bool coinsCollected;
void Start()
{
player = PlayerController.Instance;
sakuraContainer = new GameObject[PlayerController.Instance.maxTotalHealth];
sakuraFilled = new Image[PlayerController.Instance.maxTotalHealth];
PlayerController.Instance.onHealthChangedCallback += UpdateSakuraHUD;
InstantiateSakuraContainers();
UpdateSakuraHUD();
UpdateMoneyHUD();
}
void SetSakuraContainer()
{
for (int i = 0; i < sakuraContainer.Length; i++)
{
if (i < PlayerController.Instance.maxHealth)
{
sakuraContainer[i].SetActive(true);
}
else
{
sakuraContainer[i].SetActive(false);
}
}
}
void SetFilledSakura()
{
for (int i = 0; i < sakuraFilled.Length; i++)
{
if (i < PlayerController.Instance.Health)
{
sakuraFilled[i].GetComponent().SetBool("Filled", true);
}
else
{
sakuraFilled[i].GetComponent().SetBool("Filled", false);
}
}
}
void InstantiateSakuraContainers()
{
for(int i = 0; i < PlayerController.Instance.maxTotalHealth; i++)
{
GameObject temp = Instantiate(sakuraContainerPrefab);
temp.transform.SetParent(sakuraParent, false);
sakuraContainer[i] = temp;
sakuraFilled[i] = temp.transform.Find("Flower").GetComponent();
}
}
void UpdateSakuraHUD()
{
SetSakuraContainer();
SetFilledSakura();
}
public void UpdateMoneyHUD()
{
if (riceCollected)
{
StartCoroutine(RiceCoroutine());
}
if (coinsCollected)
{
StartCoroutine(CoinsCoroutine());
}
}
public void UpdateMoneyHUDForKatana()
{
StartCoroutine(RiceCoroutine());
StartCoroutine(CoinsCoroutine());
}
public IEnumerator RiceCoroutine()
{
if (riceCounter.GetBool("Opened") == false)
{
riceCollected = false;
riceCounter.SetTrigger("Open");
riceCounter.SetBool("Opened", true);
riceText.text = player.riceOwned.ToString();
yield return new WaitForSeconds(3f);
if (!riceCounter.GetBool("Closing"))
{
riceCounter.SetBool("Closing", true);
riceCounter.SetTrigger("Close");
riceCounter.SetBool("Opened", false);
yield return new WaitForSeconds(.1f);
riceCounter.SetBool("Closing", false);
}
}
else
{
riceText.text = player.riceOwned.ToString();
}
}
public IEnumerator CoinsCoroutine()
{
if (coinsCounter.GetBool("Opened") == false)
{
coinsCollected = false;
coinsCounter.SetTrigger("Open");
coinsCounter.SetBool("Opened", true);
coinsText.text = player.coinsOwned.ToString();
yield return new WaitForSeconds(3f);
if (!coinsCounter.GetBool("Closing"))
{
coinsCounter.SetBool("Closing", true);
coinsCounter.SetTrigger("Close");
coinsCounter.SetBool("Opened", false);
yield return new WaitForSeconds(.1f);
coinsCounter.SetBool("Closing", false);
}
}
else
{
coinsText.text = player.coinsOwned.ToString();
}
}
}
NDA
Please check out this Github page to see some of the work I'm doing for a still in development 3D Puzzle Game with a small team.
You can check out some other code samples on my Github Code Portfolio! Here