495 lines
17 KiB
C#
495 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
//using System.Diagnostics;
|
|
//using System.Drawing;
|
|
using UnityEngine;
|
|
|
|
namespace PA_DronePack
|
|
{
|
|
public class DroneController : MonoBehaviour
|
|
{
|
|
[Tooltip("sets the drone's max forward speed")]
|
|
public float forwardSpeed = 7f;
|
|
|
|
[Tooltip("sets the drone's max backward speed")]
|
|
public float backwardSpeed = 5f;
|
|
|
|
[Tooltip("sets the drone's max left strafe speed")]
|
|
public float rightSpeed = 5f;
|
|
|
|
[Tooltip("sets the drone's max right strafe speed")]
|
|
public float leftSpeed = 5f;
|
|
|
|
[Tooltip("sets the drone's max rise speed")]
|
|
public float riseSpeed = 5f;
|
|
|
|
[Tooltip("sets the drone's max lower speed")]
|
|
public float lowerSpeed = 5f;
|
|
|
|
[Tooltip("how fast the drone speeds up")]
|
|
public float acceleration = 0.5f;
|
|
|
|
[Tooltip("how fast the drone slows down")]
|
|
public float deceleration = 0.2f;
|
|
|
|
[Tooltip("how eaisly the drone is affected by outside forces")]
|
|
public float stability = 0.1f;
|
|
|
|
[Tooltip("how fast the drone rotates")]
|
|
public float turnSensitivty = 2f;
|
|
|
|
[Tooltip("states whether or not the drone active on start")]
|
|
public bool motorOn = true;
|
|
|
|
[Tooltip("makes the drone move relative to an external compass")]
|
|
public bool headless;
|
|
|
|
[Tooltip("the external compass used to control the drone's flight direction")]
|
|
public Transform compass;
|
|
|
|
[Tooltip("assign drone's propellers to this array")]
|
|
//[HideInInspector]
|
|
public List<GameObject> propellers;
|
|
|
|
[Tooltip("set propellers max spin speed")]
|
|
//[HideInInspector]
|
|
public float propSpinSpeed = 50f;
|
|
|
|
[Tooltip("how fast the propellers slow down")]
|
|
[HideInInspector]
|
|
[Range(0f, 1f)]
|
|
public float propStopSpeed = 1f;
|
|
|
|
[Tooltip("the transform/location used to tilt the drone forward")]
|
|
[HideInInspector]
|
|
public Transform frontTilt;
|
|
|
|
[Tooltip("the transform/location used to tilt the drone backward")]
|
|
[HideInInspector]
|
|
public Transform backTilt;
|
|
|
|
[Tooltip("the transform/location used to tilt the drone right")]
|
|
[HideInInspector]
|
|
public Transform rightTilt;
|
|
|
|
[Tooltip("the transform/location used to tilt the drone left")]
|
|
[HideInInspector]
|
|
public Transform leftTilt;
|
|
|
|
[Tooltip("set whether or not the drone falls after a large impact")]
|
|
[HideInInspector]
|
|
public bool fallAfterCollision = true;
|
|
|
|
[Tooltip("sets the min. collision force used to drop the drone")]
|
|
[HideInInspector]
|
|
public float fallMinimumForce = 6f;
|
|
|
|
[Tooltip("sets the min. collision force used to create a spark")]
|
|
[HideInInspector]
|
|
public float sparkMinimumForce = 1f;
|
|
|
|
[Tooltip("the spark particle/object spawned on a collision")]
|
|
[HideInInspector]
|
|
public GameObject sparkPrefab;
|
|
|
|
[Tooltip("audio clip played during flight")]
|
|
[HideInInspector]
|
|
public AudioSource flyingSound;
|
|
|
|
[Tooltip("audio clip played on collision")]
|
|
[HideInInspector]
|
|
public AudioSource sparkSound;
|
|
|
|
[Tooltip("displays the collision force of the last impact")]
|
|
[HideInInspector]
|
|
public float collisionMagnitude;
|
|
|
|
[Tooltip("displays the current force lifting up the drone")]
|
|
[HideInInspector]
|
|
public float liftForce;
|
|
|
|
[Tooltip("displays the current force driving the drone")]
|
|
[HideInInspector]
|
|
public float driveForce;
|
|
|
|
[Tooltip("displays the current force strafing the drone")]
|
|
[HideInInspector]
|
|
public float strafeForce;
|
|
|
|
[Tooltip("displays the current force turning the drone")]
|
|
[HideInInspector]
|
|
public float turnForce;
|
|
|
|
[Tooltip("displays the drone's distance from the ground")]
|
|
[HideInInspector]
|
|
public float groundDistance = float.PositiveInfinity;
|
|
|
|
[Tooltip("displays the drones distance from being upright")]
|
|
[HideInInspector]
|
|
public float uprightAngleDistance;
|
|
|
|
[Tooltip("displays the current propeller speed")]
|
|
[HideInInspector]
|
|
public float calPropSpeed;
|
|
|
|
[Tooltip("displays drone's starting position")]
|
|
[HideInInspector]
|
|
public Vector3 startPosition;
|
|
|
|
[Tooltip("displays the drone's rotational position")]
|
|
[HideInInspector]
|
|
public Quaternion startRotation;
|
|
|
|
public Rigidbody rigidBody;
|
|
|
|
private RaycastHit hit;
|
|
|
|
private Collider coll;
|
|
|
|
private float driveInput;
|
|
|
|
private float strafeInput;
|
|
|
|
private float liftInput;
|
|
|
|
private float _drag;
|
|
|
|
private float _angularDrag;
|
|
|
|
private bool _gravity;
|
|
|
|
private void Awake()
|
|
{
|
|
coll = GetComponent<Collider>();
|
|
rigidBody = GetComponent<Rigidbody>();
|
|
startPosition = base.transform.position;
|
|
startRotation = base.transform.rotation;
|
|
_gravity = rigidBody.useGravity;
|
|
_drag = rigidBody.drag;
|
|
_angularDrag = rigidBody.angularDrag;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
MeshRenderer component = GetComponent<MeshRenderer>();
|
|
if ((bool)component)
|
|
{
|
|
GameObject.Destroy(component);
|
|
}
|
|
|
|
Transform[] componentsInChildren = base.transform.GetComponentsInChildren<Transform>(includeInactive: true);
|
|
for (int i = 0; i < componentsInChildren.Length; i++)
|
|
{
|
|
//if (!(componentsInChildren[i] == base.transform) && (!componentsInChildren[i].GetComponent<ObjectID>() || componentsInChildren[i].GetComponent<ObjectID>().id != "uQ3mR7quTHTw2aAy"))
|
|
//{
|
|
// base.enabled = false;
|
|
// base.hideFlags = HideFlags.NotEditable;
|
|
// Debug.LogError("ERROR: Editing " + base.name + "'s prefab is NOT allowed!\n", base.gameObject);
|
|
// Debug.LogWarning("Disabling PA_DroneController script...\n<color=#0057af>(Unlock the Full version of the drone pack to customize drones!)</color>", base.gameObject);
|
|
// return;
|
|
//}
|
|
}
|
|
|
|
if (headless && !compass)
|
|
{
|
|
Debug.LogError("no headless compassed assinged! please asign a compass in order to use headless mode!");
|
|
headless = false;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
uprightAngleDistance = (1f - base.transform.up.y) * 0.5f;
|
|
uprightAngleDistance = (((double)uprightAngleDistance < 0.001) ? 0f : uprightAngleDistance);
|
|
if (Physics.Raycast(base.transform.position, Vector3.down, out hit, float.PositiveInfinity))
|
|
{
|
|
groundDistance = hit.distance;
|
|
}
|
|
|
|
calPropSpeed = (motorOn ? propSpinSpeed : (calPropSpeed * (1f - propStopSpeed / 2f)));
|
|
foreach (GameObject propeller in propellers)
|
|
{
|
|
propeller.transform.Rotate(0f, 0f, calPropSpeed);
|
|
}
|
|
|
|
if ((bool)flyingSound)
|
|
{
|
|
flyingSound.volume = calPropSpeed / propSpinSpeed;
|
|
flyingSound.pitch = 1f + liftForce * 0.02f;
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (motorOn)
|
|
{
|
|
rigidBody.useGravity = false;
|
|
rigidBody.drag = 0f;
|
|
rigidBody.angularDrag = 0f;
|
|
if (headless)
|
|
{
|
|
if (!compass)
|
|
{
|
|
Debug.LogError("no headless compassed assinged! please asign a compass in order to use headless mode!");
|
|
headless = false;
|
|
}
|
|
|
|
if (groundDistance > 0.2f && (driveInput != 0f || strafeInput != 0f))
|
|
{
|
|
rigidBody.AddForceAtPosition(Vector3.down, rigidBody.position + rigidBody.velocity.normalized * 0.5f, ForceMode.Acceleration);
|
|
}
|
|
|
|
Vector3 direction = compass.InverseTransformDirection(rigidBody.velocity);
|
|
direction.z = ((driveInput != 0f) ? Mathf.Lerp(direction.z, driveInput, acceleration * 0.3f) : Mathf.Lerp(direction.z, driveInput, deceleration * 0.2f));
|
|
driveForce = ((Mathf.Abs(direction.z) > 0.01f) ? direction.z : 0f);
|
|
direction.x = ((strafeInput != 0f) ? Mathf.Lerp(direction.x, strafeInput, acceleration * 0.3f) : Mathf.Lerp(direction.x, strafeInput, deceleration * 0.2f));
|
|
strafeForce = ((Mathf.Abs(direction.x) > 0.01f) ? direction.x : 0f);
|
|
rigidBody.velocity = compass.TransformDirection(direction);
|
|
}
|
|
else
|
|
{
|
|
if (groundDistance > 0.2f)
|
|
{
|
|
if (driveInput > 0f)
|
|
{
|
|
rigidBody.AddForceAtPosition(Vector3.down * (Mathf.Abs(driveInput) * 0.3f), frontTilt.position, ForceMode.Acceleration);
|
|
}
|
|
|
|
if (driveInput < 0f)
|
|
{
|
|
rigidBody.AddForceAtPosition(Vector3.down * (Mathf.Abs(driveInput) * 0.3f), backTilt.position, ForceMode.Acceleration);
|
|
}
|
|
|
|
if (strafeInput > 0f)
|
|
{
|
|
rigidBody.AddForceAtPosition(Vector3.down * (Mathf.Abs(strafeInput) * 0.3f), rightTilt.position, ForceMode.Acceleration);
|
|
}
|
|
|
|
if (strafeInput < 0f)
|
|
{
|
|
rigidBody.AddForceAtPosition(Vector3.down * (Mathf.Abs(strafeInput) * 0.3f), leftTilt.position, ForceMode.Acceleration);
|
|
}
|
|
}
|
|
|
|
Vector3 direction2 = base.transform.InverseTransformDirection(rigidBody.velocity);
|
|
direction2.z = ((driveInput != 0f) ? Mathf.Lerp(direction2.z, driveInput, acceleration * 0.3f) : Mathf.Lerp(direction2.z, driveInput, deceleration * 0.2f));
|
|
driveForce = ((Mathf.Abs(direction2.z) > 0.01f) ? direction2.z : 0f);
|
|
direction2.x = ((strafeInput != 0f) ? Mathf.Lerp(direction2.x, strafeInput, acceleration * 0.3f) : Mathf.Lerp(direction2.x, strafeInput, deceleration * 0.2f));
|
|
strafeForce = ((Mathf.Abs(direction2.x) > 0.01f) ? direction2.x : 0f);
|
|
rigidBody.velocity = base.transform.TransformDirection(direction2);
|
|
}
|
|
|
|
liftForce = ((liftInput != 0f) ? Mathf.Lerp(liftForce, liftInput, acceleration * 0.2f) : Mathf.Lerp(liftForce, liftInput, deceleration * 0.3f));
|
|
liftForce = ((Mathf.Abs(liftForce) > 0.01f) ? liftForce : 0f);
|
|
rigidBody.velocity = new Vector3(rigidBody.velocity.x, liftForce, rigidBody.velocity.z);
|
|
rigidBody.angularVelocity *= 1f - Mathf.Clamp(InputMagnitude(), 0.2f, 1f) * stability;
|
|
Quaternion quaternion = Quaternion.FromToRotation(base.transform.up, Vector3.up);
|
|
rigidBody.AddTorque(new Vector3(quaternion.x, 0f, quaternion.z) * 100f, ForceMode.Acceleration);
|
|
rigidBody.angularVelocity = new Vector3(rigidBody.angularVelocity.x, turnForce, rigidBody.angularVelocity.z);
|
|
}
|
|
else
|
|
{
|
|
rigidBody.useGravity = _gravity;
|
|
rigidBody.drag = _drag;
|
|
rigidBody.angularDrag = _angularDrag;
|
|
}
|
|
}
|
|
|
|
private void OnCollisionEnter(Collision newObject)
|
|
{
|
|
collisionMagnitude = newObject.relativeVelocity.magnitude;
|
|
if (collisionMagnitude > sparkMinimumForce)
|
|
{
|
|
SpawnSparkPrefab(newObject.contacts[0].point);
|
|
if ((bool)sparkSound)
|
|
{
|
|
sparkSound.pitch = collisionMagnitude * 0.1f;
|
|
sparkSound.PlayOneShot(sparkSound.clip, collisionMagnitude * 0.05f);
|
|
}
|
|
}
|
|
|
|
if (collisionMagnitude > fallMinimumForce && fallAfterCollision)
|
|
{
|
|
motorOn = false;
|
|
}
|
|
}
|
|
|
|
private void OnCollisionStay(Collision newObject)
|
|
{
|
|
if (groundDistance < coll.bounds.extents.y + 0.15f)
|
|
{
|
|
liftForce = Mathf.Clamp(liftForce, 0f, float.PositiveInfinity);
|
|
}
|
|
}
|
|
|
|
public void ToggleMotor()
|
|
{
|
|
motorOn = !motorOn;
|
|
}
|
|
|
|
public void ToggleHeadless()
|
|
{
|
|
headless = !headless;
|
|
}
|
|
|
|
public void DriveInput(float input)
|
|
{
|
|
if (input > 0f)
|
|
{
|
|
driveInput = input * forwardSpeed;
|
|
}
|
|
else if (input < 0f)
|
|
{
|
|
driveInput = input * backwardSpeed;
|
|
}
|
|
else
|
|
{
|
|
driveInput = 0f;
|
|
}
|
|
}
|
|
|
|
public void StrafeInput(float input)
|
|
{
|
|
if (input > 0f)
|
|
{
|
|
strafeInput = input * rightSpeed;
|
|
}
|
|
else if (input < 0f)
|
|
{
|
|
strafeInput = input * leftSpeed;
|
|
}
|
|
else
|
|
{
|
|
strafeInput = 0f;
|
|
}
|
|
}
|
|
|
|
public void LiftInput(float input)
|
|
{
|
|
if (input > 0f)
|
|
{
|
|
liftInput = input * riseSpeed;
|
|
motorOn = true;
|
|
}
|
|
else if (input < 0f)
|
|
{
|
|
liftInput = input * lowerSpeed;
|
|
}
|
|
else
|
|
{
|
|
liftInput = 0f;
|
|
}
|
|
}
|
|
|
|
public void TurnInput(float input)
|
|
{
|
|
turnForce = input * turnSensitivty;
|
|
}
|
|
|
|
public void ResetDronePosition()
|
|
{
|
|
rigidBody.position = startPosition;
|
|
rigidBody.rotation = startRotation;
|
|
rigidBody.velocity = Vector3.zero;
|
|
}
|
|
|
|
public void SpawnSparkPrefab(Vector3 position)
|
|
{
|
|
GameObject obj = GameObject.Instantiate(sparkPrefab, position, Quaternion.identity);
|
|
ParticleSystem.MainModule main = obj.GetComponent<ParticleSystem>().main;
|
|
GameObject.Destroy(obj, main.duration + main.startLifetime.constantMax);
|
|
}
|
|
|
|
public void AdjustLift(float value)
|
|
{
|
|
riseSpeed = value;
|
|
lowerSpeed = value;
|
|
}
|
|
|
|
public void AdjustSpeed(float value)
|
|
{
|
|
forwardSpeed = value;
|
|
backwardSpeed = value;
|
|
}
|
|
|
|
public void AdjustStrafe(float value)
|
|
{
|
|
rightSpeed = value;
|
|
leftSpeed = value;
|
|
}
|
|
|
|
public void AdjustTurn(float value)
|
|
{
|
|
turnSensitivty = value;
|
|
}
|
|
|
|
public void AdjustAccel(float value)
|
|
{
|
|
acceleration = value;
|
|
}
|
|
|
|
public void AdjustDecel(float value)
|
|
{
|
|
deceleration = value;
|
|
}
|
|
|
|
public void AdjustStable(float value)
|
|
{
|
|
stability = value;
|
|
}
|
|
|
|
public void ToggleFall(bool state)
|
|
{
|
|
fallAfterCollision = !fallAfterCollision;
|
|
}
|
|
|
|
public void ChangeFlightAudio(AudioClip newClip)
|
|
{
|
|
flyingSound.clip = newClip;
|
|
flyingSound.enabled = false;
|
|
flyingSound.enabled = true;
|
|
}
|
|
|
|
public void ChangeImpactAudio(AudioClip newClip)
|
|
{
|
|
sparkSound.clip = newClip;
|
|
sparkSound.enabled = false;
|
|
sparkSound.enabled = true;
|
|
}
|
|
|
|
private float InputMagnitude()
|
|
{
|
|
return (Mathf.Abs(driveInput) + Mathf.Abs(strafeInput) + Mathf.Abs(liftInput)) / 3f;
|
|
}
|
|
|
|
private int TextureHash(Texture2D _texture)
|
|
{
|
|
int num = 0;
|
|
try
|
|
{
|
|
Color[] pixels = _texture.GetPixels();
|
|
for (int i = 0; i < pixels.Length; i++)
|
|
{
|
|
Color color = pixels[i];
|
|
num += Mathf.FloorToInt(color.r + color.g + color.b);
|
|
}
|
|
|
|
return num;
|
|
}
|
|
catch
|
|
{
|
|
Texture2D texture2D = new Texture2D(_texture.width, _texture.height, _texture.format, _texture.mipmapCount > 1);
|
|
texture2D.LoadRawTextureData(_texture.GetRawTextureData());
|
|
texture2D.Apply();
|
|
Color[] pixels = texture2D.GetPixels();
|
|
for (int i = 0; i < pixels.Length; i++)
|
|
{
|
|
Color color2 = pixels[i];
|
|
num += Mathf.FloorToInt(color2.r + color2.g + color2.b);
|
|
}
|
|
|
|
return num;
|
|
}
|
|
}
|
|
}
|
|
} |