Переработал скрипт, чтобы понять его, но сейчас у меня ошибка, которую я не могу решить - PullRequest
0 голосов
/ 24 сентября 2019

Я пытался создать активную тряпичную куклу, когда натолкнулся на скрипт, который создал пользователь Youtube MetalCore999 (первый скрипт ниже).Я попытался реорганизовать этот код, чтобы понять, что он сделал, чтобы сделать эту работу, и в конечном итоге сам улучшить ее, однако я наткнулся на кирпичную стену и, похоже, не могу понять, что я делаю неправильно.

Проблема, с которой я сталкиваюсь, заключается в том, что в оригинальном сценарии MetalCore999 персонаж встает сам по себе, когда нет ввода, однако в моей версии сценария персонаж решает просто сесть на корточки.

Я попытался прочитать каждый элемент и проверить, есть ли какой-то фрагмент кода, который не вызывается должным образом, но я не могу до конца жизни выяснить, где находится эта ошибка.

Вот оригинальный сценарий от MetalCore999:

   using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Example : MonoBehaviour
{
    public GameObject[] PlayerParts;
    public ConfigurableJoint[] JointParts;
    Vector3 COM;
    public float TouchForce, TimeStep, LegsHeight, FallFactor;
    float Step_R_Time, Step_L_Time;
    public bool StepR, StepL,  WalkF, WalkB, Falling, Fall, StandUp;
    bool flag, Flag_Leg_R, Flag_Leg_L;
    Quaternion StartLegR1, StartLegR2, StartLegL1, StartLegL2;
    JointDrive Spring0, Spring150, Spring300, Spring320;

    private void Awake()
    {
        Physics.IgnoreCollision(PlayerParts[2].GetComponent<Collider>(), PlayerParts[4].GetComponent<Collider>(), true);
        Physics.IgnoreCollision(PlayerParts[3].GetComponent<Collider>(), PlayerParts[7].GetComponent<Collider>(), true);
        StartLegR1 = PlayerParts[4].GetComponent<ConfigurableJoint>().targetRotation;
        StartLegR2 = PlayerParts[5].GetComponent<ConfigurableJoint>().targetRotation;
        StartLegL1 = PlayerParts[7].GetComponent<ConfigurableJoint>().targetRotation;
        StartLegL2 = PlayerParts[8].GetComponent<ConfigurableJoint>().targetRotation;

        Spring0 = new JointDrive();
        Spring0.positionSpring = 0;
        Spring0.positionDamper = 0;
        Spring0.maximumForce = Mathf.Infinity;

        Spring150 = new JointDrive();
        Spring150.positionSpring = 150;
        Spring150.positionDamper = 0;
        Spring150.maximumForce = Mathf.Infinity;

        Spring300 = new JointDrive();
        Spring300.positionSpring = 300;
        Spring300.positionDamper = 100;
        Spring300.maximumForce = Mathf.Infinity;

        Spring320 = new JointDrive();
        Spring320.positionSpring = 320;
        Spring320.positionDamper = 0;
        Spring320.maximumForce = Mathf.Infinity;
    }

    private void Update()
    {
        PlayerParts[12].transform.position = Vector3.Lerp(PlayerParts[12].transform.position, PlayerParts[2].transform.position, 2 * Time.unscaledDeltaTime);

        #region Input
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            PlayerParts[0].GetComponent<Rigidbody>().AddForce(Vector3.back * TouchForce, ForceMode.Impulse);
        }
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            PlayerParts[0].GetComponent<Rigidbody>().AddForce(Vector3.forward * TouchForce, ForceMode.Impulse);
        }

        if (Input.GetKeyDown(KeyCode.Space))
            Application.LoadLevel(Application.loadedLevel);

        if (Input.GetKeyDown(KeyCode.S))
        {
            if (Time.timeScale == 1)
                Time.timeScale = 0.4f;
            else
                Time.timeScale = 1;
        }

        #endregion

        Calculate_COM();

        PlayerParts[10].transform.position = COM;

        Balance();

        PlayerParts[11].transform.LookAt(PlayerParts[10].transform.position);

        if (!WalkF && !WalkB)
        {
            StepR = false;
            StepL = false;
            Step_R_Time = 0;
            Step_L_Time = 0;
            Flag_Leg_R = false;
            Flag_Leg_L = false;
            JointParts[0].targetRotation = Quaternion.Lerp(JointParts[0].targetRotation, new Quaternion(-0.1f, JointParts[0].targetRotation.y, JointParts[0].targetRotation.z, JointParts[0].targetRotation.w), 6 * Time.fixedDeltaTime);
        }
    }

    private void FixedUpdate()
    {      
        LegsMoving();
    }

    void Balance()
    {
        if (PlayerParts[10].transform.position.z < PlayerParts[6].transform.position.z && PlayerParts[10].transform.position.z < PlayerParts[9].transform.position.z)
        {
            WalkB = true;
            JointParts[0].targetRotation = Quaternion.Lerp(JointParts[0].targetRotation, new Quaternion(-0.1f, JointParts[0].targetRotation.y, JointParts[0].targetRotation.z, JointParts[0].targetRotation.w), 6 * Time.fixedDeltaTime);
        }
        else
        {
            WalkB = false;
        }

        if (PlayerParts[10].transform.position.z > PlayerParts[6].transform.position.z && PlayerParts[10].transform.position.z > PlayerParts[9].transform.position.z)
        {
            WalkF = true;
            JointParts[0].targetRotation = Quaternion.Lerp(JointParts[0].targetRotation, new Quaternion(0, JointParts[0].targetRotation.y, JointParts[0].targetRotation.z, JointParts[0].targetRotation.w), 6 * Time.fixedDeltaTime);
        }
        else
        {
            WalkF = false;
        }

        if (PlayerParts[10].transform.position.z > PlayerParts[6].transform.position.z + FallFactor &&
           PlayerParts[10].transform.position.z > PlayerParts[9].transform.position.z + FallFactor ||
           PlayerParts[10].transform.position.z < PlayerParts[6].transform.position.z - (FallFactor + 0.2f) &&
           PlayerParts[10].transform.position.z < PlayerParts[9].transform.position.z - (FallFactor + 0.2f))
        {
            Falling = true;
        }
        else
        {
            Falling = false;
        }

        if (Falling)
        {
            JointParts[1].angularXDrive = Spring0;
            JointParts[1].angularYZDrive = Spring0;
            LegsHeight = 5;
        }
        else
        {
            JointParts[1].angularXDrive = Spring300;
            JointParts[1].angularYZDrive = Spring300;
            LegsHeight = 1;
            JointParts[2].targetRotation = Quaternion.Lerp(JointParts[2].targetRotation, new Quaternion(0, JointParts[2].targetRotation.y, JointParts[2].targetRotation.z, JointParts[2].targetRotation.w), 6 * Time.fixedDeltaTime);
            JointParts[3].targetRotation = Quaternion.Lerp(JointParts[3].targetRotation, new Quaternion(0, JointParts[3].targetRotation.y, JointParts[3].targetRotation.z, JointParts[3].targetRotation.w), 6 * Time.fixedDeltaTime);
            JointParts[2].angularXDrive = Spring0;
            JointParts[2].angularYZDrive = Spring150;
            JointParts[3].angularXDrive = Spring0;
            JointParts[3].angularYZDrive = Spring150;
        }

        if (PlayerParts[0].transform.position.y - 0.1f <= PlayerParts[1].transform.position.y)
        {
            Fall = true;
        }
        else
        {
            Fall = false;
        }

        if (Fall)
        {
            JointParts[1].angularXDrive = Spring0;
            JointParts[1].angularYZDrive = Spring0;
            StandUping();           
        }
    }

    void LegsMoving()
    {
        if (WalkF)
        {
            if (PlayerParts[6].transform.position.z < PlayerParts[9].transform.position.z && !StepL && !Flag_Leg_R)
            {
                StepR = true;
                Flag_Leg_R = true;
                Flag_Leg_L = true;
            }
            if (PlayerParts[6].transform.position.z > PlayerParts[9].transform.position.z && !StepR && !Flag_Leg_L)
            {
                StepL = true;
                Flag_Leg_L = true;
                Flag_Leg_R = true;
            }
        }

        if (WalkB)
        {
            if (PlayerParts[6].transform.position.z > PlayerParts[9].transform.position.z && !StepL && !Flag_Leg_R)
            {
                StepR = true;
                Flag_Leg_R = true;
                Flag_Leg_L = true;
            }
            if (PlayerParts[6].transform.position.z < PlayerParts[9].transform.position.z && !StepR && !Flag_Leg_L)
            {
                StepL = true;
                Flag_Leg_L = true;
                Flag_Leg_R = true;
            }
        }

        if (StepR)
        {
            Step_R_Time += Time.fixedDeltaTime;

            if (WalkF)
            {                
                JointParts[4].targetRotation = new Quaternion(JointParts[4].targetRotation.x + 0.07f * LegsHeight, JointParts[4].targetRotation.y, JointParts[4].targetRotation.z, JointParts[4].targetRotation.w);
                JointParts[5].targetRotation = new Quaternion(JointParts[5].targetRotation.x - 0.04f * LegsHeight * 2, JointParts[5].targetRotation.y, JointParts[5].targetRotation.z, JointParts[5].targetRotation.w);

                JointParts[7].targetRotation = new Quaternion(JointParts[7].targetRotation.x - 0.02f * LegsHeight / 2, JointParts[7].targetRotation.y, JointParts[7].targetRotation.z, JointParts[7].targetRotation.w);
            }

            if (WalkB)
            {
                JointParts[4].targetRotation = new Quaternion(JointParts[4].targetRotation.x - 0.00f * LegsHeight, JointParts[4].targetRotation.y, JointParts[4].targetRotation.z, JointParts[4].targetRotation.w);
                JointParts[5].targetRotation = new Quaternion(JointParts[5].targetRotation.x - 0.06f * LegsHeight * 2, JointParts[5].targetRotation.y, JointParts[5].targetRotation.z, JointParts[5].targetRotation.w);

                JointParts[7].targetRotation = new Quaternion(JointParts[7].targetRotation.x + 0.02f * LegsHeight / 2, JointParts[7].targetRotation.y, JointParts[7].targetRotation.z, JointParts[7].targetRotation.w);
            }

            if (Step_R_Time > TimeStep)
            {
                Step_R_Time = 0;
                StepR = false;

                if (WalkB || WalkF)
                {
                    StepL = true;
                }
            }
        }
        else
        {
            JointParts[4].targetRotation = Quaternion.Lerp(JointParts[4].targetRotation, StartLegR1, (8f) * Time.fixedDeltaTime);
            JointParts[5].targetRotation = Quaternion.Lerp(JointParts[5].targetRotation, StartLegR2, (17f) * Time.fixedDeltaTime);
        }

        if (StepL)
        {
            Step_L_Time += Time.fixedDeltaTime;

            if (WalkF)
            {
                JointParts[7].targetRotation = new Quaternion(JointParts[7].targetRotation.x + 0.07f * LegsHeight, JointParts[7].targetRotation.y, JointParts[7].targetRotation.z, JointParts[7].targetRotation.w);
                JointParts[8].targetRotation = new Quaternion(JointParts[8].targetRotation.x - 0.04f * LegsHeight * 2, JointParts[8].targetRotation.y, JointParts[8].targetRotation.z, JointParts[8].targetRotation.w);

                JointParts[4].targetRotation = new Quaternion(JointParts[4].targetRotation.x - 0.02f * LegsHeight / 2, JointParts[4].targetRotation.y, JointParts[4].targetRotation.z, JointParts[4].targetRotation.w);
            }

            if (WalkB)
            {
                JointParts[7].targetRotation = new Quaternion(JointParts[7].targetRotation.x - 0.00f * LegsHeight, JointParts[7].targetRotation.y, JointParts[7].targetRotation.z, JointParts[7].targetRotation.w);
                JointParts[8].targetRotation = new Quaternion(JointParts[8].targetRotation.x - 0.06f * LegsHeight * 2, JointParts[8].targetRotation.y, JointParts[8].targetRotation.z, JointParts[8].targetRotation.w);

                JointParts[4].targetRotation = new Quaternion(JointParts[4].targetRotation.x + 0.02f * LegsHeight / 2, JointParts[4].targetRotation.y, JointParts[4].targetRotation.z, JointParts[4].targetRotation.w);
            }

            if (Step_L_Time > TimeStep)
            {
                Step_L_Time = 0;
                StepL = false;

                if (WalkB || WalkF)
                {
                    StepR = true;
                }
            }
        }
        else
        {
            JointParts[7].targetRotation = Quaternion.Lerp(JointParts[7].targetRotation, StartLegL1, (8) * Time.fixedDeltaTime);
            JointParts[8].targetRotation = Quaternion.Lerp(JointParts[8].targetRotation, StartLegL2, (17) * Time.fixedDeltaTime);
        }
    }

    void StandUping()
    {
        if (WalkF)
        {
            JointParts[2].angularXDrive = Spring320;
            JointParts[2].angularYZDrive = Spring320;
            JointParts[3].angularXDrive = Spring320;
            JointParts[3].angularYZDrive = Spring320;
            JointParts[0].targetRotation = Quaternion.Lerp(JointParts[0].targetRotation, new Quaternion(-0.1f, JointParts[0].targetRotation.y, 
                JointParts[0].targetRotation.z, JointParts[0].targetRotation.w), 6 * Time.fixedDeltaTime);

            if (JointParts[2].targetRotation.x < 1.7f)
            {
                JointParts[2].targetRotation = new Quaternion(JointParts[2].targetRotation.x + 0.07f, JointParts[2].targetRotation.y, 
                    JointParts[2].targetRotation.z, JointParts[2].targetRotation.w);
            }

            if (JointParts[3].targetRotation.x < 1.7f)
            {
                JointParts[3].targetRotation = new Quaternion(JointParts[3].targetRotation.x + 0.07f, JointParts[3].targetRotation.y, 
                    JointParts[3].targetRotation.z, JointParts[3].targetRotation.w);
            }
        }

        if (WalkB)
        {
            JointParts[2].angularXDrive = Spring320;
            JointParts[2].angularYZDrive = Spring320;
            JointParts[3].angularXDrive = Spring320;
            JointParts[3].angularYZDrive = Spring320;

            if (JointParts[2].targetRotation.x > -1.7f)
            {
                JointParts[2].targetRotation = new Quaternion(JointParts[2].targetRotation.x - 0.09f, JointParts[2].targetRotation.y, 
                    JointParts[2].targetRotation.z, JointParts[2].targetRotation.w);
            }

            if (JointParts[3].targetRotation.x > -1.7f)
            {
                JointParts[3].targetRotation = new Quaternion(JointParts[3].targetRotation.x - 0.09f, JointParts[3].targetRotation.y, 
                    JointParts[3].targetRotation.z, JointParts[3].targetRotation.w);
            }
        }
    }

    void Calculate_COM()
    {
        COM = (JointParts[0].GetComponent<Rigidbody>().mass * JointParts[0].transform.position + 
            JointParts[1].GetComponent<Rigidbody>().mass * JointParts[1].transform.position +
            JointParts[2].GetComponent<Rigidbody>().mass * JointParts[2].transform.position +
            JointParts[3].GetComponent<Rigidbody>().mass * JointParts[3].transform.position +
            JointParts[4].GetComponent<Rigidbody>().mass * JointParts[4].transform.position +
            JointParts[5].GetComponent<Rigidbody>().mass * JointParts[5].transform.position +
            JointParts[6].GetComponent<Rigidbody>().mass * JointParts[6].transform.position +
            JointParts[7].GetComponent<Rigidbody>().mass * JointParts[7].transform.position +
            JointParts[8].GetComponent<Rigidbody>().mass * JointParts[8].transform.position +
            JointParts[9].GetComponent<Rigidbody>().mass * JointParts[9].transform.position) /
            (JointParts[0].GetComponent<Rigidbody>().mass + JointParts[1].GetComponent<Rigidbody>().mass +
            JointParts[2].GetComponent<Rigidbody>().mass + JointParts[3].GetComponent<Rigidbody>().mass +
            JointParts[4].GetComponent<Rigidbody>().mass + JointParts[5].GetComponent<Rigidbody>().mass +
            JointParts[6].GetComponent<Rigidbody>().mass + JointParts[7].GetComponent<Rigidbody>().mass +
            JointParts[8].GetComponent<Rigidbody>().mass + JointParts[9].GetComponent<Rigidbody>().mass);
    }
}

А вот моя версия (и ниже, где вы найдете мой класс данных для буровой установки):

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActiveRagdoll : MonoBehaviour
{
    #region Inspector
    [Header("Ragdoll Rig")] 
    [SerializeField] private RagdollRig rig;

    [Header("Movement")] 
    [SerializeField] private float touchForce;
    [SerializeField] private float timeStep;
    [SerializeField] private float legHeight;
    [SerializeField] private float fallFactor;

    #endregion

    #region Variables
    private float _rightStepTime, _leftStepTime;
    private bool _stepRight, _stepLeft, _walkForward, _walkBackwards, _falling;
    private bool _flag, _flagRightLeg, _flagLeftLeg;

    private Quaternion _startLegR1, _startLegR2, _startLegL1, _startLegL2;
    private JointDrive _spring0, _spring150, _spring300, _spring320;
    private Rigidbody _body;
    #endregion

    private void Awake()
    {
        _body = rig.torso.GetComponent<Rigidbody>();

        Physics.IgnoreCollision(rig.rightArm.GetComponent<Collider>(),
            rig.upperRightLeg.GetComponent<Collider>());
        Physics.IgnoreCollision(rig.leftArm.GetComponent<Collider>(),
            rig.upperLeftLeg.GetComponent<Collider>());

        SetupSprings();
    }

    private void Update()
    {
        var input = Vector2.zero;

        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            input = new Vector2(0, 1);
        }
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            input = new Vector2(0, -1);
        }

        Movement(input);
    }

    public void Movement(Vector2 input)
    {
        if (input.y < -.3f)
            _body.AddForce(Vector3.back * touchForce, ForceMode.Impulse);
        else if (input.y > .3f)
            _body.AddForce(Vector3.forward * touchForce, ForceMode.Impulse);

        if (input.x < -.3f)
        {
            //TODO: ROTATE
        }
        else if (input.x > .3f)
        {
            //TODO: ROTATE
        }

        rig.centerOfMass.position = rig.CalculateCenterOfMass();
        Balance();

        if (!_walkForward && !_walkBackwards)
            ResetMovement();
    }

    private void FixedUpdate()
    {
        MoveLegs();
    }

    private void Balance()
    {
        var comPosition = rig.centerOfMass.position;
        var rightFootPosition = rig.rightFoot.transform.position;
        var leftFootPosition = rig.leftFoot.transform.position;

        if (comPosition.z < rightFootPosition.z && comPosition.z < leftFootPosition.z)
        {
            var targetRotation = rig.torso.targetRotation;

            _walkBackwards = true;
            rig.torso.targetRotation = Quaternion.Lerp(targetRotation, new Quaternion(-0.1f, targetRotation.y,
                    targetRotation.z, targetRotation.w), 6 * Time.fixedDeltaTime);
        }
        else
            _walkBackwards = false;

        if (comPosition.z > rightFootPosition.z && comPosition.z > leftFootPosition.z)
        {
            var targetRotation = rig.torso.targetRotation;

            _walkForward = true;
            rig.torso.targetRotation = Quaternion.Lerp(targetRotation,
                new Quaternion(0, targetRotation.y, targetRotation.z, targetRotation.w), 6 * Time.fixedDeltaTime);
        }
        else
            _walkForward = false;

        _falling = comPosition.z > rightFootPosition.z + fallFactor && comPosition.z > leftFootPosition.z + fallFactor ||
                   comPosition.z < rightFootPosition.z - (fallFactor + 0.2f) && comPosition.z < leftFootPosition.z - (fallFactor + 0.2f);

        if (_falling)
        {
            rig.pelvis.angularXDrive = _spring0;
            rig.pelvis.angularYZDrive = _spring0;
            legHeight = 5;
        }
        else
        {
            rig.pelvis.angularXDrive = _spring300;
            rig.pelvis.angularYZDrive = _spring300;
            legHeight = 1;

            var rightArmRotation = rig.rightArm.targetRotation;
            var leftArmRotation = rig.leftArm.targetRotation;

            rig.rightArm.targetRotation = Quaternion.Lerp(rightArmRotation,
                new Quaternion(0, rightArmRotation.y, rightArmRotation.z, rightArmRotation.w), 6 * Time.fixedDeltaTime);
            rig.leftArm.targetRotation = Quaternion.Lerp(leftArmRotation,
                new Quaternion(0, leftArmRotation.y, leftArmRotation.z, leftArmRotation.w), 6 * Time.fixedDeltaTime);

            rig.rightArm.angularXDrive = _spring0;
            rig.rightArm.angularYZDrive = _spring150;
            rig.leftArm.angularXDrive = _spring0;
            rig.leftArm.angularYZDrive = _spring150;
        }

        if (!(rig.torso.transform.position.y - 0.1f <= rig.pelvis.transform.position.y)) return;
        rig.pelvis.angularXDrive = _spring0;
        rig.pelvis.angularYZDrive = _spring0;
        StandUp();
    }

    private void MoveLegs()
    {
        if (_walkForward)
        {
            if (rig.rightFoot.transform.position.z < rig.leftFoot.transform.position.z && !_stepLeft && !_flagRightLeg)
                _stepRight = _flagRightLeg = _flagLeftLeg = true;

            if (rig.rightFoot.transform.position.z > rig.leftFoot.transform.position.z && !_stepRight && !_flagLeftLeg)
                _stepLeft = _flagLeftLeg = _flagRightLeg = true;
        }
        else if (_walkBackwards)
        {
            if (rig.rightFoot.transform.position.z > rig.leftFoot.transform.position.z && !_stepLeft && !_flagRightLeg)
                _stepRight = _flagRightLeg = _flagLeftLeg = true;

            if (rig.rightFoot.transform.position.z < rig.leftFoot.transform.position.z && !_stepRight && !_flagLeftLeg)
                _stepLeft = _flagLeftLeg = _flagRightLeg = true;
        }

        TakeSteps();
    }

    private void TakeSteps()
    {
        if (_stepRight)
        {
            _rightStepTime += Time.fixedDeltaTime;
            CalculateStep(ref rig.upperRightLeg, ref rig.lowerRightLeg, ref rig.upperLeftLeg);

            if (_rightStepTime > timeStep)
            {
                _rightStepTime = 0;
                _stepRight = false;

                if (_walkBackwards || _walkForward)
                    _stepLeft = true;
            }
        }
        else
            LerpLegs(ref rig.upperRightLeg, ref rig.lowerRightLeg, _startLegR1, _startLegR2);

        if (_stepLeft)
        {
            _leftStepTime += Time.fixedDeltaTime;
            CalculateStep(ref rig.upperLeftLeg, ref rig.lowerLeftLeg, ref rig.upperRightLeg);

            if (_leftStepTime > timeStep)
            {
                _leftStepTime = 0;
                _stepLeft = false;

                if (_walkBackwards || _walkForward)
                    _stepRight = true;
            }
        }
        else
            LerpLegs(ref rig.upperLeftLeg, ref rig.lowerLeftLeg, _startLegL1, _startLegL2);
    }

    private void StandUp()
    {
        rig.rightArm.angularXDrive = _spring320;
        rig.rightArm.angularYZDrive = _spring320;
        rig.leftArm.angularXDrive = _spring320;
        rig.leftArm.angularYZDrive = _spring320;

        if (_walkForward)
        {
            var targetRotation = rig.torso.targetRotation;

            rig.torso.targetRotation = Quaternion.Lerp(targetRotation,
                new Quaternion(-.1f, targetRotation.y, targetRotation.z,
                    targetRotation.w), 6 * Time.fixedDeltaTime);

            RotateArmInDirection(ref rig.rightArm, 1.7f);
            RotateArmInDirection(ref rig.leftArm, 1.7f);
        }

        if (!_walkBackwards) return;
        RotateArmInDirection(ref rig.rightArm, -1.7f);
        RotateArmInDirection(ref rig.leftArm, -1.7f);
    }

    private void ResetMovement()
    {
        _stepRight = _stepLeft = false;
        _rightStepTime = _leftStepTime = 0;
        _flagRightLeg = _flagLeftLeg = false;

        var targetRotation = rig.torso.targetRotation;
        rig.torso.targetRotation = Quaternion.Lerp(targetRotation,
            new Quaternion(-.1f, targetRotation.y, targetRotation.z, targetRotation.w),
            6 * Time.fixedDeltaTime);
    }

    private void SetupSprings()
    {
        _spring0 = new JointDrive
        {
            positionSpring = 0, positionDamper = 0,
            maximumForce = Mathf.Infinity
        };

        _spring150 = new JointDrive
        {
            positionSpring = 150, positionDamper = 0,
            maximumForce = Mathf.Infinity
        };

        _spring300 = new JointDrive
        {
            positionSpring = 300, positionDamper = 100,
            maximumForce = Mathf.Infinity
        };

        _spring320 = new JointDrive
        {
            positionSpring = 320, positionDamper = 0,
            maximumForce = Mathf.Infinity
        };
    }

    private void RotateArmInDirection(ref ConfigurableJoint arm, float limit)
    {
        if (arm.targetRotation.x < limit)
        {
            var targetRotation = arm.targetRotation;
            arm.targetRotation = new Quaternion(targetRotation.x + .07f, targetRotation.y,
                targetRotation.z, targetRotation.w);
        }
        else if (arm.targetRotation.x < limit)
        {
            var targetRotation = arm.targetRotation;
            arm.targetRotation = new Quaternion(targetRotation.x - .09f, targetRotation.y, targetRotation.z,
                targetRotation.w);
        }
    }

    private void LerpLegs(ref ConfigurableJoint upperLeg, ref ConfigurableJoint lowerLeg, Quaternion upperStart, Quaternion lowerStart)
    {
        upperLeg.targetRotation =
            Quaternion.Lerp(upperLeg.targetRotation, upperStart, 8f * Time.fixedDeltaTime);
        lowerLeg.targetRotation =
            Quaternion.Lerp(lowerLeg.targetRotation, lowerStart, 17f * Time.fixedDeltaTime);
    }

    private void CalculateStep(ref ConfigurableJoint upperDominant, ref ConfigurableJoint lowerDominant,
        ref ConfigurableJoint upperSupport)
    {
        var upperDominantRotation = upperDominant.targetRotation;
        var lowerDominantRotation = lowerDominant.targetRotation;
        var upperSupportRotation = upperSupport.targetRotation;

        if (_walkForward)
        {
            upperDominant.targetRotation = new Quaternion(upperDominantRotation.x + 0.07f * legHeight, upperDominantRotation.y, 
                upperDominantRotation.z, upperDominantRotation.w);

            lowerDominant.targetRotation = new Quaternion(lowerDominantRotation.x - 0.04f * legHeight * 2,
                lowerDominantRotation.y, lowerDominantRotation.z, lowerDominantRotation.w);

            upperSupport.targetRotation = new Quaternion(upperSupportRotation.x - 0.02f * legHeight / 2,
                upperSupportRotation.y, upperSupportRotation.z, upperSupportRotation.w);
        }

        if (!_walkBackwards) return;
        upperDominant.targetRotation = new Quaternion(upperDominantRotation.x - 0.00f * legHeight, upperDominantRotation.y, 
            upperDominantRotation.z, upperDominantRotation.w);

        lowerDominant.targetRotation = new Quaternion(lowerDominantRotation.x - 0.06f * legHeight * 2,
            lowerDominantRotation.y, lowerDominantRotation.z, lowerDominantRotation.w);

        upperSupport.targetRotation = new Quaternion(upperSupportRotation.x + 0.02f * legHeight / 2,
            upperSupportRotation.y, upperSupportRotation.z, upperSupportRotation.w);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class RagdollRig
{
    public ConfigurableJoint torso,
        pelvis,
        rightArm,
        leftArm,
        upperRightLeg,
        lowerRightLeg,
        rightFoot,
        upperLeftLeg,
        lowerLeftLeg,
        leftFoot;

    public Transform centerOfMass;

    private List<Rigidbody> GetRigidbodies()
    {
        return new List<Rigidbody>
        {
            torso.gameObject.GetComponent<Rigidbody>(),
            pelvis.gameObject.GetComponent<Rigidbody>(),
            rightArm.gameObject.GetComponent<Rigidbody>(),
            leftArm.gameObject.GetComponent<Rigidbody>(),
            upperRightLeg.gameObject.GetComponent<Rigidbody>(),
            lowerRightLeg.gameObject.GetComponent<Rigidbody>(),
            rightFoot.gameObject.GetComponent<Rigidbody>(),
            upperLeftLeg.gameObject.GetComponent<Rigidbody>(),
            lowerLeftLeg.gameObject.GetComponent<Rigidbody>(),
            leftFoot.gameObject.GetComponent<Rigidbody>()
        };
    }

    public Vector3 CalculateCenterOfMass()
    {
        var parts = GetRigidbodies();
        var mass = Vector3.zero;
        float division = 0;

        foreach (var t in parts)
        {
            var objMass = t.mass;
            mass += objMass * t.transform.position;
            division += objMass;
        }

        return mass / division;
    }
}

Просто для того, чтобы вам было немного легче проверить здесь есть ссылка на сам проект Unity .

Любые советы или идеи о том, как это исправить, очень ценятся!

1 Ответ

0 голосов
/ 27 сентября 2019

Хорошо, так что я просто удалил свой рефакторинг кода выше (за исключением класса Ragdoll Rig) и начал заново.

Я не уверен на 100%, почему это не сработало раньше, но думаю, что я мог поменять местами некоторые переменные в нескольких местах.

Некоторые из функций, которые я создал в предыдущем сценарии, также могли быть виновниками, поэтому я решил не использовать созданные мной функции ref.

В любом случае, это то, чем я закончил, надеюсь, что это пригодится всем, кто захочет поиграть с активными тряпичными куклами

``

using UnityEngine;
using Quaternion = UnityEngine.Quaternion;
using Vector2 = UnityEngine.Vector2;
using Vector3 = UnityEngine.Vector3;

public class ActiveRagdoll : MonoBehaviour
{
    #region Inspector

    [Header("Ragdoll Rig")] [SerializeField]
    private RagdollRig rig;

    [Header("Movement")] [SerializeField] private float touchForce;
    [SerializeField] private float timeStep;
    [SerializeField] private float legHeight;
    [SerializeField] private float fallFactor;

    #endregion

    #region Variables
    private float _rightStepTime, _leftStepTime;
    private bool _stepRight, _stepLeft, _walkForward, _walkBackwards, _falling;
    private bool _flag, _flagRightLeg, _flagLeftLeg;

    private Quaternion _startLegR1, _startLegR2, _startLegL1, _startLegL2;
    private JointDrive _spring0, _spring150, _spring300, _spring320;
    private Rigidbody _body;
    #endregion

    private void Awake()
    {
        rig.InitializeRig();
        _body = rig.torso.gameObject.GetComponent<Rigidbody>();

        Physics.IgnoreCollision(rig.rightArm.GetComponent<Collider>(), rig.upperRightLeg.GetComponent<Collider>(),
            true);
        Physics.IgnoreCollision(rig.leftArm.GetComponent<Collider>(), rig.upperLeftLeg.GetComponent<Collider>(), true);

        SetupJoints();
    }

    //FOR TESTING, REMOVE LATER
    private void Update()
    {
        MovementInput(new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")));
    }

    private void FixedUpdate()
    {
        LegsMoving();
    }

    public void MovementInput(Vector2 input)
    {
        var direction = new Vector3(input.x, 0, input.y);

        if (input.y < 0 || input.y > 0)
            _body.AddForce(Time.fixedDeltaTime * touchForce * direction, ForceMode.Impulse);

        rig.centerOfMass.position = rig.CalculateCenterOfMass();

        Balance();

        if (!_walkForward && !_walkBackwards)
            ResetMovement();
    }

    private void ResetMovement()
    {
        var targetRotation = rig.torso.targetRotation;

        _stepRight = false;
        _stepLeft = false;
        _rightStepTime = 0;
        _leftStepTime = 0;
        _flagRightLeg = false;
        _flagLeftLeg = false;

        rig.torso.targetRotation = Quaternion.Lerp(targetRotation,
            new Quaternion(-0.1f, targetRotation.y, targetRotation.z, targetRotation.w), 6 * Time.fixedDeltaTime);
    }

    private void Balance()
    {
        var comPosition = rig.centerOfMass.transform.position;
        var rightFootPosition = rig.rightFoot.transform.position;
        var leftFootPosition = rig.leftFoot.transform.position;
        var targetRotation = rig.torso.targetRotation;

        _walkBackwards = comPosition.z < rightFootPosition.z && comPosition.z < leftFootPosition.z;

        if (_walkBackwards)
            rig.torso.targetRotation = Quaternion.Lerp(targetRotation,
                new Quaternion(-0.1f, targetRotation.y, targetRotation.z, targetRotation.w), 6 * Time.fixedDeltaTime);

        _walkForward = comPosition.z > rightFootPosition.z && comPosition.z > leftFootPosition.z;

        if (_walkForward)
            rig.torso.targetRotation = Quaternion.Lerp(targetRotation,
                new Quaternion(0, targetRotation.y, targetRotation.z, targetRotation.w), 6 * Time.fixedDeltaTime);

        CheckForFall(comPosition, rightFootPosition, leftFootPosition);

        if (!(rig.torso.transform.position.y - 0.1f <= rig.pelvis.transform.position.y)) return;
        rig.pelvis.angularXDrive = _spring0;
        rig.pelvis.angularYZDrive = _spring0;
        StandUp();
    }

    private void LegsMoving()
    {
        var upperRightLegRotation = rig.upperRightLeg.targetRotation;
        var lowerRightLegRotation = rig.lowerRightLeg.targetRotation;
        var upperLeftLegRotation = rig.upperLeftLeg.targetRotation;
        var lowerLeftLegRotation = rig.lowerLeftLeg.targetRotation;

        CheckFooting(rig.rightFoot.transform.position, rig.leftFoot.transform.position);

        if (_stepRight)
        {
            _rightStepTime += Time.fixedDeltaTime;

            if (_walkForward)
            {
                rig.upperRightLeg.targetRotation = new Quaternion(upperRightLegRotation.x + 0.07f * legHeight, upperRightLegRotation.y,
                    upperRightLegRotation.z, upperRightLegRotation.w);

                rig.lowerRightLeg.targetRotation = new Quaternion(lowerRightLegRotation.x - 0.04f * legHeight * 2, lowerRightLegRotation.y,
                    lowerRightLegRotation.z, lowerRightLegRotation.w);

                rig.upperLeftLeg.targetRotation = new Quaternion(upperLeftLegRotation.x - 0.02f * legHeight / 2, upperLeftLegRotation.y, 
                    upperLeftLegRotation.z, upperLeftLegRotation.w);
            }

            if (_walkBackwards)
            {
                rig.upperRightLeg.targetRotation = new Quaternion(upperRightLegRotation.x - 0.00f * legHeight, upperRightLegRotation.y, 
                    upperRightLegRotation.z, upperRightLegRotation.w);

                rig.lowerRightLeg.targetRotation = new Quaternion(lowerRightLegRotation.x - 0.06f * legHeight * 2, lowerRightLegRotation.y,
                    lowerRightLegRotation.z, lowerRightLegRotation.w);

                rig.upperLeftLeg.targetRotation = new Quaternion(upperLeftLegRotation.x + 0.02f * legHeight / 2, upperLeftLegRotation.y, 
                    upperLeftLegRotation.z, upperLeftLegRotation.w);
            }

            if (_rightStepTime > timeStep)
            {
                _rightStepTime = 0;
                _stepRight = false;
                _stepLeft = _walkBackwards || _walkForward;
            }
        }
        else
        {
            rig.upperRightLeg.targetRotation = Quaternion.Lerp(upperRightLegRotation, _startLegR1,
                8f * Time.fixedDeltaTime);
            rig.lowerRightLeg.targetRotation = Quaternion.Lerp(lowerRightLegRotation, _startLegR2,
                17f * Time.fixedDeltaTime);
        }

        if (_stepLeft)
        {
            _leftStepTime += Time.fixedDeltaTime;

            if (_walkForward)
            {
                rig.upperLeftLeg.targetRotation = new Quaternion(upperLeftLegRotation.x + 0.07f * legHeight, upperLeftLegRotation.y, 
                    upperLeftLegRotation.z, upperLeftLegRotation.w);

                rig.lowerLeftLeg.targetRotation = new Quaternion(lowerLeftLegRotation.x - 0.04f * legHeight * 2, lowerLeftLegRotation.y, 
                    lowerLeftLegRotation.z, lowerLeftLegRotation.w);

                rig.upperRightLeg.targetRotation = new Quaternion(upperRightLegRotation.x - 0.02f * legHeight / 2, upperRightLegRotation.y,
                    upperRightLegRotation.z, upperRightLegRotation.w);
            }

            if (_walkBackwards)
            {
                rig.upperLeftLeg.targetRotation = new Quaternion(upperLeftLegRotation.x - 0.00f * legHeight,
                    upperLeftLegRotation.y, upperLeftLegRotation.z, upperLeftLegRotation.w);

                rig.lowerLeftLeg.targetRotation = new Quaternion(lowerLeftLegRotation.x - 0.06f * legHeight * 2,
                        lowerLeftLegRotation.y, lowerLeftLegRotation.z, lowerLeftLegRotation.w);

                rig.upperRightLeg.targetRotation = new Quaternion(upperRightLegRotation.x + 0.02f * legHeight / 2, 
                    upperRightLegRotation.y, upperRightLegRotation.z, upperRightLegRotation.w);
            }

            if (_leftStepTime > timeStep)
            {
                _leftStepTime = 0;
                _stepLeft = false;
                _stepRight = _walkBackwards || _walkForward;
            }
        }
        else
        {
            rig.upperLeftLeg.targetRotation = Quaternion.Lerp(upperLeftLegRotation, _startLegL1, (8) * Time.fixedDeltaTime);
            rig.lowerLeftLeg.targetRotation = Quaternion.Lerp(lowerLeftLegRotation, _startLegL2, (17) * Time.fixedDeltaTime);
        }
    }

    private void CheckFooting(Vector3 rightFoot, Vector3 leftFoot)
    {
        if (_walkForward)
        {
            if (rightFoot.z < leftFoot.z && !_stepLeft && !_flagRightLeg)
                _stepRight = _flagRightLeg = _flagLeftLeg = true;

            if (rightFoot.z > leftFoot.z && !_stepRight && !_flagLeftLeg)
                _stepLeft = _flagLeftLeg = _flagRightLeg = true;
        }

        if (!_walkBackwards) return;
        if (rightFoot.z > leftFoot.z && !_stepLeft && !_flagRightLeg)
            _stepRight = _flagRightLeg = _flagLeftLeg = true;

        if (rightFoot.z < leftFoot.z && !_stepRight && !_flagLeftLeg)
            _stepLeft = _flagLeftLeg = _flagRightLeg = true;
    }

    private void StandUp()
    {
        var leftArmRotation = rig.leftArm.targetRotation;
        var rightArmRotation = rig.rightArm.targetRotation;
        var torsoRotation = rig.torso.targetRotation;

        rig.rightArm.angularXDrive = _spring320;
        rig.rightArm.angularYZDrive = _spring320;
        rig.leftArm.angularXDrive = _spring320;
        rig.leftArm.angularYZDrive = _spring320;

        if (_walkForward)
        {
            rig.torso.targetRotation = Quaternion.Lerp(torsoRotation, new Quaternion(-0.1f,
                    torsoRotation.y,torsoRotation.z, torsoRotation.w), 6 * Time.fixedDeltaTime);

            if (rightArmRotation.x < 1.7f)
                rig.rightArm.targetRotation = new Quaternion(rightArmRotation.x + 0.07f,
                    rightArmRotation.y,rightArmRotation.z, rightArmRotation.w);

            if (leftArmRotation.x < 1.7f)
                rig.leftArm.targetRotation = new Quaternion(leftArmRotation.x + 0.07f,
                    leftArmRotation.y,leftArmRotation.z, leftArmRotation.w);
        }

        if (_walkBackwards)
        {
            if (rightArmRotation.x > -1.7f)
                rig.rightArm.targetRotation = new Quaternion(rightArmRotation.x - 0.09f,
                    rightArmRotation.y,rightArmRotation.z, rightArmRotation.w);

            if (leftArmRotation.x > -1.7f)
                rig.leftArm.targetRotation = new Quaternion(leftArmRotation.x - 0.09f,
                    leftArmRotation.y,leftArmRotation.z, leftArmRotation.w);
        }
    }

    private void CheckForFall(Vector3 comPosition, Vector3 rightFootPosition, Vector3 leftFootPosition)
    {
        _falling = comPosition.z > rightFootPosition.z + fallFactor && comPosition.z > leftFootPosition.z + fallFactor ||
                   comPosition.z < rightFootPosition.z - (fallFactor + 0.2f) && comPosition.z < leftFootPosition.z - (fallFactor + 0.2f);

        if (_falling)
        {
            rig.pelvis.angularXDrive = _spring0;
            rig.pelvis.angularYZDrive = _spring0;
            legHeight = 5;
        }
        else
        {
            var rightArmRotation = rig.rightArm.targetRotation;
            var leftArmRotation = rig.leftArm.targetRotation;

            rig.pelvis.angularXDrive = _spring300;
            rig.pelvis.angularYZDrive = _spring300;
            legHeight = 1;

            rig.rightArm.targetRotation = Quaternion.Lerp(rightArmRotation,
                new Quaternion(0, rightArmRotation.y, rightArmRotation.z, rightArmRotation.w), 6 * Time.fixedDeltaTime);

            rig.leftArm.targetRotation = Quaternion.Lerp(leftArmRotation,
                new Quaternion(0, leftArmRotation.y, leftArmRotation.z, leftArmRotation.w), 6 * Time.fixedDeltaTime);

            rig.rightArm.angularXDrive = _spring0;
            rig.rightArm.angularYZDrive = _spring150;
            rig.leftArm.angularXDrive = _spring0;
            rig.leftArm.angularYZDrive = _spring150;
        }
    }

    private void SetupJoints()
    {
        _startLegR1 = rig.upperRightLeg.targetRotation;
        _startLegR2 = rig.lowerRightLeg.targetRotation;
        _startLegL1 = rig.upperLeftLeg.targetRotation;
        _startLegL2 = rig.lowerLeftLeg.targetRotation;

        _spring0 = new JointDrive {positionSpring = 0, positionDamper = 0, maximumForce = Mathf.Infinity};
        _spring150 = new JointDrive {positionSpring = 150, positionDamper = 0, maximumForce = Mathf.Infinity};
        _spring300 = new JointDrive {positionSpring = 300, positionDamper = 100, maximumForce = Mathf.Infinity};
        _spring320 = new JointDrive {positionSpring = 320, positionDamper = 0, maximumForce = Mathf.Infinity};
    }
}

``

, а затем класс буровой установки

``

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class RagdollRig
{
    public ConfigurableJoint torso,
        pelvis,
        rightArm,
        leftArm,
        upperRightLeg,
        lowerRightLeg,
        rightFoot,
        upperLeftLeg,
        lowerLeftLeg,
        leftFoot;

    public Transform centerOfMass;

    private List<Rigidbody> _rigidbodies;

    public void InitializeRig()
    {
        _rigidbodies = GetRigidbodies();
    }

    private List<Rigidbody> GetRigidbodies()
    {
        return new List<Rigidbody>
        {
            torso.gameObject.GetComponent<Rigidbody>(),
            pelvis.gameObject.GetComponent<Rigidbody>(),
            rightArm.gameObject.GetComponent<Rigidbody>(),
            leftArm.gameObject.GetComponent<Rigidbody>(),
            upperRightLeg.gameObject.GetComponent<Rigidbody>(),
            lowerRightLeg.gameObject.GetComponent<Rigidbody>(),
            rightFoot.gameObject.GetComponent<Rigidbody>(),
            upperLeftLeg.gameObject.GetComponent<Rigidbody>(),
            lowerLeftLeg.gameObject.GetComponent<Rigidbody>(),
            leftFoot.gameObject.GetComponent<Rigidbody>()
        };
    }

    public Vector3 CalculateCenterOfMass()
    {
        var mass = Vector3.zero;
        float division = 0;

        foreach (var t in _rigidbodies)
        {
            var objMass = t.mass;
            mass += objMass * t.transform.position;
            division += objMass;
        }

        return mass / division;
    }
}

``

Еще раз огромное спасибо MetalCore999 (Youtube) за публикацию его оригинального сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...