5397人加入学习
(16人评价)
3D数学基础:Unity游戏开发

制作于2018.2.4,基于Unity2017.2。

价格 ¥ 144.00
该课程属于 Unity - A计划(永久有效期) 请加入后再学习

向量的叉积与行列式

参考书籍:

1. 《平面向量和空间向量》-吕学礼-中学生文库-1990

2. 《数理化自学丛书-平面三角函数》,余弦定理和向量点积

3. 《漫画线性代数-欧姆社学习漫画》

[展开全文]

坐标系转换,也就是计算不同坐标系下某个点的坐标

假设物体A、B 的世界坐标分别为 (2,3,4)、(2,2,3)

计算以 A 为坐标原点时 B 的坐标,即 AB=B-A=(2,2,3)-(2,3,4)=(0,-1,-1)。

在物体A上挂载脚本并执行:

// 物体 A 的世界坐标为 (2,3,4)
// 物体 B 的世界坐标为 (2,3,3)
Vector B = new Vector3(2,3,3);
// 打印以 A 为坐标原点时的坐标系中 B 点的位置
Debug.Log(transform.InverseTransformPoint(B)); // 打印 [0.00,0.00,-1.00],也就是坐标 (0,0,-1)

假设物体 A 的世界坐标为 (2,3,4)

若以物体 A 为坐标原点时,有一个坐标为 (2,3,3) 的物体 B,计算物体 B 的世界坐标,即 B+A=(2,2,3)+(2,3,4)=(4,6,7)。

在物体A上挂载脚本并执行:

// 物体 A 的世界坐标为 (2,3,4)
// 当以物体 A 为坐标原点时,物体 B 的坐标为 (2,3,3)
Vector B = new Vector3(2,3,3);

// 打印以物体 B 的世界坐标
Debug.Log(transform.InverseTransformPoint(B)); // 打印 [4.00,6.00,7.00],也就是坐标 (4,6,7)。

 

[展开全文]

若有两个坐标:A(1,2,3), B(2,3,4)

将 B 放置到 A 物体下使 B 成为 A 的子物体。

那么此时的 B 坐标为向量 AB=B-A=(2-1, 3-2, 4-3)=(1,1,1)

[展开全文]

第一个是表达了在平面zuobiaoxi

[展开全文]

    // Stretch a mesh at an arbitrary angle around the X axis.

 

    // Angle and amount of stretching.

    public float rotAngle;

    public float stretch;


 

    MeshFilter mf;

    Vector3[] origVerts;

    Vector3[] newVerts;


 

    void Start()

    {

        // Get the Mesh Filter component, save its original vertices

        // and make a new vertex array for processing.

        mf = GetComponent< MeshFilter > ();

        origVerts = mf.mesh.vertices;

        newVerts = new Vector3[origVerts.Length];

    }


 

    void Update()

    {

        // Create a rotation matrix from a Quaternion.

        Quaternion rot = Quaternion.Euler(rotAngle, 0, 0);

        Matrix4x4 m = Matrix4x4.TRS(Vector3.zero, rot, Vector3.one);

 

        // Get the inverse of the matrix (ie, to undo the rotation).

        Matrix4x4 inv = m.inverse;

 

        // For each vertex...

        for (var i = 0; i < origVerts.Length; i++)

        {

            // Rotate the vertex and scale it along its new Y axis.

            var pt = m.MultiplyPoint3x4(origVerts[i]);

            pt.y *= stretch;

 

            // Return the vertex to its original rotation (but with the

            // scaling still applied).

            newVerts[i] = inv.MultiplyPoint3x4(pt);

        }

 

        // Copy the transformed vertices back to the mesh.

        mf.mesh.vertices = newVerts;

    }

 

沿着x轴反向旋转,然后y方向拉伸,然后再旋转回来

[展开全文]

#### 叉积的应用

 

* 得到一个平面的法向量

* 判断旋转方向:axb旋转方向就是从a到b,顺时针和逆时针取决于观察方向,走到对侧观察,顺逆性就刚好反过来了。

** 用左手定则,假设知道了axb(中指),和a(大拇指),我们大致可以判断b的方向,知道axb(大拇指)和b(食指)也是一样。在该系中,axb,a到b永远是顺时针。 +

就是说,站在大拇指和食指形成的平面,头朝向axb观察,是顺时针,顺时针就是角度变大的旋转方向。

** 0 共线(可能同向,或反向)

[展开全文]

### unity中的点和向量

 

vector2 vector3 分别用来表示二维 或 三维 的点或向量。

 

* transform.position transform所在对象在世界坐标系中的点的位置

* transform.forwoard 等相关值,是transform所在对象z正向在世界坐标系的单位向量

* 在unity中,用vector3来表示对象的位置

* 在unity中,*用vector3来表示物体移动的长度和方向*。

** update函数相当于差分,每帧移动ds距离

** 设匀速运动s=vt,则ds=v*dt,从t到t+1秒积分得:s=v,也就是说,累积一秒的若干帧更新,刚好走过了速度标定的距离,因此我们也把向量当作速度来用

*** update函数中的移动距离计算为:ds=time.deltatime*移动矢量,其中移动矢量是一秒物体移动的距离,也就是速度

* 在unity中,可以通过两个对象transform.position值相减得到的矢量的模,得到两个对象的距离

[source,csharp]

----

private Vector3 movingvect;

 

private bool movingSetted=false;

private float movingtime=3;

 

//set in inspector panel

public  Transform target;

// Update is called once per frame

void Update()

{

    //第一次,求移动矢量,也就是距离

    if (movingSetted==false){

        movingSetted=true;

        movingvect=target.position-transform.position;

    }

    //距离足够小停止运动

    var distanceVector=target.position-transform.position;

    //模平方获得较好运行性能

    if(Vector3.SqrMagnitude(distanceVector)>=0.1f)

    transform.Translate(movingvect/movingtime*Time.deltaTime,Space.World);

}

----

 

[展开全文]

    void Update()

    {

        //每秒移动两秒抵达屏幕边界时停止

        var vpp = Camera.main.WorldToViewportPoint(transform.position);

        if (vpp.x > 0 && vpp.y > 0 && vpp.x < 1 && vpp.y < 1)

            transform.Translate(Time.deltaTime * Vector3.right * 2, Space.World);

 

    }

[展开全文]

### 屏幕坐标与视口坐标转换

 

#### Camera.ScreenToViewportPoint

 

public Vector3 ScreenToViewportPoint(Vector3 position);

 

Transforms position from screen space into viewport space.

 

Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.


 

#### Camera.ViewportToScreenPoint

 

public Vector3 ViewportToScreenPoint(Vector3 position);

 

Transforms position from viewport space into screen space.

 

Viewport space is normalized and relative to the camera. The bottom-left of the camera is (0,0); the top-right is (1,1). The z position is in world units from the camera.

[展开全文]

//下列两条语句等价

transform.Translate(Time.deltaTime*transform.up,Space.World);

transform.Translate(Time.deltaTime*Vector3.up);

[展开全文]

## 坐标系关联与相互转换

 

### Transform.Translate

 

`public void Translate(Vector3 translation, Space relativeTo = Space.Self);`

 

将transform,相对于space坐标系,移动translation的距离

 

* 移动谁:移动transform所在对象

* 相对于哪个坐标系移动:相对于space移动

* 移动多少:移动translation

* space枚举取值有哪些:space.world,space.self(默认值)

 

## Transform.TransformPoint

 

`public Vector3 TransformPoint(Vector3 position);`

 

将本transform空间中的点position,转换到世界坐标系。

 

## Transform.InverseTransformPoint

 

`public Vector3 InverseTransformPoint(Vector3 position);`

 

将世界坐标系中的点position,转换到本transform的局部坐标系

[展开全文]

* 屏幕坐标系 Screen Space

** 标准定义:Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.

*** 以像素为单位

*** 原点左下角,右上角宽度screen.width和高度screen.height

** unity实现

*** 原点左下角,右上角宽度screen.width和高度screen.

**** 注意:Event.mousePosition原点在左上角,而不是坐下

height

*** 鼠标位置坐标属于屏幕坐标,input.mouseposition,是一个**三维向量**,z始终为0,可能是为了性能,不处理z。如果要精确,可以理解为z在视锥近平面cam.nearClipPlane。

*** 将世界坐标转换为屏幕坐标时,*Z是以世界单位衡量的到相机的距离*:摄像机对游戏世界的渲染范围是一个平截头体,渲染边界是一个矩形,用与near clippingplane或者far clippingplane平行的平面截取这个平截头体,可以获得无数个平行的矩形面,也就是我们看到的屏幕矩形。离摄像机越远,矩形越大,离摄像机越近,矩形越小。所以,同样大小的物体,随着离摄像机越来越远,相对于对应屏幕矩形就越来越小,所看起来就越来越小。在屏幕上,关键在于这个点在哪个截面上,也就是说,关键在于这个截面离摄像机有多远!*参数中的z坐标的作用就是:用来表示上述平面离摄像机的距离*。

**** Input.mouseposition移动到屏幕之外也会有值

*** 手指触摸屏幕也为屏幕坐标, 单手指input.gettouch(0).position,是一个**二维向量**

 

* 视口坐标系 ViewPort Space

** 标准定义:Viewport space is normalized and relative to the camera. The bottom-left of the viewport is (0,0); the top-right is (1,1). The z position is in world units from the camera.

*** 将屏幕坐标系单位化

*** 左下角 (0,0),右上角 (1,1)

** unity实现

*** 无法直接得到

*** 可以将屏幕坐标->视口坐标,或反之

*** 可以将世界坐标->视口坐标,或反之

*** 左下角 (0,0),右上角 (1,1)

*** 如前所述,当采集鼠标位置时,z不做处理,此时,z始终为0

[展开全文]

不是,模为1的任何方向向量为单位向量。 v3.Normalize();

Vector3.Distance(v1,v2);

2*3*cos60;2*3*sin60;

Vector3.Cross(a,b)>0  , 逆时针

 

[展开全文]
        //Vector3 m_target = m_go2.transform.position;
        //m_go1.transform.Translate((m_go2.transform.position - m_go1.transform.position).normalized * Time.deltaTime, Space.World);
        //m_go1.transform.position = new Vector3(Mathf.Clamp(m_go1.transform.position.x, m_go1.transform.position.x, m_target.x), Mathf.Clamp(m_go1.transform.position.y, m_go1.transform.position.y, m_target.y), Mathf.Clamp(m_go1.transform.position.z, m_go1.transform.position.z, m_target.z));

 

[展开全文]
    private void Update()
    {
        //if (timer <= 1)
        {
            m_go1.transform.Translate(Vector3.right * 2 * Time.deltaTime);
            Vector3 viewPos = Camera.main.WorldToViewportPoint(m_go1.transform.position);
            if (viewPos.x >= 1f || viewPos.x < 0.0 || viewPos.y >= 1f || viewPos.y < 0.0)
            {
                m_go1.transform.position = oldPos;
                return;
            }
            oldPos = m_go1.transform.position;
            timer += Time.deltaTime;
        }
    }

 

[展开全文]

transform.Translate(translation:Vector3,relativeTo:Space=Space.Self);

relativeTo为空,则默认为局部坐标系。

最后加Space.World,则是世界坐标系

[展开全文]

一个物体参照  世界坐标 原点  —— 世界坐标

一个物体参照  3d物体   原点 ——  局部坐标

世界坐标  转换  局部坐标  参照 3d物体坐标

局部坐标  转换  世界坐标  参照  世家坐标原点

[展开全文]

授课教师

SIKI学院老师

课程特色

下载资料(1)
视频(49)

学员动态

Stormthra 加入学习
史家桐 加入学习
yuanpeng 加入学习
Leo2002 加入学习
123hai 加入学习