Von links
Der als Spielbildschirm gespielte ist wie folgt. </ s>
Als WebGL-App veröffentlicht.
https://hibit-at.github.io/StarSphere/
Es scheint, dass es auf der Welt eine Sternendatenbank gibt. Wenn Sie diese also so wie sie ist als Kugel anordnen, können Sie ein realistisches Planetarium erstellen? Ich habe darüber nachgedacht und es versucht. Der Code des Skripts unten.
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class Reader : MonoBehaviour
{
TextAsset csvFile;
List<string[]> csvDatas = new List<string[]>();
public Material[] _material;//Dieses Material muss im Voraus vorbereitet werden
//Liste zum Ausmalen bestimmter Konstellationen
List<string> Spring = new List<string> { "Arcturus" , "Spica" , "Denebola" };
List<string> Summer = new List<string> { "Deneb", "Altair", "Vega" };
List<string> Autumn = new List<string> { "Markab", "Sheat", "Algenib" , "Alpheratz" };
List<string> Winter = new List<string> { "Capella", "Aldebaran", "Rigel", "Pollux" ,"Procyon" , "Sirius" };
int Color(string target) //Eine Funktion, die eine Zahl zurückgibt, um die Konstellation einzufärben
{
foreach (string c in Spring) if (target == c) return 1;
foreach (string c in Summer) if (target == c) return 2;
foreach (string c in Autumn) if (target == c) return 3;
foreach (string c in Winter) if (target == c) return 4;
return 0;
}
void Start()
{
csvFile = Resources.Load("mdata") as TextAsset; //Geben Sie hier Ihre eigenen Daten zurück
StringReader reader = new StringReader(csvFile.text);
while (reader.Peek() != -1)
{
string line = reader.ReadLine();
csvDatas.Add(line.Split(','));
}
foreach (string[] c in csvDatas)
{
int lon1 = int.Parse(c[3]);
int lon2 = int.Parse(c[4]);
float theta = lon1 * 15 + lon2 / 4;
theta *= 2.0f * Mathf.PI / 360;
int lat1 = int.Parse(c[7]);
int lat2 = int.Parse(c[8]);
float phi = lat1 + lat2 / 60;
if (c[6] == "0") phi = -phi;
phi *= 2.0f * Mathf.PI / 360;
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.position = new Vector3(10 * Mathf.Cos(theta) * Mathf.Cos(phi),
10 * Mathf.Sin(phi),
10 * Mathf.Sin(theta) * Mathf.Cos(phi));
float tokyu = float.Parse(c[10]);
tokyu = 0.6f - tokyu / 10;
if (tokyu < 0) tokyu = 0;
sphere.transform.localScale = new Vector3(tokyu, tokyu, tokyu);
sphere.GetComponent<Renderer>().material = _material[Color(c[2])];
}
}
}
Wenn Sie dies an ein geeignetes Spielobjekt anhängen, werden zu Beginn des Spiels etwa 3.000 Sterne (Kugeln) in die Szene gezeichnet. Wenn Sie es tatsächlich versuchen, ist eine Vorbehandlung erforderlich, wie später beschrieben.
Es verwendet die Daten aus der oben in hip_lite_major.csv
erwähnten Datenbank (ca. 3.000 Zeilen), enthält jedoch nicht die Namen der Sterne. Für alle Sterne [Hippalcos Star Chart](https://ja.wikipedia.org/wiki/%E3%83%92%E3%83%83%E3%83%91%E3%83%AB%E3% Es scheint, dass die Zahlen (HIP-Nummern) in der Tabelle angegeben sind. 82% B3% E3% 82% B9% E6% 98% 9F% E8% A1% A8) (Wow!), Aber natürlich sind die Namen darin angegeben. Es gibt nur wenige prominente Sterne, die angebracht werden können. Die Daten sind separat in "hip_proper_name.csv" organisiert, müssen jedoch als sogenannte relationale Daten kombiniert werden. Glücklicherweise ist die HIP-Nummer der Primärschlüssel, sodass der Vorgang schnell vonstatten geht.
Die Vorverarbeitung hier ist schnell mit Python und "Pandas" erledigt.
import pandas as pd
data = pd.read_csv('hip_proper_name.csv',header=None)
detail = pd.read_csv('hip_lite_major.csv',header=None)
mdata = pd.merge(detail,data,on=0,how="left")
mdata.to_csv('mdata.csv',header=None)
Dadurch wird eine "mdata.csv" erstellt, die eine Zusammenführung der beiden ist. Fügen Sie diese also in Ihr Unity-Projekt ein.
Außerdem werden die Materialeinstellungen auf der Unity-Seite manuell vorgenommen. Wenn Sie Ihr Bestes geben, können Sie es in ein Skript schreiben, aber Sie können hier wirklich Kompromisse eingehen.
Erstellen Sie ein Konstellationsfarbmaterial und legen Sie es im Slot "GameObject" -Material fest, um das Skript anzuhängen.
//Liste zum Ausmalen bestimmter Konstellationen
List<string> Spring = new List<string> { "Arcturus" , "Spica" , "Denebola" };
List<string> Summer = new List<string> { "Deneb", "Altair", "Vega" };
List<string> Autumn = new List<string> { "Markab", "Sheat", "Algenib" , "Alpheratz" };
List<string> Winter = new List<string> { "Capella", "Aldebaran", "Rigel", "Pollux" ,"Procyon" , "Sirius" };
Der Name der Konstellation (es ist keine Konstellation, sondern etwas, das mehrere Sterne überspannt, aber ich kann keinen anderen guten Namen finden, also nenne ich es eine Konstellation) steht nicht auf der CSV, daher müssen Sie ihn selbst vorbereiten Es gibt. Machen Sie eine Liste jeder Konstellation.
Informationen zum Lesen der CSV-Datei finden Sie unter https://note.com/macgyverthink/n/n83943f3bad60. Vielen Dank.
Aus jeder Zeile von csv berechnen wir den Winkel und die Skalierung.
Der Winkel wird aus dem roten Längengrad (Stunden, Minuten, Sekunden) und dem roten Breitengrad (Grad, Minuten, Sekunden) in der Datenbank berechnet. Es ist ein wenig kompliziert, weil es Grad, Minuten und Sekunden sind, aber der Winkel des roten Breitengrads $ \ phi $
Sie können herausfinden, dass es ist. In Bezug auf das rote Sutra $ \ theta $ sind es ** Stunden **, Minuten, Sekunden, die nicht herauskamen, selbst wenn ich es überprüft habe, aber der Punkt ist, dass 360 Grad in 24 geteilt sind, also ** Es wird 15 Grad ** pro Stunde sein. Sie können also sehen, dass Sie der obigen Formel $ 15 $ hinzufügen können.
Sie können mit den oben genannten berechnen. Beachten Sie, dass die Drehung von Unity in Bogenmaßeinheiten erfolgt und das Koordinatensystem linkshändig ist.
theta *= 2.0f * Mathf.PI / 360;
(Weggelassen)
phi *= 2.0f * Mathf.PI / 360;
(Weggelassen)
sphere.transform.position = new Vector3(10 * Mathf.Cos(theta) * Mathf.Cos(phi),
10 * Mathf.Sin(phi),
10 * Mathf.Sin(theta) * Mathf.Cos(phi));
Sie können jeden Stern an den richtigen Koordinaten mit platzieren. Zusätzlich wird der Helligkeitsunterschied für jede Klasse durch die Größe der Kugel angezeigt.
float tokyu = float.Parse(c[10]);
tokyu = 0.6f - tokyu / 10;
if (tokyu < 0) tokyu = 0;
sphere.transform.localScale = new Vector3(tokyu, tokyu, tokyu);
Dies gibt Ihnen das Gefühl eines Sternenhimmels.
Da es als Daten zu Unity verarbeitet werden kann, kann ein interaktives Planetarium realisiert werden, wenn ein Mechanismus erstellt wird, mit dem die angezeigten Sterne manipuliert und die Konstellationslinien entstehen können. Wenn Sie es mit Quest bauen, können Sie anscheinend auch im Freien ein eigenständiges und einfaches Planetarium erstellen (und jedes Mal, wenn Sie das Headset entfernen, vom tatsächlichen Sternenhimmel-Shobo enttäuscht sein). Ich würde es gerne versuchen, wenn ich Zeit und Energie habe.
Danach bat ich einen Freund, der mit astronomischer Beobachtung vertraut ist, sie zu sehen, passte Größe und Farbe an und veröffentlichte sie als WebGL-Anwendung. Die neueste Version des Codes.
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class Reader : MonoBehaviour
{
TextAsset csvFile;
List<string[]> csvDatas = new List<string[]>();
public Material[] _material;
List<string> Spring = new List<string> { "Arcturus" , "Spica" , "Denebola" };
List<string> Summer = new List<string> { "Deneb", "Altair", "Vega" };
List<string> Autumn = new List<string> { "Markab", "Sheat", "Algenib" , "Alpheratz" };
List<string> Winter = new List<string> { "Capella", "Aldebaran", "Rigel", "Pollux" ,"Procyon" , "Sirius" };
int Colorization(string target)
{
foreach (string c in Spring) if (target == c) return 1;
foreach (string c in Summer) if (target == c) return 2;
foreach (string c in Autumn) if (target == c) return 3;
foreach (string c in Winter) if (target == c) return 4;
return 0;
}
Color Spectrum(string s)
{
if(s == "")
{
return new Color(.5f, .5f, .5f, 1);
}
char c = s[0];
if(c == 'O')
{
return new Color(.3f, .3f, .8f,1);
}
else if (c == 'B')
{
return new Color(.3f, .3f, .8f, 1);
}
else if (c == 'A')
{
return new Color(.5f, .5f, 1, 1);
}
else if (c == 'F')
{
return new Color(1, 1, 1, 1);
}
else if (c == 'G')
{
return new Color(.8f, .8f, .4f, 1);
}
else if (c == 'K')
{
return new Color(.8f, .4f, 0, 1);
}
else if(c == 'M')
{
return new Color(.4f, 0, 0, 0);
}
else
{
return new Color(.5f, .5f, .5f, 1);
}
}
void Start()
{
csvFile = Resources.Load("mdata") as TextAsset;
StringReader reader = new StringReader(csvFile.text);
while (reader.Peek() != -1)
{
string line = reader.ReadLine();
csvDatas.Add(line.Split(','));
}
foreach (string[] c in csvDatas)
{
int lon1 = int.Parse(c[3]);
int lon2 = int.Parse(c[4]);
float theta = lon1 * 15 + lon2 / 4;
theta *= 2.0f * Mathf.PI / 360;
int lat1 = int.Parse(c[7]);
int lat2 = int.Parse(c[8]);
float phi = lat1 + lat2 / 60;
if (c[6] == "0") phi = -phi;
phi *= 2.0f * Mathf.PI / 360;
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.position = new Vector3(10 * Mathf.Cos(theta) * Mathf.Cos(phi),
10 * Mathf.Sin(phi),
10 * Mathf.Sin(theta) * Mathf.Cos(phi));
float tokyu = float.Parse(c[10]);
tokyu = 0.3f - tokyu / 20;
if (tokyu < 0) tokyu = 0;
sphere.transform.localScale = new Vector3(tokyu, tokyu, tokyu);
MeshRenderer r = sphere.GetComponent<MeshRenderer>();
r.material = _material[0];
r.material.EnableKeyword("_EMISSION");
Color StarColor = Spectrum(c[11]) * tokyu / 0.3f;
if (float.Parse(c[10]) <= 1.5f)
{
r.material.SetColor("_EmissionColor", StarColor * .3f);
}
//sphere.GetComponent<Renderer>().material = _material[Colorization(c[2])];
}
}
}
Die Farbe des Sterns ist [Spektrumklassifizierung](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%9A%E3%82%AF%E3%83%88%E3%83% Es ist assoziiert mit AB% E5% 88% 86% E9% A1% 9E). Da es durch Buchstaben wie O und K klassifiziert ist, wird es mit der if-Anweisung verarbeitet. Die Farbe wird angepasst, indem sie mit r.material.SetColor (" _EmissionColor ", StarColor * .3f);
auf die Emissionsfarbe des Materials eingestellt wird.
Das GitHub-Repository befindet sich hier.
Recommended Posts