I’m using Edy’s Vehicle Physics and I’ve managed to implement a gearshift system in order for me to add sound. Somehow though I can’t get it to work. I always get this:
NullReferenceException: Object reference not set to an instance of an object
Boo.Lang.Runtime.RuntimeServices.InvokeBinaryOperator (System.String operatorName, System.Object lhs, System.Object rhs)
CarGears.Main () (at Assets/EdyVehiclePhysics/CarGears.js:20)
So there’s problem one. The second problem is that nothing happens to the sound. To my knowledge everything is set up right. I’ve picked the gearshift code out of another car tutorial and didn’t leave anything out. All I want is the gearshifting to work in order for the audio to properly work. Here’s the piece of code:
var RearLeftWheel : Transform;
var RearRightWheel : Transform;
// These variables are for the gears, the array is the list of ratios. The script
// uses the defined gear ratios to determine how much torque to apply to the wheels.
var GearRatio : float[];
var CurrentGear : int = 0;
// These variables are just for applying torque to the wheels and shifting gears.
// using the defined Max and Min Engine RPM, the script can determine what gear the
// car needs to be in.
var MaxEngineRPM : float = 3000.0;
var MinEngineRPM : float = 1000.0;
private var EngineRPM : float = 0.0;
// Compute the engine RPM based on the average RPM of the two wheels, then call the shift gear function
EngineRPM = (RearLeftWheel.angularVelocity + RearRightWheel.angularVelocity)/2 * GearRatio[CurrentGear];
ShiftGears();
// set the audio pitch to the percentage of RPM to the maximum RPM plus one, this makes the sound play
// up to twice it's pitch, where it will suddenly drop when it switches gears.
audio.pitch = Mathf.Abs(EngineRPM / MaxEngineRPM) + 1.0 ;
// this line is just to ensure that the pitch does not reach a value higher than is desired.
if ( audio.pitch > 2.0 ) {
audio.pitch = 2.0;
}
function ShiftGears()
{
// this funciton shifts the gears of the vehcile, it loops through all the gears, checking which will make
// the engine RPM fall within the desired range. The gear is then set to this "appropriate" value.
if ( EngineRPM >= MaxEngineRPM ) {
var AppropriateGear : int = CurrentGear;
for ( var i = 0; i < GearRatio.length; i ++ ) {
if ( RearRightWheel.angularVelocity * GearRatio[i] < MaxEngineRPM ) {
AppropriateGear = i;
break;
}
}
CurrentGear = AppropriateGear;
}
if ( EngineRPM <= MinEngineRPM ) {
AppropriateGear = CurrentGear;
for ( var j = GearRatio.length-1; j >= 0; j -- ) {
if ( RearRightWheel.angularVelocity * GearRatio[j] > MinEngineRPM ) {
AppropriateGear = j;
break;
}
}
CurrentGear = AppropriateGear;
}
}
It’s a seperate JavaScript attached to the car with the name ‘CarGears’. Everything is set up right (Gear Ratio for instance) and the RearLeftWheel and RearRightWheel variables are pointed to the actual wheels but it doesn’t seem to work. Can anyone see why? (I tried using the WheelColliders.rpm that was originally used in the script but that didn’t do anything either).
I’ve attached a screenshot of the part where the Audio Source and CarGears script are inserted
You should write everything other than declarations etc. inside a function. This part does not have a function:
// Compute the engine RPM based on the average RPM of the two wheels, then call the shift gear function
EngineRPM = (RearLeftWheel.angularVelocity + RearRightWheel.angularVelocity)/2 * GearRatio[CurrentGear];
ShiftGears();
// set the audio pitch to the percentage of RPM to the maximum RPM plus one, this makes the sound play
// up to twice it's pitch, where it will suddenly drop when it switches gears.
audio.pitch = Mathf.Abs(EngineRPM / MaxEngineRPM) + 1.0 ;
// this line is just to ensure that the pitch does not reach a value higher than is desired.
if ( audio.pitch > 2.0 ) {
audio.pitch = 2.0;
}
you should probably put a function Update() { to the beginning of this section.
Thanks for the answer. During my search I also found that, but it still gives me the NullReferenceException :\ I tried adding function Start () { to the beginning, and putting all var’s in it, but that just gives me an error.
I did all that, no errors but still the NullReferenceException. Also, what exactly do you mean with ‘bracket structure’? I’m not quite a scripter/programmer but more a 3D artis. The only thing I’m spending hours on this bit is because I want some sound out of my car so I can get on with the rest of what I’m working on
This is what the code looks like right now:
var RearLeftWheel : Transform;
var RearRightWheel : Transform;
var GearRatio : float[];
var CurrentGear : int = 0;
var MaxEngineRPM : float = 3000.0;
var MinEngineRPM : float = 1000.0;
private var EngineRPM : float = 0.0;
function Update()
{
EngineRPM = (RearLeftWheel.angularVelocity.x + RearRightWheel.angularVelocity.x)/2 * GearRatio[CurrentGear];
ShiftGears();
audio.pitch = Mathf.Abs(EngineRPM / MaxEngineRPM) + 1.0 ;
if ( audio.pitch > 2.0 ) {audio.pitch = 2.0;}
}
function ShiftGears()
{
if ( EngineRPM >= MaxEngineRPM ) {
var AppropriateGear : int = CurrentGear;
for ( var i = 0; i < GearRatio.length; i ++ ) {
if ( RearRightWheel.angularVelocity.x * GearRatio[i] < MaxEngineRPM ) {
AppropriateGear = i;
break;
}
}
CurrentGear = AppropriateGear;
}
if ( EngineRPM <= MinEngineRPM ) {
AppropriateGear = CurrentGear;
for ( var j = GearRatio.length-1; j >= 0; j -- ) {
if ( RearRightWheel.angularVelocity.x * GearRatio[j] > MinEngineRPM ) {
AppropriateGear = j;
break;
}
}
CurrentGear = AppropriateGear;
}
}
I just saw that the NullReferenceException has changed:
NullReferenceException: Object reference not set to an instance of an object
Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.String cacheKeyName, System.Type[] cacheKeyTypes, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.Object[] args, System.String cacheKeyName, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.GetProperty (System.Object target, System.String name)
UnityScript.Lang.UnityRuntimeServices.GetProperty (System.Object target, System.String name)
CarGears.Update () (at Assets/EdyVehiclePhysics/CarGears.js:19)
Ok, I had to load this script to a scene to see what is going on.
Well, when you write “RearLeftWheel.angularVelocity.x” you try to acess the transform’s angularVelocity, but it does not have one as angularVelocity is a property of rigidbody. You should write “RearLeftWheel.rigidbody.angularVelocity.x”
Do this to all angularVelocity and make sure the transforms in the editor has rigidbodies.
Yep, that works, but the wheels don’t have RigidBodies attached so that kinda makes it difficult. I can send you the project if you want so you can take a look?
You should add rigidbodies if you want to measure the RPM of an object. In unity if an object does not have a rigidbody than it is not meant to move/rotate.
I do not know how Edy’s Vehicle Physics handles things but probably it has a script that assigns a virtual RPM to wheels or engine. You need to get that variable from that script and use that.
The Wheels have a script attached to them which handles things like Rigidbodies and WheelColliders. That’s probably the whole reason nothing works like it should.
I started by exposing the wheel’s spin rate, then testing if your script could work properly with it, and I ended writing a very simple engine sound script that actually does a pretty good job! Much better that I had expected.
I’ve been playing with the addon script for about half an hour now and it is an absolute beauty! I’m going to try to add skidding sounds and wind sounds ( I know that’s also on your wishlist, but I’m gonna try anyways ;)) but damn dude! Beautiful script! One thing I changed though is the Gear Down Speed to 5 which makes the gearing down a bit more subtle, and I’ve changed the RPM readout for the rear-wheel drive car to the front wheels. That doesn’t make any sense as far as realism goes, but now the RPM won’t drop down to idle as soon as I hit the handbrake, which sounds a bit more realistic. I can’t thank enough man!
Such as SomerenV, I tried to implement the sound to Edy’s Vehicle Physics package that I purchased on the asset store.
I tried to modify the SoundController.js of the car tutorial, but I did not get something satisfying, so i would like to know if you guys ( SomerenV or Edy ), could send me the sound script please ?
I would like to test it
Thank You !
Edit: finally I could get the audio script at the project repository