I don't understand the problem

Hi everyone !
Before I add the code in this course, everything work well :

  • Rotation stopped after collision
  • Sound work normally for thrust and collision

After I add the code in this course :

  • Rotation still working
  • Sound of Thrust don’t stop
  • Sound on collision don’t work anymore, but need to be triggered multiples times before to work.

I tried to look at before courses to see if I missed something and also tried to copy the code on this course. Even tried to restart my unity but still doesn’t work.

Can someone help me ?

CollisionHandler script

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.SceneManagement;

public class CollisionHandler : MonoBehaviour

{

    AudioSource audioSource;

    [SerializeField] float levelLoadDelay = 1.5f;

    [SerializeField] AudioClip crash;

    [SerializeField] AudioClip success;

    bool isTransitioning = false;

    void Start()

    {

        audioSource = GetComponent<AudioSource>();

    }

    void OnCollisionEnter(Collision other)

    {

        if (isTransitioning)

        {

            return;

        }

        switch (other.gameObject.tag)

        {

            case "Friendly":

                Debug.Log("This is friendly");

                break;

            case "Finish":

                StartFinishSequence();

                break;

            default:

                StartCrashSequence();

                break;

        }        

    }

    void StartFinishSequence()

    {

        isTransitioning = true;

        audioSource.Stop();

        audioSource.PlayOneShot(success);

        GetComponent<Movement>().enabled = false;

        Invoke("LoadNextLevel", levelLoadDelay);

    }

   

    void StartCrashSequence()

    {

        isTransitioning = true;

        audioSource.Stop();

        audioSource.PlayOneShot(crash);

        GetComponent<Movement>().enabled = false;

        Invoke("ReloadScene", levelLoadDelay);

    }

    void ReloadScene()

    {

        int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;

        SceneManager.LoadScene(currentSceneIndex);

    }

    void LoadNextLevel()

    {

        int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;

        int nextSceneIndex = currentSceneIndex + 1;

        if (nextSceneIndex == SceneManager.sceneCountInBuildSettings)

        {

            nextSceneIndex = 0;

        }

        SceneManager.LoadScene(nextSceneIndex);

    }

}

Movement script

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UIElements;

public class Movement : MonoBehaviour

{

    Rigidbody myRigidbody;

    [SerializeField] float moveSpeed = 100f;

    [SerializeField] float rotationSpeed = 10f;

    [SerializeField] AudioClip mainThrust;

    AudioSource audioSource;

    void Start()

    {

        myRigidbody = GetComponent<Rigidbody>();

        audioSource = GetComponent<AudioSource>();

    }

    void Update()

    {

        ProcessThrust();

        RotationThrust();

    }

    void ProcessThrust()

    {

        if (Input.GetKey(KeyCode.Space))

        {

            myRigidbody.AddRelativeForce(Vector3.up * Time.deltaTime * moveSpeed);

            if (!audioSource.isPlaying)

            {

                audioSource.PlayOneShot(mainThrust);

            }

        }

        else

        {

            audioSource.Stop();

        }

    }

    void RotationThrust()

    {

        if(Input.GetKey(KeyCode.Q))

        {

            ApplyRotation(rotationSpeed);

        }

        else if(Input.GetKey(KeyCode.D))

        {

            ApplyRotation(-rotationSpeed);

        }

    }

    void ApplyRotation(float RotateMe)

    {

        myRigidbody.freezeRotation = true;

        transform.Rotate(Vector3.forward * Time.deltaTime * RotateMe);

        myRigidbody.freezeRotation = false;

    }

}

Hi Eike,

Welcome to our community! :slight_smile:

How/where did you stop the rotation? From what I see in the Movement script you shared here, there is no restriction in the Update method, so RotationThrust(); gets executed each frame unless you disable or destroy the component. In the RotationThrust method, there is no restriction either, so the player is able to rotate the rocket as long as the Movement component is active in the scene.

In your CollisionHandler object, you disable a Movement component (given the GetComponent method found such a component). If you have, for example, multiple Movement components, it might be that one of them is still active.

In the Start method of the Movement class, add the following:

Debug.Log("Movement component is attached to " + name, gameObject);
Debug.Log("Movement component id: " + GetInstanceID(), gameObject);

Save your script, then test your game. Different ids means different objects.

I hope this helped. If not, try to use Debug.Log to narrow this problem and the other problems down further. Since you know what you want to achieve, and since you know what doesn’t work as expected, this should not be too challenging. Let me know what you figured out. :slight_smile:

1 Like

Hi Nina !

Thank you for your answer.
In fact, I had mutiple “Movement” component in my game object. And it only disable one.
Thank you for you help !

But I have a question, for my personal knowledge :
Since the script “CollisionHandler” disable the movement with this line :

GetComponent<Movement>().enabled = false;

and in my gameobject, there is 2 components of the script “Movement”, why does it only disable 1 of them and not both ? Since it has the same name, it should disable botth of them.

For a general understanding of coding, you could, for example, ask yourself what concept makes sense in the context of a game engine. In many if not most cases, the makers of a game engine very likely had the same idea as you.

In your game, you might want to be able to do different things like, for example, selecting one component and selecting multiple components of the same name/type. That are two different cases, aren’t they?

Since this is a fairly common scenario, we can assume that the makers of Unity provided a solution. And that’s in fact the case. The name ‘GetComponent’ indicates that the method gets one component. There is also a method named ‘GetComponents’. You may guess what it does. :wink:

The following does not have anything to do with Unity: In C#, it is not possible to perform an action on multiple objects simultaneously. For this reason, even if we are able to get multiple Movement objects, we are not able to disable all of them without iterating over all of them. In some cases, there might be a method which does that for us, and it looks as if we were able to disable everything in one step. While this is true for the method, it is not true for the implementation of that method. The method (or another method) will perform an action on every single object in the collection it is supposed to process.

I hope this made sense. :slight_smile:


See also:

1 Like

Thank you very much !

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

Privacy & Terms