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

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


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.

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).

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.

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 :)
Credits
Space skybox by Ian Mac
Planet textures by NASA
Teaser video for an upcoming tumblr post about a Newtonian gravity script in Unity3D…
Original movie poster © 1979 Kennedy Miller Productions, Crossroads, Mad Max Films
A fellow tumblerista asked me if the perlin noise cloud script could be purchased somewhere… well, no: it’s free :-)


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…
Credits
Perlin noise, smooth noise and white noise by Herman Tulleken
Simplex noise by Ilya Suzdalnitski
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?
That’s it? No! There’s more:
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();
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
Oh hai, didn’t log in to tumblr for a while… it’s not for sale, but I can do a post about it with the code for free. How about that ;-)
Will take a little time though, much to do these days…
Cheers!
Edit: voilà http://fkm1900.tumblr.com/post/66492688325/c-perlin-noise-clouds-script-for-unity3d
All props and characters crayoned with Sakura oil pastels. Layers arranged in 3D space with Cinema 4D. Characters animated with After Effects’ puppet tool.









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):

Typo reference (627 x 785 px):

The final blowup image (5906 x 7693 px):

Detail:

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

Original artwork © 1997 Oscar Chichoni
Starship Titanic book © 1997 Terry Jones, Douglas Adams
Starship Titanic game © 1997 Douglas Adams, The Digital Village
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)

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).

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




