Skip to content

Instantly share code, notes, and snippets.

@kihira

kihira/Health.cs Secret

Last active December 10, 2015 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kihira/fa06f238737bae968989 to your computer and use it in GitHub Desktop.
Save kihira/fa06f238737bae968989 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
public class Health : MonoBehaviour {
[SerializeField]
private float health = 5;
[SerializeField]
private Color damageColor = Color.red;
private float lastDamageTime;
public float HealthValue
{
get { return health; }
set
{
health = value;
// Show damage
lastDamageTime = Time.time + 0.175f;
GetComponent<SpriteRenderer>().color = damageColor;
if (health <= 0 && GetComponent<Score>() != null)
{
Score score = GetComponent<Score>();
GameObject.Find("Score").GetComponent<ScoreManager>().AddScore(new ScoreManager.ScoreData(score.name, score.score, 1));
}
}
}
// Update is called once per frame
void Update () {
if (lastDamageTime > 0 && lastDamageTime < Time.time)
{
lastDamageTime = 0;
GetComponent<SpriteRenderer>().color = Color.white;
}
if (health <= 0)
{
Destroy(gameObject);
}
}
}
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.UI;
public class LevelEnd : MonoBehaviour {
private SortedList<string, int> scoreCount = new SortedList<string, int>();
private int updateRate = 50;
private int scoreToAdd;
private int currScoreIndex;
private float maxMultiplier = 1f;
public Rating rating = Rating.Fail;
private Text targetText;
private Text scoreText;
private Text ratingText;
private bool touched = false;
void OnEnable()
{
targetText = GameObject.Find("Targets").GetComponent<Text>();
scoreText = GameObject.Find("Scores").GetComponent<Text>();
ratingText = GameObject.Find("Rating").GetComponent<Text>();
// Load data from score manager and parse it
// Count up enemy kills and track highest multiplier
foreach (ScoreManager.ScoreData scoreData in GameObject.Find("Score").GetComponent<ScoreManager>().Scores)
{
if (scoreCount.ContainsKey(scoreData.name))
{
scoreCount[scoreData.name] += scoreData.score;
}
else
{
scoreCount.Add(scoreData.name, scoreData.score);
}
if (scoreData.multiplier > maxMultiplier)
{
maxMultiplier = scoreData.multiplier;
}
}
//updateRate = scoreCount.Values.Sum()/(scoreCount.Count*5*30);
updateRate = 50;
// Init the text objects
targetText.text = scoreCount.Keys[0] + "\n";
scoreText.text = "0\n";
}
void Update () {
string[] targetsText = targetText.text.Split(Convert.ToChar("\n"));
string[] scoresText = scoreText.text.Split(Convert.ToChar("\n"));
if (scoreCount.Count > currScoreIndex)
{
// Skip if touched
if (Input.GetMouseButtonDown(0) && !touched)
{
scoresText[currScoreIndex] = scoreCount.Values[currScoreIndex].ToString();
NextEntry(targetsText, scoresText);
}
else if (touched)
{
touched = false;
}
// Set scoreToAdd if currently no score
if (scoreToAdd == 0)
{
scoreToAdd = scoreCount.Values[currScoreIndex];
}
int score = Convert.ToInt32(scoresText[currScoreIndex]);
if ((scoreToAdd > 0 && scoreToAdd < updateRate) || (scoreToAdd < 0 && scoreToAdd > -updateRate))
{
// When remaining scoreToAdd is less then updateRate
score += scoreToAdd;
scoreToAdd = 0;
}
else
{
// Support for negative scores
int scoreAdd = scoreToAdd > 0 ? updateRate : -updateRate;
scoreToAdd -= scoreAdd;
score += scoreAdd;
}
// Update score text
scoresText[currScoreIndex] = score.ToString();
// Move onto next score entry if complete
if (scoreToAdd == 0)
{
NextEntry(targetsText, scoresText);
}
UpdateText(targetsText, scoresText);
// Show rating at the end
if (scoreCount.Count <= currScoreIndex)
{
if (rating == Rating.Fail)
{
ratingText.text = "FAIL";
ratingText.color = Color.red;
}
else
{
ratingText.text = "PASS";
ratingText.color = Color.green;
}
}
}
}
private void NextEntry(string[] targetsText, string[] scoresText)
{
targetsText[currScoreIndex] += "\n";
scoresText[currScoreIndex] += "\n";
// Add next target name if there is one
if (scoreCount.Count > currScoreIndex + 1)
{
targetsText[currScoreIndex] += scoreCount.Keys[currScoreIndex + 1];
scoresText[currScoreIndex] += "0";
}
currScoreIndex++;
scoreToAdd = 0;
}
private void UpdateText(string[] targetsText, string[] scoresText)
{
targetText.text = string.Join("\n", targetsText);
scoreText.text = string.Join("\n", scoresText);
}
public enum Rating
{
Pass,
Fail
}
}
using UnityEngine;
using System.Collections;
/// <summary>
/// Attach this script to any object that modifies the score on its death
/// </summary>
public class Score : MonoBehaviour {
public string name;
public int score = 100;
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ScoreInfo : MonoBehaviour
{
public Vector2 targetPos;
public float moveSpeed = 10; // How fast the text scrolls up
public float fadeOutTime = 2; // When to start fading out
private float timeRemaining;
void Start ()
{
timeRemaining = fadeOutTime;
}
void Update ()
{
// Move text up the screen
Vector2 pos = GetComponent<RectTransform>().anchoredPosition;
if (pos.y < targetPos.y)
{
GetComponent<RectTransform>().anchoredPosition = new Vector2(pos.x, pos.y + (moveSpeed * Time.deltaTime));
}
// Begin fading out as we get near the end
if (targetPos.y - pos.y < fadeOutTime * moveSpeed)
{
timeRemaining -= Time.deltaTime;
// Fade out
Color color = gameObject.GetComponent<Text>().color;
color.a = ((timeRemaining / fadeOutTime) * 2);
gameObject.GetComponent<Text>().color = color;
}
if (timeRemaining <= 0)
{
Destroy(gameObject);
}
}
void OnDestroy()
{
GameObject.Find("Score").GetComponent<ScoreManager>().RemoveScoreInfo(gameObject);
}
}
using System;
using UnityEngine;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine.UI;
public class ScoreManager : MonoBehaviour {
public struct ScoreData
{
public string name;
public int score;
public float multiplier;
public ScoreData(string name, int score, float multiplier)
{
this.name = name;
this.score = score;
this.multiplier = multiplier;
}
}
// Defines how much score is added per frame to the display
public int updateRate = 2;
public GameObject scoreInfoPrefab;
public GameObject multiplier;
private readonly float multiScaleRate = 0.005f;
private int currentMult = 1;
private int score;
private int scoreToAdd;
private List<GameObject> scoreDisplay;
public List<ScoreData> Scores { get; private set; }
/**
* MonoBehaviour Methods
**/
void Start ()
{
Scores = new List<ScoreData>();
scoreDisplay = new List<GameObject>();
}
void Update ()
{
if (scoreToAdd != 0)
{
if ((scoreToAdd < updateRate && scoreToAdd >= 0) || (scoreToAdd < 0 && scoreToAdd > -updateRate))
{
score += scoreToAdd;
scoreToAdd = 0;
}
else
{
// Support for negative scores
int scoreAdd = scoreToAdd > 0 ? updateRate : -updateRate;
scoreToAdd -= scoreAdd;
score += scoreAdd;
}
// Don't let score drop below 0
if (score <= 0)
{
score = 0;
scoreToAdd = 0;
}
// Update text display for the scoreData
gameObject.GetComponent<Text>().text = (score < 0 ? "-" : "") + Math.Abs(score).ToString().PadLeft(8, '0');
}
// Check size of multiplier object and reduce it if required
if (multiplier.transform.localScale.x > 1)
{
multiplier.transform.localScale = new Vector3(multiplier.transform.localScale.x - (multiScaleRate * Time.timeScale), multiplier.transform.localScale.y - (multiScaleRate * Time.timeScale));
}
}
void OnDestroy()
{
// TODO For now, submit high score on scene change (which is when this is destroyed)
SubmitScore();
}
/**
* Publically accessible methods
**/
public void AddScore(ScoreData scoreData)
{
scoreData.multiplier = currentMult;
// Store score data and add score to score counter
Scores.Add(scoreData);
scoreToAdd += (int)(scoreData.score * scoreData.multiplier);
// Add text on screen for score
CreateScoreText(scoreData);
Debug.Log("Add score:" + scoreData);
}
public void RemoveScoreInfo(GameObject gameObject)
{
scoreDisplay.Remove(gameObject);
}
/// <summary>
/// Creates a GameObject on the In-Game Canvas that provides current score information
/// </summary>
/// <param name="scoreData">The ScoreData to parse and display</param>
/// <returns></returns>
private GameObject CreateScoreText(ScoreData scoreData)
{
GameObject scoreInfo = Instantiate(scoreInfoPrefab);
RectTransform rectTransform = scoreInfo.GetComponent<RectTransform>();
// Set the canvas as parent
rectTransform.SetParent(GameObject.Find("In-Game Canvas").GetComponent<RectTransform>(), false);
// Format text into columns and styles
scoreInfo.GetComponent<Text>().text = string.Format("{0, -30} {1, 5}", scoreData.name.ToUpper(), scoreData.score);
// Offset below other scores being displayed if needs be
if (scoreDisplay.Count > 0)
{
rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, scoreDisplay[scoreDisplay.Count-1].GetComponent<RectTransform>().anchoredPosition.y-17);
}
scoreDisplay.Add(scoreInfo);
return gameObject;
}
/// <summary>
/// Adds the current score to the local highscore data string
/// </summary>
private void SubmitScore()
{
// Make sure all the score is added to the main variable
score += scoreToAdd;
scoreToAdd = 0;
// Due to the limitations of PlayerPrefs not supporting lists, we'll conjoin everything into a semi colon seperated string
// In the future, a custom serialiser could be written which can store more data in a nicer fashion
// Scores are seperate by semi colons, score data is seperated by colons.
// scoreValue:date:username;
String scores = PlayerPrefs.GetString("HighScores", "");
scores += String.Format("{0}:{1}:{2};", score, DateTime.UtcNow.ToFileTimeUtc(), "AAA");
PlayerPrefs.SetString("HighScores", scores);
PlayerPrefs.Save();
}
private void SetMultiplyer(int mult)
{
// Don't do anything if multiplyer hasn't changed
if (mult == currentMult)
{
return;
}
currentMult = mult;
multiplier.GetComponent<Text>().text = mult + "x";
multiplier.transform.localScale = new Vector3(1.5f, 1.5f, 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment