The very easiest and most consistent way is to keep the object in control of the physics system at all times. That way, it can handle the collisions and physics responses internally.
Your code could then look something like this:
Rigidbody body;
void Start() {
body = GetComponent<Rigidbody>();
}
void FixedUpdate() {
if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
{
var touch = Input.GetTouch(0);
var touchVelocity = touch.deltaPosition/touch.deltaTime;
var targetVelocity = touchVelocity * speedMultiplier;
body.velocity = targetVelocity;
}
}
I've removed the foreach
because you weren't actually using the results of the additional touches - touch 0 was the only one your code ever read, it just applied touch 0 repeatedly if there were other touches present.
I also simplified the multiplication by speed
(you don't need to do it one component at a time) and renamed the varaible to speedMultiplier
to convey that it's a magnification/minification factor on the speed of the touch itself. I adjusted the touch deltaPosition
by its deltaTime
so that you get consistent results independent of the relative timing/sampling frequency of touch updates and FixedUpdate
.
Or, if you want to move using transform.Translate
then you should "look before you leap": do your physics query first to check how far you can move, and then move only that far.
Vector3 direction = targetVelocity.normalized;
float maxTravelThisFrame = targetVelocity.magnitude * Time.deltaTime;
RaycastHit hit;
if ( Physics.BoxCast(
transform.position, // Where our cube is now.
halfExtents, // How big is our cube, measured from the center out?
direction, // Which direction do we want the cube to go?
out hit, // Capture information about what we hit.
transform.rotation, // How is our cube oriented?
maxTravelThisFrame // Where to stop our query?
)) {
// Moving a hair less than we're allowed leaves us some padding,
// helping to avoid kissing contacts & unintended tunneling.
maxTravelThisFrame = Mathf.Max(0, hit.distance - 0.001f);
}
transform.Translate(maxTravelThisFrame * direction, Space.World);
Lastly, I've noticed in your previous versions of this question, you were using a mix of 2D and 3D physics types. These are processed by completely separate physics engines in Unity, so a 3D Rigidbody or BoxCast will not respond to collisions with a BoxCollider2D. Be sure you're using one regime - 2D or 3D - consistently, with all physics components and callback methods you want to interact together.