Files
HauntedBloodlines/Assets/Obi/Samples/Cloth/SampleResources/Scripts/AutoCannon.cs
2025-05-29 22:31:40 +03:00

64 lines
1.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AutoCannon : MonoBehaviour
{
public GameObject cannonBall;
public Transform target;
public Rigidbody targetRigidbody;
public float launchAngle = 45;
public float shotFrequency = 10;
public float shotVariability = 2;
Vector3 projectileXZPos;
Vector3 targetXZPos;
Vector3 targetXZVel;
private void Awake()
{
StartCoroutine(Shoot());
}
void Update()
{
projectileXZPos = new Vector3(transform.position.x, 0.0f, transform.position.z);
targetXZPos = new Vector3(target.position.x, 0.0f, target.position.z);
targetXZVel = new Vector3(targetRigidbody.linearVelocity.x, 0.0f, targetRigidbody.linearVelocity.z);
transform.LookAt(targetXZPos);
}
IEnumerator Shoot()
{
while (true)
{
yield return new WaitForSeconds(shotFrequency - shotVariability + UnityEngine.Random.value * shotVariability);
var ball = Instantiate(cannonBall, transform.position, Quaternion.identity);
Launch(ball.GetComponent<Rigidbody>());
}
}
void Launch(Rigidbody rb)
{
float G = Physics.gravity.y;
float tanAlpha = Mathf.Tan(launchAngle * Mathf.Deg2Rad);
float H = target.position.y - transform.position.y;
float R = Vector3.Distance(projectileXZPos, targetXZPos);
float Vz = Mathf.Sqrt(G * R * R / (2.0f * (H - R * tanAlpha)));
if (Vz > 0.001f)
{
float projectileT = R / Vz;
Vector3 extrapolatedPos = targetXZPos + targetXZVel * projectileT;
transform.LookAt(extrapolatedPos);
R = Vector3.Distance(projectileXZPos, extrapolatedPos);
Vz = Mathf.Sqrt(G * R * R / (2.0f * (H - R * tanAlpha)));
rb.linearVelocity = transform.TransformDirection(new Vector3(0f, tanAlpha * Vz, Vz));
}
}
}