当前位置: 首页 > 知识库问答 >
问题:

Unity-2D瞄准鼠标,同时限制最小/最大旋转,并考虑父旋转

刁文光
2023-03-14

所以,我有一艘附加了“硬点”的船,可以把武器放在上面。放置后,它们瞄准鼠标位置,旋转范围有限:参见此处

旋转范围基于minAngle和maxAngle,并通过eulerAngles计算。父硬点槽的z,加/减角度修改器(在本例中为20)。我不得不做一些奇怪的旋转巫术(参见代码片段中的OneEightyToThreeSixty()),以使鼠标的视角与minAngle/maxAngle的格式匹配。

角度是-180-

我重写这个脚本的次数多得数不清,但最终我被这个问题击中了。

正如你所看到的,对于270度的360度旋转,瞄准和限制完全正常。但在旋转的右上角,一切都变得混乱。

我尝试了很多不同的实现,但它们似乎都有这个一致的问题。我不知道我错过了什么。代码如下:

public class HardpointSlot : MonoBehaviour
{
    public HardpointController ship;
    public GameObject hardpoint;

    public float minAngle;
    public float maxAngle;
    public float angle;
    public float offsetAngle;
    public bool switched;

    void Update()
    {
        AimAtMouse();
    }

    public void AimAtMouse()
    {
        Vector3 dir = Input.mousePosition - Camera.main.WorldToScreenPoint(transform.position);

        angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

        minAngle = (transform.eulerAngles.z - 20) + 90f;
        maxAngle = (transform.eulerAngles.z + 20) + 90f;

        angle = OneEightyToThreeSixty(angle);
        if (angle < minAngle)
        {
            angle = minAngle;
        }
        else if (angle > maxAngle)
        {
            angle = maxAngle;
        }

        hardpoint.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
    }

    public float OneEightyToThreeSixty(float angle)
    {
        float newAngle = 0f;

        if (angle >= 0 && angle <= 180)
        {
            return angle;
        } else
        {
            return newAngle = 360 + angle;
        }


    }
}

所以请快速回顾一下:

  • Hardpoint需要查看鼠标,但前提是鼠标在其目标范围边界内,该范围由baseAim偏移(20)和父Hardpoint插槽的旋转计算
  • 适用于270度旋转,但不适用于最后90度

有什么想法吗?我是不是漏掉了什么很明显的东西?

共有1个答案

董建茗
2023-03-14

我会采取另一种方法,利用Vector3。SignedAngle获取从中性方向到鼠标方向的角度。然后,使用Mathf。夹紧将其夹紧在边界之间,然后夹紧四元数。AngleAxis创建结果方向。最后,使用四元数。LookRotation要将旋转指定给硬点的变换,请执行以下操作:

public class HardpointSlot : MonoBehaviour
{
    [SerializeField] HardpointController ship;
    [SerializeField] GameObject hardpoint;

    [SerializeField] float minAngle;
    [SerializeField] float maxAngle;
    [SerializeField] float angle;

    void Update()
    {
        AimAtMouse();
    }

    public void AimAtMouse()
    {
        Vector3 dir = Camera.main.ScreenToWorldPoint(Input.mousePosition)
                - transform.position;

        // flatten z axis
        dir.z = 0;
    
        Vector3 neutralDir = transform.up;
        float angle = Vector3.SignedAngle(neutralDir, dir, Vector3.forward);
    
        minAngle = -20f;
        maxAngle = 20f;
        
        angle = Mathf.Clamp(angle, minAngle, maxAngle);
       
        // rotate neutral dir by the clamped angle
        dir = Quaternion.AngleAxis(angle, Vector3.forward) * neutralDir;
    
        // set the rotation so that local up points in dir direction 
        // and local forward in global forward
        hardpoint.transform.rotation = Quaternion.LookRotation(Vector3.forward, dir);
    }
}

 类似资料:
  • 本文向大家介绍Unity3D实现鼠标控制旋转转盘,包括了Unity3D实现鼠标控制旋转转盘的使用技巧和注意事项,需要的朋友参考一下 在培训模拟考试软件中,我们经常会遇到类似用鼠标旋转转盘打开开关的需求。让用户更加真实的操作设备仪器。接下来说下我的解决方案。 因为鼠标操作是在UI平面上,所以我们要先将被操作的模型的世界坐标转换到屏幕坐标上。代码如下: 这里有个声明,这个模型代表的是转盘,而且要保证模

  • 我正在libGDX中制作一个游戏,我在设置Bullet类时遇到了麻烦。我无法让射弹去鼠标位置。 我试图用Math.atan()来找到我需要射击的角度,但是我不能让它工作。现在我只是用距离来寻找x轴和y轴上的速度。

  • NowCoder 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 解题思路 将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的数组元素是原数组的一半,从而将问题规模减少了一半,这种折半性质的算法的时间复杂度为 O(logN)(为了方便,这里将 log2N 写为 lo

  • 一、题目 把一个数组最开始的若干个元素搬到数组的末尾, 我们称之数组的旋转。输入一个递增排序的数组的一个旋转, 输出旋转数组的最小元素。例如数组{3,4,5,1,2 }为{ 1,2,3,4,5}的一个旋转,该数组的最小值为1。 二、解题思路 Step1.和二分查找法一样,我们用两个指针分别指向数组的第一个元素和最后一个元素。 Step2.接着我们可以找到数组中间的元素: 如果该中间元素位于前面的递

  • 我真的很困惑为什么我的Java代码不起作用,它给了黑客地球上的代码僧侣TLE。这里是指向1的链接 链接质疑第一个问题和尚和旋转 我不知道为什么它给了TLE我想这是一个无限循环。 现场的问题是- 蒙克和旋转蒙克喜欢对数组执行不同的操作,所以作为哈克地球学校的校长,他给他的新学生米什基布置了一个任务。Mishki将被提供一个大小为N的整数数组A和一个整数K,在这里她需要将数组向正确的方向旋转K步,然后

  • 我有一个带有子视图控制器的视图控制器。 应强制A始终保持纵向,但应允许B自由旋转。 我知道shouldAutorotate应该适用于任何视图控制器及其子级,但有什么方法可以绕过它吗?看起来我可以使用shouldAutorotateToInterfaceOrientation,但这在iOS 8中被阻止了。 我想保持视频播放器静态(因此无论设备方向如何,水平视频始终是水平的),而控制层子视图覆盖允许自