Stopping a rigidbody on collision - Transforming objects 'on top' of other objects - how to handle this?

I have a simple physics game working whereby spheres fly around and may collide with a larger sphere (set as a trigger) - the trigger script being…

function OnTriggerEnter (other : Collider) {
	other.rigidbody.velocity = Vector3.zero;
    other.transform.position = Vector3(0,1.5,0);
}

So balls are fired/moved around but when they hit the collider, they are ‘stopped’ (velocity zero) and moved to the centre of the area.

This sort-of works - they move to the correct spot BUT they sometimes seem to retain some inertia/velocity because they fly upwards (Y axis) with considerable force!!

Either I’m not resetting something OR I’m sending 2 spheres to the same spot and they’re ‘bouncing off’ each other.

Is there somethign else I need to do to kill their velocity/inertia and/or how do you deal with the possibility that you may transform an object ‘on top’ of another object??

The rigidbody “energy” is stored in rigidbody.velocity and rigidbody.angularVelocity - you must zero both to effectively stop the rigidbody (although angularVelocity isn’t too perceptible in a sphere).

But rigidbodies can’t penetrate each other, or a “penalty” force is applied to push both away - that’s probably what pushes the spheres at “random” directions.

You can use Rigidbody.SweepTest to predict a collision, like syclamoth suggested: do the sweep test from the current position to the center, and if something is hit, use the RaycastHit info to find a safe free spot:

var center = Vector3(0,1.5,0); // center point
var radius = 0.5; // radius of this sphere

function OnTriggerEnter (other : Collider) {
  var rgd = other.rigidbody;
  if (rgd){
    rgd.velocity = Vector3.zero; // kill the rigidbody energy
    rgd.angularVelocity = Vector3.zero; // including the angular one
    var newPos = center; // let's suppose the center is free
    var sweepDir = center - rgd.position; // sweep direction = sphere->center
    var hit: RaycastHit;
    if (rdg.SweepTest(dir, hit, dir.magnitude)){ // if something hit...
      // get a vector from the hit object's center to the hit point
      var hitDir = hit.point - hit.transform.position;
      // calculate the "no-hit" point:
      newPos = hit.point + radius * hitDir.normalized;
    }
    transform.position = newPos;
}