C# 用操纵杆瞄准最近的敌人

C# 用操纵杆瞄准最近的敌人,c#,list,unity3d,C#,List,Unity3d,我的瞄准系统并不像我想的那样。我的方法是首先获取敌人(绿色三角形)的局部位置(如下图所示),然后使用操纵杆的x轴和y轴从选定目标(紫色圆圈)过滤列表 假设我把棍子推到X轴的+1处,它过滤所有X为正的绿色三角形,并按与紫色圆圈(选定目标)最近的距离对列表进行排序,以获得下一个目标 为了更清晰,这里有一个我的代码示例 // Switching target system private void SwitchTarget() { // Right stick direction fl

我的瞄准系统并不像我想的那样。我的方法是首先获取敌人(绿色三角形)的局部位置(如下图所示),然后使用操纵杆的x轴和y轴从选定目标(紫色圆圈)过滤列表

假设我把棍子推到X轴的+1处,它过滤所有X为正的绿色三角形,并按与紫色圆圈(选定目标)最近的距离对列表进行排序,以获得下一个目标

为了更清晰,这里有一个我的代码示例

// Switching target system
private void SwitchTarget()
{
    // Right stick direction
    float rightXRaw = Input.GetAxisRaw("RightStickX");
    float rightYRaw = Input.GetAxisRaw("RightStickY");

    // List for the enemies
    localTargets = new List<Transform>();

    // Filtering and adding the target based on the right stick direction (Only right, left, up and down)
    foreach (Transform localTarget in targets)
    {
        // Setting the enemies' world coordinate to local coordinate relative to the selected target
        Vector3 localChildPos = selectedTarget.Find("localChild").transform.InverseTransformPoint(localTarget.position);

        if (rightXRaw == 1 && localChildPos.x < 0)
        {
            localTargets.Add(localTarget);
        }

        if (rightXRaw == -1 && localChildPos.x > 0)
        {
            localTargets.Add(localTarget);
        }

        if (rightYRaw == 1 && localChildPos.z < 0 && Mathf.Abs (localChildPos.x) < 3)
        {
            localTargets.Add(localTarget);
        }

        if (rightYRaw == -1 && localChildPos.z > 0 && Mathf.Abs (localChildPos.x) < 3)
        {
            localTargets.Add(localTarget);
        }

    }

    // Sorting the created list based on distance from the selected target, then select the first member from the list.
    SortDistTarget(localTargets);
    SelectTarget();
}
//切换目标系统
私有void SwitchTarget()
{
//右斗杆方向
float rightXRaw=Input.GetAxisRaw(“RightStickX”);
float rightYRaw=Input.GetAxisRaw(“RightStickY”);
//敌人名单
localTargets=新列表();
//基于右斗杆方向过滤和添加目标(仅右、左、上和下)
foreach(在目标中转换localTarget)
{
//将敌人的世界坐标设置为相对于选定目标的局部坐标
Vector3 localChildPos=selectedTarget.Find(“localChild”).transform.InverseTransformPoint(localTarget.position);
if(rightXRaw==1&&localChildPos.x<0)
{
添加(localTarget);
}
if(rightXRaw==-1&&localChildPos.x>0)
{
添加(localTarget);
}
如果(rightYRaw==1&&localChildPos.z<0&&Mathf.Abs(localChildPos.x)<3)
{
添加(localTarget);
}
如果(rightYRaw==-1&&localChildPos.z>0&&Mathf.Abs(localChildPos.x)<3)
{
添加(localTarget);
}
}
//根据与选定目标的距离对创建的列表进行排序,然后从列表中选择第一个成员。
SortDistTarget(本地目标);
选择目标();
}
没关系,但在某些情况下,它不会选择我想要的,因为它只是基于4个方向(例如左、右、上和下)进行过滤。所以我想也许有一种更好更精确的方法,可以直接使用操纵杆方向,也许是使用光线投射。我很想听到这个问题的任何替代方案

回到这个方法,我的问题是,如何通过操纵杆方向(从选定目标的紫色圆圈投射)从投射射线中获得与敌人最近的距离


你需要做的是计算每个敌人相对于你当前位置的角度。您可以通过计算得到:

Math.Atan(localchildpos.x/localchildpos.y)*180/Math.PI

对于每个本地目标。您还需要具有不同操纵杆方向的角度。该方向上“最近”的敌人将是角度最接近操纵杆方向的敌人(请记住,355度处的敌人与操纵杆方向零度仅相差5度)


我怀疑这可能仍然不能让你达到你真正想要的行为。如果一个敌人离得很远,但直接与操纵杆方向成直线,那么这个敌人将被选中,而不是更近但只是稍微偏离直线的敌人。如果是这样的话,请告诉em,我很乐意为您提供解决方案。

好主意,使用两个矢量之间的增量角从未与我的矢量相交。如果速度更快的话,我愿意换成这种方法。不管怎么说,我用的是一个很棒的人的解决方案,我想这是一个更直接的方法,用叉积来计算距离
float targetRayDist=Vector3.Cross(selectedTarget.TransformDirection(stickDirection)、localTarget.transform.position-selectedTarget.position)此时它比以前工作得更好。我选择最近点的方法是,用棍子方向的点积和目标做一个条件,排除棍子方向相反的目标,再加上另一个条件,用叉积只返回小于1个单位。因此,只有接近棍棒方向向量的目标才会出现在列表中。条件满足后,我会在选择下一个目标之前,按与选定目标的距离对过滤后的目标列表进行排序。这是为了确保在切换到使用新筛选列表选择下一个新目标之前选择最近的目标。我可以看出,当目标距离1个单位或更近时,我会遇到一些问题。因此,对你的解决方案感到好奇,如果不是的话,我很想听听你的想法。本质上,我的方法是在距离中心和相对于操纵杆的角度之间进行权衡。类似于浮动目标接近度=2.4*(操纵杆和目标之间的角度)+3.7(到目标的距离)。数量最少的目标获胜。你必须玩弄这些数字,才能得到感觉正确的东西。点积法与之类似,但距离更远的目标会比距离更近的目标更受欢迎(如果我记得的话,我的向量数学有点生疏)。