Now Playing Tracks

Test runs with different amounts of Newton bodies. As calculation increases almost quadratically (n * (n -1)), simulation gets slower with every Newton body added.

n * (n - 1)

Newton gravitation space body simulation (Unity3D)

image

Newton’s law of universal gravitation is really helpful when it comes to simulating celestial bodies like stars, planets and moons according to their mass and velocity. It’s quite simple and doesn’t take into account the theory of relativity or other magical physics stuff ;-)

Left vs right: the mass of the moon orbiting on the green line changes the trajectory of the moon on the blue line.

image

Left vs right: the mass of the moon orbiting on the green line makes the big blue planet move despite it’s much higher mass (compare position to blue and orange markers).

image

Left vs right: the effect of the comparison above shown with longer trajectory lines. Notice how the moon on the red line moves forward with the big blue planet.

image

The package you can download below contains two scripts for calculating and handling the Newtonian gravitation, a script for drawing trajectories and basic camera control script. Let’s have a look at the scripts.

Code Newton.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Newton : MonoBehaviour {

	// Gravitational constant
	public float g = 0.01f;

	static List<NewtonBody> bodies;
	static Vector3 acceleration;
	static Vector3 direction;
	static float fixedDeltaTime;

	static Newton self;

	void Start() {

		self = this;

		NewtonSetup();
	}

	void FixedUpdate() {

		foreach(NewtonBody body in bodies) {

			NewtonUpdate(body);
		}
	}

	static void NewtonSetup() {

		fixedDeltaTime = Time.fixedDeltaTime;

		bodies = new List<NewtonBody>();
		bodies.AddRange(FindObjectsOfType(typeof(NewtonBody)) as NewtonBody[]);

		Debug.Log("There are probably " + bodies.Count + " Newton bodies in space (±42).");

		foreach(NewtonBody body in bodies) {

			body.velocity = body._transform.TransformDirection(body.initialForwardSpeed);
		}
	}

	static void NewtonUpdate(NewtonBody body) {

		acceleration = Vector3.zero;

		foreach(NewtonBody otherBody in bodies) {

			if(body == otherBody) continue;
			direction = (otherBody._transform.position - body._transform.position);
			acceleration += self.g * (direction.normalized * otherBody.mass) / direction.sqrMagnitude;
		}

		body.velocity += acceleration * fixedDeltaTime;
		body._transform.position += body.velocity * fixedDeltaTime;
	}
}

What happens? First, all planets or other celestial bodies with a NewtonBody component attached are collected. Then, each one gets assigned an initial forward speed to get things moving. Finally, Newton’s law of universal gravitation is calculated on every FixedUpdate. The new values are stored in the respective NewtonBody and the position is changed according to it’s new velocity vector.

Code NewtonBody.cs

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Transform))]

public class NewtonBody : MonoBehaviour {

	public Transform _transform;

	public float mass = 1f;
	public Vector3 velocity = Vector3.zero;
	public Vector3 initialForwardSpeed = Vector3.zero;

	void Awake() {

		_transform = GetComponent<Transform>();
	}
}

The NewtonBody component simply holds some values needed for the calculation. Note that the use of the NewtonBody component on a GameObject cancels out the use of a Rigidbody component on the same object. You can use Rigidbody on other objects, though.

Have fun in space :)

Download the example package

Credits

Space skybox by Ian Mac

Planet textures by NASA

Teaser video for an upcoming tumblr post about a Newtonian gravity script in Unity3D…

C# perlin noise clouds script for Unity3D

A fellow tumblerista asked me if the perlin noise cloud script could be purchased somewhere… well, no: it’s free :-)

image

image

Code Clouds.cs

using UnityEngine;
using System.Collections;

public class Clouds : MonoBehaviour {
	
	Texture2D texture;
	
	public int width = 128;
	public int height = 128;
	
	public Color cloudColor = Color.white;
	
	public float scale = 5f;
	public int octaves = 6;
	public float persistence = 0.6f;
	public int seed = 0;
	
	public float contrastLow = 0f;
	public float contrastHigh = 1f;
	public float brightnessOffset = 0f;
	
	public float xSpeed = 0.001f;
	public float ySpeed = 0.0005f;
	
	// Start
	void Start () {
	
		texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
		renderer.material.mainTexture = texture;
		
		GenerateCloudNoise(width, height);
	}
	
	// Update
	void Update () {
				
		renderer.material.mainTextureOffset = new Vector2(renderer.material.mainTextureOffset.x + xSpeed, renderer.material.mainTextureOffset.y + ySpeed);
	}
	
	// Generate cloud noise
	void GenerateCloudNoise(int noiseWidth, int noiseHeight) {
	
		float[,] perlinNoise = PerlinNoise.GeneratePerlinNoise(seed, octaves, persistence, noiseWidth, noiseHeight);
		float noiseValue;
		
		for(int y = 0; y < noiseWidth; y++) {
			
			for(int x = 0; x < noiseHeight; x++) {
				
				noiseValue = perlinNoise[x, y];
				noiseValue *= SimplexNoise.SeamlessNoise((float) x / (float) width, (float) y / (float) height, scale, scale, 0f);

				noiseValue = Mathf.Clamp(noiseValue, contrastLow, contrastHigh + contrastLow) - contrastLow;
				noiseValue = Mathf.Clamp(noiseValue, 0f, 1f);
				
				float r = Mathf.Clamp(cloudColor.r + brightnessOffset, 0f, 1f);
				float g = Mathf.Clamp(cloudColor.g + brightnessOffset, 0f, 1f);
				float b = Mathf.Clamp(cloudColor.b + brightnessOffset, 0f, 1f);
				
				texture.SetPixel(x, y, new Color(r, g, b, noiseValue));
			}
		}
		
		texture.Apply();
	}
}

Hope you enjoy the script, let me know if you add some major improvements…

Download the example package 

Credits

Perlin noise, smooth noise and white noise by Herman Tulleken

Simplex noise by Ilya Suzdalnitski

C# Messenger for Unity3D (compatible with Flash export)

Aren’t there already enough messenger/notification systems for Unity? Yes, but most of them don’t work with Flash export (which is sometimes required by clients)…

I decided to give it a try and the result is simply awesome! Well, maybe not awesome, but it works very well! We will need two scripts:

Code Messenger.cs

using UnityEngine;
using System.Collections;

public class Messenger : MonoBehaviour {
    
	static ArrayList subscriptions;
	
	// Awake
	void Awake() {

		subscriptions = new ArrayList();
	}
	
	// Add listener
	public static void Subscribe(GameObject subscriber, string subscription, string callback) {

		MessengerSubscription subscriptionToAdd = new MessengerSubscription();
		
		subscriptionToAdd.subscriber = subscriber;
		subscriptionToAdd.subscription = subscription;
		subscriptionToAdd.callback = callback;
		
		bool subscriptionExists = false;
		
		for(int i = 0; i < subscriptions.Count; i++) {
		
			if(CompareSubscriptions(subscriptions[i] as MessengerSubscription, subscriptionToAdd)) {
				
				subscriptionExists = true;
			}
		}
		
		if(!subscriptionExists) {
			
			subscriptions.Add(subscriptionToAdd);
		}
	}
	
	// Remove listener
	public static void Unsubscribe(GameObject subscriber, string subscription, string callback) {

		MessengerSubscription subscriptionToRemove = new MessengerSubscription();
		
		subscriptionToRemove.subscriber = subscriber;
		subscriptionToRemove.subscription = subscription;
		subscriptionToRemove.callback = callback;
				
		for(int i = 0; i < subscriptions.Count; i++) {
		
			if(CompareSubscriptions(subscriptions[i] as MessengerSubscription, subscriptionToRemove)) {
				
				subscriptions.RemoveAt(i);
			}
		}
	}
	
	// Broadcast without values
	public static void Broadcast(string subscription) {

		foreach(MessengerSubscription messengerSubscription in subscriptions) {
		
			if(messengerSubscription.subscription == subscription) {
				
				messengerSubscription.subscriber.SendMessage(messengerSubscription.callback, SendMessageOptions.DontRequireReceiver);
			}
		}
	}
	
	// Broadcast with values
	public static void Broadcast(string subscription, object value) {

		foreach(MessengerSubscription messengerSubscription in subscriptions) {
		
			if(messengerSubscription.subscription == subscription) {
				
				messengerSubscription.subscriber.SendMessage(messengerSubscription.callback, value, SendMessageOptions.DontRequireReceiver);
			}
		}
	}
	
	// Compare subscriptions
	static bool CompareSubscriptions(MessengerSubscription first, MessengerSubscription second) {
	
		if(first.subscriber == second.subscriber && first.subscription == second.subscription && first.callback == second.callback) {
			
			return true;
		}
		
		return false;
	}
	
	// Debug subscriptions
	public static void DebugSubscriptions() {
				
		foreach(MessengerSubscription debugSubscription in subscriptions) {
		
			Debug.Log(debugSubscription.subscriber.name + " " + debugSubscription.subscription + " " + debugSubscription.callback);
		}
	}
}

Code MessengerSubscription.cs

using UnityEngine;
using System.Collections;

public class MessengerSubscription {
    
	public GameObject subscriber;
	public string subscription;
	public string callback;
}

Wait, you’re using SendMessage?

Yup, I do. The problem with SendMessage itself is: you can only send messages to objects you know (or their children or their parents). This means you always have to store and update a list of GameObjects which can quickly become a mess.

This is exactly what my messenger script does in a comfortable way. You can focus on subscribing and broadcasting, the script manages the list for you.

However, SendMessage is apparently not really fast. Messenger.cs is probably not suited for handling thousands of subscribers. While a native C# event handling approach would be preferable, this script has to work with Flash export (must-have feature for me). This is why I’m using SendMessage.

Functionality

Now, what can you do with these scripts?

  • subscribe a GameObject to a message list
  • unsubscribe it from a message list
  • broadcast a message without passing variables
  • broadcast a message, passing one or more variables (multiple variables are passed inside an object or an array, so basically it is still one variable/object, but it can hold more than one value)

That’s it? No! There’s more:

  • subscribe a GameObject to a message list and route it to more than one callback function
  • unsubscribe only some of the callback functions of that GameObject

Setup

To get this messenger working, you simply have to create an empty GameObject and assign the Messenger.cs script to it. The MessengerSubscription.cs script should not be assigned to anything.

Examples

Subscribing

// Messenger.Subscribe(GameObject subscriber, string subscription, string callback);
Messenger.Subscribe(gameObject, "Pause", "OnPause");

Unsubscribing

// Messenger.Unsubscribe(GameObject subscriber, string subscription, string callback);
Messenger.Unsubscribe(gameObject, "Pause", "OnPause");

Broadcasting without values

// Messenger.Broadcast(string subscription);
Messenger.Broadcast("Pause");

Broadcasting with values

// Messenger.Broadcast(string subscription, value object);
Messenger.Broadcast("Pause", 10f);

Debugging subscriptions

// Prints a list of all subscriptions
Messenger.DebugSubscriptions();

Download the example package 

Troubleshooting

As this script doesn’t have any error handling routines yet, it may show some weird errors from time to time. In this case, remove the Messenger.cs component from the GameObject and simply assign it again.

Roadmap

  • fix weird editor mode bug (see above)
  • add error/exception handling
  • make it faster

Nostalgia XXI: Starship Titanic poster blowup (Photoshop)

Starship Titanic is a book and a game which had outstanding graphics for its time. The book was written by Terry Jones (based on an idea by Douglas Adams), the game was produced by Douglas Adams.

Oscar Chichoni is an illustrator. There’s an official game page as well as an “Starship Titanic Construction Intranet" page.

Base image (1041 x 1354 px):

image

Typo reference (627 x 785 px):

image

The final blowup image (5906 x 7693 px):

image

Detail:

image

Looks good on my wall (60 x 100 cm):

image

Original artwork © 1997 Oscar Chichoni
Starship Titanic book © 1997 Terry Jones, Douglas Adams
Starship Titanic game © 1997 Douglas Adams, The Digital Village

Procedural cloud textures in Unity3D

Hey y’all, finally something new :D

I made a C# script creating 2D cloud textures at runtime.

Advantages

- not a single image file is required
- infinite variations
- tweakable at runtime

Disadvantages

- certain cloud types are hard to recreate with the current version
- noise computation consumes quite a lot of performance (heavily depending on the size of the noise texture)

image

The script creates four types of noises: white noise, smooth noise, Simplex noise and Perlin noise. At the end, the Simplex and Perlin noise are combined into a single image (white and smooth noise are required for computing the other noises).

image

By changing parameters like scale, number of octave, persistence and others the script generates quite different types of cloud textures.

image

image

image

image

image

To Tumblr, Love Pixel Union