Last active
August 29, 2015 14:21
-
-
Save LordNed/30e3322f4c9a61364e98 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 DG.Tweening; | |
public class ArrowProjectile : AmmoPickup, IStatusAfflictionReciever | |
{ | |
[SerializeField] private ParticleSystem m_fireTrailParticle; | |
[SerializeField] private int m_damageAmount = 2; | |
[SerializeField] private float m_antiGravDuration = 0.15f; | |
[SerializeField] private float m_gravityScale = 0.2f; | |
[SerializeField] private float m_dragAmount = 1.5f; | |
private Rigidbody2D m_rigidBody2D; | |
private Transform m_transformCache; | |
private GameObject m_arrowOwner; | |
private TriggeredStatusAffliction m_statusAffliction; | |
private Vector2 m_velocity; | |
private float m_currentGravityScale; | |
private float m_currentDrag; | |
private bool m_isAtRest; | |
private void Awake() | |
{ | |
m_fireTrailParticle.Play(); | |
m_fireTrailParticle.enableEmission = false; | |
m_fireTrailParticle.renderer.sortingLayerName = "Foreground"; | |
m_rigidBody2D = GetComponent<Rigidbody2D>(); | |
m_transformCache = transform; | |
m_statusAffliction = GetComponent<TriggeredStatusAffliction>(); | |
m_statusAffliction.Affliction = StatusAfflictionType.None; | |
// Ramp on the gravity after a short delay. | |
DOTween.To(() => m_currentGravityScale, x => m_currentGravityScale = x, m_gravityScale, 0.1f).SetDelay(m_antiGravDuration).SetEase(Ease.InQuart); | |
PickupType = Type.None; | |
AmmoType = WeaponAmmoType.Arrow; | |
Amount = 1; | |
} | |
public void Setup(GameObject owner, Vector2 velocity) | |
{ | |
m_arrowOwner = owner; | |
m_velocity = velocity; | |
} | |
private void Update() | |
{ | |
if (m_isAtRest) | |
return; | |
// Apply gravity | |
m_velocity += Physics2D.gravity * m_currentGravityScale * Time.deltaTime; | |
// Apply drag - to horizontal and vertical y components. | |
// This should keep drag from slowing down gravity falls. | |
m_velocity.x -= m_velocity.x * m_currentDrag * Time.deltaTime; | |
if (m_velocity.y > 0) | |
{ | |
m_velocity.y -= m_velocity.y * m_currentDrag * Time.deltaTime; | |
// Also always apply gravity to vertical y components. | |
m_velocity.y += Physics2D.gravity.y * m_gravityScale * Time.deltaTime; | |
} | |
// Fire a ray in the directon of our velocity to handle collisions ourselves since Unity fucking sucks at it. | |
Vector3 dir = m_velocity.normalized; | |
float dist = m_velocity.magnitude * Time.deltaTime; | |
Vector2 rayStart = m_transformCache.TransformPoint(0.35f, 0, 0); | |
RaycastHit2D raycastHit = Physics2D.Raycast(rayStart, dir, dist, LayerMask.GetMask("Platforms", "One Way Platforms")); | |
if(raycastHit) | |
{ | |
// Check the impact angle and our current speed. | |
float dotResult = Vector2.Dot(raycastHit.normal, m_velocity.normalized); | |
float speed = m_velocity.magnitude; | |
Debug.Log("Speed: " + m_velocity.magnitude + " Dot: " + dotResult); | |
// Take reasonably straight on impacts at sufficiently high speeds as "stick into wall". | |
if(dotResult < -0.9f && speed >= 8f) | |
{ | |
Debug.Log("Stuck into wall."); | |
m_isAtRest = true; | |
PickupType = Type.Ammo; | |
m_velocity = m_velocity.normalized; | |
// Step it 1 further forward so it's in the wall somewhat. | |
m_transformCache.position += new Vector3(m_velocity.x, m_velocity.y, 0) * 0.2f; | |
return; | |
} | |
m_currentDrag += m_dragAmount; | |
m_velocity = Vector3.Reflect(m_velocity, raycastHit.normal); | |
m_transformCache.position += new Vector3(m_velocity.x, m_velocity.y) * Time.deltaTime; | |
if(m_velocity.magnitude < 0.1f) | |
{ | |
m_isAtRest = true; | |
PickupType = Type.Ammo; | |
m_velocity = Vector2.zero; | |
} | |
} | |
m_transformCache.position += dir * dist; | |
} | |
private void LateUpdate() | |
{ | |
// Orient the arrow to face in the direction of the velocity. | |
transform.rotation = Quaternion.FromToRotation(Vector3.right, m_velocity); | |
} | |
private void OnTriggerEnter2D(Collider2D col) | |
{ | |
if (m_isAtRest) | |
return; | |
// See if it's something that takes damage, if so we're going to kill the velocity and its ability to hurt. | |
IDamageable damageable = (IDamageable)col.gameObject.GetComponent(typeof(IDamageable)); | |
if (damageable != null) | |
{ | |
AttackerInfo attackInfo = new AttackerInfo(m_arrowOwner, m_statusAffliction.Affliction, KnockbackForceAmount.Low, m_damageAmount); | |
damageable.OnTakeDamage(attackInfo); | |
} | |
} | |
public void OnEnterStatusAffliction(StatusAfflictionType type, TriggeredStatusAffliction other) | |
{ | |
switch (type) | |
{ | |
case StatusAfflictionType.Fire: | |
OnIgnition(); | |
break; | |
case StatusAfflictionType.Water: | |
OnExtinguish(); | |
break; | |
} | |
} | |
public void OnExitStatusAffliction(StatusAfflictionType type, TriggeredStatusAffliction other) | |
{ | |
} | |
public void OnIgnition() | |
{ | |
m_statusAffliction.Affliction = StatusAfflictionType.Fire; | |
m_fireTrailParticle.enableEmission = true; | |
} | |
public void OnExtinguish() | |
{ | |
m_fireTrailParticle.enableEmission = false; | |
m_statusAffliction.Affliction = StatusAfflictionType.None; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment