Солнечная система, планеты и спутники

При создании допустим, стратегии на просторах космоса, может понадобиться модель солнечной системы, впрочем, не обязательно солнечной. В любом случаи, нам нужно вращение планет, вокруг звезды и, чтобы планеты вращались вокруг своей оси. У планет могут быть спутники, их тоже надо вращать и вокруг своей оси тоже. Всю систему организуем в одном скрипте, у каждого объекта будут свои опции скорости, вращения и т.д. Кроме того, добавим глобальный параметр, который позволит регулировать все скорости сразу, это может быть удобно если нужно создать эффект перемотки времени. Дополнительно, у нас будет возможность сделать овальную орбиту планеты или спутника.


Итак, если уже готовы модельки планет и спутников, нам нужно расставить их на позиции. Важный момент в том, что так как для всех объектов позиция будет просчитываться отдельно, нельзя их делать дочерними друг к другу. Например, нельзя делать спутники, дочерними планете, вокруг которой они будут вращаться.

Собственно сам скрипт:

using UnityEngine;
using System.Collections;

public class SolarSystem : MonoBehaviour {

	public Transform theStar;
	public float globalSpeed = 1; // влияет на скорость движения планет, спутников и их вращение
	public Planets[] planets;

	void Start()
	{
		GetDistance();
	}

	void Update()
	{
		Move();
	}

	void Move()
	{
		for(int j = 0; j < planets.Length; j++)
		{
			planets[j].target.position = GetPositon(theStar.position, planets[j].distance, planets[j].currentAng, planets[j].offsetSin, planets[j].offsetCos);
			planets[j].target.Rotate(Vector3.up * planets[j].rotationSpeed * globalSpeed);
			planets[j].currentAng += planets[j].speed * Time.deltaTime * globalSpeed;

			for(int i = 0; i < planets[j].satellite.Length; i++)
			{
				planets[j].satellite[i].target.position = GetPositon(planets[j].target.position, planets[j].satellite[i].distance, planets[j].satellite[i].currentAng, planets[j].satellite[i].offsetSin, planets[j].satellite[i].offsetCos);
				planets[j].satellite[i].target.Rotate(Vector3.up * planets[j].satellite[i].rotationSpeed * globalSpeed);
				planets[j].satellite[i].currentAng += planets[j].satellite[i].speed * Time.deltaTime * globalSpeed;
			}
		}
	}

	Vector3 GetPositon(Vector3 around, float dist, float angle, float sin, float cos)
	{
		around.x += Mathf.Sin(angle) * dist * sin;
		around.z += Mathf.Cos(angle) * dist * cos;
		return around;
	}

	void GetDistance()
	{
		for(int j = 0; j < planets.Length; j++)
		{
			planets[j].distance = (planets[j].target.position - theStar.position).magnitude;

			for(int i = 0; i < planets[j].satellite.Length; i++)
			{
				planets[j].satellite[i].distance = (planets[j].satellite[i].target.position - planets[j].target.position).magnitude;
			}
		}
	}
}

[System.Serializable]
public class Planets
{
	public Transform target;
	public float speed = 0.5f;
	public float rotationSpeed = 1;
	public float offsetSin = 1, offsetCos = 1; // если значения не 1, то будет овальное смещение
	[HideInInspector] public float distance, currentAng;
	public Satellite[] satellite;
}


[System.Serializable]
public class Satellite
{
	public Transform target;
	public float speed = 0.05f;
	public float rotationSpeed = 1;
	public float offsetSin = 1, offsetCos = 1;
	[HideInInspector] public float distance, currentAng;
}

Для наглядности, можно скачать демо проект:

Внимание! Посетители, находящиеся в группе Гости, не могут скачивать файлы.

Комментариев 3

Офлайн
TheFatDoge 12 июля 2017
Неплохо, но с помощью чего можно реализовать кольцо, показывающие орбиту планеты?
Офлайн
Light 12 июля 2017
TheFatDoge, спрайтом например...
Офлайн
tolk 11 мая 2018
TheFatDoge,
linerenderer повесь чтоб шлейф был
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика