void CastFX(EarthFX.EarthFXData FX, RaycastHit SurfaceHitPoint) { /// BRAKE SKIDS if (FX.BrakeSkid != null && Mathf.Abs(this.slipRatio) > FX.BrakeSkidStartSlip) { Skids = FX.BrakeSkid.GetComponent(typeof(RGKCar_Skidmarks)) as RGKCar_Skidmarks; lastSkid = Skids.AddSkidMark(SurfaceHitPoint.point, SurfaceHitPoint.normal, Mathf.Abs(slipRatio), lastSkid); if (FX.BrakeSmoke != null) { SkidSmoke = FX.BrakeSmoke.GetComponent(typeof(ParticleEmitter)) as ParticleEmitter; SkidSmoke.Emit( SurfaceHitPoint.point + new Vector3(UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f)), //pos new Vector3(this.slipVelo * 0.05f, 0), //vel UnityEngine.Random.Range(SkidSmoke.minSize, SkidSmoke.maxSize) * Mathf.Clamp(0.5f, 1f, 1.5f), //size UnityEngine.Random.Range(SkidSmoke.minEnergy, SkidSmoke.maxEnergy), //energy Color.white); } } else { lastSkid = -1; } ///TRAIL SMOKE if (FX.TrailSmoke != null && Mathf.Abs(angularVelocity) > FX.TrailSmokeStartVelocity) { TrailSmoke = FX.TrailSmoke.GetComponent(typeof(ParticleEmitter)) as ParticleEmitter; TrailSmoke.Emit( SurfaceHitPoint.point + new Vector3(UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f)), new Vector3(this.slipVelo * 0.05f, 1), UnityEngine.Random.Range(TrailSmoke.minSize, TrailSmoke.maxSize) * Mathf.Clamp(0.5f, 1f, 1.5f), UnityEngine.Random.Range(TrailSmoke.minEnergy, TrailSmoke.maxEnergy), Color.white); } ///TRAIL SKIDS if (FX.TrailSkid != null && Math.Abs(angularVelocity) > 5) { Trails = FX.TrailSkid.GetComponent(typeof(RGKCar_Skidmarks)) as RGKCar_Skidmarks; lastTrail = Trails.AddSkidMark(SurfaceHitPoint.point, SurfaceHitPoint.normal, Mathf.Abs(1) - 0.2f, lastTrail); } else { lastTrail = -1; } ///SPLATTERS if (FX.Splatter != null && Math.Abs(angularVelocity) > 5 && !surfaceChanged) { Splatter = FX.Splatter.GetComponent(typeof(ParticleEmitter)) as ParticleEmitter; Splatter.Emit( SurfaceHitPoint.point + new Vector3(UnityEngine.Random.Range(-0.2f, 0.2f), UnityEngine.Random.Range(-0.1f, 0.2f), UnityEngine.Random.Range(-0.1f, 0.1f)), new Vector3(this.slipVelo * 0.05f, 0), UnityEngine.Random.Range(Splatter.minSize, Splatter.maxSize), UnityEngine.Random.Range(Splatter.minEnergy, Splatter.maxEnergy), Color.white); } ///DRIVE SOUND if (FX.SurfaceDriveSound != null) { SurfaceSound = FX.SurfaceDriveSound; } else { SurfaceSound = null; } ///BRAKE SOUND if (FX.BrakeSound != null) { BrakeSound = FX.BrakeSound; } else { BrakeSound = null; } ///FORWARDGRIP LOSE PERCENT if (FX.ForwardGripLosePercent > 0) { wheelGrip = definedGrip - (definedGrip * (FX.ForwardGripLosePercent / 100f)); } else { wheelGrip = definedGrip; } ///SIDEGRIP LOSE PERCENT if (FX.SidewaysGripLosePercent > 0) { sideGrip = definedSideGrip - (definedSideGrip * (FX.SidewaysGripLosePercent / 100f)); } else { sideGrip = definedSideGrip; } ///DRAG SurfaceAngularDrag = FX.AngularDrag; SurfaceForwardDrag = FX.ForwardDrag; }
void FixedUpdate() { if (!UseEarthFX || EarthFX == null) { wheelGrip = definedGrip; sideGrip = definedSideGrip; } if (suspensionHeight < 0.05f) { suspensionHeight = 0.05f; } suspensionLineRenderer.enabled = ShowForces; Vector3 pos = transform.position; up = transform.up; RaycastHit hit; onGround = Physics.Raycast(pos, -up, out hit, suspensionHeight + radius); if (onGround && hit.collider.isTrigger) { onGround = false; float dist = suspensionHeight + radius; RaycastHit[] hits = Physics.RaycastAll(pos, -up, suspensionHeight + radius); foreach (RaycastHit test in hits) { if (!test.collider.isTrigger && test.distance <= dist) { hit = test; onGround = true; dist = test.distance; } } } fullCompressionSpringForce = body.mass * massFraction * 2.0f * -Physics.gravity.y; float staticFrictionForce = wheelGrip * fullCompressionSpringForce; float latGravityForce = fullCompressionSpringForce * Mathf.Cos(Vector3.Angle(right, Vector3.up) * Mathf.Deg2Rad); if (latGravityForce < staticFrictionForce) { body.AddForceAtPosition(latGravityForce * -right, WheelModel.transform.position); } if (onGround) { groundNormal = transform.InverseTransformDirection(inverseLocalRotation * hit.normal); compression = 1.0f - ((hit.distance - radius) / suspensionHeight); suspensionForce = SuspensionForce(); suspensionLineRenderer.SetPosition(1, new Vector3(0, 0.0005f * suspensionForce.y, 0)); if (slipVelo < 30) { wheelVelo = body.GetPointVelocity(pos); localVelo = transform.InverseTransformDirection(inverseLocalRotation * wheelVelo); roadForce = RoadForce(); body.AddForceAtPosition(suspensionForce + roadForce, pos); } else { angularVelocity = 0; slipVelo = 0; } } else { if (slipVelo < 10) { float totalInertia = inertia + drivetrainInertia; float angularDelta = Time.deltaTime * invSlipRes / totalInertia; float driveAngularDelta = driveTorque * angularDelta; float totalFrictionTorque = brakeTorque * brake + handbrakeTorque * handbrake + frictionTorque + driveFrictionTorque; float frictionAngularDelta = totalFrictionTorque * angularDelta; angularVelocity += driveAngularDelta; if (Mathf.Abs(angularVelocity) > frictionAngularDelta) { angularVelocity -= frictionAngularDelta * Mathf.Sign(angularVelocity); } else { angularVelocity = 0; } } else { //compression = 0.0f; //suspensionForce = Vector3.zero; //roadForce = Vector3.zero; //angularVelocity = 0; //slipRatio = 0; //slipVelo = 0; } } if (onGround && UseEarthFX && EarthFX != null) { Texture2D hitTexture = null; string strTerrainName = ""; if (Terrain.activeTerrain != null) { strTerrainName = Terrain.activeTerrain.name; } if (hit.collider.gameObject.name == strTerrainName) // means hititng terrain { int TextureIndex = SurfaceTextureDedector.GetMainTexture(WheelModel.transform.position); hitTexture = Terrain.activeTerrain.terrainData.splatPrototypes[TextureIndex].texture; } else { if (hit.collider.gameObject.renderer != null) { if (hit.collider.gameObject.renderer.material.mainTexture != null) { hitTexture = (hit.collider.gameObject.renderer.material.mainTexture) as Texture2D; } } } if (hitTexture != null) { if (previousSurface != hitTexture.name) { previousSurface = hitTexture.name; surfaceChanged = true; lastSkid = -1; } } bool FXFound = false; foreach (EarthFX.EarthFXData FX in EarthFX.SurfaceFX) { if (FX.FxTexture == hitTexture) { FXFound = true; CastFX(FX, hit); } if (!FXFound) { CastFX(EarthFX.GlobalFX, hit); } } if (EarthFX.SurfaceFX.Count == 0) { CastFX(EarthFX.GlobalFX, hit); } if (surfaceChanged) { surfaceChanged = false; } } else if (onGround && this.Skids != null && Mathf.Abs(this.slipRatio) > 0.15) { lastSkid = Skids.AddSkidMark(hit.point, hit.normal, Mathf.Abs(slipRatio) - 0f, lastSkid); if (this.SkidSmoke != null) { this.SkidSmoke.Emit( hit.point + new Vector3(UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f), UnityEngine.Random.Range(-0.1f, 0.1f)), new Vector3(this.slipVelo * 0.05f, 0), UnityEngine.Random.Range(SkidSmoke.minSize, SkidSmoke.maxSize) * Mathf.Clamp(0.5f, 1f, 1.5f), UnityEngine.Random.Range(SkidSmoke.minEnergy, SkidSmoke.maxEnergy), Color.white); } } else { lastSkid = -1; lastTrail = -1; } compression = Mathf.Clamp01(compression); rotation += angularVelocity * Time.deltaTime; UpdateModels(); }