Unity3D射线检测墙面前停止移动

功能:

计算角色/怪物走到目标,如果有墙就再墙前停止,防止一直怼墙走现象。

思路:

1. θ角 = 入射线(self - target) 与 法线(raycastHit.normal) 的夹角度(V3.angle)

2. 距墙停止距离 = 自身半径R / cosθ角

3. |应走向量| = 走到墙前向量.长度(magnitude) -  距墙停止距离

4. 应走向量 = 到墙向量.单位向量 *  |应走向量|

限制:

①不能是斜着的墙或人

②地形是平面

③不能太小的阻挡物,太细的夹角需要增加一次计算

实验截图:

橙色圆柱是角色,绿色是要走到的目标位置,计算结果是灰色圆柱

   

    

上码:

public class test : MonoBehaviour
{
    public GameObject Self;
    public GameObject Fake;
    public GameObject Target;
    public float width;

    public float rayAngle;
    public float rayDirectValue;
    public float realGetLenght;
    public Vector3 rayVector;
    public Vector3 realGetVector;

    public float offerAngle;
    public float offerSin;
    public float offerCos;
    public float offerXValue;
    public float offerZValue;

    void Start()
    {
        width = Self.GetComponent<CapsuleCollider>().radius * Self.transform.localScale.x;
    }

    void Update()
    {
        Vector3 wantPos = Target.transform.position;
        Vector3 realGetPos = Vector3.zero;
        RaycastHit raycastHit = new RaycastHit();
        Ray wallCheck = new Ray(Self.transform.position, Target.transform.position - Self.transform.position);
        if (Physics.Raycast(wallCheck, out raycastHit, Vector3.Distance(Target.transform.position, Self.transform.position) + 8, 1 << LayerMask.NameToLayer("Ground")))
        {
            rayAngle = Vector3.Angle(Self.transform.position - Target.transform.position, raycastHit.normal);
            rayDirectValue = width / Mathf.Cos(Mathf.PI / 180 * rayAngle);
            rayVector = raycastHit.point - Self.transform.position;
            realGetLenght = rayVector.magnitude - rayDirectValue;           
            realGetVector = rayVector.normalized * realGetLenght;
            realGetPos = new Vector3(
                    Self.transform.position.x + realGetVector.x,
                    Self.transform.position.y,
                    Self.transform.position.z + realGetVector.z);
        }
        else
            realGetPos = wantPos;
        
        Fake.transform.position = realGetPos;
        Debug.DrawLine(Self.transform.position, wantPos, Color.red);
        Debug.DrawLine(Self.transform.position, realGetPos, Color.blue);
    }
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值