using UnityEngine;
namespace ActionGameFramework.Projectiles
{
///
/// A projectile that shoots upwards and then starts homing
///
public class WobblingHomingProjectile : HomingLinearProjectile
{
protected enum State
{
Wobbling,
Turning,
Targeting
}
///
/// The time the projectile wobbles upward is randomized from this range
///
public Vector2 wobbleTimeRange = new Vector2(1, 2);
///
/// The number of wobble direction changes per second
///
public float wobbleDirectionChangeSpeed = 4;
///
/// The intensity of the wobble
///
public float wobbleMagnitude = 7;
///
/// The time the projectile takes to turn and home
///
public float turningTime = 0.5f;
///
/// State of projectile
///
State m_State;
///
/// Seconds wobbling
///
protected float m_CurrentWobbleTime;
///
/// Total time to wobble
///
protected float m_WobbleDuration;
///
/// Seconds turning to face homing target
///
protected float m_CurrentTurnTime;
///
/// Seconds for current turn
///
protected float m_WobbleChangeTime;
protected Vector3 m_WobbleVector,
m_TargetWobbleVector;
protected override void Update()
{
// regular HomingLinearProjectile behaviour, handles a null homing target
if (m_HomingTarget == null || m_State == State.Targeting)
{
base.Update();
return;
}
switch (m_State)
{
// wobble the projectile
case State.Wobbling:
m_CurrentWobbleTime += Time.deltaTime;
if (m_CurrentWobbleTime >= m_WobbleDuration)
{
m_State = State.Turning;
m_CurrentTurnTime = 0;
}
m_WobbleChangeTime += Time.deltaTime * wobbleDirectionChangeSpeed;
if (m_WobbleChangeTime >= 1)
{
m_WobbleChangeTime = 0;
m_TargetWobbleVector = new Vector3(Random.Range(-wobbleMagnitude, wobbleMagnitude),
Random.Range(-wobbleMagnitude, wobbleMagnitude), 0);
m_WobbleVector = Vector3.zero;
}
m_WobbleVector = Vector3.Lerp(m_WobbleVector, m_TargetWobbleVector, m_WobbleChangeTime);
m_Rigidbody.velocity = Quaternion.Euler(m_WobbleVector) * m_Rigidbody.velocity;
m_Rigidbody.rotation = Quaternion.LookRotation(m_Rigidbody.velocity);
break;
// turn the projectile to face the homing target
case State.Turning:
m_CurrentTurnTime += Time.deltaTime;
Quaternion aimDirection = Quaternion.LookRotation(GetHeading());
m_Rigidbody.rotation = Quaternion.Lerp(m_Rigidbody.rotation, aimDirection, m_CurrentTurnTime / turningTime);
m_Rigidbody.velocity = transform.forward * m_Rigidbody.velocity.magnitude;
if (m_CurrentTurnTime >= turningTime)
{
m_State = State.Targeting;
}
break;
}
}
// select first wobble vector and set to wobble state
protected override void Fire(Vector3 firingVector)
{
m_TargetWobbleVector = new Vector3(Random.Range(-wobbleMagnitude, wobbleMagnitude),
Random.Range(-wobbleMagnitude, wobbleMagnitude), 0);
m_WobbleDuration = Random.Range(wobbleTimeRange.x, wobbleTimeRange.y);
base.Fire(firingVector);
m_State = State.Wobbling;
m_CurrentWobbleTime = 0.0f;
}
}
}