# 【用Unity实现抛物线向目标点发射炮弹功能】

## 用Unity实现抛物线向目标点发射炮弹功能

• 准备阶段
实现此功能，我一共创建了三个脚本：
DirectionalArtilleryShell.cs挂载到附加了Collider和Rigbody的炮弹物体上。
DirectionalArtilleryController.cs 挂载到发射台上
DirectionalArtilleryShootPoint.cs挂载到发射点组件上，其实这个脚本可以省略掉的，为了后面加上对发射台其他的操作，就先加上吧，哈哈。
炮弹和特效存放目录位置如图（可根据不同项目自行设置）：

组件节点顺序
• 一、实现炮弹的飞行功能，脚本名称【DirectionalArtilleryShell】
``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DirectionalArtilleryShell : MonoBehaviour
{
//打击目标
private Transform Target;
//发射速度
private float speed = 0f;
//最小接近距离
private float min_distance = 0f;
//是否需要追踪
private bool IsTrace = false;
//炮弹与目标点距离
private float distanceToTarget;
//是否移动
private bool move_flag = true;
//目标点坐标
private Vector3 TargetPosition = Vector3.zero;
//击中目标点时与目标点的角度
public float HitAngle = 45f;
//集中特效
private GameObject HitEffect;

private void Awake()
{
}

/// <summary>
/// 参数： 攻击目标点、发射速度、最小停止运动距离
/// </summary>
public void SetShellData(Transform target,float speed,float distance,float hitAngle,bool isTrace)
{
Target = target;
TargetPosition = Target.position;
this.speed = speed;
min_distance = distance;
HitAngle = hitAngle;
IsTrace = isTrace;
distanceToTarget = Vector3.Distance(transform.position, Target.position);
}

/// <summary>
/// 发射炮弹
/// </summary>
public void Shoot()
{
StartCoroutine(Parabola());
}

/// <summary>
/// 炮弹主要实现
/// </summary>
/// <returns></returns>
IEnumerator Parabola()
{
while (move_flag)
{
if (IsTrace)
{
TargetPosition = Target.position;
}
transform.LookAt(TargetPosition);
float angle = Mathf.Min(1, Vector3.Distance(transform.position, TargetPosition) / distanceToTarget) * HitAngle;
transform.rotation = transform.rotation * Quaternion.Euler(Mathf.Clamp(-angle, -42,42), 0, 0);
float currentDist = Vector3.Distance(transform.position, TargetPosition);
if (currentDist < min_distance)
{
move_flag = false;
}
transform.Translate(Vector3.forward * Mathf.Min(speed * Time.deltaTime, currentDist));
yield return null;
}
if (move_flag == false)
{
transform.position = TargetPosition;
StopCoroutine(Parabola());
GameObject vfx = Instantiate(HitEffect);
vfx.transform.position = transform.position;
Destroy(gameObject);
}
}
}

``````
• 二、下面是实例化炮弹的控制器了，脚本名称【DirectionalArtilleryController】
``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DirectionalArtilleryController : MonoBehaviour
{
public Transform Target;

public float speed = 10;

public float min_distance = 0.5f;

public float HitAngle = 45f;

public bool IsTrace = false;

//炮弹实例
private GameObject DirShell;

//炮弹发射位置
private DirectionalArtilleryShootPoint ShootPoint = null;

private void Awake()
{
}

private void Start()
{
if (ShootPoint == null)
{
ShootPoint = GetComponentInChildren<DirectionalArtilleryShootPoint>();
}
}

// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
DirectionalArtilleryShell artilleryShell = CreatShell();
artilleryShell.transform.SetParent(ShootPoint.transform);
artilleryShell.transform.localPosition = Vector3.zero;
artilleryShell.SetShellData(Target,speed,min_distance, HitAngle, IsTrace);
artilleryShell.Shoot();
}
}

/// <summary>
/// 创建定向炮弹实例
/// </summary>
/// <returns></returns>
private DirectionalArtilleryShell CreatShell()
{
GameObject shellObj = Instantiate(DirShell);

shellObj.transform.TryGetComponent(out DirectionalArtilleryShell shell);

return shell;
}
}

``````
• 三、下面是炮弹的发射位置，脚本名称【DirectionalArtilleryShootPoint 】
``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DirectionalArtilleryShootPoint : MonoBehaviour
{
//这是没有方法的空脚本确实没啥用...哈哈哈
}
``````

THE END

)">