You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
6.4 KiB
204 lines
6.4 KiB
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
namespace Forces
|
|
{
|
|
public class Force : System.Object
|
|
{
|
|
|
|
public ForceProps properties;
|
|
|
|
protected Vector2 goal_vector = Vector2.up;
|
|
protected Vector2 last_velocity = Vector2.zero;
|
|
protected Vector2 init_in = Vector2.zero;
|
|
protected Vector2 init_out = Vector2.zero;
|
|
protected Vector2 current_output = Vector2.zero;
|
|
protected float init_time = 0.0f;
|
|
|
|
/// <summary>
|
|
/// last call from velocity method
|
|
/// </summary>
|
|
protected float last_step_time = 0.0f;
|
|
/// <summary>
|
|
/// last call from user (like AddForce) to now when start fading out
|
|
/// </summary>
|
|
protected float last_call_time = 0.0f;
|
|
|
|
protected float current_delta_step = 0.0f;
|
|
protected float current_delta_call = 0.0f;
|
|
protected float current_delta_notCall = 0.0f;
|
|
|
|
/// <summary>
|
|
/// time since init calling
|
|
/// </summary>
|
|
protected float time_calling = 0.0f;
|
|
/// <summary>
|
|
/// absolute time since init
|
|
/// </summary>
|
|
protected float time_stepping = 0.0f;
|
|
/// <summary>
|
|
/// time since left calling
|
|
/// </summary>
|
|
protected float time_notCalling = 0.0f;
|
|
|
|
protected bool killed = false;
|
|
|
|
public Force(string id, Vector2 target_direction, float target_speed, float inertia_in = 1.0f, float inertia_out = 1.0f, float impulse = 0.0f)
|
|
{
|
|
properties = new ForceProps(id, target_speed, inertia_in, inertia_out, impulse);
|
|
|
|
Call(target_direction);
|
|
}
|
|
public Force(ForceProps props, Vector2 target_direction)
|
|
{
|
|
properties = props;
|
|
|
|
Call(target_direction);
|
|
}
|
|
public Vector2 Velocity()
|
|
{
|
|
Vector2 delta = Vector2.zero;
|
|
Vector2 current_target_velocity = Vector2.zero;
|
|
|
|
if (init_time == 0.0f) Initialize();
|
|
|
|
StartStep();
|
|
|
|
current_target_velocity = FadeIn() + FadeOut();
|
|
delta = current_target_velocity;
|
|
current_output = Clamp(last_velocity + delta, goal_vector);
|
|
|
|
EndStep();
|
|
|
|
return current_output;
|
|
}
|
|
/// <summary>
|
|
/// called by user to add force
|
|
/// </summary>
|
|
public void Call(Vector2 new_goal_vector)
|
|
{
|
|
if (properties.forceMode == ForceMode.Impulse)
|
|
Initialize();
|
|
|
|
last_call_time = Time.time;
|
|
goal_vector = new_goal_vector.normalized * properties.target_speed;
|
|
}
|
|
/// <summary>
|
|
/// Determines if the force is being used after reaching zero force
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool Using()
|
|
{
|
|
//Wait half a second to check if the velocity is null
|
|
return ((Time.time - last_call_time) < 0.5f || last_velocity != Vector2.zero) && !killed;
|
|
}
|
|
public void Kill ()
|
|
{
|
|
last_call_time = 0.0f;
|
|
current_delta_call = 0.0f;
|
|
current_delta_notCall = 0.0f;
|
|
last_velocity = Vector2.zero;
|
|
killed = true;
|
|
}
|
|
/// <summary>
|
|
/// Returns the value of the last call
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Vector2 LastVelocity()
|
|
{
|
|
return last_velocity;
|
|
}
|
|
|
|
protected void Initialize()
|
|
{
|
|
init_time = Time.time;
|
|
}
|
|
|
|
protected void StartStep()
|
|
{
|
|
///Is the force acting like an impulse? if it is, then stop calling if impulse time < currentTime
|
|
bool impulse = (properties.impulse > 0.0f && Time.time - init_time < properties.impulse);
|
|
|
|
current_delta_step = last_step_time == 0.0f ? 0.0f : Time.time - last_step_time;
|
|
|
|
if (last_call_time == 0.0f)
|
|
{
|
|
current_delta_call = 0.0f;
|
|
current_delta_notCall = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
if (last_step_time - last_call_time > current_delta_step && !impulse)
|
|
{
|
|
current_delta_notCall = current_delta_step;
|
|
///set a start point to fade velocity
|
|
init_out = last_velocity;
|
|
current_delta_call = 0.0f;
|
|
time_calling = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
current_delta_call = current_delta_step;
|
|
///set a start point to fade velocity
|
|
init_in = last_velocity;
|
|
current_delta_notCall = 0.0f;
|
|
time_notCalling = 0.0f;
|
|
}
|
|
}
|
|
|
|
time_calling += current_delta_call;
|
|
time_stepping += current_delta_step;
|
|
}
|
|
|
|
protected Vector2 FadeIn()
|
|
{
|
|
// float fade_in_fact = 0.0f;
|
|
Vector2 output = Vector2.zero;
|
|
|
|
if (current_delta_call <= 0.0f) return Vector2.zero;
|
|
|
|
//fade_in_fact = Mathf.Clamp01(time_calling / inertia_in);
|
|
output = (goal_vector - last_velocity) * (current_delta_call / properties.inertia_in);
|
|
|
|
return output;
|
|
}
|
|
protected Vector2 FadeOut()
|
|
{
|
|
//float fade_out_fact = 0.0f;
|
|
Vector2 output = Vector2.zero;
|
|
|
|
if (current_delta_notCall <= 0.0f) return Vector2.zero;
|
|
|
|
//fade_out_fact = Mathf.Clamp01(time_notCalling / inertia_in);
|
|
output = (Vector2.zero - last_velocity) * (current_delta_notCall / properties.inertia_out);
|
|
|
|
return output;
|
|
}
|
|
protected Vector2 Clamp(Vector2 vector, Vector2 max)
|
|
{
|
|
float max_magnitude = max.magnitude;
|
|
float currentMagnitude = vector.magnitude;
|
|
float dot = Vector2.Dot(vector, max);
|
|
Vector2 output = vector;
|
|
|
|
//check if it is calling to clamp
|
|
if (currentMagnitude > max_magnitude && dot > 0.0f && current_delta_call != 0.0f)
|
|
{
|
|
output = max;
|
|
}
|
|
//checl if is not calling to clamp to zero
|
|
else if (dot <= 0.0f && current_delta_call == 0.0f)
|
|
{
|
|
output = Vector2.zero;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
protected void EndStep()
|
|
{
|
|
last_step_time = Time.time;
|
|
last_velocity = current_output;
|
|
}
|
|
}
|
|
}
|
|
|
|
|