I'm working on a 3D game, and having issues with the colliders.
My Cube Controller has movement input by keyboard, with collider and rigidbody components.
Cylinder objects have basic colliders and rigidbodies attached. The main cylinder has a custom script that rotates the child objects (which have colliders and rigidbodies attached). Rotation script is a basic vector transform on the y axis.
When the Cube collides with the stationary cylinder, it collides as expected. However, when the Cube collides with the rotating child cylinder, there is a mixed variation. Moving in opposite direction collision allows the Cube to fall through the Cylinder collider; moving in the same direction causes the Cube to collide normally.
Can anyone help explain how and why this type of behavior happens, and what I can do to correct it?
Here is my rotation script:
public class Rotate : MonoBehaviour {
public float RotationSpeedX = 0f;
public float RotationSpeedY = 0f;
public float RotationSpeedZ = 0f;
public float distance = 100;
private bool closeEnoughToPlayer = false;
private bool rotate = false;
void Start () {}
void Update() {
transform.Rotate(new Vector3(RotationSpeedX, RotationSpeedY, RotationSpeedZ) * Time.deltaTime);
// ... remaining code not shown.
}
}
And here is how it is configured on my main cylinder:
Here is the collision script:
void OnTriggerEnter(Collider collider) {
if (collider.gameObject.tag == "Diamond") {
AudioSource.PlayClipAtPoint(DiamondGetSound, collider.transform.position);
Destroy(collider.gameObject); numDiamonds++;
}
else if (collider.gameObject.tag == "Obstacle")
{
obstacleCounter ++ ;
AudioSource.PlayClipAtPoint(BumpSound,this.transform.position);
Vector3 force = collider.rigidbody.velocity.normalized * (forceFromCollision*10);
collider.rigidbody.AddForce(force,ForceMode.Impulse);
trans = transform;
thisRB = trans.GetComponent();
Vector3 directionToObject = thisRB.position - trans.position;
//adding these bottom two lines from Unity documentation, seeing how it effects cube movement with rotating platforms
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
m_Rigidbody.MovePosition(transform.position + m_Input * Time.deltaTime * m_Speed);
}
}
I also posted this on Unity Answers
//////////////////////////////////////////////////////////////// EDIT 3/3/22 Ok, so I tried manipulating the rigidbodies one more time. The parent cylinder has a rigidbody, which the main rotating script controls. The rotating script now uses...
void Start () {
//GetComponent<Rigidbody>().rotation = Quaternion.identity;
//Fetch the Rigidbody from the GameObject with this script attached
thisRigidbody = GetComponent<Rigidbody>();
//Set the angular velocity of the Rigidbody (rotating around the Y axis, 100 deg/sec)
//m_EulerAngleVelocity = new Vector3(100, 0, 0);
angleVelocity = new Vector3(angleVelocityX,angleVelocityY,angleVelocityZ);
//cubeObject = GameObject.FindGameObjectsWithTag("Cube");
}
// Update is called once per frame
void Update ()
{
Quaternion deltaRotation = Quaternion.Euler(angleVelocity * Time.fixedDeltaTime);
thisRigidbody.MoveRotation(thisRigidbody.rotation * deltaRotation);
}
...instead of the old transform script.
Additionally, to try and spice it up, I added this to the collision script Update function, on the character...
void FixedUpdate() { if (transform.parent.GetComponent().grounded && transform.parent.GetComponent().IsGrounded()) jumpPitch = jumpPitchDefault;
if (collider.gameObject.tag == "Obstacle")
{
//adding these bottom two lines from Unity documentation, seeing how it effects cube movement with rotating platforms
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
m_Rigidbody.MovePosition(transform.position + m_Input * Time.deltaTime * m_Speed);
}
////the below 8 lines are taken from ::: https://docs.unity3d.com/ScriptReference/Rigidbody.AddExplosionForce.html
float power = 10f;
float radius = 10f;
Vector3 explosionPos = transform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
foreach (Collider hit in colliders)
{
Rigidbody rb = hit.GetComponent<Rigidbody>();
if (rb != null)
rb.AddExplosionForce(power, explosionPos, radius, 3.0F);
}
}
However, even with these changes, the Cube does that same exact thing. Collides with the cylinders on the first frame, showing collision, but does not push the Cube out of the way, as the Cylinders rotate.
Requesting more help on how to fix this issue.
Transform
component. If you want the physics engine to handle resolving collisions for you consistently, then you need to let it handle the movement, by treating theTransform
as read-only and routing all changes you want to make via theRigidbody
component instead. – DMGregory Feb 27 '22 at 20:15