Unity 限制范围-限制在4分之一圆柱形范围内活动

在我的游戏中,玩家的两只手操控中,不想让他们的手围着自己在一个圆形范围内随便乱跑,左手只想让他在左上角,右手在右上角范围活动。所以我制作这样一个算法来实现。
在这里插入图片描述

首先用Dot函数划分出4个区域,然后根据区域计算修正后的位置。
先上代码:
hero就是图中蓝色胶囊,hand是黄色的球,红色的newhand是最后修正的位置。如果两个球重叠表示不需要修正,如果修正了红色就是真实算法位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class testRange : MonoBehaviour
{
    
    
    public Transform hero;  //角色位置
    public Transform hand;  //模型手
    public Transform newhand;   //修正后的位置

    public float maxDis = 0.6f;
    protected void Update()
    {
    
    

        Vector3 dir;

        //让左手在第二象限。dot是0-1,dot2是-1~0
        Vector3 atHero = hero.position;
        Vector3 atHand = hand.position;
        atHero.y = atHand.y;
        dir = (atHand - atHero).normalized;
        float dot = Vector3.Dot(hero.forward, dir);
        float dot2 = Vector3.Dot(hero.right, dir);
        
        Debug.Log(dot + "," + dot2);
        Vector3 nowat = hand.position;
        if (dot < 0f)
        {
    
    
            //hand超过身后
            nowat = GetIntersectWithLineAndPlane(nowat, hero.forward, hero.forward, hero.position);
            
        }
        if (dot2 > 0f)
        {
    
    
            //hand超过右边
            nowat = GetIntersectWithLineAndPlane(nowat, hero.right, hero.right, hero.position);
            
        }

        //只能围绕身边
        Vector3 heroat = hero.position;
        heroat.y = nowat.y;
        float dis = Vector3.Distance(nowat, heroat);
        if (dis < maxDis)
        {
    
    
            Vector3 todir = (nowat - heroat).normalized;
            if (!todir.Equals(Vector3.zero))
                nowat = heroat + todir * maxDis;
            else
            {
    
    
                todir = (heroat - hand.position).normalized;
                nowat = heroat + todir * maxDis;
            }
        }
        newhand.position = nowat;
    }

    /// <summary>
    /// 计算直线与平面的交点
    /// </summary>
    /// <param name="point">直线上某一点</param>
    /// <param name="direct">直线的方向</param>
    /// <param name="planeNormal">垂直于平面的的向量</param>
    /// <param name="planePoint">平面上的任意一点</param>
    /// <returns></returns>
    private Vector3 GetIntersectWithLineAndPlane(Vector3 point, Vector3 direct, Vector3 planeNormal, Vector3 planePoint)
    {
    
    
        float d = Vector3.Dot(planePoint - point, planeNormal) / Vector3.Dot(direct.normalized, planeNormal);

        return d * direct.normalized + point;
    }
}

上面的代码就是计算hand在第二象限的限制,首先我们观察到dot 在第二象限是 0 ~ 1 的范围,dot2是 -1 ~ 0 ,当超过这个范围了,我们可以通过GetIntersectWithLineAndPlane函数来计算超过这个结界的碰撞点,防止出界。

最后我们可能不希望他跑到玩家某型里面了,我们给一个半径范围maxDis ,让他不要和玩家重叠。
看看效果图。
请添加图片描述

当我们移动到背后的时候,小球最多和我们平行,当小球移动到右边的时候那么最多知道面前,而且不会进入玩家模型范围。

相交算法链接来自

猜你喜欢

转载自blog.csdn.net/thinbug/article/details/131704881