1

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?

I have uploaded a video here

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:

enter image description here

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&lt;Rigidbody&gt;();

//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(&quot;Cube&quot;);

}

// 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&lt;Rigidbody&gt;();

    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.

Sheath9
  • 11
  • 3
  • 2
    You're making the usual beginners' mistake of moving physics objects with the 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 the Transform as read-only and routing all changes you want to make via the Rigidbody component instead. – DMGregory Feb 27 '22 at 20:15
  • 1
    To add to what DMGregory said. You can think of Rigidbody as moving objects gradually taking physics into account. While using Transform can be made to look like gradual movement it always is an instantaneous "teleporting" from one pose to the next. – Nikaas Feb 28 '22 at 07:23
  • @DMGregory So I should add a rotation function using the rigid body instead of transform. I did a quick look on the unity documentation and see Rigidbody.MoveRotation so I'll test that out. Thank you for the help! – Sheath9 Feb 28 '22 at 10:32
  • Also, if I have additional questions regarding this specific task can I continue commenting here or should I create and entirely new Question? @DMGregory – Sheath9 Feb 28 '22 at 11:00
  • @Nikaas thank you for the advice as well – Sheath9 Feb 28 '22 at 11:01
  • If you're able to solve the problem with this, post your solution as an answer. If not, edit your question to show your latest code/setup steps, and what problems still occur. As an aside, you probably don't want that movement code inside OnTriggerEnter — it will run only the first frame that the objects overlap, and then not again until they separate and overlap again (or one or the other teleports). – DMGregory Feb 28 '22 at 12:00

0 Answers0