先上結果圖:
結果圖片
行星代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class planet : MonoBehaviour {
public Transform center; // 太陽
public float distance; // 公轉半徑
public float normal_x; // 方便在inspector窗口中指定法線
public float normal_y;
public float normal_z;
public float speed; // 角速度
private Vector3 normal; // 法線
void Start () {
transform.position = center.position + new Vector3 (distance, 0, 0); // 初始化行星位置
normal = new Vector3 (normal_x, normal_y, normal_z);
}
void Update () {
transform.RotateAround (center.position, normal, speed * Time.deltaTime);
}
}
行星的代碼比較簡單。這里只說明一下transform.RotateAround只適用于center.position靜止不動的情況,或者中心是公轉者的父對象的情況,否則公轉者的軌道會非常奇怪。(你可以嘗試使用transform.RotateAround再制作一個月球繞地球轉,地球繞太陽轉的例子,地球不作為月球的父對象,當你將地球的公轉速度設置得很快的時候,月球會出現“跟不上”地球的情況!)
衛星代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class moon : MonoBehaviour {
public Transform center; // 地球
public float distance; // 地月距離
public float normal_x;
public float normal_y;
public float normal_z;
public float speed;
private Vector3 normal; // 法線
private GameObject shadow; // 地球的影子空對象
void Start () {
shadow = new GameObject ();
shadow.transform.position = center.position;
transform.parent = shadow.transform; // 月球是影子地球的子對象
transform.localPosition = new Vector3 (distance, 0, 0); // 設置月球相對于影子地球的距離
normal = new Vector3 (normal_x, normal_y, normal_z);
}
void Update () {
shadow.transform.position = center.position; // 時刻保持影子對象與地球同步
shadow.transform.Rotate (normal, speed*Time.deltaTime); // 影子對象自轉,月球就會跟著旋轉。
}
}
將月球設置為影子地球的子對象以后,月球與影子地球的相對方位就不會變化了,所以影子對象自轉,就會使得月球繞著它公轉。
創建幾個球體,布置好位置和大小,將以上幾個代碼分別掛載到行星和衛星上,設置一下各種public參數,就可以運行了。
注意如果初始狀態,如果行星與太陽的連線不與法線垂直,行星就不會繞著太陽的中心旋轉,而是:
行星初始位置與法線
造成這個問題的根本原因是transform.Rotate是繞一條軸線旋轉的,第一個參數指定軸線上的一個點,第二個參數指定軸線的方向,兩者共同確定一條軸線。