rotation 与vector3乘积关系

文章详细介绍了如何在Unity中利用旋转角度和距离来计算目标点的三维坐标,包括沿特定轴旋转和向前平移的具体实现,并通过代码示例展示了计算过程。进一步探讨了如何在特定角度范围内计算目标点,并通过判断点是否位于由目标点前方的三角形区域内来实现简单的碰撞检测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.已知3D坐标,和一个旋转角度,以及一段距离,求目标点的3D坐标。

已知当前点为Target,目标点沿着Target的Y轴旋转30度,沿着Target的X轴延伸10米求目标点的3D坐标?

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
usingUnityEngine;  
usingSystem.Collections;  
        
publicclass Test : MonoBehaviour  
{  
        
    publicTransform Target;  
        
    voidLateUpdate ()  
    {  
        Quaternion rotation = Quaternion.Euler(0f,30f,0f) * Target.rotation;  
        Vector3  newPos = rotation * newVector3(10f,0f,0f);  
        Debug.DrawLine(newPos,Vector3.zero,Color.red);  
        Debug.Log("newpos " + newPos +" nowpos " + Target.position + " distance " + Vector3.Distance(newPos,Target.position));  
    }  
        
}

输出结果 :新坐标 (8.7, 0.0, -5.0) 当前坐标 (0.0, 0.0, 0.0)两点之间的距离 10。

2.已知3D模型的角度求它的向量。

已知3D模型Target,Y轴旋转30度后向前平移。

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
usingUnityEngine;  
usingSystem.Collections;  
        
publicclass Test : MonoBehaviour  
{  
        
    publicTransform Target;  
        
    voidLateUpdate ()  
    {  
        
        if(Input.GetMouseButton(0))  
        {  
            Quaternion rotation = Quaternion.Euler(0f,30f,0f) * Target.rotation;  
            Vector3  newPos = rotation * Vector3.forward;  
            Target.Translate(newPos.x,newPos.y,newPos.z);  
        }  
    }  
        
}

3.已知一个目标点,让模型朝着这个目标点移动。

这是一个比较简单的例子,大家应该都能看明白。

双击代码全选
1
2
Target.transform.LookAt(newVector3 (100f,200f,300f));  
        Target.Translate(Vector3.forward);

这里我要说的就是Vector3.forward ,它等价与 new Vector3(0,0,1);它并不是一个坐标,它是一个标准向量,方向是沿着Z轴向前。这样平移一次的距离就是1米, 如果Vector3.forward * 100那么一次平移的距离就是100米。

在看看下面这段代码

双击代码全选
1
2
3
Vector3 vecn = (TargetCube.position - Target.position).normalized;  
        
        Target.Translate(vecn *0.1f);

用向量减去一个向量求出它们的差值,normalized 是格式化向量,意思是把它们之间向量格式化到1米内。这样就可以更加精确的计算一次平移的距离了 vecn *0.1f 就标示一次平移1分米,蛤蛤。

向量不仅可以进行X Y Z轴的移动,同样可以进行旋转 ,下面这段代码就是让向量沿着Y轴旋转30度。

双击代码全选
1
2
3
4
5
Vector3 vecn = (TargetCube.position - Target.position).normalized;  
        
    vecn = Quaternion.Euler(0f,30f,0f) * vecn;  
        
    Target.Translate(vecn *0.1f);

如果上述三道简单的练习题 你都能了然于心的话,那么本文最大的难题我相信也不会是什么难事,继续阅读吧。

假设我们需要计算主角面前5米内所有的对象时。以主角为圆心计算面前5米外的一个点,为了让大家看清楚我现将这条线绘制出来。

双击代码全选
1
2
3
4
5
6
7
privatefloat distance = 5f;  
voidUpdate ()   
{  
    Quaternion r= transform.rotation;  
    Vector3 f0 =  (transform.position  + (r *Vector3.forward) * distance);  
    Debug.DrawLine(transform.position,f0,Color.red);  
}

如下图所,我们已经将这两个点计算出来了。此时你可以动态的编辑主角Y轴的坐标,这个点永远都是沿着主角当前角度面前5米以外的点。

接下来,我们需要计算主角面前的一个发散性的角度。假设主角看到的是向左30度,向右30度在这个区域。

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
privatefloat distance = 5f;  
voidUpdate ()   
{  
    Quaternion r= transform.rotation;  
    Vector3 f0 =  (transform.position  + (r *Vector3.forward) * distance);  
    Debug.DrawLine(transform.position,f0,Color.red);  
        
    Quaternion r0= Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y - 30f,transform.rotation.eulerAngles.z);  
    Quaternion r1= Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y + 30f,transform.rotation.eulerAngles.z);  
        
    Vector3 f1 =  (transform.position  + (r0 *Vector3.forward) * distance);  
    Vector3 f2 =  (transform.position  + (r1 *Vector3.forward) * distance);  
        
    Debug.DrawLine(transform.position,f1,Color.red);  
    Debug.DrawLine(transform.position,f2,Color.red);  
        
    Debug.DrawLine(f0,f1,Color.red);  
    Debug.DrawLine(f0,f2,Color.red);  
}

如下图所示,这时主角面前的区域就计算出来了。看起来就是两个三角形之间的区域。

最后就是简单的套用公式,计算一个点是否在三角形内,在本文中就是计算敌人的点是否在面前的这两个三角形内。

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
usingUnityEngine;  
usingSystem.Collections;  
        
publicclass MyTest : MonoBehaviour {  
        
    publicTransform cube;  
        
    privatefloat distance = 5f;  
    voidUpdate ()   
    {  
        Quaternion r= transform.rotation;  
        Vector3 f0 =  (transform.position  + (r *Vector3.forward) * distance);  
        Debug.DrawLine(transform.position,f0,Color.red);  
        
        Quaternion r0= Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y - 30f,transform.rotation.eulerAngles.z);  
        Quaternion r1= Quaternion.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y + 30f,transform.rotation.eulerAngles.z);  
        
        Vector3 f1 =  (transform.position  + (r0 *Vector3.forward) * distance);  
        Vector3 f2 =  (transform.position  + (r1 *Vector3.forward) * distance);  
        
        Debug.DrawLine(transform.position,f1,Color.red);  
        Debug.DrawLine(transform.position,f2,Color.red);  
        
        Debug.DrawLine(f0,f1,Color.red);  
        Debug.DrawLine(f0,f2,Color.red);  
        
        Vector3 point = cube.position;  
        
        if(isINTriangle(point,transform.position,f1,f0) || isINTriangle(point,transform.position,f2,f0) )  
        {  
            Debug.Log("cube in this !!!");  
        }else
        {  
            Debug.Log("cube not in this !!!");  
        }  
        
    }  
        
    private float triangleArea(floatv0x,floatv0y,floatv1x,floatv1y,floatv2x,floatv2y)   
    {  
        returnMathf.Abs((v0x * v1y + v1x * v2y + v2x * v0y  
            - v1x * v0y - v2x * v1y - v0x * v2y) / 2f);  
    }  
        
    boolisINTriangle(Vector3 point,Vector3 v0,Vector3 v1,Vector3 v2)  
    {  
        floatx = point.x;  
        floaty = point.z;  
        
        floatv0x = v0.x;  
        floatv0y = v0.z;  
        
        floatv1x = v1.x;  
        floatv1y = v1.z;  
        
        floatv2x = v2.x;  
        floatv2y = v2.z;  
        
        floatt = triangleArea(v0x,v0y,v1x,v1y,v2x,v2y);  
        floata = triangleArea(v0x,v0y,v1x,v1y,x,y) + triangleArea(v0x,v0y,x,y,v2x,v2y) + triangleArea(x,y,v1x,v1y,v2x,v2y);  
        
        if(Mathf.Abs(t - a) <= 0.01f)   
        {  
            returntrue;  
        }else
        {  
            returnfalse;  
        }  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值