264 lines
5.9 KiB
C#
264 lines
5.9 KiB
C#
|
using UnityEngine;
|
||
|
|
||
|
public class FanPropeller : BasePropulsion
|
||
|
{
|
||
|
private const float LowPowerSoundLimit = 1f;
|
||
|
|
||
|
public float m_force;
|
||
|
|
||
|
public Direction m_forceDirection;
|
||
|
|
||
|
public bool m_isRotor;
|
||
|
|
||
|
public bool m_enabled;
|
||
|
|
||
|
public float m_defaultSpeed;
|
||
|
|
||
|
public Transform m_fanVisualization;
|
||
|
|
||
|
protected Quaternion m_origRot;
|
||
|
|
||
|
protected float m_angle;
|
||
|
|
||
|
private Vector3 m_originalDirection;
|
||
|
|
||
|
private float m_maximumRotationSpeed;
|
||
|
|
||
|
private float m_rotationSpeed;
|
||
|
|
||
|
private float m_maximumForce;
|
||
|
|
||
|
private float m_maximumSpeed;
|
||
|
|
||
|
private GameObject loopingSound;
|
||
|
|
||
|
private float powerFactor;
|
||
|
|
||
|
public ParticleSystem smokeCloud;
|
||
|
|
||
|
public override JointConnectionStrength GetJointConnectionStrength()
|
||
|
{
|
||
|
if (m_partType == PartType.Fan && m_gridRotation == GridRotation.Deg_270)
|
||
|
{
|
||
|
return JointConnectionStrength.High;
|
||
|
}
|
||
|
return m_jointConnectionStrength;
|
||
|
}
|
||
|
|
||
|
public override bool CanBeEnabled()
|
||
|
{
|
||
|
return m_maximumRotationSpeed > 0f;
|
||
|
}
|
||
|
|
||
|
public override bool IsEnabled()
|
||
|
{
|
||
|
return m_enabled;
|
||
|
}
|
||
|
|
||
|
public override Direction EffectDirection()
|
||
|
{
|
||
|
return BasePart.Rotate(m_forceDirection, m_gridRotation);
|
||
|
}
|
||
|
|
||
|
public override void Awake()
|
||
|
{
|
||
|
base.Awake();
|
||
|
m_enabled = false;
|
||
|
}
|
||
|
|
||
|
public override void Initialize()
|
||
|
{
|
||
|
m_origRot = m_fanVisualization.transform.localRotation;
|
||
|
m_enabled = false;
|
||
|
Vector3 directionVector = BasePart.GetDirectionVector(m_forceDirection);
|
||
|
m_originalDirection = base.transform.TransformDirection(directionVector);
|
||
|
}
|
||
|
|
||
|
public override void InitializeEngine()
|
||
|
{
|
||
|
powerFactor = base.contraption.GetEnginePowerFactor(this);
|
||
|
if (powerFactor > 1f)
|
||
|
{
|
||
|
powerFactor = Mathf.Pow(powerFactor, 0.75f);
|
||
|
}
|
||
|
m_maximumSpeed = powerFactor * m_defaultSpeed;
|
||
|
m_maximumForce = m_force * powerFactor;
|
||
|
m_maximumRotationSpeed = 1000f * powerFactor;
|
||
|
if (m_maximumRotationSpeed > 0f)
|
||
|
{
|
||
|
m_maximumRotationSpeed += 700f;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_angle = 0f;
|
||
|
if (m_enabled)
|
||
|
{
|
||
|
SetEnabled(false);
|
||
|
}
|
||
|
}
|
||
|
if ((bool)loopingSound)
|
||
|
{
|
||
|
AudioManager.Instance.RemoveLoopingEffect(ref loopingSound);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void FixedUpdate()
|
||
|
{
|
||
|
if (!base.contraption || !base.contraption.isRunning)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
if (m_enabled)
|
||
|
{
|
||
|
m_rotationSpeed = m_maximumRotationSpeed;
|
||
|
}
|
||
|
else if (m_rotationSpeed < 450f)
|
||
|
{
|
||
|
m_rotationSpeed *= 0.9f;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_rotationSpeed *= 0.98f;
|
||
|
}
|
||
|
m_angle += m_rotationSpeed * Time.deltaTime;
|
||
|
if (m_angle > 180f)
|
||
|
{
|
||
|
m_angle -= 360f;
|
||
|
}
|
||
|
if (!m_enabled)
|
||
|
{
|
||
|
if (m_isRotor)
|
||
|
{
|
||
|
base.rigidbody.angularDrag = 1f;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
if (m_isRotor)
|
||
|
{
|
||
|
base.rigidbody.angularDrag = 1000f;
|
||
|
}
|
||
|
Vector3 directionVector = BasePart.GetDirectionVector(m_forceDirection);
|
||
|
Vector3 vector = base.transform.TransformDirection(directionVector);
|
||
|
Vector3 vector2 = base.transform.position + vector * 0.5f;
|
||
|
Vector3 vector3 = vector;
|
||
|
if (m_isRotor)
|
||
|
{
|
||
|
vector3 = 0.5f * (vector3 + m_originalDirection);
|
||
|
}
|
||
|
float num = LimitForceForSpeed(m_maximumForce, vector3);
|
||
|
float num2 = 1f;
|
||
|
if (m_forceDirection == Direction.Left)
|
||
|
{
|
||
|
float value = Vector3.Dot(base.rigidbody.velocity, -vector3);
|
||
|
float num3 = Mathf.Clamp(value, -2f, 2f);
|
||
|
Vector3 position = base.transform.position;
|
||
|
position.z = 0f;
|
||
|
RaycastHit hitInfo;
|
||
|
if (Physics.Raycast(position, -vector3, out hitInfo, 1f) && m_enabled)
|
||
|
{
|
||
|
num2 = 1f + (2f + num3) * Mathf.Pow(1f - hitInfo.distance, 1.5f);
|
||
|
}
|
||
|
}
|
||
|
if (m_partType == PartType.Rotor && m_enabled)
|
||
|
{
|
||
|
Vector3 velocity = base.rigidbody.velocity;
|
||
|
if (velocity.magnitude > m_maximumSpeed && Vector3.Dot(vector3, velocity) > 0f)
|
||
|
{
|
||
|
float num4 = velocity.magnitude - m_maximumSpeed;
|
||
|
base.rigidbody.AddForceAtPosition(-4f * num4 * num4 * velocity.normalized, vector2, ForceMode.Force);
|
||
|
}
|
||
|
}
|
||
|
base.rigidbody.AddForceAtPosition(num * num2 * vector3, vector2, ForceMode.Force);
|
||
|
Debug.DrawRay(vector2, 0.1f * num * num2 * vector3, Color.green);
|
||
|
}
|
||
|
|
||
|
private float LimitForceForSpeed(float forceMagnitude, Vector3 forceDir)
|
||
|
{
|
||
|
Vector3 velocity = base.rigidbody.velocity;
|
||
|
float num = Vector3.Dot(velocity.normalized, forceDir);
|
||
|
if (num > 0f)
|
||
|
{
|
||
|
Vector3 vector = velocity * num;
|
||
|
if (vector.magnitude > m_maximumSpeed)
|
||
|
{
|
||
|
return forceMagnitude / (1f + vector.magnitude - m_maximumSpeed);
|
||
|
}
|
||
|
}
|
||
|
return forceMagnitude;
|
||
|
}
|
||
|
|
||
|
public override void ProcessTouch()
|
||
|
{
|
||
|
SetEnabled(!m_enabled);
|
||
|
}
|
||
|
|
||
|
public override void SetEnabled(bool toggle)
|
||
|
{
|
||
|
if (toggle && m_maximumRotationSpeed == 0f)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
m_enabled = toggle;
|
||
|
if (!m_enabled)
|
||
|
{
|
||
|
m_rotationSpeed = 800f;
|
||
|
m_angle = 292.3f;
|
||
|
if ((bool)smokeCloud)
|
||
|
{
|
||
|
smokeCloud.Stop();
|
||
|
}
|
||
|
}
|
||
|
else if ((bool)smokeCloud)
|
||
|
{
|
||
|
smokeCloud.Play();
|
||
|
}
|
||
|
base.contraption.UpdateEngineStates(base.ConnectedComponent);
|
||
|
if (m_enabled)
|
||
|
{
|
||
|
PlayPropellerSound();
|
||
|
}
|
||
|
else if ((bool)loopingSound)
|
||
|
{
|
||
|
AudioManager.Instance.RemoveLoopingEffect(ref loopingSound);
|
||
|
}
|
||
|
Billboard component = GetComponent<Billboard>();
|
||
|
if ((bool)component)
|
||
|
{
|
||
|
component.enabled = !m_enabled;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void PlayPropellerSound()
|
||
|
{
|
||
|
AudioManager instance = AudioManager.Instance;
|
||
|
switch (m_partType)
|
||
|
{
|
||
|
case PartType.Fan:
|
||
|
loopingSound = instance.SpawnLoopingEffect(instance.CommonAudioCollection.fan, base.gameObject.transform);
|
||
|
break;
|
||
|
case PartType.Rotor:
|
||
|
loopingSound = instance.SpawnLoopingEffect(instance.CommonAudioCollection.rotorLoop, base.gameObject.transform);
|
||
|
break;
|
||
|
default:
|
||
|
loopingSound = instance.SpawnLoopingEffect(instance.CommonAudioCollection.propeller, base.gameObject.transform);
|
||
|
break;
|
||
|
}
|
||
|
loopingSound.audio.time = loopingSound.audio.clip.length * Random.value;
|
||
|
}
|
||
|
|
||
|
public void LateUpdate()
|
||
|
{
|
||
|
Vector3 axis = ((!m_isRotor) ? Vector3.right : Vector3.up);
|
||
|
m_fanVisualization.transform.localRotation = m_origRot * Quaternion.AngleAxis(m_angle, axis);
|
||
|
}
|
||
|
|
||
|
public override void OnDetach()
|
||
|
{
|
||
|
Debug.Log("on detach audio");
|
||
|
if ((bool)loopingSound)
|
||
|
{
|
||
|
AudioManager.Instance.RemoveLoopingEffect(ref loopingSound);
|
||
|
}
|
||
|
}
|
||
|
}
|