I'm making a game where you can build a rocket, launch it into space, and land on other planets. I need the planets to proportionally scaled from the rocket (See Spaceflight Simulator as an example). I'm not sure how to make a good 2D planet.
What I've been doing recently was making the planets in a software called Affinity Designer 2, then I would export them as images. The problem with that is images like that lose resolution when scaled up, sprites do the same thing too. So I can't make the planets as images or sprites, I have to use something else I believe. I thought I could maybe export them as an SVG file, but doesn't look like Unity supports those because I can't put the asset image in the scene.
The loss of resolution prevent a defined surface from showing up, because all you see is pixels. It's also not a great sight for a potential player to see. I'm also trying to create terrain (Craters, Mountains, Hills), nothing in detail right now, just an uneven terrain at minimum.
I've tried searching the internet, Unity discussions, and YouTube. They don't completely help my situation. I either find tutorials on 3D planet generation, not what I'm doing because I'm doing 2D. I've also found a few tutorials on 2D planet generation, but they're not as proportionally scaled to the rocket as I would like it.
I'm running out of online resources, what I mean by that is I don't know many places to look. I've been searching, even got as far as emailed the creators of Spaceflight Simulator and Juno: New Origins. If I'm being honest, they're not going to respond. If anyone has suggestions on resources, or areas to look, that would be great.
This has been my biggest roadblock in creating my game so far, if I figure this out, that would be a major breakthrough for me.
This question has also been associated with this separate question https://stackoverflow.com/questions/52562020/how-to-import-svg-to-unity-2018-2
That topic didn't answer my question I was looking for. That topic is specifically asking how to import SVG files, my topic is more broad not specifically focused on SVG files. I was asking how to make 2D planets that don't lose resolution. Yes, I was pointing out that I'm unable to import SVG files, but that's not what my topic was focused on. Mentioning the SVG file was part of my attempt to solve the problem. I was expecting to get a planet that doesn't lose as much resolution as an image, but the result was me unable to drag and drop the image onto the scene.
I've already solved my problem, but hopefully this topic can be reopened in case someone else who has the same problem has additional questions.
I found a solution, I think. It doesn't exactly give me what I want, but it's a great start and I no longer feel stuck.
I made an empty game object, and attached a script to it that contains LineRenderer and Mesh.
Here is the code below I have now
using UnityEngine;
/* Ensures that the attached GameObject has a MeshFilter and MeshRenderer component.
* Unity automatically generates one if not.*/
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ProceduralPlanet : MonoBehaviour
{
/* Number of points around the circle.
* Increasing the number makes it smoother and increases resolution */
public int segments = 1000;
/* The radius of the object */
public float baseRadius = 50f;
/* Controls the scale of the Perlin noise applied to the radius */
public float noiseScale = 4f;
/* Controls the amplitude of the Perlin noise applied to the radius */
public float noiseAmplitude = 0.05f;
private void Start()
{
/* Takes the attached MeshFilter, creates a mesh object, and names it */
MeshFilter meshFilter = GetComponent<MeshFilter>();
Mesh mesh = new Mesh();
mesh.name = "Procedural Planet";
/* Create arrays for vertices and triangles.
* Vertices will hold the positions of the points in 3D space,
* Triangles will define how these points are connected to form the mesh */
Vector3[] vertices = new Vector3[segments + 2]; // center + edge points
int[] triangles = new int[segments * 3]; // 3 per triangle (center + 2 edge points)
/* Center of the planet */
vertices[0] = Vector3.zero; // center point of planet
for (int i = 0; i <= segments; i++)
{
/* Goes around to create a circle*/
float angle = (float)i / segments * Mathf.PI * 2f;
// Calculate unit vector for the current angle
float xUnit = Mathf.Cos(angle);
float yUnit = Mathf.Sin(angle);
// Apply Perlin noise
float noise = Mathf.PerlinNoise(xUnit * noiseScale + 100f, yUnit * noiseScale + 100f);
// Calculate the radius with noise applied
float radius = baseRadius + (noise - 0.5f) * 2f * noiseAmplitude;
// Set the vertex position
vertices[i + 1] = new Vector3(xUnit, yUnit, 0) * radius;
// Create triangles (except on last iteration)
if (i < segments)
{
// Each triangle consists of the center and two consecutive edge points
int start = i * 3;
triangles[start] = 0; // center
triangles[start + 1] = i + 1;
triangles[start + 2] = i + 2;
}
}
// Handle the last triangle to close the circle
mesh.vertices = vertices;
// The last triangle connects the last edge point back to the first edge point
mesh.triangles = triangles;
// Calculate normals and bounds for lighting and rendering
mesh.RecalculateNormals();
mesh.RecalculateBounds();
// Assign the mesh to the MeshFilter
meshFilter.mesh = mesh;
}
}
I'll make this a community wiki, so anyone is free to edit and help other people.