1. 程式人生 > 實用技巧 >unity 3d 三、空間與運動

unity 3d 三、空間與運動

3D遊戲程式設計第三次作業

簡答並用程式驗證【建議做】

遊戲物件運動的本質是什麼?

遊戲物件運動的本質是遊戲物件Position、Rotate、Scale屬性數值的變化。

請用三種方法以上方法,實現物體的拋物線運動。(如,修改Transform屬性,使用向量Vector3的方法…)

  • 使用Vector3
 public int xSpeed = 1;  //單位時間x方向的位移量    
 public int ySpeed = 1;  //單位時間y方向的位移量    
 public int T = 1;       //時間
 void Update()
 {
     transform.position += Vector3.right * Time.deltaTime * xSpeed;
     transform.position += Vector3.down * Time.deltaTime * ySpeed * Time.deltaTime * T;
     T++;
 }
  • 使用Transform.Translate
 public int xSpeed = 1;  //單位時間x方向的位移量    
 public int ySpeed = 1;  //單位時間y方向的位移量    
 public int T = 1;       //時間
 void Update()
 {
     transform.Translate(Vector3.right * Time.deltaTime * xSpeed + Vector3.down * Time.deltaTime * ySpeed * Time.deltaTime * T);
     T++;
 }
  • 直接修改transform
 public int speed = 2;

 void Update()
 {
     transform.position += new Vector3(Time.deltaTime * speed, -Time.deltaTime * speed * (2 * transform.position.x + Time.deltaTime * speed), 0);
 }

寫一個程式,實現一個完整的太陽系, 其他星球圍繞太陽的轉速必須不一樣,且不在一個法平面上。

仿照如上課堂的練習,我們可以將太陽系的八大行星都列出來,為他們的position賦值,並且為了滿足圍繞太陽轉速不同以及不在同一法平面的要求,我們額外增加一個向量來表示他們的轉動方向,並且在執行RotateAround時傳入不同的轉動週期。程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SolarSystem : MonoBehaviour
{
	public Transform Sun, Mercury, Venus, Earth, Moon, Mars, Jupiter, Saturn, Uranus, Neptune;
    Vector3 vectMercury, vectVenus, vectEarth, vectMoon, vectMars, vectJupiter, vectSaturn, vectUranus, vectNeptune;
    // Start is called before the first frame update
    void Start()
    {
    	// 初始化位置
        Sun.position = Vector3.zero;
        Mercury.position = new Vector3(8, 0, 0);
        Venus.position = new Vector3(10, 0, 0);
        Earth.position = new Vector3(15, 0, 0);
        Moon.position = new Vector3(18, 0, 0);
        Mars.position = new Vector3(24, 0, 0);
        Jupiter.position = new Vector3(34, 0, 0);
        Saturn.position = new Vector3(44, 0, 0);
        Uranus.position = new Vector3(51, 0, 0);
        Neptune.position = new Vector3(55, 0, 0);
        // Pluto.position = new Vector3(58, 0, 0);

        // 初始化方向向量
        vectMercury = new Vector3(3, 11, 0);
        vectVenus = new Vector3(2, 3, 0);
        vectEarth = new Vector3(0, 1, 0);
        vectMoon = Vector3.up;
        vectMars = new Vector3(1, 5, 0);
        vectJupiter = new Vector3(1, 5, 0);
        vectSaturn = new Vector3(1, 9, 0);
        vectUranus = new Vector3(2, 7, 0);
        vectNeptune = new Vector3(1, 5, 0);
        // vectPluto = new Vector3(1, 3, 0);
    }

    // Update is called once per frame
    void Update()
    {
    	// 以向量向太陽做公轉
        Mercury.RotateAround(Sun.position, vectMercury, 10 * Time.deltaTime);
        Venus.RotateAround(Sun.position, vectVenus, 30 * Time.deltaTime);
        Earth.RotateAround(Sun.position, vectEarth, 20 * Time.deltaTime);
        Moon.RotateAround(Earth.position, Vector3.up, 359 * Time.deltaTime);
        Mars.RotateAround(Sun.position, vectMars, 60 * Time.deltaTime);
        Jupiter.RotateAround(Sun.position, vectJupiter, 5 * Time.deltaTime);
        Saturn.RotateAround(Sun.position, vectSaturn, 6 * Time.deltaTime);
        Uranus.RotateAround(Sun.position, vectUranus, 35 * Time.deltaTime);
        Neptune.RotateAround(Sun.position, vectNeptune, 10 * Time.deltaTime);
        // Pluto.RotateAround(Sun.position, vectPluto, 20 * Time.deltaTime);

        // 自轉速度
        Sun.Rotate(Vector3.up * 10 * Time.deltaTime);
        Mercury.Rotate(Vector3.up * 600 * Time.deltaTime);
        Venus.Rotate(Vector3.up * 400 * Time.deltaTime);
        Earth.Rotate(Vector3.up * 360 * Time.deltaTime);
        Moon.Rotate(Vector3.up * 1000 * Time.deltaTime);
        Mars.Rotate(Vector3.up * 300 * Time.deltaTime);
        Jupiter.Rotate(Vector3.up * 300 * Time.deltaTime);
        Saturn.Rotate(Vector3.up * 200 * Time.deltaTime);
        Uranus.Rotate(Vector3.up * 400 * Time.deltaTime);
        Neptune.Rotate(Vector3.up * 500 * Time.deltaTime);
        // Pluto.Rotate(Vector3.up * 400 * Time.deltaTime);
    }
}

在製作指令碼之後,我們需要為指令碼製作prefabs:

並且根據不同星球的大小製作不同的屬性:

最終程式執行效果如下:

特別注意的是,在製作prefabs之後每個星球的顏色基本是看不見的,這是因為unity中預設使用的是平行光源,我們可以在太陽處增加一個range極大的點光源,這樣就可以基本看出一個太陽系的特點:

程式設計實踐

思考題【選做】

  • 使用向量與變換,實現並擴充套件 Tranform 提供的方法,如 Rotate、RotateAround 等

其中position表示物體的位置,rotation表示物體的角度

Rotate:

void Rotate(Transform t,Vector3 axis,float angle){ 
    var rot=Quaternion.AngleAxis(angle,axis);
    t.rotation*=rot;
}

RotateAround:

void RotateAround(Transform t,Vector3 center,Vector axis,float angle){		
    var rot=Quaternion.AngleAxis(angle,axis);
    t.position=(center+(t.position-center)*rot);
    t.rotation=t.rotation*rot;
}