製作一個仿真星系

 

from https://www.twblogs.net/a/5f03ab3e0b1faa3719590bed


void KeepUniversalG() { var Center = this.transform.position; Collider[] colliders = Physics.OverlapSphere (Center, GalaxyRange); foreach (Collider obj in colliders) { Rigidbody rb = obj.GetComponent<Rigidbody> (); if (rb != null) rb.AddExplosionForce (-1 * UniversalG(this.gameObject, obj.gameObject) * Time.deltaTime, Center, GalaxyRange); } }


1. 萬有引力的計算。

萬有引力公式不貼了。 這個是比較好確定的一個函數。 因爲理論給出了具體計算方法, 不需要分析實際數據。

代碼如下:

	float UniversalG(GameObject obj1, GameObject obj2) {
		var pos1 = obj1.transform.position;
		var pos2 = obj2.transform.position;
		Rigidbody rb1 = obj1.GetComponent<Rigidbody>();
		Rigidbody rb2 = obj2.GetComponent<Rigidbody>();
		return rb1.mass * rb2.mass / Distance(pos1, pos2);

	}
	float Distance(Vector3 pos1, Vector3 pos2) {
		Vector3 diff = (pos1 - pos2);
		float dist = Mathf.Sqrt (diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
		if (dist < 1)
			return 1;
		else return (dist);
	}



float ProperForce(GameObject Obj) { var pos = Obj.transform.position; var rb = Obj.GetComponent<Rigidbody> (); var Rb = GameObject.Find ("Sphere").GetComponent<Rigidbody> (); return G * rb.mass * Mathf.Sqrt(Rb.mass / Distance (pos, Vector3.zero)); }



void CreateRandomPlanet() { GameObject Star = Resources.Load ("Prefabs/Star") as GameObject; GameObject T = Instantiate (Star); T.transform.SetParent (GameObject.Find("Galaxy").transform); T.transform.position= ProperArea(GalaxyRange / 20, GalaxyRange / 3); float Scale = 4 + Random.value * 20; T.transform.localScale = new Vector3(Scale, Scale, Scale); T.GetComponent<Rigidbody> ().mass = 5 + 100 * Random.value; var TColor = new Color(Random.value, Random.value, Random.value); T.GetComponent<MeshRenderer> ().material.color = TColor; T.GetComponent<TrailRenderer> ().material.color = TColor; }

 1,2 是約束的基礎, 也是對客觀事實的描述。 事實上只有約束條件1,2即可。 然而我們加上這個約束代碼之後, 將會發現事情並不是那麼簡單。 我們將很難得到一個    穩定存在的 星系。而3條件其實就是爲了使我們更易得到穩定星系所需要的約束性更強的條件。

如果前面工作都做好, 那麼這裏的代碼簡單是相當簡單的:


	void OnTriggerEnter(Collider other) {
		if (10 * other.gameObject.GetComponent<Rigidbody> ().mass < this.GetComponent<Rigidbody> ().mass)
			Destroy (other.gameObject);
	}

	bool FarAway() {
		return (Distance (this.transform.position, Vector3.zero) > GalaxyRange);
	}


, 在MainCamara下, 新建一個C#腳本,然後將剛纔寫好的創建對象的函數放進去。這就是這個腳本的主要目的, 我們再通過寫一些小函數, 來規範我們創建行星的規則。


這次我直接貼整個文件代碼了:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreateStar : MonoBehaviour {
	private float GalaxyRange;
	private float Timer = 2.0f;
	// Use this for initialization
	void Start () {
		GalaxyRange = GameObject.Find ("Sphere").transform.localScale.x * 20;
	}
	
	// Update is called once per frame
	void Update () {
		if (Timer <= 0) {
			if (StarLessthan(10)) CreateRandomPlanet ();
			Timer = 0.3f;
		} else
			Timer -= Time.deltaTime;
	}
	void CreateRandomPlanet() {
		GameObject Star = Resources.Load ("Prefabs/Star") as GameObject;
		GameObject T = Instantiate (Star);
		T.transform.SetParent (GameObject.Find("Galaxy").transform);
		T.transform.position= ProperArea(GalaxyRange / 20, GalaxyRange / 3);
		float Scale = 4 + Random.value * 20;
		T.transform.localScale = new Vector3(Scale, Scale, Scale);
		T.GetComponent ().mass = 5 + 100 * Random.value;
		var TColor = new Color(Random.value, Random.value, Random.value);
		T.GetComponent ().material.color = TColor;
		T.GetComponent ().material.color = TColor;
	}
	Vector3 ProperArea(float min, float max) {
		float x = (max - min) * Random.value + min;
		float y = (max - min) * Random.value + min;
		float z = (max - min) * Random.value + min;
		return new Vector3 (x * PosiOrNega(), y * PosiOrNega() / 10, z * PosiOrNega() / 10);
	}
	int PosiOrNega() {
		return Random.Range (1, 3) * 2 - 3;
	}
	bool StarLessthan(int x) {
		Rigidbody[] T = GameObject.FindObjectsOfType ();
		return (T.Length < x + 1);
	}
}


Name 爲Sphere的是我的中心天體












留言

熱門文章