Exemple #1
0
    //根据motorInput和steerInput为车轮碰撞器添加力矩
    private void CalculateSingleWheelMotorTorque(float motorInput, float steerInput, BaseTrackData trackData, WheelCollider wheelCollider, float wheelSpeedKMPH)
    {
        AnimationCurve singleWheelMotorAnimationCurve = wheelFeaturesAnimationCurves.singleWheelMotorAnimationCurve;

        float direction = 0.0f;

        if (trackData is LeftTrackData)
        {
            direction = 1.0f;
        }
        else
        {
            direction = -1.0f;
        }

        if (motorInput == 0.0f && steerInput == 0.0f)
        {
            wheelCollider.motorTorque = 0.0f;
        }
        else if (motorInput == 0.0f && steerInput != 0.0f)
        {
            wheelCollider.motorTorque = steerInput * direction * singleWheelMotorAnimationCurve.Evaluate(wheelSpeedKMPH);;
        }
        else if (motorInput != 0.0f && steerInput == 0.0f)
        {
            wheelCollider.motorTorque = motorInput * singleWheelMotorAnimationCurve.Evaluate(wheelSpeedKMPH);
        }
        else //if (motorInput != 0.0f && steerInput != 0.0f)
        {
            wheelCollider.motorTorque = motorInput * singleWheelMotorAnimationCurve.Evaluate(wheelSpeedKMPH);
        }
    }
Exemple #2
0
    //更新履带控制,
    private float UpdateTrackController(float motorInput, float steerInput, BaseTrackData trackData)
    {
        //总转向扭矩在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;

        #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));


            CalculateSingleWheelMotorTorque(motorInput, steerInput, trackData, wheelCollider, wheelSpeedKMPH);

            CalculateSingleWheelBrakeTorque(motorInput, steerInput, wheelCollider, wheelSpeedKMPH);


            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);
    }
Exemple #3
0
    //判断坦克履带数据是否设置正确
    public bool CheckIfTrackDataSettingIsCorrect(BaseTrackData trackData)
    {
        string trackDataName = string.Empty;

        //判断trackData是LeftTrackData还是RightTrackData
        if (trackData is LeftTrackData)
        {
            trackDataName = "LeftTrackData";
        }
        else
        {
            trackDataName = "RightTrackData";
        }

        //创建用于存储内部数据的对象
        UpperWheelData[] upperWheelArray = trackData.upperWheelDataArray;

        SuspendedWheelData[] suspendedWheelDataArray = trackData.suspendedWheelDataArray;

        SkinnedMeshRenderer trackRender = trackData.trackSkinnedMeshRenderer;

        //遍历数组,如果为完全设置正确,返回false
        for (int i = 0; i < upperWheelArray.Length; i++)
        {
            UpperWheelData upperWheelData = upperWheelArray[i];

            Transform wheelTransform = upperWheelData.wheelTransform;

            if (wheelTransform == null)
            {
                string message = string.Format("You are not set {0}-> UpperWheelData0{1} -> Wheel Model !", trackDataName, i);

                EditorUtility.DisplayDialog("Track Simulator", message, "OK");

                return(false);
            }
        }

        for (int i = 0; i < suspendedWheelDataArray.Length; i++)
        {
            SuspendedWheelData suspendedWheelData = suspendedWheelDataArray[i];

            Transform wheelTransform = suspendedWheelData.wheelTransform;

            Transform wheelBoneTransform = suspendedWheelData.wheelBoneTransform;

            WheelCollider wheelCollider = suspendedWheelData.wheelCollider;

            if (wheelTransform == null)
            {
                string message = string.Format("You are not set {0} -> SuspendedWheelData0{1} -> Wheel Model !", trackDataName, i);

                EditorUtility.DisplayDialog("Track Simulator", message, "OK");

                return(false);
            }

            if (wheelBoneTransform == null)
            {
                string message = string.Format("You are not set {0} -> SuspendedWheelData0{1} -> Wheel Bone !", trackDataName, i);

                EditorUtility.DisplayDialog("Track Simulator", message, "OK");

                return(false);
            }

            if (wheelCollider == null)
            {
                string message = string.Format("You are not set {0} -> suspendedWheelData0{1} -> Wheel Collider !", trackDataName, i);

                EditorUtility.DisplayDialog("Track Simulator", message, "OK");

                return(false);
            }
        }

        if (trackRender == null)
        {
            string message = string.Format("You are not set {0} -> Track SkinnedMeshRenderer !", trackDataName);

            EditorUtility.DisplayDialog("Track Simulator", message, "OK");

            return(false);
        }

        return(true);
    }