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.
I don’t understand what you are asking. You don’t seem to have a question in that paragraph above.
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.
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.
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.