Constraints ignoring when dying. Project Boost

Hi. I added Dying delay with Invoke(“LoadScene”, 3f) and disabling controls in this time.
So everything works fine - constraints working. But if i hit an object and enter Dying state, rocket could rotate in X and Y when falling, ignoring Constraints in Rigidbody. It happens not common, so you can miss it, but if rocket hits multiplie surfaces and may hit some when falling - it happens. Why it happens?

123

public class Rocket : MonoBehaviour
{
    // Start is called before the first frame update
    private Rigidbody _rigidbody;
    private AudioSource _audio;
    private float _startVolume = 0.5f;
    [SerializeField] private float rscThrustRotate = 100f;
    [SerializeField] private float rscThrustThrust = 100f;

    enum State
    {
        Alive,
        Dying,
        Transcending
    }

    private State _state = State.Alive;

    void OnCollisionEnter(Collision collision)
    {

        if (_state != State.Alive)
        {
            return;
        }
        
        switch (collision.gameObject.tag)
        {
            case "Friendly":
                break;
            case "Finish":
                _state = State.Transcending;
                Invoke("LoadScene", 3f);
                break;
            default:
                _state = State.Dying;
                Invoke("LoadScene2", 3f);
                break;
        }
    }

    private void LoadScene2()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

    private void LoadScene()
    {
        SceneManager.LoadScene(1);
    }

    void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
        _audio = GetComponent<AudioSource>();
        Physics.gravity = new Vector3(0, -10.0F, 0);
    }

    // Update is called once per frame
    void Update()
    {
        if (_state == State.Alive)
        {
            Thrust();
            Rotate();    
        }
        else
        {
            StartCoroutine(VolumeFade(_audio, 0f, 0.1f));
        }
    }

    void Rotate()
    {
        _rigidbody.freezeRotation = true;
        float rotationThisFrame = Time.deltaTime * rscThrustRotate;

        if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.D))
        {
        }
        else if (Input.GetKey(KeyCode.A))
        {
            transform.Rotate(Vector3.forward * rotationThisFrame);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            transform.Rotate(-Vector3.forward * rotationThisFrame);
        }

        _rigidbody.freezeRotation = false;
    }

    private void Thrust()
    {
        float thrustThisFrame = Time.deltaTime * rscThrustThrust;
        if (Input.GetKey(KeyCode.W))
        {
            _rigidbody.AddRelativeForce(Vector3.up * thrustThisFrame);
            
            _audio.volume = _startVolume;

            if (!_audio.isPlaying)
            {
                _audio.Play();
            }
        }
        else
        {
            StartCoroutine(VolumeFade(_audio, 0f, 0.1f));

        }
    }

    IEnumerator VolumeFade(AudioSource _AudioSource, float _EndVolume, float _FadeLength)
    {
        float _StartTime = Time.time;
        while (Time.time < _StartTime + _FadeLength)
        {
            float alpha = (_StartTime + _FadeLength - Time.time) / _FadeLength;
            // use the square here so that we fade faster and without popping
            alpha = alpha * alpha;
            _AudioSource.volume = alpha * _startVolume + _EndVolume * (1.0f - alpha);

            yield return null;
        }
    }
}

Hi,

Welcome to our community! :slight_smile:

Have you already tried to add Debug.Logs to your code to see what is going on during runtime? Log _rigidbody.freezeRotation into your console. Do that in the Start method. In the Update method after setting the value to true, and after setting it to false. Maybe you do not get the initial value.

If that’s the case, declare a new variable at the top of your code:
RigidbodyConstraints constraints;

In the Start method, assign the initial value that you configured in the Inspector:
constraints = _rigidbody.constraints;

Instead of setting the freezeRotation to false, you set the _rigidbody.constraints value to the initial value. I’m leaving this little challenge for you. If you do not know what I mean or want to see if you had the same idea as I, here is the code:

_rigidbody.constraints = constraints;


Alternatively, you could try to remove the lines with freezeRotation to see if that fixes the issue. If it didn’t readd the lines removed but use the following code at the top of the Update method:
_rigidbody.angularVelocity = Vector3.zero;

Did this fix it?


See also:

just removed freezeRotation lines and problem is fixed. anyway it is not longer needed. thx!

It could be that you have broken the prefab in the hierarchy, where you modified the actual instance in the Hierarchy and it no longer has the same attributes as the prefab. Not sure from the image cut you supplied if you are inspecting the actual prefab, or the instance of the prefab you dragged into the scene. You may want to check that, as an idea.

It also seem like in this case the only time you do not want full control of the rotation is in the Death State. You could remove the _rigidbody.freezeRotation = false from Rotate and move it to the OnCollisionEnter under default. Do not think that would change anything but maybe.

Or you could try either under the Update function add:

if( _state == State.Dying )
{ _rigidbody.constraints = RigidbodyConstraints.FreezeRotationX & RigidbodyConstraints.FreezeRotationY;}

… or in the OnCollisionEnter under default add that code…

_rigidbody.constraints = RigidbodyConstraints.FreezeRotationX & RigidbodyConstraints.FreezeRotationY;

thought I would add some ideas here for you. Good luck!

1 Like

first suggestion works too, but its not 100% clear for me how its work, i will sort it out later with more knowledge

prefab looks ok. thx for suggestions, now i have more understanding how things work.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms