Update() being run on disabled scripts

I’m making a game and collision detection is going kind of wild, so I’m trying to see if it would be better with a physics-based or a kinematic physics engine. I built scripts for both and attached them to the same object, thinking that I could get the same results by disabling one as only using one script. This turned out to be false, however, because the object behaves differently with just one script attached, with both scripts but only one enabled, or with both scripts enabled. If it helps, I can show my code, but there’s a lot of it and there are 2 different scripts, so if it’s not needed I won’t show it.
Thanks in advance for trying to help.

Update will not run on a disabled script. You can test this easily by putting a log statement inside the Update() method in the script and disabling it. It will not print.

As for the rest of your problem it’s very hard to help you without knowing any details or a specific problem you’re having.

3 Likes

I don’t understand what you are asking. You don’t seem to have a question in that paragraph above.

1 Like

Collider callback functions still fire on disabled scripts, as per the documentation:

Is that what is happening? The point is to allow waking up objects that get bumped.

3 Likes

I’m asking if there’s a way to get the scripts to run properly. Here’s the code if it helps:
Kinematic engine:

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

public class PlayerBehaviour : MonoBehaviour
{
    //variables: input
    public float ud;
    public float rl;
    //variables: physics
    public Vector3 velocity;
    public float walkForce;
    public float jumpForce;
    public Rigidbody rb;
    public float terminalVelocity;
    public bool decel;
    //variables: random
    public int health = 22;
    public int jumps = 2;
    public float dir = 1f;
    public bool grounded;
    public bool pounding;
    public bool jumping;
    //variables: communication
    public GameObject sword;
    public SwordBehaviour script;
    public GameObject guiText;
    public TextManipulator text;
    //variables: dashing
    public float dashSpeed;
    public bool dashing;
    public bool endDash;
    public float dashTime;
    public int maxAirDashes = 1;
    public int airDashes = 1;

    // Start is called before the first frame update
    void Start()
    {
        //initialize communications
        rb = GetComponent<Rigidbody>();
        script = sword.GetComponent<SwordBehaviour>();
        text = guiText.GetComponent<TextManipulator>();
    }
   
    //methods & IEnumerators
    IEnumerator BeginDash()
    {
        airDashes--;
        velocity.y = 0;
        jumping = false;
        yield return new WaitForSeconds(0);
        script.sword.SetActive(false);
        yield return new WaitForSeconds(dashTime);
        if (!jumping)
        {
            dashing = false;
        }
        else
        {
            endDash = true;
        }
    }
    public void BeginPound()
    {
        pounding = true;
        rb.velocity = Vector3.zero;
        velocity = Vector3.down * 25;
    }

    // Update is called once per frame
    void Update()
    {
        //input
        ud = Input.GetAxis("Vertical");
        rl = Input.GetAxis("Horizontal");
        //walking
        if (!pounding && rl > 0)
        {
            velocity.x += 5.92063160084f;
            decel = false;
        }
        if (!pounding && rl < 0)
        {
            velocity.x -= 5.92063160084f;
            decel = false;
        }
        if (Mathf.Abs(velocity.x) < 0.1)
        {
            velocity.x = 0;
        }
        if (velocity.x > 16)
        {
            velocity.x = 16;
        }
        if (velocity.x < -16)
        {
            velocity.x = -16;
        }
        if (Input.GetKeyUp(KeyCode.RightArrow) || Input.GetKeyUp(KeyCode.LeftArrow))
        {
            decel = true;
        }
        //jumping
        if (Input.GetKeyDown(KeyCode.Z) && jumps > 0)
        {
            grounded = false;
            jumping = true;
            jumps--;
            velocity.y = jumpForce + 9 * jumps;
        }
        //gravity
        if (!grounded && !dashing || dashing && jumping && !grounded)
        {
            velocity.y -= 0.4f;
        }
        if (velocity.y < terminalVelocity)
        {
            velocity.y = terminalVelocity;
        }
        if (grounded)
        {
            velocity.y = 0;
        }
        //dashing
        if (Input.GetKeyUp(KeyCode.C) && !dashing && airDashes > 0)
        {
            dashing = true;
            StartCoroutine("BeginDash");
        }
        if  (rl > 0 && !dashing)
        {
            dir = 1f;
        }
        if (rl < 0 && !dashing)
        {
            dir = -1f;
        }
        if (dashing)
        {
            velocity.x = dir * dashSpeed;
        }
        //moving
        transform.position += velocity * Time.deltaTime;
        rb.velocity = Vector3.zero;
        if (decel)
        {
            velocity.x *= 0.39685026299f;
        }
        if (!decel)
        {
            velocity.x *= 0.62996052494f;
        }
    }

    //all collisions
    void OnCollisionEnter(Collision collision)
    {
        //damage
        if (collision.gameObject.CompareTag("Hazard"))
        {
            health -= 3;
            velocity.x = -96*(collision.transform.position.x - transform.position.x) / Mathf.Abs(collision.transform.position.x - transform.position.x);
        }
        //instant death
        if (collision.gameObject.CompareTag("Death Hazard"))
        {
            health = 0;
            Destroy(gameObject);
        }
        //ground resetting
        if (collision.gameObject.CompareTag("Ground"))
        {
            jumps = 2;
            grounded = true;
            airDashes = maxAirDashes;
            if (pounding)
            {
                script.Dspawn();
            }
        }
        //walls and cielings
        if (collision.gameObject.CompareTag("LWall") && rl < 0)
        {
            velocity.x = 0;
            Debug.Log("Collision with LWall");
        }
        if (collision.gameObject.CompareTag("RWall") && rl > 0)
        {
            velocity.x = 0;
        }
        if (collision.gameObject.CompareTag(" Cieling") && velocity.y != 0)
        {
            velocity.y = 0;
        }
        //coins
        if (collision.gameObject.CompareTag("Money"))
        {
            Destroy(collision.gameObject);
            text.AddMoney(1);
        }
    }
    void OnCollisionStay(Collision collision)
    {
        //ground resetting
        if (collision.gameObject.CompareTag("Ground"))
        {
            jumps = 2;
            grounded = true;
            pounding = false;
            jumping = false;
            if (!dashing)
            {
                airDashes = maxAirDashes;
            }
            if (endDash)
            {
                dashing = false;
                endDash = false;
            }
        }
    }
    void OnCollisionExit(Collision collision)
    {
        //leaving the ground
        if (collision.gameObject.CompareTag("Ground"))
        {
            grounded = false;
        }
    }
}

Physics-based engine:

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

public class PlayerPhysics : MonoBehaviour
{
    //variables: input
    public float ud;
    public float rl;
    //variables: physics
    public float walkForce;
    public float jumpForce;
    public Rigidbody rb;
    public float terminalVelocity;
    public Vector3 temp;
    //variables: random
    public int health = 22;
    public int jumps = 2;
    public float dir = 1f;
    public bool grounded;
    public bool pounding;
    public bool jumping;
    //variables: communication
    public GameObject sword;
    public SwordBehaviour script;
    public GameObject guiText;
    public TextManipulator text;
    //variables: dashing
    public float dashSpeed;
    public bool dashing;
    public bool endDash;
    public float dashTime;
    public int maxAirDashes = 1;
    public int airDashes = 1;

    // Start is called before the first frame update
    void Start()
    {
        //initialize communications
        rb = GetComponent<Rigidbody>();
        script = sword.GetComponent<SwordBehaviour>();
        text = guiText.GetComponent<TextManipulator>();
    }

    //methods & IEnumerators
    IEnumerator BeginDash()
    {
        airDashes--;
        temp.y = 0;
        jumping = false;
        yield return new WaitForSeconds(0);
        script.sword.SetActive(false);
        yield return new WaitForSeconds(dashTime);
        if (!jumping)
        {
            dashing = false;
        }
        else
        {
            endDash = true;
        }
    }
    public void BeginPound()
    {
        pounding = true;
        temp = Vector3.down * 25;
    }

    // Update is called once per frame
    void Update()
    {
        //input
        ud = Input.GetAxis("Vertical");
        rl = Input.GetAxis("Horizontal");
        //walking
        if (!pounding && rl > 0)
        {
            rb.AddForce(walkForce * Vector3.right, ForceMode.Impulse);
        }
        if (!pounding && rl < 0)
        {
            rb.AddForce(walkForce * Vector3.left, ForceMode.Impulse);
        }
        if (rb.velocity.x > 16)
        {
            temp.x = 16;
        }
        if (rb.velocity.x < -16)
        {
            temp.x = -16;
        }
        //jumping
        if (Input.GetKeyDown(KeyCode.Z) && jumps > 0)
        {
            grounded = false;
            jumping = true;
            jumps--;
            rb.AddForce((jumpForce + 9 * jumps) * Vector3.up, ForceMode.Impulse);
        }
        //dashing
        if (Input.GetKeyUp(KeyCode.C) && !dashing && airDashes > 0)
        {
            dashing = true;
            StartCoroutine("BeginDash");
        }
        if (rl > 0 && !dashing)
        {
            dir = 1f;
        }
        if (rl < 0 && !dashing)
        {
            dir = -1f;
        }
        if (dashing)
        {
            temp.x = dir * dashSpeed;
        }
        //moving
        rb.velocity = temp;
    }

    //all collisions
    void OnCollisionEnter(Collision collision)
    {
        //damage
        if (collision.gameObject.CompareTag("Hazard"))
        {
            health -= 3;
            rb.AddForce(-96 * Vector3.right * (collision.transform.position.x - transform.position.x) / Mathf.Abs(collision.transform.position.x - transform.position.x), ForceMode.Impulse);
        }
        //instant death
        if (collision.gameObject.CompareTag("Death Hazard"))
        {
            health = 0;
            Destroy(gameObject);
        }
        //ground resetting
        if (collision.gameObject.CompareTag("Ground"))
        {
            jumps = 2;
            grounded = true;
            airDashes = maxAirDashes;
            if (pounding)
            {
                script.Dspawn();
            }
        }
        //coins
        if (collision.gameObject.CompareTag("Money"))
        {
            Destroy(collision.gameObject);
            text.AddMoney(1);
        }
    }
    void OnCollisionStay(Collision collision)
    {
        //ground resetting
        if (collision.gameObject.CompareTag("Ground"))
        {
            jumps = 2;
            grounded = true;
            pounding = false;
            jumping = false;
            if (!dashing)
            {
                airDashes = maxAirDashes;
            }
            if (endDash)
            {
                dashing = false;
                endDash = false;
            }
        }
    }
    void OnCollisionExit(Collision collision)
    {
        //leaving the ground
        if (collision.gameObject.CompareTag("Ground"))
        {
            grounded = false;
        }
    }
}

With both scripts enabled, the game runs really smoothly and the player goes right through walls.
With just the first script enabled, jumping sends the player out of bounds and walking is really jittery.
With only the first script on the object, none of these problems occur.
Thanks for any consideration; that’s a lot of code to dig through.

Why do you want both scripts on the same object at the same time? As already mentioned, disabled scripts still get their collision methods called. If you really want to do it this way, in the collision methods first check if the component is enabled before doing anything.

1 Like

How is that done? I want them both so I can do a side-by-side comparison between them and see which one is better.

Start your OnCollisionEnter with a check to see if the component is currently enabled. Skip the rest or return out of it if its not enabled. For example " if (!isActiveAndEnabled) return) " in the first line of your OnCollisionEnter.

Kurt says about the collider callback thing and they are in your script, I’ve had this happen to me in the past prior to knowing they behave like this.

Make 2 objects next to each other. Each one having a different script.
Both will be controlled together and youll be able to see the difference easily without the 2 scripts competing on the same object.