174 lines
5.2 KiB
C#
174 lines
5.2 KiB
C#
|
|
using System;
|
||
|
|
using UnityEditor;
|
||
|
|
using UnityEngine;
|
||
|
|
using Random = UnityEngine.Random;
|
||
|
|
|
||
|
|
public class CapitalShipCannon : MonoBehaviour
|
||
|
|
{
|
||
|
|
[Header("Transform Refs")]
|
||
|
|
public Transform CannonYaw;
|
||
|
|
public Transform CannonPitch;
|
||
|
|
public Transform[] Barrels;
|
||
|
|
|
||
|
|
[Header("Shooting")]
|
||
|
|
public int teamIndex;
|
||
|
|
public Transform ManualAim;
|
||
|
|
public bool autoFire = true;
|
||
|
|
public float fireRate = 100;
|
||
|
|
public float range = 350;
|
||
|
|
|
||
|
|
// Shooting
|
||
|
|
private ParticleSpawnSystem partSpawner;
|
||
|
|
private bool firing;
|
||
|
|
private int barrelIndex;
|
||
|
|
|
||
|
|
// auto aiming
|
||
|
|
public Vector3 targetPosition = Vector3.zero;
|
||
|
|
public Vector3 aimingPosition;
|
||
|
|
private Boids.Boid targetBoid;
|
||
|
|
private bool newBoid = true;
|
||
|
|
private float cooldown;
|
||
|
|
// Yaw
|
||
|
|
private Vector3 yawValue;
|
||
|
|
private Vector3 manualYawValue;
|
||
|
|
//private Vector3 yawVel;
|
||
|
|
// Pitch
|
||
|
|
private Quaternion pitchValue;
|
||
|
|
private Quaternion manualPitchValue;
|
||
|
|
private float pitchSmooth;
|
||
|
|
private float pitchVel;
|
||
|
|
|
||
|
|
|
||
|
|
[Range(0, 1)]
|
||
|
|
public float manualBlend = 1f;
|
||
|
|
|
||
|
|
|
||
|
|
private void Start()
|
||
|
|
{
|
||
|
|
if (partSpawner == null)
|
||
|
|
{
|
||
|
|
var systems = FindObjectsByType<ParticleSpawnSystem>(FindObjectsSortMode.None);
|
||
|
|
foreach (var system in systems)
|
||
|
|
{
|
||
|
|
if (system.CompareTag(gameObject.tag))
|
||
|
|
{
|
||
|
|
partSpawner = system;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
manualYawValue = CannonYaw.forward;
|
||
|
|
manualPitchValue = CannonPitch.localRotation;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Update is called once per frame
|
||
|
|
void Update()
|
||
|
|
{
|
||
|
|
if (!CannonYaw || !CannonPitch) return;
|
||
|
|
|
||
|
|
// do auto aim
|
||
|
|
if (Boids.Instance && manualBlend < 1)
|
||
|
|
{
|
||
|
|
if (newBoid || targetBoid.id < 0 || targetBoid.health <= 0f || Vector3.Distance(targetBoid.position, CannonYaw.position) > (350f + 200f))
|
||
|
|
{
|
||
|
|
targetBoid = Boids.Instance.GetClosestBoid(ManualAim.position, teamIndex);
|
||
|
|
newBoid = false;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
targetBoid = Boids.Instance.GetBoid(targetBoid.id);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(targetBoid.id == -1)
|
||
|
|
return;
|
||
|
|
|
||
|
|
targetPosition = targetBoid.position + targetBoid.velocity * targetBoid.speed;
|
||
|
|
|
||
|
|
// manual aim
|
||
|
|
aimingPosition = Vector3.Lerp(targetPosition, ManualAim.position, manualBlend);
|
||
|
|
|
||
|
|
// Yaw
|
||
|
|
var yawDest = transform.InverseTransformPoint(aimingPosition);
|
||
|
|
yawDest.y = 0f;
|
||
|
|
var yawDestWorld = transform.TransformDirection(yawDest.normalized);//.normalized;
|
||
|
|
|
||
|
|
|
||
|
|
var debugfwd = yawDestWorld * 10;
|
||
|
|
Debug.DrawLine(CannonYaw.position, CannonYaw.position + debugfwd, Color.blue);
|
||
|
|
|
||
|
|
manualYawValue = Vector3.RotateTowards(manualYawValue, yawDestWorld, 70f * Mathf.Deg2Rad * Time.deltaTime, Time.deltaTime * 0.1f);
|
||
|
|
|
||
|
|
// Pitch
|
||
|
|
var localPitch = CannonYaw.InverseTransformPoint(aimingPosition);
|
||
|
|
localPitch.x = 0;
|
||
|
|
localPitch.y -= CannonPitch.localPosition.y;
|
||
|
|
var pitch = Vector3.Angle(Vector3.forward, localPitch.normalized);
|
||
|
|
pitch = localPitch.y > 0f ? -pitch : pitch;
|
||
|
|
pitch = Mathf.Clamp(pitch, -60f, 5f);
|
||
|
|
|
||
|
|
pitchSmooth = Mathf.SmoothDamp(pitchSmooth, pitch, ref pitchVel, 0.2f, 25f);
|
||
|
|
|
||
|
|
manualPitchValue = Quaternion.AngleAxis(pitchSmooth, Vector3.right);
|
||
|
|
|
||
|
|
// blend
|
||
|
|
|
||
|
|
CannonYaw.rotation = Quaternion.LookRotation(manualYawValue, transform.up);
|
||
|
|
CannonPitch.localRotation = manualPitchValue;
|
||
|
|
|
||
|
|
if (autoFire == false) return;
|
||
|
|
|
||
|
|
// Shooting
|
||
|
|
if (Vector3.Distance(CannonPitch.position, aimingPosition) < range) // in range
|
||
|
|
{
|
||
|
|
firing = Vector3.Dot(CannonPitch.forward, (aimingPosition - CannonPitch.position).normalized) > 0.95f; // aiming at target
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
firing = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!firing) return;
|
||
|
|
|
||
|
|
if (cooldown < 0f)
|
||
|
|
{
|
||
|
|
// shoot
|
||
|
|
var barrel = Barrels[barrelIndex];
|
||
|
|
partSpawner.Spawn(barrel.position, barrel.forward, aimingPosition);
|
||
|
|
if (Boids.Instance && manualBlend <= float.Epsilon)
|
||
|
|
{
|
||
|
|
Boids.Instance.DamageBoid(targetBoid.id, 10f);
|
||
|
|
}
|
||
|
|
|
||
|
|
barrelIndex = (int)Mathf.Repeat(barrelIndex + 1, Barrels.Length);
|
||
|
|
cooldown += (Random.Range(0.9f, 1.1f) / fireRate) * 60f;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
cooldown -= Time.deltaTime;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnDrawGizmos()
|
||
|
|
{
|
||
|
|
// Manual
|
||
|
|
var c = Color.blue;
|
||
|
|
c.a = 0.1f;
|
||
|
|
Gizmos.color = c;
|
||
|
|
var manualAimPosition = ManualAim.position;
|
||
|
|
Gizmos.DrawSphere(manualAimPosition, 2f);
|
||
|
|
Gizmos.DrawLine(manualAimPosition, CannonPitch.position);
|
||
|
|
// Auto
|
||
|
|
c = Color.green;
|
||
|
|
c.a = 0.1f;
|
||
|
|
Gizmos.color = c;
|
||
|
|
Gizmos.DrawSphere(targetPosition, 2f);
|
||
|
|
Gizmos.DrawLine(targetPosition, CannonPitch.position);
|
||
|
|
// Actual
|
||
|
|
c = Color.red;
|
||
|
|
c.a = 0.25f;
|
||
|
|
Gizmos.color = c;
|
||
|
|
//Gizmos.DrawSphere(aimingPosition, 2f);
|
||
|
|
Gizmos.DrawRay(CannonPitch.position, CannonPitch.forward * 250);
|
||
|
|
}
|
||
|
|
}
|