using UnityEngine;
using System.Collections;
public class SpeedTest : MonoBehaviour {
private float lastTime;
private Vector3 lastPos;
private float dTime;
[HideInInspector]
public Vector3 currentVector;
[HideInInspector]
public float speed;
void OnEnable()
{
lastTime = Time.time;
lastPos = transform.position;
}
void Update()
{
dTime = Time.time - lastTime;
speed = PhysicsMath.GetSpeed(lastPos, transform.position, dTime);
currentVector = PhysicsMath.GetDir(lastPos, transform.position);
if(Mathf .Abs (speed )<0.001f)
{
currentVector = transform.TransformDirection(Vector3.forward);
}
lastPos = transform.position;
}
}
using UnityEngine;
using System.Collections;
public class PhysicsMath {
/// <summary>
/// 获取速度,speed=distance/time
/// <returns></returns>
public static float GetSpeed(Vector3 lastPos,Vector3 newPos,float time)
{
if (time == 0) return 0;
return Vector3.Distance(lastPos, newPos) / time;
}
/// <summary>
/// 获取方向
/// <returns></returns>
public static Vector3 GetDir(Vector3 lastPos,Vector3 newPos)
{
return (newPos - lastPos).normalized;
}
public static float GetDelta(float a,float b,float c)
{
return b * b - 4 * a * c;
}
public static float GetRad(float dis,float angle)
{
return -(2 * dis * Mathf.Cos(angle * Mathf.Deg2Rad));
}
public static float GetPom(float a,float b)
{
return 1 - Mathf.Pow(a, b);
}
public static float GetSqrtOfMath(float a,float b,float d)
{
float a1 = (-b + Mathf.Sqrt(d))/ (2 * a);
float a2 = (-b - Mathf.Sqrt(d)) / (2 * a);
return a1 > a2 ? a1 : a2;
}
public Vector3 GetHitPoint()
{
return Vector3.zero;
}
}
using UnityEngine;
using System.Collections;
public class RadarOfRocket : MonoBehaviour {
public Transform target;
private SpeedTest rocketSpeed;
private SpeedTest targetSpeed;
private Vector3 targetDir;
private float angle;
private float distance;
private bool isAim = false;
public bool IsAim
{
get { return isAim; }
set { isAim = value; }
}
private Vector3 aimPos;
public Vector3 AimPos
{
get { return aimPos; }
set { aimPos = value; }
}
private void CheckTarget()
{
if(!(rocketSpeed =GetComponent <SpeedTest >()))
{
gameObject.AddComponent<SpeedTest>();
rocketSpeed = GetComponent<SpeedTest>();
}
if(target &&!(targetSpeed =target .GetComponent <SpeedTest >()))
{
target.gameObject.AddComponent<SpeedTest>();
targetSpeed = target.GetComponent<SpeedTest>();
}
}
void OnEnable()
{
CheckTarget();
}
void Update()
{
if(target )
{
TestAim();
}
}
public void TestAim()
{
if(Mathf .Abs (targetSpeed .speed )<0.01f)
{
isAim = true;
aimPos = target.position;
}
else
{
targetDir = transform.position - target.position;
angle = Vector3.Angle(targetDir, targetSpeed.currentVector);
distance = targetDir.magnitude;
float a = PhysicsMath.GetPom((rocketSpeed.speed / targetSpeed.speed), 2);
float b = PhysicsMath.GetRad(distance, angle);
float c = distance * distance;
float d = PhysicsMath.GetDelta(a, b, c);
isAim = d >= 0 && !float.IsNaN(d) && !float.IsInfinity(d);
if(isAim )
{
float r = PhysicsMath.GetSqrtOfMath(a, b, d);
if (r < 0) isAim = false;
aimPos = target.transform.position + targetSpeed.currentVector * r;
}
}
}
}
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(RadarOfRocket))]
public class Missile : MonoBehaviour
{
private RadarOfRocket radar;
public float Speed = 100;
public float RoteSpeed = 3;
public float Noise = 0;
void OnEnable()
{
radar = GetComponent<RadarOfRocket>();
}
void Update()
{
Fly();
if (radar.IsAim)
{
FlyToTarget(radar.AimPos - transform.position);
}
}
private void FlyToTarget(Vector3 point)
{
if (point != Vector3.zero)
{
Quaternion missileRotation = Quaternion.LookRotation(point, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, missileRotation, Time.deltaTime * RoteSpeed);
}
}
private void Fly()
{
Move(transform.forward.normalized + transform.right * Mathf.PingPong(Time.time, 0.5f) * Noise, Speed * Time.deltaTime);
}
public void Move(Vector3 dir, float speed)
{
transform.Translate(dir * speed, Space.World);
}
void OnTriggerEnter(Collider other)
{
print("hit");
}
}