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
|
using UnityEngine;
using System.Collections;
public class
Test : MonoBehaviour { public Transform
Target; void LateUpdate
() { Quaternion
rotation = Quaternion.Euler(0f,30f,0f) * Target.rotation; Vector3
newPos = rotation * new Vector3(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
|
using UnityEngine;
using System.Collections;
public class
Test : MonoBehaviour { public Transform
Target; void LateUpdate
() { 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( new Vector3
(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
|
private float
distance = 5f; void Update
() { 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
|
private float
distance = 5f; void Update
() { 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
|
using UnityEngine;
using System.Collections;
public class
MyTest : MonoBehaviour { public Transform
cube; private float
distance = 5f; void Update
() { 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( float v0x, float v0y, float v1x, float v1y, float v2x, float v2y)
{ return Mathf.Abs((v0x
* v1y + v1x * v2y + v2x * v0y -
v1x * v0y - v2x * v1y - v0x * v2y) / 2f); } bool isINTriangle(Vector3
point,Vector3 v0,Vector3 v1,Vector3 v2) { float x
= point.x; float y
= point.z; float v0x
= v0.x; float v0y
= v0.z; float v1x
= v1.x; float v1y
= v1.z; float v2x
= v2.x; float v2y
= v2.z; float t
= triangleArea(v0x,v0y,v1x,v1y,v2x,v2y); float a
= 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) { return true ; } else { return false ; } } } |