unity 3d 三、空間與運動
阿新 • • 發佈:2020-10-04
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;
}