Here’s how to create a really simple parallax effect in Unity, in this case in the game’s UI.

  • Check if the mouse is inside the Rect, then rotate it based on its distance from the centre.
  • Setup the Character’s frame adding what you prefer;I’ve added a Mask (so the character doesn’t go outside the panel when rotating), a Text and an Image.
  • To create the “Parallax” effect while the panel rotates, move the characters’ image (or the element where you want the effect) backwards/forward. On my example the Z value of the Slime’s transform is set to -100.
  • Reset the target rotation if the mouse is outside the rect and rotate it smoothly.
    • I’m using the function AngleLerp, because if you try to use Vector3.Lerp etc, the transition doesn’t work properly and the angle messes up.

Code

using UnityEngine;
 
[RequireComponent(typeof(RectTransform))]
public class ParallaxPanel : MonoBehaviour
{
 
    //Set to 0 if you want don't want it to rotate along this axis
    public float y_maxRot;
 
    //Set to 0 if you want don't want it to rotate along this axis
    public float x_maxRot;
 
    //Speed for the rotation
    public float speed;
    
    RectTransform rect;
    //The rect we want to rotate
    public RectTransform rectToRotate;
 
    private void Awake()
    {
        rect = GetComponent<RectTransform>();
    }
    
    //Our target eulerangles rotation
    Vector2 targetEulerAngles = Vector3.zero;
 
    /// <summary>
    /// Check each frame where the mouse is and rotates the panel
    /// P.S. if you have multiple panels, use a list of "Panels classes" and use only one update, it's better for performance
    /// You could also look for UI methods from the EventTrigger component
    /// </summary>
    private void Update()
    {
        //Difference between the mouse pos and the panel's position
        Vector2 diff = (Vector2)transform.position - (Vector2)Input.mousePosition;
 
        //If the mouse is inside the rect/panel [...]
        if (Mathf.Abs(diff.x) <= (rect.sizeDelta.x / 2f) &&
            Mathf.Abs(diff.y) <= (rect.sizeDelta.y / 2f))
        {
            targetEulerAngles = new Vector3(
                //Rotates along the X axis, based on the Y distance from the centre
                x_maxRot * -Mathf.Clamp(diff.y / (rect.sizeDelta.y/2f), -1, 1),
                //Same thing, but along the Y axis (so, depends on the X distance)
                y_maxRot * Mathf.Clamp(diff.x / (rect.sizeDelta.x/2f), -1, 1),
                //No rotation along the Z axis
                0);
        }
        else  //Mouse is outside the rect, target euler is zero
        {
            targetEulerAngles = Vector3.zero;
        }
 
        //Lerps the rotation
        rectToRotate.eulerAngles = AngleLerp(rectToRotate.eulerAngles, targetEulerAngles, speed * Time.deltaTime);
    }
 
    //Lerps two angles (using Mathf.LerpAngle for each axis)
    public static Vector3 AngleLerp(Vector3 StartAngle, Vector3 FinishAngle, float t)
    {
        return new Vector3(
            Mathf.LerpAngle(StartAngle.x, FinishAngle.x, t),
            Mathf.LerpAngle(StartAngle.y, FinishAngle.y, t),
            Mathf.LerpAngle(StartAngle.z, FinishAngle.z, t)
            );
    }
    
}