New Website?

December 13, 2018 by

I’m really really not a big fan of WordPress (running my current site) so I’ve been looking for alternatives and recently I’ve found a new CMS that’s caught my fancy.

It’s called October CMS and I’ve already slowly begun building a new site and adding/moving stuff there. I’m trying to collect knowledge and usefull information, also gained from personal experiments.

A different CMS will obviously not make me create more content, but my developer heart feels better working with a nicer framework.

So, until I’ve moved enough stuff over, I’ll just have a link to the new content:

http://october.lychesis.net

…and yeah, I also crave for a custom self made design, but I’ve got to be realistic with my available time.

Atom Editor

August 23, 2016 by

The Atom editor is a very versatile and extendable coding editor made by the folks from GitHub.

https://atom.io/

Being extendable also means that the functionality out of the box is pretty limited. I therefore have a personal collection of plugins that I find interesting:

  • atom-beautify Code Highlighting for a whole bunch of different languages.
  • file-watcher Detects file changes outside of Atom and notifies you.
  • keyboard-localization Fixes inaccessable hotkeys for people using non-us keyboards.
  • less-than-slash Automatically closes HTML tags.
  • minimap Visual minimap of your code – conficts with symbols-list.
  • pigments Tints color values inside the code.
  • symbols-list Lists functions and methods of the current file in the right sidebar – conficts with minimap

McLaren Material Tests

August 18, 2015 by

This is an experiment to test various techiques for car material setups.

I took a pre-existing mesh from a McLaren MP4-12C (sorry – I don’t know who made it) and created proper UVs and the corresponding occlusion maps for it in MODO.

The yellow car paint material is just the standard shader from Unity 5 (at the moment). Lighting is generated by a direction light and a HDRI map, which can also be seen in the background. Reflections are rendered with a reflection probe, but not yet utilized effectively. Linear and HDR color space are used for rendering, together with the usual depth of field and vinette image filters.

I used a shader that I created with Shaderforge for the color variations. Goal was to create a shader that would be able to do normal color paint and silver or metallic paint simply by adjusting the parameters. At the moment I can’t use the PBR shader, since Shaderforge doesn’t give me enough freedom with the shading. Therefore I input the individual environments as cubemaps and calculate the shading myself. Not yet perfect, but getting there.

Construction ahead

August 5, 2015 by

It’s been much too long since the last update, and since the design is also getting quite rusty, I’ll now be upgrading the whole site. This will probably break things here and there along the way, but bear with me.

Bahn Escape Plan

October 15, 2013 by

This is a small tool that shows all trains for a particular route. The trains are shown in a timeline with their trip times running from top to bottom. Delays shift the bars further down with the original trip time appearing in red beneath the actual bar.

The system reads the data from the train services’ delay page. The html code is parsed with an array of regular expressions to extract the desired information.

Don’t access Unity projects via network shares

January 20, 2013 by

I must admit that I feel stupid for not having realized this earlier but I was updating / dual using Unity 3.5 and 4.0 as well when this happened, so I was a little unsure what was causing it, but here goes:

If you access your Unity project on a network share (like: \\server\project\game) then it will run quite well except a small error that pops up in the logs:

UriFormatException: Absolute URI is too short

This is part of the interface that is supposed to link Unity and MonoDevelop together and it is trying to tell you that it can’t generate the solution files (.sln) that MonoDevelop needs to properly integrate into Unity. It’s failure is mainly noticable because MonoDevelop’s intellisense or code complete completely stops working, degrading Mono to a simple text editor and making it very much frustrating to work with it.

If you are unsure if you are having this problem then simply try to use the > Assets > Sync MonoDevelop Project menu. That should instantly generate the error in the logs.

The easiest solution (besides having your project files on your local harddrive) is to map the network share to a network drive and everything will be ok.

Offroad Speeder v02

July 17, 2012 by

I updated the version of the Speeder with the CarSmoothFollow Script from the Unity Wiki.

I also added detachable spoilers via the Hinge Joints (setting the Limits very narrow so that they don’t move by themselves). The Fixed Joints seemed a good idea at first but they wouldn’t keep still. So to prevent the spoilers from wobbeling around I used the Hinge Joints instead.

I also tweaked the physics a little bit more but without getting significantly better handling from the car…

Speeder v02

Basic Car Setup

June 26, 2012 by

My current findings for setting up a car rig have been the following:

As we usually deal with several wheels I use arrays to store everything. This lets me add more wheels without breaking into a sweat or having to go copy-paste all over the place.

The base vehicle Axis contains four wheel axis objects that have the WheelColliders. Parented to these we find the wheel meshes. To link these up to the script we have to add these definitions.

public Transform[] wheels;
public WheelCollider[] colliders;
public float[] powers;
public float[] brakes;
public float[] rotations;
public Transform[] steerings;
public Transform centerOfMass;

wheels is for the mesh objects
colliders is for the wheelcolliders
powers is for the amount of torque we apply to each wheel
brakes is for the amount of brakes we apply to each wheel
rotations is for the rotation ratio that is applied to each wheel
steerings is for the amount of steering we apply to each wheel
centerOfMass defines the center of gravity

I set all the WheelCollider settings via script. You can also do this in the inspector, which is much more convinient since you are now able to edit all wheels at one, but in earlier versions you had to do this for every wheel individually.

void Start () {
rigidbody.centerOfMass = centerOfMass.localPosition;

JointSpring suspensionSpring = new JointSpring();
suspensionSpring.spring = 2048.0F;
suspensionSpring.damper = 16.0F;
suspensionSpring.targetPosition = 0.0F;

WheelFrictionCurve forwardFriction = new WheelFrictionCurve();
forwardFriction.extremumSlip = 2.0F;
forwardFriction.extremumValue = 1024.0F;
forwardFriction.asymptoteSlip = 4.0F;
forwardFriction.asymptoteValue = 512.0F;
forwardFriction.stiffness = 1.0F;

WheelFrictionCurve sidewaysFriction = new WheelFrictionCurve();
sidewaysFriction.extremumSlip = 8.0F;
sidewaysFriction.extremumValue = 128.0F;
sidewaysFriction.asymptoteSlip = 16.0F;
sidewaysFriction.asymptoteValue = 64.0F;
sidewaysFriction.stiffness = 1.0F;

for (int i = 0; i < colliders.Length; i++) { colliders[i].suspensionDistance = 1.0F; colliders[i].suspensionSpring = suspensionSpring; colliders[i].forwardFriction = forwardFriction; colliders[i].sidewaysFriction = sidewaysFriction; } }

I first have to define the JointSpring, which defines how much the wheel colliders will bounce. Usually you'll want to set everything to "0" and then increase the spring value until the car stays up by itself. This is very dependant on the number of wheels and the weight of the car. Then set the damper until the car stops bouncing.

The WheelFrictionCurves are a bit more difficult. They will usually define when the wheels will start to spin (forwardFriction) and when the car begins to slide (sidewaysFriction). I still haven't found a good method to set these up right but usually you'll want to set the extremumValue to a force value where you want the car to skid and then set the asymptoteValue to a value of force or grip that you want to have when the wheels have begun to slide.

Finally the values are applied to each individual WheelCollider including the suspensionDistance, which defines how far down the suspension will travel when the wheels are not touching the ground.

Next are the physics calculcations which take place in the FixedUpdate function because these have to run at a constant rate, independant of the frame rate.

void FixedUpdate() {
float speed = Vector3.Magnitude(rigidbody.velocity);
float rpm = (colliders[0].rpm + colliders[1].rpm) / 2.0F;
float torque = 0.0F;
float brake = 0.0F;
float throttle = Input.GetAxis("Vertical");
float steering = Input.GetAxis("Horizontal");
float steering_magnitude = speed;
float steering_range = 45.0F;

if (throttle > 0.0F) {
torque = throttle;
} else if (throttle < 0.0F) { brake = Mathf.Abs(throttle); }

if (steering_magnitude > 0.0F) {
float ratio = steering_magnitude / 45.0F;
steering_range *= 1.0F - ratio;
}
steering_range = Mathf.Clamp(steering_range, 15.0F, 45.0F);

speed gets the velocity of the car
rpm gets the rpm values from the front wheels
throttle reads the throttle input from the player
torque torque applied by the player
brake brakes applied by the player
steering amount of steering applied by the player
steering_magnitude controls the amount of steering and is decreased at higher speeds to prevent the car from rolling over
steering_range maximum steering angle

for (int i = 0; i < steerings.Length; i++) { steerings[i].localEulerAngles = new Vector3(0.0F, steering * steering_range, 0.0F); }
for (int i = 0; i < colliders.Length; i++) { colliders[i].motorTorque = torque * powers[i]; colliders[i].brakeTorque = brake * brakes[i]; wheels[i].Rotate(colliders[i].rpm * rotations[i] * Time.deltaTime,0 ,0); UpdateWheelHeight(wheels[i], colliders[i]); }
rigidbody.AddForce(Vector3.down * downforce * Vector3.Magnitude(rigidbody.velocity));
}

Apply steering to the wheels (by multiplying these with the array values I can freely set up steering of the wheels in the front or of all wheels or even only the back wheels

Then apply the throttle and/or brake forces to all wheels, again multiplying these with the array values to switch between FWD / RWD / 4WD, and even braking can be set up to equal the usual 60% front / 40% rear braking force

The visible wheel meshes don't realy contribute to the simulation but are necessary for the player to see what's going on. Therefore the rotation values for the wheels are somewhat approximated. I haven't yet found a reliable calculation example for this allthough I am almost certain there should be one. Simple experiment for the time beeing.

Last but not least the function that sets the wheel height. This was taken from some other example I currently don't remember - probably the official Unity car tutorial.

void UpdateWheelHeight(Transform wheelTransform, WheelCollider collider) {
Vector3 localPosition = wheelTransform.localPosition;
WheelHit hit = new WheelHit();
// see if we have contact with ground
if (collider.GetGroundHit(out hit)) {
// calculate the distance between current wheel position and hit point, correct
// wheel position
localPosition.y -= Vector3.Dot(wheelTransform.position - hit.point, transform.up) - collider.radius;
} else {
// no contact with ground, just extend wheel position with suspension distance
localPosition = -Vector3.up * collider.suspensionDistance;
}
// actually update the position
wheelTransform.localPosition = localPosition;
}

There's also a good thread in the Unity forums which deals with adding anti rollbars to the simulation. I removed these again since they didn't improve the handling in later tests of the setup and I wanted to eliminate factors that may make the handling unstable. There'll probably be setups where these anti rollbars serve a usefull purpose:

Unity Forum - anti rollbars