public void UpdateMove(float motorInput, float steerInput, AutoCruiseState autoCruiseState) { float leftTrackSteerTorqueYValue = UpdateTrackController(motorInput, steerInput, leftTrackData, autoCruiseState); float rightTrackSteerTorqueYValue = UpdateTrackController(motorInput, steerInput, rightTrackData, autoCruiseState); float totalSteerTorqueYValue = leftTrackSteerTorqueYValue + rightTrackSteerTorqueYValue; //车辆旋转 if (Mathf.Abs(m_Rigidbody.angularVelocity.y) < 1.0f) { if (CheckIfMoveBackward(motorInput) == false) { m_Rigidbody.AddRelativeTorque(0.0f, totalSteerTorqueYValue, 0.0f, ForceMode.Acceleration); } else { m_Rigidbody.AddRelativeTorque(0.0f, -totalSteerTorqueYValue, 0.0f, ForceMode.Acceleration); } } }
//为车轮碰撞器添加阻力矩(自动巡航) private void AutoCruiseSingleWheelBrakeTorque(WheelCollider wheelCollider, float wheelSpeedKMPH, AutoCruiseState autoCruiseState) { AnimationCurve autoCruiseSingleWheelBrakeAnimationCurve = autoCruiseAnimationCurves.moveForwardByFristGearBrakeAnimationCurve; if (autoCruiseState.state == AutoCruiseState.moveForwardByFristGear) { autoCruiseSingleWheelBrakeAnimationCurve = autoCruiseAnimationCurves.moveForwardByFristGearBrakeAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.moveForwardBySecondGear) { autoCruiseSingleWheelBrakeAnimationCurve = autoCruiseAnimationCurves.moveForwardBySecondGearBrakeAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.moveForwardByThirdGear) { autoCruiseSingleWheelBrakeAnimationCurve = autoCruiseAnimationCurves.moveForwardByThirdGearBrakeAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.backUpByFristGear) { autoCruiseSingleWheelBrakeAnimationCurve = autoCruiseAnimationCurves.backUpByFristGearBrakeAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.backUpBySecondGear) { autoCruiseSingleWheelBrakeAnimationCurve = autoCruiseAnimationCurves.backUpBySecondGearBrakeAnimationCurve; } if (wheelCollider.rpm > 0.0f && autoCruiseState.state < AutoCruiseState.close) { wheelCollider.brakeTorque = autoCruiseSingleWheelBrakeAnimationCurve.Evaluate(wheelSpeedKMPH); } else if (wheelCollider.rpm < 0.0f && autoCruiseState.state > AutoCruiseState.close) { wheelCollider.brakeTorque = autoCruiseSingleWheelBrakeAnimationCurve.Evaluate(wheelSpeedKMPH); } else { wheelCollider.brakeTorque = 0.0f; } }
//为车轮碰撞器添加力矩(自动巡航) private void AutoCruiseSingleWheelMotorTorque(WheelCollider wheelCollider, float wheelSpeedKMPH, AutoCruiseState autoCruiseState) { int direction = 0; AnimationCurve autoCruiseSingleWheelMotorAnimationCurve = autoCruiseAnimationCurves.moveForwardByFristGearMotorAnimationCurve; if (autoCruiseState.state == AutoCruiseState.moveForwardByFristGear) { autoCruiseSingleWheelMotorAnimationCurve = autoCruiseAnimationCurves.moveForwardByFristGearMotorAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.moveForwardBySecondGear) { autoCruiseSingleWheelMotorAnimationCurve = autoCruiseAnimationCurves.moveForwardBySecondGearMotorAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.moveForwardByThirdGear) { autoCruiseSingleWheelMotorAnimationCurve = autoCruiseAnimationCurves.moveForwardByThirdGearMotorAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.backUpByFristGear) { autoCruiseSingleWheelMotorAnimationCurve = autoCruiseAnimationCurves.backUpByFristGearMotorAnimationCurve; } else if (autoCruiseState.state == AutoCruiseState.backUpBySecondGear) { autoCruiseSingleWheelMotorAnimationCurve = autoCruiseAnimationCurves.backUpBySecondGearMotorAnimationCurve; } if (autoCruiseState.state > AutoCruiseState.close) { direction = 1; } else if (autoCruiseState.state < AutoCruiseState.close) { direction = -1; } wheelCollider.motorTorque = direction * autoCruiseSingleWheelMotorAnimationCurve.Evaluate(wheelSpeedKMPH); }
//更新履带控制, private float UpdateTrackController(float motorInput, float steerInput, BaseTrackData trackData, AutoCruiseState autoCruiseState) { //总转向扭矩在Y轴上的值 float totalWheelSteerTorqueYValue = 0.0f; //准备工作,用于定义各种实例 #region Prepare UpperWheelData[] upperWheelArray = trackData.upperWheelDataArray; SuspendedWheelData[] suspendedWheelDataArray = trackData.suspendedWheelDataArray; SkinnedMeshRenderer trackRender = trackData.trackSkinnedMeshRenderer; WheelAndBoneTransformOffsetDirection wheelAndBoneTransformOffsetDirection = adjustParameters.wheelAndBoneTransformOffsetDirection; bool inverseWheelAndBoneTransformOffsetDirection = adjustParameters.inverseWheelAndBoneTransformOffsetDirection; float singleWheelAndBoneTransfromVerticalOffset = adjustParameters.singleWheelAndBoneTransfromVerticalOffset; WheelRotateAxis wheelRotateAxis = adjustParameters.wheelRotateAxis; bool inverseWheelRotateDirection = adjustParameters.inverseWheelRotateDirection; TrackTextureOffsetType trackTextureOffsetType = adjustParameters.trackTextureOffsetType; bool inverseTrackTextureOffsetDirection = adjustParameters.inverseTrackTextureOffsetDirection; float singleTrackTextureOffsetSpeedMultiplier = adjustParameters.singleTrackTextureOffsetSpeedMultiplier; float inverseWheelAndBoneTransformOffsetDirectionFlag = 0.0f; //根据inverseWheelAndBoneTransformOffsetDirection,指定inverseWheelAndBoneTransformOffsetDirectionFlag的值(作为车轮模型和bone位移的乘数) if (inverseWheelAndBoneTransformOffsetDirection == true) { inverseWheelAndBoneTransformOffsetDirectionFlag = -1.0f; } else { inverseWheelAndBoneTransformOffsetDirectionFlag = 1.0f; } //车轮模型旋转方向乘数 float inverseWheelRotateDirectionFlag = 0.0f; if (inverseWheelRotateDirection == true) { inverseWheelRotateDirectionFlag = -1.0f; } else { inverseWheelRotateDirectionFlag = 1.0f; } //履带贴图偏移方向乘数 float inverseTrackTextureOffsetDirectionFlag = 0.0f; if (inverseTrackTextureOffsetDirection == true) { inverseTrackTextureOffsetDirectionFlag = -1.0f; } else { inverseTrackTextureOffsetDirectionFlag = 1.0f; } //车轮平均每分钟旋转次数 float wheelAverageSpeedRpm = CalculateWheelsAverageRPM(suspendedWheelDataArray); //车轮平均每分钟旋转度数(Time.fixedDeltaTime作为乘数) float wheelAverageSpeedDegreePerSecond = Time.fixedDeltaTime * wheelAverageSpeedRpm * 360.0f / 60.0f;/*60f*/ #endregion //上车轮模型数组处理 #region Handle UpperWheelArray for (int i = 0; i < upperWheelArray.Length; i++) { UpperWheelData upperWheelData = upperWheelArray[i]; Transform wheelTransform = upperWheelData.wheelTransform; if (wheelRotateAxis == WheelRotateAxis.X) { wheelTransform.rotation = wheelTransform.rotation * Quaternion.Euler(inverseWheelRotateDirectionFlag * wheelAverageSpeedDegreePerSecond, 0.0f, 0.0f); } else if (wheelRotateAxis == WheelRotateAxis.Y) { wheelTransform.rotation = wheelTransform.rotation * Quaternion.Euler(0.0f, inverseWheelRotateDirectionFlag * wheelAverageSpeedDegreePerSecond, 0.0f); } else //(wheelRotateAxis == WheelRotateAxis.Z) { wheelTransform.rotation = wheelTransform.rotation * Quaternion.Euler(0.0f, 0.0f, inverseWheelRotateDirectionFlag * wheelAverageSpeedDegreePerSecond); } } #endregion //下车轮数据数组处理 #region Handle SuspendedWheelDataArray for (int i = 0; i < suspendedWheelDataArray.Length; i++) { SuspendedWheelData suspendedWheelData = suspendedWheelDataArray[i]; WheelCollider wheelCollider = suspendedWheelData.wheelCollider; wheelCollider.wheelDampingRate = Mathf.Lerp(100.0f, 0.0f, Mathf.Abs(motorInput)); //移动目标位置 Vector3 wheelTranformTargetPosition = Vector3.zero; Quaternion wheelTransfromTargetRotation = Quaternion.identity; //获取车轮碰撞器的世界坐标位置与旋转 wheelCollider.GetWorldPose(out wheelTranformTargetPosition, out wheelTransfromTargetRotation); //车轮碰撞器竖值方向 Vector3 wheelColliderVerticalDirection = Vector3.zero; if (wheelAndBoneTransformOffsetDirection == WheelAndBoneTransformOffsetDirection.X) { wheelColliderVerticalDirection = wheelCollider.transform.right * inverseWheelAndBoneTransformOffsetDirectionFlag; } else if (wheelAndBoneTransformOffsetDirection == WheelAndBoneTransformOffsetDirection.Y) { wheelColliderVerticalDirection = wheelCollider.transform.up * inverseWheelAndBoneTransformOffsetDirectionFlag; } else //wheelAndBoneTransformOffsetDirection == WheelAndBoneTransformOffsetDirection.Z { wheelColliderVerticalDirection = wheelCollider.transform.forward * inverseWheelAndBoneTransformOffsetDirectionFlag; } //由于履带存在厚度,骨架与车轮模型需在竖直方向上偏移 Transform wheelBoneTransform = suspendedWheelData.wheelBoneTransform; Vector3 wheelBoneTransformVerticalOffset = wheelColliderVerticalDirection * singleWheelAndBoneTransfromVerticalOffset; wheelBoneTransform.position = wheelTranformTargetPosition + wheelBoneTransformVerticalOffset; Transform wheelTransform = suspendedWheelData.wheelTransform; Vector3 wheelTranformVerticalOffset = wheelColliderVerticalDirection * singleWheelAndBoneTransfromVerticalOffset; wheelTransform.position = wheelTranformTargetPosition + wheelTranformVerticalOffset; //根据旋转轴和每分钟旋转度数控制车轮模型旋转 if (wheelRotateAxis == WheelRotateAxis.X) { wheelTransform.rotation = wheelTransform.rotation * Quaternion.Euler(inverseWheelRotateDirectionFlag * wheelAverageSpeedDegreePerSecond, 0.0f, 0.0f); } else if (wheelRotateAxis == WheelRotateAxis.Y) { wheelTransform.rotation = wheelTransform.rotation * Quaternion.Euler(0.0f, inverseWheelRotateDirectionFlag * wheelAverageSpeedDegreePerSecond, 0.0f); } else //wheelRotateAxis == WheelRotateAxis.Z { wheelTransform.rotation = wheelTransform.rotation * Quaternion.Euler(0.0f, 0.0f, inverseWheelRotateDirectionFlag * wheelAverageSpeedDegreePerSecond); } //根据车轮碰撞器的半径和转速计算出车轮的速度 float wheelSpeedKMPH = Mathf.Abs(ConvertSingleWheelRPMToKMPH(wheelCollider.radius, wheelCollider.rpm)); //Debug.Log(wheelSpeedKMPH / 0.5); if (autoCruiseState.state == AutoCruiseState.close) { CalculateSingleWheelMotorTorque(motorInput, steerInput, trackData, wheelCollider, wheelSpeedKMPH); CalculateSingleWheelBrakeTorque(motorInput, steerInput, wheelCollider, wheelSpeedKMPH); } else { AutoCruiseSingleWheelMotorTorque(wheelCollider, wheelSpeedKMPH, autoCruiseState); AutoCruiseSingleWheelBrakeTorque(wheelCollider, wheelSpeedKMPH, autoCruiseState); } float singleWheelSteerTorqueYValue = CalculateSingleWheelSteerTorqueYValue(motorInput, steerInput, wheelCollider, wheelSpeedKMPH); totalWheelSteerTorqueYValue = totalWheelSteerTorqueYValue + singleWheelSteerTorqueYValue; } #endregion //履带贴图偏移处理 #region Handle TrackSkinnedMeshRenderer Vector2 trackMainTextureOffset = trackRender.material.GetTextureOffset("_MainTex"); Vector2 trackBumpMapOffset = trackRender.material.GetTextureOffset("_BumpMap"); if (trackTextureOffsetType == TrackTextureOffsetType.X) { trackMainTextureOffset.x = Mathf.Repeat(trackMainTextureOffset.x + (inverseTrackTextureOffsetDirectionFlag * wheelAverageSpeedDegreePerSecond * singleTrackTextureOffsetSpeedMultiplier) / 360.0f, 1.0f); trackBumpMapOffset.x = Mathf.Repeat(trackBumpMapOffset.x + (inverseTrackTextureOffsetDirectionFlag * wheelAverageSpeedDegreePerSecond * singleTrackTextureOffsetSpeedMultiplier) / 360.0f, 1.0f); } else { trackMainTextureOffset.y = Mathf.Repeat(trackMainTextureOffset.y + (inverseTrackTextureOffsetDirectionFlag * wheelAverageSpeedDegreePerSecond * singleTrackTextureOffsetSpeedMultiplier) / 360.0f, 1.0f); trackBumpMapOffset.y = Mathf.Repeat(trackBumpMapOffset.y + (inverseTrackTextureOffsetDirectionFlag * wheelAverageSpeedDegreePerSecond * singleTrackTextureOffsetSpeedMultiplier) / 360.0f, 1.0f); } trackRender.material.SetTextureOffset("_MainTex", trackMainTextureOffset); trackRender.material.SetTextureOffset("_BumpMap", trackBumpMapOffset); #endregion return(totalWheelSteerTorqueYValue); }
void Awake() { m_TrackSimulator = GetComponent <TrackSimulator>(); autoCruiseState = new AutoCruiseState(); }