|
|
@@ -63,8 +63,7 @@ void CreateScene()
|
|
|
light.lightType = LIGHT_DIRECTIONAL;
|
|
|
light.castShadows = true;
|
|
|
light.shadowBias = BiasParameters(0.00025f, 0.5f);
|
|
|
- light.shadowCascade =
|
|
|
- CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f);
|
|
|
+ light.shadowCascade = CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f);
|
|
|
light.specularIntensity = 0.5f;
|
|
|
// Create heightmap terrain with collision
|
|
|
Node@ terrainNode = scene_.CreateChild("Terrain");
|
|
|
@@ -73,10 +72,8 @@ void CreateScene()
|
|
|
terrain.patchSize = 64;
|
|
|
terrain.spacing = Vector3(2.0f, 0.1f, 2.0f); // Spacing between vertices and vertical resolution of the height map
|
|
|
terrain.smoothing = true;
|
|
|
- terrain.heightMap =
|
|
|
- cache.GetResource("Image", "Textures/HeightMap.png");
|
|
|
- terrain.material =
|
|
|
- cache.GetResource("Material", "Materials/Terrain.xml");
|
|
|
+ terrain.heightMap = cache.GetResource("Image", "Textures/HeightMap.png");
|
|
|
+ terrain.material = cache.GetResource("Material", "Materials/Terrain.xml");
|
|
|
// The terrain consists of large triangles, which fits well for occlusion rendering, as a hill can occlude all
|
|
|
// terrain patches and other objects behind it
|
|
|
terrain.occluder = true;
|
|
|
@@ -89,25 +86,19 @@ void CreateScene()
|
|
|
for (uint i = 0; i < NUM_MUSHROOMS; ++i)
|
|
|
{
|
|
|
Node@ objectNode = scene_.CreateChild("Mushroom");
|
|
|
- Vector3 position(Random(2000.0f) - 1000.0f, 0.0f,
|
|
|
- Random(2000.0f) - 1000.0f);
|
|
|
+ Vector3 position(Random(2000.0f) - 1000.0f, 0.0f, Random(2000.0f) - 1000.0f);
|
|
|
position.y = terrain.GetHeight(position) - 0.1f;
|
|
|
objectNode.position = position;
|
|
|
// Create a rotation quaternion from up vector to terrain normal
|
|
|
- objectNode.rotation =
|
|
|
- Quaternion(Vector3(0.0f, 1.0f, 0.0),
|
|
|
- terrain.GetNormal(position));
|
|
|
+ objectNode.rotation = Quaternion(Vector3(0.0f, 1.0f, 0.0), terrain.GetNormal(position));
|
|
|
objectNode.SetScale(3.0f);
|
|
|
StaticModel@ object = objectNode.CreateComponent("StaticModel");
|
|
|
object.model = cache.GetResource("Model", "Models/Mushroom.mdl");
|
|
|
- object.material =
|
|
|
- cache.GetResource("Material", "Materials/Mushroom.xml");
|
|
|
+ object.material = cache.GetResource("Material", "Materials/Mushroom.xml");
|
|
|
object.castShadows = true;
|
|
|
- RigidBody@ mushroomBody =
|
|
|
- objectNode.CreateComponent("RigidBody");
|
|
|
+ RigidBody@ mushroomBody = objectNode.CreateComponent("RigidBody");
|
|
|
mushroomBody.collisionLayer = 2;
|
|
|
- CollisionShape@ mushroomShape =
|
|
|
- objectNode.CreateComponent("CollisionShape");
|
|
|
+ CollisionShape@ mushroomShape = objectNode.CreateComponent("CollisionShape");
|
|
|
mushroomShape.SetTriangleMesh(object.model, 0);
|
|
|
}
|
|
|
}
|
|
|
@@ -120,9 +111,7 @@ CreateVehicle()
|
|
|
vehicleNode.position = Vector3(0.0f, 5.0f, 0.0f);
|
|
|
// First createing player-controlled vehicle
|
|
|
// Create the vehicle logic script object
|
|
|
- Vehicle@ vehicle =
|
|
|
- cast < Vehicle >
|
|
|
- (vehicleNode.CreateScriptObject(scriptFile, "Vehicle"));
|
|
|
+ Vehicle@ vehicle = cast<Vehicle>(vehicleNode.CreateScriptObject(scriptFile, "Vehicle"));
|
|
|
// Initialize vehicle component
|
|
|
vehicle.Init();
|
|
|
vehicleNode.AddTag("vehicle");
|
|
|
@@ -191,16 +180,11 @@ HandleUpdate(StringHash eventType, VariantMap& eventData)
|
|
|
TouchState@ state = input.touches[i];
|
|
|
if (state.touchedElement is null) // Touch on empty space
|
|
|
{
|
|
|
- Camera@ camera =
|
|
|
- cameraNode.GetComponent("Camera");
|
|
|
+ Camera@ camera = cameraNode.GetComponent("Camera");
|
|
|
if (camera is null)
|
|
|
return;
|
|
|
- vehicle.controls.yaw +=
|
|
|
- TOUCH_SENSITIVITY * camera.fov /
|
|
|
- graphics.height * state.delta.x;
|
|
|
- vehicle.controls.pitch +=
|
|
|
- TOUCH_SENSITIVITY * camera.fov /
|
|
|
- graphics.height * state.delta.y;
|
|
|
+ vehicle.controls.yaw += TOUCH_SENSITIVITY * camera.fov / graphics.height * state.delta.x;
|
|
|
+ vehicle.controls.pitch += TOUCH_SENSITIVITY * camera.fov / graphics.height * state.delta.y;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -210,39 +194,30 @@ HandleUpdate(StringHash eventType, VariantMap& eventData)
|
|
|
vehicle.controls.pitch += input.mouseMoveY * YAW_SENSITIVITY;
|
|
|
}
|
|
|
// Limit pitch
|
|
|
- vehicle.controls.pitch =
|
|
|
- Clamp(vehicle.controls.pitch, 0.0f, 80.0f);
|
|
|
+ vehicle.controls.pitch = Clamp(vehicle.controls.pitch, 0.0f, 80.0f);
|
|
|
// Check for loading / saving the scene
|
|
|
if (input.keyPress[KEY_F5])
|
|
|
{
|
|
|
- File saveFile(fileSystem.programDir +
|
|
|
- "Data/Scenes/RaycastScriptVehicleDemo.xml",
|
|
|
- FILE_WRITE);
|
|
|
+ File saveFile(fileSystem.programDir + "Data/Scenes/RaycastScriptVehicleDemo.xml", FILE_WRITE);
|
|
|
scene_.SaveXML(saveFile);
|
|
|
}
|
|
|
if (input.keyPress[KEY_F7])
|
|
|
{
|
|
|
- File loadFile(fileSystem.programDir +
|
|
|
- "Data/Scenes/RaycastScriptVehicleDemo.xml",
|
|
|
- FILE_READ);
|
|
|
+ File loadFile(fileSystem.programDir + "Data/Scenes/RaycastScriptVehicleDemo.xml", FILE_READ);
|
|
|
scene_.LoadXML(loadFile);
|
|
|
// After loading we have to reacquire the vehicle scene node, as it has been recreated
|
|
|
// Simply find by name as there's only one of them
|
|
|
- Array < Node@ >@vehicles =
|
|
|
- scene_.GetChildrenWithTag("vehicle");
|
|
|
+ Array<Node@>@ vehicles = scene_.GetChildrenWithTag("vehicle");
|
|
|
for (int i = 0; i < vehicles.length; i++)
|
|
|
{
|
|
|
- Vehicle@ vehicleData =
|
|
|
- cast < Vehicle > (vehicles[i].scriptObject);
|
|
|
+ Vehicle@ vehicleData = cast<Vehicle>(vehicles[i].scriptObject);
|
|
|
vehicleData.CreateEmitters();
|
|
|
}
|
|
|
vehicleNode = scene_.GetChild("Vehicle", true);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
- vehicle.
|
|
|
- controls.Set(CTRL_FORWARD | CTRL_BACK | CTRL_LEFT | CTRL_RIGHT |
|
|
|
- CTRL_BRAKE, false);
|
|
|
+ vehicle.controls.Set(CTRL_FORWARD | CTRL_BACK | CTRL_LEFT | CTRL_RIGHT | CTRL_BRAKE, false);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -256,23 +231,17 @@ HandlePostUpdate(StringHash eventType, VariantMap& eventData)
|
|
|
return;
|
|
|
// Physics update has completed. Position camera behind vehicle
|
|
|
Quaternion dir(vehicleNode.rotation.yaw, Vector3(0.0f, 1.0f, 0.0f));
|
|
|
- dir =
|
|
|
- dir * Quaternion(vehicle.controls.yaw, Vector3(0.0f, 1.0f, 0.0f));
|
|
|
- dir =
|
|
|
- dir * Quaternion(vehicle.controls.pitch, Vector3(1.0f, 0.0f, 0.0f));
|
|
|
- Vector3 cameraTargetPos =
|
|
|
- vehicleNode.position - dir * Vector3(0.0f, 0.0f, CAMERA_DISTANCE);
|
|
|
+ dir = dir * Quaternion(vehicle.controls.yaw, Vector3(0.0f, 1.0f, 0.0f));
|
|
|
+ dir = dir * Quaternion(vehicle.controls.pitch, Vector3(1.0f, 0.0f, 0.0f));
|
|
|
+ Vector3 cameraTargetPos = vehicleNode.position - dir * Vector3(0.0f, 0.0f, CAMERA_DISTANCE);
|
|
|
Vector3 cameraStartPos = vehicleNode.position;
|
|
|
// Raycast camera against static objects (physics collision mask 2)
|
|
|
// and move it closer to the vehicle if something in between
|
|
|
- Ray cameraRay(cameraStartPos,
|
|
|
- (cameraTargetPos - cameraStartPos).Normalized());
|
|
|
+ Ray cameraRay(cameraStartPos, (cameraTargetPos - cameraStartPos).Normalized());
|
|
|
float cameraRayLength = (cameraTargetPos - cameraStartPos).length;
|
|
|
- PhysicsRaycastResult result =
|
|
|
- scene_.physicsWorld.RaycastSingle(cameraRay, cameraRayLength, 2);
|
|
|
+ PhysicsRaycastResult result = scene_.physicsWorld.RaycastSingle(cameraRay, cameraRayLength, 2);
|
|
|
if (result.body !is null)
|
|
|
- cameraTargetPos =
|
|
|
- cameraStartPos + cameraRay.direction * (result.distance - 0.5f);
|
|
|
+ cameraTargetPos = cameraStartPos + cameraRay.direction * (result.distance - 0.5f);
|
|
|
cameraNode.position = cameraTargetPos;
|
|
|
cameraNode.rotation = dir;
|
|
|
}
|
|
|
@@ -289,40 +258,27 @@ class Vehicle:ScriptObject
|
|
|
|
|
|
RigidBody@ hullBody;
|
|
|
|
|
|
-
|
|
|
// Current left/right steering amount (-1 to 1.)
|
|
|
float steering = 0.0f;
|
|
|
|
|
|
// Vehicle controls.
|
|
|
Controls controls;
|
|
|
|
|
|
- float m_fsuspensionRestLength = 0.6f;
|
|
|
-
|
|
|
- float m_fsuspensionStiffness = 14.0f;
|
|
|
-
|
|
|
- float m_fsuspensionDamping = 2.0f;
|
|
|
-
|
|
|
- float m_fsuspensionCompression = 4.0f;
|
|
|
-
|
|
|
- float m_fwheelFriction = 1000.0f;
|
|
|
-
|
|
|
- float m_frollInfluence = 0.12f;
|
|
|
-
|
|
|
+ float suspensionRestLength = 0.6f;
|
|
|
+ float suspensionStiffness = 14.0f;
|
|
|
+ float suspensionDamping = 2.0f;
|
|
|
+ float suspensionCompression = 4.0f;
|
|
|
+ float wheelFriction = 1000.0f;
|
|
|
+ float rollInfluence = 0.12f;
|
|
|
float maxEngineForce = ENGINE_FORCE;
|
|
|
|
|
|
float wheelWidth = 0.4f;
|
|
|
-
|
|
|
float wheelRadius = 0.5f;
|
|
|
-
|
|
|
float brakingForce = 50.0f;
|
|
|
-
|
|
|
- Array < Vector3 > connectionPoints;
|
|
|
-
|
|
|
- Array < Node@ >particleEmitterNodeList;
|
|
|
-
|
|
|
+ Array<Vector3> connectionPoints;
|
|
|
+ Array<Node@> particleEmitterNodeList;
|
|
|
protected Vector3 prevVelocity;
|
|
|
|
|
|
-
|
|
|
void Load(Deserializer& deserializer)
|
|
|
{
|
|
|
controls.yaw = deserializer.ReadFloat();
|
|
|
@@ -343,16 +299,14 @@ class Vehicle:ScriptObject
|
|
|
CollisionShape@ hullShape = node.CreateComponent("CollisionShape");
|
|
|
node.scale = Vector3(2.3f, 1.0f, 4.0f);
|
|
|
hullObject.model = cache.GetResource("Model", "Models/Box.mdl");
|
|
|
- hullObject.material =
|
|
|
- cache.GetResource("Material", "Materials/Stone.xml");
|
|
|
+ hullObject.material = cache.GetResource("Material", "Materials/Stone.xml");
|
|
|
hullObject.castShadows = true;
|
|
|
hullShape.SetBox(Vector3(1.0f, 1.0f, 1.0f));
|
|
|
hullBody.mass = 800.0f;
|
|
|
hullBody.linearDamping = 0.2f; // Some air resistance
|
|
|
hullBody.angularDamping = 0.5f;
|
|
|
hullBody.collisionLayer = 1;
|
|
|
- RaycastVehicle@ raycastVehicle =
|
|
|
- node.CreateComponent("RaycastVehicle");
|
|
|
+ RaycastVehicle@ raycastVehicle = node.CreateComponent("RaycastVehicle");
|
|
|
raycastVehicle.Init();
|
|
|
connectionPoints.Reserve(4);
|
|
|
float connectionHeight = -0.4f; //1.2f;
|
|
|
@@ -361,21 +315,13 @@ class Vehicle:ScriptObject
|
|
|
Vector3 wheelAxle(-1, 0, 0);
|
|
|
float wheelX = CHASSIS_WIDTH / 2.0 - wheelWidth;
|
|
|
// Front left
|
|
|
- connectionPoints.Push(Vector3
|
|
|
- (-wheelX, connectionHeight,
|
|
|
- 2.5f - wheelRadius * 2.0f));
|
|
|
+ connectionPoints.Push(Vector3(-wheelX, connectionHeight, 2.5f - wheelRadius * 2.0f));
|
|
|
// Front right
|
|
|
- connectionPoints.Push(Vector3
|
|
|
- (wheelX, connectionHeight,
|
|
|
- 2.5f - wheelRadius * 2.0f));
|
|
|
+ connectionPoints.Push(Vector3(wheelX, connectionHeight, 2.5f - wheelRadius * 2.0f));
|
|
|
// Back left
|
|
|
- connectionPoints.Push(Vector3
|
|
|
- (-wheelX, connectionHeight,
|
|
|
- -2.5f + wheelRadius * 2.0f));
|
|
|
+ connectionPoints.Push(Vector3(-wheelX, connectionHeight, -2.5f + wheelRadius * 2.0f));
|
|
|
// Back right
|
|
|
- connectionPoints.Push(Vector3
|
|
|
- (wheelX, connectionHeight,
|
|
|
- -2.5f + wheelRadius * 2.0f));
|
|
|
+ connectionPoints.Push(Vector3(wheelX, connectionHeight, -2.5f + wheelRadius * 2.0f));
|
|
|
const Color LtBrown(0.972f, 0.780f, 0.412f);
|
|
|
for (int id = 0; id < connectionPoints.length; id++)
|
|
|
{
|
|
|
@@ -385,32 +331,18 @@ class Vehicle:ScriptObject
|
|
|
// back wheels are at z < 0
|
|
|
// Setting rotation according to wheel position
|
|
|
bool isFrontWheel = connectionPoints[id].z > 0.0f;
|
|
|
- wheelNode.rotation =
|
|
|
- (connectionPoint.x >=
|
|
|
- 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) : Quaternion(0.0f,
|
|
|
- 0.0f,
|
|
|
- 90.0f));
|
|
|
- wheelNode.worldPosition =
|
|
|
- (node.worldPosition +
|
|
|
- node.worldRotation * connectionPoints[id]);
|
|
|
+ wheelNode.rotation = (connectionPoint.x >= 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) : Quaternion(0.0f, 0.0f, 90.0f));
|
|
|
+ wheelNode.worldPosition = (node.worldPosition + node.worldRotation * connectionPoints[id]);
|
|
|
wheelNode.scale = Vector3(1.0f, 0.65f, 1.0f);
|
|
|
- raycastVehicle.AddWheel(wheelNode, wheelDirection, wheelAxle,
|
|
|
- m_fsuspensionRestLength, wheelRadius,
|
|
|
- isFrontWheel);
|
|
|
- raycastVehicle.SetWheelSuspensionStiffness(id,
|
|
|
- m_fsuspensionStiffness);
|
|
|
- raycastVehicle.SetWheelDampingRelaxation(id,
|
|
|
- m_fsuspensionDamping);
|
|
|
- raycastVehicle.SetWheelDampingCompression(id,
|
|
|
- m_fsuspensionCompression);
|
|
|
- raycastVehicle.SetWheelFrictionSlip(id, m_fwheelFriction);
|
|
|
- raycastVehicle.SetWheelRollInfluence(id, m_frollInfluence);
|
|
|
- StaticModel@ pWheel =
|
|
|
- wheelNode.CreateComponent("StaticModel");
|
|
|
- pWheel.model =
|
|
|
- cache.GetResource("Model", "Models/Cylinder.mdl");
|
|
|
- pWheel.material =
|
|
|
- cache.GetResource("Material", "Materials/Stone.xml");
|
|
|
+ raycastVehicle.AddWheel(wheelNode, wheelDirection, wheelAxle, suspensionRestLength, wheelRadius, isFrontWheel);
|
|
|
+ raycastVehicle.SetWheelSuspensionStiffness(id, suspensionStiffness);
|
|
|
+ raycastVehicle.SetWheelDampingRelaxation(id, suspensionDamping);
|
|
|
+ raycastVehicle.SetWheelDampingCompression(id, suspensionCompression);
|
|
|
+ raycastVehicle.SetWheelFrictionSlip(id, wheelFriction);
|
|
|
+ raycastVehicle.SetWheelRollInfluence(id, rollInfluence);
|
|
|
+ StaticModel@ pWheel = wheelNode.CreateComponent("StaticModel");
|
|
|
+ pWheel.model = cache.GetResource("Model", "Models/Cylinder.mdl");
|
|
|
+ pWheel.material = cache.GetResource("Material", "Materials/Stone.xml");
|
|
|
pWheel.castShadows = true;
|
|
|
}
|
|
|
CreateEmitters();
|
|
|
@@ -420,14 +352,9 @@ class Vehicle:ScriptObject
|
|
|
void CreateEmitter(Vector3 place)
|
|
|
{
|
|
|
Node@ emitter = scene_.CreateChild();
|
|
|
- emitter.worldPosition =
|
|
|
- node.worldPosition + node.worldRotation * place + Vector3(0,
|
|
|
- -wheelRadius,
|
|
|
- 0);
|
|
|
- ParticleEmitter@ particleEmitter =
|
|
|
- emitter.CreateComponent("ParticleEmitter");
|
|
|
- particleEmitter.effect =
|
|
|
- cache.GetResource("ParticleEffect", "Particle/Dust.xml");
|
|
|
+ emitter.worldPosition = node.worldPosition + node.worldRotation * place + Vector3(0, -wheelRadius, 0);
|
|
|
+ ParticleEmitter@ particleEmitter = emitter.CreateComponent("ParticleEmitter");
|
|
|
+ particleEmitter.effect = cache.GetResource("ParticleEffect", "Particle/Dust.xml");
|
|
|
particleEmitter.emitting = false;
|
|
|
particleEmitterNodeList.Push(emitter);
|
|
|
emitter.temporary = true;
|
|
|
@@ -436,12 +363,10 @@ class Vehicle:ScriptObject
|
|
|
void CreateEmitters()
|
|
|
{
|
|
|
particleEmitterNodeList.Clear();
|
|
|
- RaycastVehicle@ raycastVehicle =
|
|
|
- node.GetComponent("RaycastVehicle");
|
|
|
+ RaycastVehicle@ raycastVehicle = node.GetComponent("RaycastVehicle");
|
|
|
for (int id = 0; id < raycastVehicle.numWheels; id++)
|
|
|
{
|
|
|
- Vector3 connectionPoint =
|
|
|
- raycastVehicle.GetWheelConnectionPoint(id);
|
|
|
+ Vector3 connectionPoint = raycastVehicle.GetWheelConnectionPoint(id);
|
|
|
CreateEmitter(connectionPoint);
|
|
|
}
|
|
|
}
|
|
|
@@ -451,8 +376,7 @@ class Vehicle:ScriptObject
|
|
|
float newSteering = 0.0f;
|
|
|
float accelerator = 0.0f;
|
|
|
bool brake = false;
|
|
|
- RaycastVehicle@ raycastVehicle =
|
|
|
- node.GetComponent("RaycastVehicle");
|
|
|
+ RaycastVehicle@ raycastVehicle = node.GetComponent("RaycastVehicle");
|
|
|
if (controls.IsDown(CTRL_LEFT))
|
|
|
newSteering = -1.0f;
|
|
|
if (controls.IsDown(CTRL_RIGHT))
|
|
|
@@ -476,6 +400,7 @@ class Vehicle:ScriptObject
|
|
|
raycastVehicle.SetEngineForce(2, maxEngineForce * accelerator);
|
|
|
raycastVehicle.SetEngineForce(3, maxEngineForce * accelerator);
|
|
|
for (int i = 0; i < raycastVehicle.numWheels; i++)
|
|
|
+ {
|
|
|
if (brake)
|
|
|
{
|
|
|
raycastVehicle.SetBrake(i, brakingForce);
|
|
|
@@ -484,21 +409,17 @@ class Vehicle:ScriptObject
|
|
|
{
|
|
|
raycastVehicle.SetBrake(i, 0.0f);
|
|
|
}
|
|
|
+ }
|
|
|
// Apply downforce proportional to velocity
|
|
|
- Vector3 localVelocity =
|
|
|
- hullBody.rotation.Inverse() * hullBody.linearVelocity;
|
|
|
- hullBody.ApplyForce(hullBody.rotation *
|
|
|
- Vector3(0.0f, -1.0f,
|
|
|
- 0.0f) * Abs(localVelocity.z) *
|
|
|
- DOWN_FORCE);
|
|
|
+ Vector3 localVelocity = hullBody.rotation.Inverse() * hullBody.linearVelocity;
|
|
|
+ hullBody.ApplyForce(hullBody.rotation * Vector3(0.0f, -1.0f, 0.0f) * Abs(localVelocity.z) * DOWN_FORCE);
|
|
|
}
|
|
|
|
|
|
void PostUpdate(float timeStep)
|
|
|
{
|
|
|
if (particleEmitterNodeList.length == 0)
|
|
|
return;
|
|
|
- RaycastVehicle@ raycastVehicle =
|
|
|
- node.GetComponent("RaycastVehicle");
|
|
|
+ RaycastVehicle@ raycastVehicle = node.GetComponent("RaycastVehicle");
|
|
|
RigidBody@ vehicleBody = node.GetComponent("RigidBody");
|
|
|
Vector3 velocity = hullBody.linearVelocity;
|
|
|
Vector3 accel = (velocity - prevVelocity) / timeStep;
|
|
|
@@ -506,18 +427,11 @@ class Vehicle:ScriptObject
|
|
|
for (int i = 0; i < raycastVehicle.numWheels; i++)
|
|
|
{
|
|
|
Node@ emitter = particleEmitterNodeList[i];
|
|
|
- ParticleEmitter@ particleEmitter =
|
|
|
- emitter.GetComponent("ParticleEmitter");
|
|
|
- if (raycastVehicle.WheelIsGrounded(i)
|
|
|
- && (
|
|
|
- raycastVehicle.GetWheelSkidInfoCumulative(i) < 0.9f
|
|
|
- ||
|
|
|
- raycastVehicle.GetBrake(i) > 2.0f
|
|
|
- ||
|
|
|
- planeAccel > 15.0f))
|
|
|
+ ParticleEmitter@ particleEmitter = emitter.GetComponent("ParticleEmitter");
|
|
|
+ if (raycastVehicle.WheelIsGrounded(i) && (raycastVehicle.GetWheelSkidInfoCumulative(i) < 0.9f || raycastVehicle.GetBrake(i) > 2.0f ||
|
|
|
+ planeAccel > 15.0f))
|
|
|
{
|
|
|
- emitter.worldPosition =
|
|
|
- raycastVehicle.GetContactPosition(i);
|
|
|
+ emitter.worldPosition = raycastVehicle.GetContactPosition(i);
|
|
|
if (!particleEmitter.emitting)
|
|
|
particleEmitter.emitting = true;
|
|
|
}
|
|
|
@@ -528,7 +442,6 @@ class Vehicle:ScriptObject
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// Create XML patch instructions for screen joystick layout specific to this sample app
|
|
|
String patchInstructions = "";
|
|
|
|