解决方法大致描述就是在子弹飞行的每一帧时记录当前位置,下一帧时从上一帧的位置向当前的子弹位置发射一条射线,来检测是否有命中物体
这个方案相比于只刚体可以模拟弹道但不能让刚体高速运动,与通过发射射线检测是否命中虽可以让子弹飞行速度达到绝对的高速但无法模拟弹道,这个方案算是一个折中的方法,这里的每一个命中点都会有一个红三角作为标记,当然图中的例子出现了对一个刚体重复检测的情况,但这个相必不难解决
下面的“子弹”对象中添加了拖尾效果方便观察
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fly : MonoBehaviour
{
[SerializeField]
[Tooltip("红色标记")]
private GameObject _RadMark;
[SerializeField]
[Tooltip("速度")]
private float Speed;
[SerializeField]
[Tooltip("作为墙面的图层")]
private LayerMask blockLayerMask;
[Tooltip("上一帧的位置")]
private Vector2 frontPoint;
void Start()
{
frontPoint = this.transform.position;//隐式转换
}
// Update is called once per frame
private void FixedUpdate()
{
FlyAA();
}
private void Update()
{
CheckIsHit();
}
private void FlyAA()
{
this.transform.position = this.transform.position + Vector3.right * Speed * Time.deltaTime;
}
//检查是否有命中物体
private void CheckIsHit()
{
//发射从上一帧到下一帧位置的射线
RaycastHit2D[] RaycastHitArray = Physics2D.LinecastAll(frontPoint, this.transform.position,blockLayerMask);
Debug.DrawLine(frontPoint, this.transform.position,Color.red);//可视射线
检查是否有命中物体
Debug.Log("检测的图层"+blockLayerMask);
Debug.Log("命中的物体数量:"+RaycastHitArray.Length);
foreach (RaycastHit2D i in RaycastHitArray) //遍历检测到的物体
{
Debug.Log(i.collider.name);//显示命中
BulletHit(i.point);
}
//更新上一帧点的位置
frontPoint = this.transform.position;
}
//子弹命中
private void BulletHit(Vector3 HitPostion)
{
//放置标识
Instantiate(_RadMark,HitPostion, Quaternion.AngleAxis( 0 ,Vector3.zero));
}
}