Created
March 25, 2015 01:44
-
-
Save LordNed/0bbb3c97d7cb4da849b1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System; | |
[RequireComponent(typeof(CharacterController2D))] | |
public class CreatureGarfunkel : StatelyMachine, IDamageable | |
{ | |
public enum MoveDirection | |
{ | |
None, Left, Right | |
} | |
public IdleState Idle; | |
public EnragedState Enraged; | |
[SerializeField] private float m_rageIncreaseRate = 0.2f; | |
[SerializeField] private float m_rageDecayRate = 0.3f; | |
[SerializeField] private float m_maxHealth = 25f; | |
[SerializeField] private float m_enrageThreashold = 0.9f; | |
public float Gravity = -25f; | |
private float m_currentRage; | |
private float m_currentHealth; | |
private Vector3 m_velocity; | |
private CharacterController2D m_controller; | |
private MoveDirection m_movementDir; | |
private void Start() | |
{ | |
m_currentRage = 0f; | |
m_currentHealth = m_maxHealth; | |
m_controller = GetComponent<CharacterController2D>(); | |
m_movementDir = MoveDirection.None; | |
} | |
[System.Serializable] | |
public class EnragedState : BaseCreatureState | |
{ | |
private CreatureGarfunkel m_baseState; | |
public override void OnAddedToMachine(StatelyMachine machine) | |
{ | |
m_baseState = (CreatureGarfunkel)machine; | |
base.OnAddedToMachine(machine); | |
} | |
} | |
[System.Serializable] | |
public class IdleState : BaseCreatureState | |
{ | |
private CreatureGarfunkel m_baseState; | |
public override void OnAddedToMachine(StatelyMachine machine) | |
{ | |
m_baseState = (CreatureGarfunkel)machine; | |
base.OnAddedToMachine(machine); | |
StartCoroutine(TestMovementState()); | |
} | |
private IEnumerator TestMovementState() | |
{ | |
while(true) | |
{ | |
m_baseState.m_movementDir = (MoveDirection)UnityEngine.Random.Range(0, 3); | |
yield return new WaitForSeconds(UnityEngine.Random.Range(0.5f, 1.2f)); | |
} | |
} | |
public override void Update() | |
{ | |
base.Update(); | |
// Apply decay to any rage we currently have. | |
m_baseState.m_currentRage -= m_baseState.m_rageDecayRate * Time.deltaTime; | |
m_baseState.m_currentRage = Mathf.Clamp(m_baseState.m_currentRage, 0f, 1f); | |
if (m_baseState.m_currentRage >= m_baseState.m_enrageThreashold) | |
{ | |
Trigger("ToEnraged"); | |
} | |
} | |
} | |
[System.Serializable] | |
public class BaseCreatureState : StatelyState, IDamageable | |
{ | |
public virtual void TakeDamage(GameObject attacker, float damageAmount) | |
{ | |
} | |
} | |
public void TakeDamage(GameObject attacker, float damageAmount) | |
{ | |
// Forward the damage event onto the current state. | |
BaseCreatureState baseState = currentState as BaseCreatureState; | |
if(baseState != null) | |
{ | |
baseState.TakeDamage(attacker, damageAmount); | |
} | |
// Each time we take a bit of damage, increase our rage amount. | |
// Rage will automatically decay over time so if you space out | |
// your hits enough, then it won't ever get enraged. However, | |
// hitting too fast/often will cause it to trigger the enraged | |
// state which will have its own cooldown. | |
m_currentRage += m_rageIncreaseRate; | |
m_currentHealth -= damageAmount; | |
// Impart some velocity from the attacker. | |
Vector3 dir = transform.position - attacker.transform.position; | |
dir.Normalize(); | |
m_velocity += dir * 5f; | |
if(m_currentHealth <= 0f) | |
{ | |
Debug.Log("Garfunkel has died. :("); | |
Destroy(gameObject); | |
} | |
} | |
public override void Update() | |
{ | |
base.Update(); | |
// Only allow us to change velocity state | |
// if we're on the ground. | |
if(m_controller.isGrounded) | |
{ | |
switch (m_movementDir) | |
{ | |
case MoveDirection.None: | |
m_velocity.x = 0; | |
break; | |
case MoveDirection.Left: | |
m_velocity.x = -4; | |
break; | |
case MoveDirection.Right: | |
m_velocity.x = 4; | |
break; | |
} | |
} | |
// Apply gravity and move us. | |
m_velocity.y += Gravity * Time.deltaTime; | |
DoThatTracyThing(transform.position + (m_velocity * Time.deltaTime)); | |
m_controller.move(m_velocity * Time.deltaTime); | |
if (m_controller.isGrounded) | |
m_velocity.y = 0; | |
} | |
private void DoThatTracyThing(Vector3 destPos) | |
{ | |
Vector3 curPos = transform.position; | |
// Look down to make sure where we're trying to go is valid. | |
int xBlock = Mathf.RoundToInt(destPos.x + (-1 * Mathf.Sign(destPos.x))); | |
Vector3 traceStartPos = new Vector3(xBlock, curPos.y + 1.15f, 0f); | |
Debug.DrawRay(traceStartPos, Vector3.down * 2.5f, Color.blue); | |
RaycastHit2D hitInfo = Physics2D.Raycast(traceStartPos, Vector3.down, 2.5f, (1 << LayerMask.NameToLayer("Platforms"))); | |
if(hitInfo.collider != null) | |
{ | |
// We did hit something. Let's check the Y value of our hit. If it's 1 block above us, | |
float deltaY = hitInfo.point.y - curPos.y; | |
if(deltaY > 0f && deltaY < 1.25f) | |
{ | |
// Jump and keep going that direction lol | |
m_velocity.y = 8; | |
} | |
} | |
else | |
{ | |
// We didn't hit anything. Don't move that way! | |
m_velocity.x = 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment