I am making a 2D game in which an object deflects of the wall. I am able to get the reflection vector easily by using Vector2.Reflect method. passing the inDirection and the surface normal. The question: is it possible to fake the normal? I know normal is always perpendicular to the surface(90 Degree) But I want it to be a little less or more based on a condition(±45). The image will explain it better.

The blue line is the normal result, I want to get the one in red

There’s various ways of doing that but here’s one way that should work:

// Create the normal vector of the surface (in this case just a horizontal plane facing upwards)
Vector2 normalVec = new Vector2( 0.0f , -1.0f );
// Create the incoming vector (in this case just a ray pointing straight down)
Vector2 rayVec = new Vector2( 0.0f , 1.0f );
// Create the reflection vector (in this case a ray pointing straight up)
Vector2 reflectVec = Vector2.Reflect( rayVec , normalVec );
Vector2 reflectVecWithOffset = new Vector2();
// Find the angle of the reflection vector (in radians)
float reflectAngle = Mathf.Atan2( reflectVec.y , reflectVec.x );
// Add a plus/minus 20 degree offset to that angle
reflectAngle += UnityEngine.Random.Range( -20.0f , 20.0f ) * Mathf.Deg2Rad;
// Create a new normal vector with the offset on it
reflectVecWithOffset.x = Mathf.Cos( reflectAngle );
reflectVecWithOffset.y = Mathf.Sin( reflectAngle );
// 'reflectVecWithOffset' is now your reflected vector with some offset

Rotate the normal vector by X degrees before you use it in Vecto2.Reflect.

I don’t think Unity specifically has a ‘Vector2.Rotate’ method (maybe they’ve added it… but they didn’t before).

Here is my own implementation:

public static Vector2 RotateBy(Vector2 v, float a, bool bUseRadians = false)
{
if (!bUseRadians) a *= MathUtil.DEG_TO_RAD;
var ca = System.Math.Cos(a);
var sa = System.Math.Sin(a);
var rx = v.x * ca - v.y * sa;
return new Vector2((float)rx, (float)(v.x * sa + v.y * ca));
}

However now that I’m thinking about this more, it’s probably best to calculate the axis of rotation rather than assuming Vector3.forward, because if the reflection is inverted, the rotation axis would be inverted as well.