Improved Trucking Physics

June 7, 2012 by

Had another go at the WheelCollider, as I wasn’t convinced that completely custom built vehicle physics would save that much time, and I have made a couple of improvements. Most of all the Suspension is now correct, as I was doing it wrong most of the time:

  • The best way to start is to set “Spring”, “Damper” and “Target Position” to zero.
  • Set “Suspension Distance” to the distance you want the wheels to drop when the vehicle is in the air.
  • Set “Spring” to something high (try 10240, depending on the weight and number of wheels of the vehicle) and start the game. Tweak the “Spring” value until the suspension is strong enough to keep the body of the vehicle from hitting the ground.
  • Now set the “Damper” to roughly 1/20 of the “Spring” value and tweak it until the vehicle stops bouncing (depending on how much you like it to bounce)
  • Note that everything you attach to the vehicle as well as the center of mass will affect the suspension behaviour and you will probably have to tweak it all over again

Here’s the new version with the improved settings.

Trucking v02

Trucking Physics

May 20, 2012 by

I experimented a little with the Unity physics and wheel collider features to try to get a working truck + trailer configuration working for rough terrain.

As I had already done some truck and trailer physics for a farm simulator at work I wasn’t expecting this to be that tricky.

I uploaded my current state with still quite a number of problems and my research in forums has only resulted in finding many other developers not really happy with the build in car physics, saying you should do your own or use one off the Asset Store.

Trucking v01

I’m not yet ready to give up on the built in system (but close).

Not working at the moment are:

  • Suspension isn’t following the ground properly, especially with the twin-axles. Resulting in one axle having ground contact while the other is hanging in the air. I may have to reduce the real twin axles to a single virtual one, driving the visible twin axles.
  • The truck tips over to easily. Lowering the center of gravity will fix this, but when tipping over the truck will then flip back to it’s wheels, looking pretty weird. I may have to animated the center of gravity so that it will rise if the truck is tipping over and lower it while it is going normally
  • The trailer sometimes drags the truck pretty violently. It uses a configurable joint with restrictions but these sometimes pull very hard on the truck (or it may lift the truck into the air when braking hard).
  • Sometimes the truck will not be able to gain speed. Very strange, I can only think of there being some large friction between truck and trailer leading to this behaviour.
  • Grip and slip isn’t configured properly. Either the wheels simply spin or the wheels stick so violently to the ground that it tips over. It would be nice to get more information out of the wheel collider. This again speaks towards using a custom made system.

iTween

March 18, 2012 by

iTween must be one of the single most usefull scripts that are available. There is just one thing that makes working with it slightly obscure, because of the way extended options have to be added via the hash table by using the iTween.Hash() function.
iTween.MoveTo(exhibitObject, iTween.Hash(
"position", presenterTransform.position,
"time", reloadDelay,
"islocal", false,
"easetype", iTween.EaseType.easeOutQuad
));

Realtime Cubemap for Reflections

February 25, 2012 by

A nice script for creating a real time cubemap from an object position for use with a reflection shader to create realtime reflections in Unity. Converted from the JavaScript example. Note: This script requires the Unity Pro license.

using UnityEngine;
using System.Collections;

public class RealtimeCubemap : MonoBehaviour {

    public int cubemapSize = 128;
    public bool oneFacePerFrame = false;
    private Camera cam;
    private RenderTexture rtex;
    private GameObject go;

    [ExecuteInEditMode]
    void Start() {
        // render all six faces at startup
        UpdateCubemap(63);
    }

    void LateUpdate() {
        if (oneFacePerFrame) {
            int faceToRender = Time.frameCount % 6;
            int faceMask = 1 << faceToRender;
            UpdateCubemap(faceMask);
        } else {
            UpdateCubemap(63); // all six faces
        }
    }

    void UpdateCubemap(int faceMask) {
        if (!cam) {
            go = new GameObject("CubemapCamera");
            go.AddComponent(typeof(Camera));
            go.hideFlags = HideFlags.HideAndDontSave;
            go.transform.position = transform.position;
            go.transform.rotation = Quaternion.identity;
            cam = go.camera;
            cam.farClipPlane = 100; // don't render very far into cubemap
            cam.enabled = false;
        }

        if (!rtex) {    
            rtex = new RenderTexture(cubemapSize, cubemapSize, 16);
            rtex.isCubemap = true;
            rtex.hideFlags = HideFlags.HideAndDontSave;
            renderer.sharedMaterial.SetTexture ("_Cube", rtex);
        }

        cam.transform.position = transform.position;
        cam.RenderToCubemap(rtex, faceMask);
    }

    void OnDisable() {
        DestroyImmediate (cam);
        DestroyImmediate (rtex);
    }
}

String formatting

February 2, 2012 by

Something small but usefull is the String.Format function, with which you can format your numerical outputs:

using System;
using System.Collections;

...

// formatted float with three zero padded digits
// in front of the "." and three digits after it.
debugText += String.Format("H{0:000.000}\n", heading);

// formatted int with formats for positive;negative;zero values
debugText += String.Format("S{0:+000;-000; 000}\n", speed);

Calculate intersection between to lines

January 25, 2012 by

Here’s something that will calculate where two lines will intersect. If they don’t intersect then the two resulting vectors will mark the points where both lines are closest together.

/* setup vectors */
 Vector3 l1begin = playerCurrentPosition;
 Vector3 l1end = playerTargetPosition - l1begin;
 Vector3 l2begin = enemyCurrentPosition;
 Vector3 l2end = enemyTargetPosition - l2begin;
/* calculate vectors */
 Vector3 n = Vector3.Cross(l1end, l2end);
 Vector3 u = Vector3.Cross(n, l1begin - l2begin) / Vector3.Dot(n, n);
 Vector3 intersection1 = l1begin - l1end * Vector3.Dot(l2end, u);
 Vector3 intersection2 = l2begin - l2end * Vector3.Dot(l1end, u);
/* draw vectors */
 Debug.DrawRay(l1begin, l1end, Color.cyan);
 Debug.DrawRay(l2begin, l2end, Color.magenta);
 Debug.DrawLine(intersection1, intersection2, Color.white);

Calculate angle from current heading to target object

October 16, 2011 by

If you want to have an object turn automatically towards a target then you have to find out in which direction to turn. The usual angle function just returns the smallest angle between the current heading and the heading towards the target but not which way around.

Vector3 lTarget = transform.InverseTransformPoint(target.position);
targetDistance = lTarget.magnitude;
targetAngle = Mathf.Atan2(lTarget.x, lTarget.z) * Mathf.Rad2Deg;

  • This calculates the position in relation to the current objects local coordinate system.
  • It then calculates the distance (because you’ll need it anyway).
  • Finally it calculates the angle in radians and then converts it to degrees, just for good measure.

Get Vector3 from Quaternion / Rotate Vector3

September 13, 2011 by

To get the vector from a quaternion rotation you simply multiply the quaternion by the forward vector.

Debug.DrawRay(transform.position, transform.rotation * Vector3.forward, Color.red);

This also effectively rotates the forward-vector with the rotation of the transform, positioning it relative to the rotation of the actual object.