I want to share my final solution which works quite well. Maybe it can help someone else.
Summary: I used a trigger - instead of collision - in order to fully avoid any physical interaction between the objects and simulated the physical impact on the coin manually. This works better than initially expected ;-)
The setup for the coin game object (which shall receive the simulated physical impact) looks like this:
The coin_Master has a Collider with isTrigger = true and the Layer set to "Collectibles_noCollision"
The justCollider sub-object has just another collider with isTrigger = false and the Layer set to "Collectibles_DoCollision".
The layer collision matrix looks like this:
And this is the code which simulates the physical interaction. As you can see there are some parameters with which I finetuned the solution.
// The Collider of the coins has to be marked as "Is Trigger"
private void OnTriggerEnter(Collider other)
{
HandleTrigger(other);
}
private void HandleTrigger(Collider other)
{
if (other.CompareTag("Player"))
{
// Calculate an impulse, e.g., away from the player
Vector3 adjustedPlayerPosition = other.transform.position + new Vector3(0, 0, -1);
Vector3 direction = (transform.position - adjustedPlayerPosition).normalized;
// Get current player speed
Rigidbody playerRigidbody = other.GetComponent<Rigidbody>();
float playerSpeed = playerRigidbody.linearVelocity.magnitude;
float speedFactor = 0.18f; // Scaling factor to adjust the influence of player speed
// Calculate the final impulse:
// Here, the base impulse (impulseForce) is multiplied by the player's speed.
// You can also add or weight both components (the base impulse and speed).
Vector3 finalImpulse = direction * impulseForce * (1 + speedFactor * playerSpeed);
// Define scaling factor for negative y-component
float yScale = 0.2f; // Example: 20% of the original Y-force if downward
// If the y-value is negative, weaken it -> avoid a too strong braking effect, if the player is (much) bigger than the target object (coin)
if (finalImpulse.y < 0)
{
// Debug.Log($"LevelObject_Coin > OnTriggerEnter > CORRECTing y impulse - finalImpulse: {finalImpulse} finalImpulse.y: {finalImpulse.y} ");
finalImpulse.y *= yScale;
}
Debug.Log($"LevelObject_Coin > OnTriggerEnter {gameObject.name} > playerSpeed: {playerSpeed} finalImpulse: " + finalImpulse + "> finalImpulse.magnitude: " + finalImpulse.magnitude);
// Apply the impulse – using ForceMode.Impulse for an immediate effect
coinRigidbody.AddForce(finalImpulse, ForceMode.Impulse);
// Disable the trigger or collider object, so this logic is only executed once
coinCollider.enabled = false;
}
}