What is Parallax? 什么是视差

简单地说,视差背景其实就是通过多层次的背景来模拟透视视差效果:就是当发生移动时,离照相机越近的背景移动越快;反之越慢。这样,我们的背景就会形成类似于透视视差的效果。

比如:你在火车上高速移动的时候,离你最近的树木会快速向后移动,但离你最远的高山向后移动的速度会变慢。这就是视觉差。

1. 实现 背景跟随人物移动

  • 两帧之间摄像机移动的距离?
  • 背景位置 = 背景位置 + 这个距离

image

2. 实现:背景视差效果

比如:树木,山

人物(摄像机)向前移动 1 m时,树木向前移动 0.4 m, 山向前移动 0.6m

3. 实现:无线滚动效果

image-1704682940003

人物的位置(摄像机) 与 背景的位置 之差 等于 背景的长度。

using UnityEngine;
public class ParallaxBackgournd : MonoBehaviour
{
    private Transform camTF; // 相机的位置
    private Vector3 lastFrameCameraTF; // 最后一帧相机的位置

    [SerializeField]private Vector2 parallaxEffect;
    [SerializeField] private bool LockX;
    [SerializeField] private bool LockY;

    private float textureUnitSizeX;
    private float textureUnitSizeY;

  

    public void Start()
    {
        camTF = Camera.main.transform;
        lastFrameCameraTF = camTF.position;
        Sprite sprite = GetComponent<SpriteRenderer>().sprite;
        textureUnitSizeX = sprite.texture.width / sprite.pixelsPerUnit;
        textureUnitSizeY = sprite.texture.height / sprite.pixelsPerUnit;
    }

    public void LateUpdate()
    {
        Vector3 deltaMovement =  camTF.position - lastFrameCameraTF;
        transform.position = transform.position + 
            new Vector3(deltaMovement.x * parallaxEffect.x, deltaMovement.y * parallaxEffect.y);
        lastFrameCameraTF = camTF.position;

        if (LockX)
        {
            if (Mathf.Abs(camTF.position.x - transform.position.x) >= textureUnitSizeX)
            {
                float offsetPosX = (camTF.position.x - transform.position.x) % textureUnitSizeX;
                transform.position = new Vector3(camTF.position.x + offsetPosX, transform.position.y);
            }
        }
    

        if(LockY)
        {
            if (Mathf.Abs(camTF.position.y - transform.position.y) >= textureUnitSizeY)
            {
                float offsetPosY = (camTF.position.y - transform.position.y) % textureUnitSizeY;
                transform.position = new Vector3(transform.position.x, camTF.position.y + offsetPosY);
            }
        }
    }
  

}