OldBlueWater/BlueWater/Assets/Blobcreate/Projectile Toolkit/Demos/Scripts/03 Cannon-Like Weapons/CannonLike.cs
2023-08-10 17:23:04 +09:00

175 lines
4.5 KiB
C#

using Blobcreate.Universal;
using UnityEngine;
namespace Blobcreate.ProjectileToolkit.Demo
{
public class CannonLike : MonoBehaviour
{
public LaunchType type;
public Rigidbody shell;
public Transform barrel;
public Transform launchPoint;
public Transform uiRange;
// ForceByAngle
public float launchAngle;
// AnglesBySpeed and ForcesBySpeed
public float launchSpeed;
public bool useHighAngle;
public bool useLowAngle;
public DynamicUI ui;
bool hasTarget;
bool outOfReach;
Vector3 lookPoint;
void Update()
{
// Target
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out var mouseHitInfo, 200f))
{
lookPoint = mouseHitInfo.point;
lookPoint.y = transform.position.y;
if (Input.GetMouseButtonDown(0))
hasTarget = true;
}
outOfReach = false;
var launchVelocity = default(Vector3);
// Rotate and launch
if (type == LaunchType.VelocityByAngle)
{
launchVelocity = Projectile.VelocityByAngle(launchPoint.position, mouseHitInfo.point, launchAngle);
transform.rotation = Quaternion.LookRotation(lookPoint - transform.position);
barrel.localRotation = Quaternion.AngleAxis(-launchAngle, Vector3.right);
}
else if (type == LaunchType.AnglesBySpeed)
{
if (Projectile.AnglesBySpeed(launchPoint.position, mouseHitInfo.point, launchSpeed,
out var lowA, out var highA))
{
transform.rotation = Quaternion.LookRotation(lookPoint - transform.position);
// Rotates along local x.
if (useLowAngle)
barrel.localRotation = Quaternion.AngleAxis(-lowA, Vector3.right);
else if (useHighAngle)
barrel.localRotation = Quaternion.AngleAxis(-highA, Vector3.right);
launchVelocity = barrel.forward * launchSpeed;
}
else
{
outOfReach = true;
}
}
else if (type == LaunchType.VelocitiesBySpeed)
{
if (Projectile.VelocitiesBySpeed(launchPoint.position, mouseHitInfo.point, launchSpeed,
out var lowV, out var highV))
{
// VelocitiesBySpeed is an extended version of AnglesBySpeed.
// It is more convenient than AnglesBySpeed when the rotation
// is not separated into y axis and x axis.
transform.rotation = Quaternion.LookRotation(lookPoint - transform.position);
if (useLowAngle)
{
barrel.rotation = Quaternion.LookRotation(lowV);
launchVelocity = lowV;
}
else if (useHighAngle)
{
barrel.rotation = Quaternion.LookRotation(highV);
launchVelocity = highV;
}
}
else
{
outOfReach = true;
}
}
if (outOfReach)
{
// Out of reach, so we find the max range and aim at it.
var range = Projectile.ElevationalReach(launchPoint.position, 0f, launchSpeed, out var angle);
ui?.SetRangeText(range);
if (range > 0f)
{
var ro = Quaternion.LookRotation(lookPoint - transform.position);
transform.rotation = ro;
barrel.localRotation = Quaternion.AngleAxis(-angle, Vector3.right);
launchVelocity = barrel.forward * launchSpeed;
// Range Indicator's activation and animation.
if (!uiRange.gameObject.activeSelf)
{
uiRange.localScale = Vector3.zero;
uiRange.gameObject.SetActive(true);
}
uiRange.rotation = ro;
uiRange.localScale = Vector3.Lerp(uiRange.localScale, range * Vector3.one, 0.3f);
}
}
else
{
ui?.HideRangeText();
// Range Indicator's animation and deactivation.
if (uiRange.gameObject.activeSelf)
{
uiRange.localScale = Vector3.Lerp(uiRange.localScale, Vector3.zero, 0.3f);
if (uiRange.localScale.x < 1f)
uiRange.gameObject.SetActive(false);
}
}
if (!hasTarget)
return;
if (launchVelocity != default)
{
var bullet = Instantiate(shell, launchPoint.position, Quaternion.identity);
// Don't forget to call Launch(...) (or use your own explosion logic instead).
bullet.GetComponent<ProjectileBehaviour>().Launch(Vector3.one);
bullet.AddForce(launchVelocity, ForceMode.VelocityChange);
// Shows the time of flight stats.
FlightTestMode mode;
if (outOfReach)
mode = FlightTestMode.VerticalB;
else
mode = FlightTestMode.Both;
if (Projectile.FlightTest(bullet.position, mouseHitInfo.point, launchVelocity,
mode, out var t))
ui?.SetTOFText(t);
}
hasTarget = false;
}
void OnDisable()
{
if (uiRange != null)
uiRange.gameObject.SetActive(false);
}
public enum LaunchType
{
VelocityByAngle,
AnglesBySpeed,
VelocitiesBySpeed
}
}
}