视差滚动:
通常相机和人物绑定以一定的速度向前,而背后的景物设置不同的速度这样就实现了视差效果
- 获取主相机的transform,记录相机的初始位置
- 记录相机的移动的位置,刷新背景的位置(因为保证不同速度所以要乘以一个系数),刷新相机初始位置(通过计算每帧的路程实现速度不一样)
无限背景:
- 获取sprite,再获取texture
- 计算材质再unity中占几个单位(unity中的默认单位是:1单位100px)
- 当摄像机位置减去背景的位置的绝对值(左右)大于材质宽度(unity单位)时刷新背景位置
代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BackGroundController : MonoBehaviour
{
private Transform cameraTransform;
private Vector3 lastCameraPosition;
[SerializeField] private float parallaxCoefficient;
private Sprite bgSprite;
private Texture2D bgTexture;
private float textureUnitSizeX;
// Start is called before the first frame update
void Start()
{
parallaxCoefficient = 0.5f;
cameraTransform = Camera.main.transform;
lastCameraPosition = cameraTransform.position;
bgSprite = GetComponent<SpriteRenderer>().sprite;
bgTexture = bgSprite.texture;
textureUnitSizeX = bgTexture.width / bgSprite.pixelsPerUnit;
}
// Update is called once per frame
void Update()
{
Vector3 deltaMovement = cameraTransform.position - lastCameraPosition;
transform.position += new Vector3(deltaMovement.x * parallaxCoefficient,0,0);
lastCameraPosition = cameraTransform.position;
if (Mathf.Abs(cameraTransform.position.x - transform.position.x) >= textureUnitSizeX)
{
float offsetPositionX = (cameraTransform.position.x- transform.position.x) % textureUnitSizeX;
transform.position = new Vector3(cameraTransform.position.x+offsetPositionX, transform.position.y, transform.position.z);
}
}
}
/*
视差滚动:
通常相机和人物绑定以一定的速度向前,而背后的景物设置不同的速度这样就实现了视差效果
1.获取主相机的transform,记录相机的初始位置
2.记录相机的移动的位置,刷新背景的位置(因为保证不同速度所以要乘以一个系数),刷新相机初始位置(通过计算每帧的路程实现速度不一样)
无限背景:
1.获取sprite,再获取texture
2.计算材质再unity中占几个单位(unity中的默认单位是:1单位100px)
3.当摄像机位置减去背景的位置的绝对值(左右)大于材质宽度(unity单位)时刷新背景位置
*/
知识点
[SerializeField]private float parallaxCoefficient;
[SerializeField]序列化可以使私有属性在unity中显示
cameraTransform=Camera.main.transform;
获取主相机的transform
GetComponent<SpriteRenderer>().sprite;
获取SpriteRenderer组件里的sprite
bgTexture = bgSprite.texture;
从sprite里获取材质
Texture:Unity 将3D工程目录下的Asset文件夹下的任何图片和 image or movie file 识别为Texture (2D projects工程中,它们被当作 Sprites). 只要图像符合下列尺寸要求, ).
textureUnitSizeX = bgTexture.width / bgSprite.pixelsPerUnit;
将材质大小由像素转换为unity单位(默认为1unity单位为100px)
bgTexture.width:材质的像素宽
bgSprite.pixelsPerUnit:精灵图每单元的像素数
Vector3 deltaMovement = cameraTransform.position - lastCameraPosition;
三维数据可由三维数据互相减而得(加法同理)
transform.position += new Vector3(deltaMovement.x * parallaxCoefficient,0,0);
parallaxCoefficient为视差系数,给不同的图层设置不同的系数,这样每帧每个图层移动不同的距离可以形成良好的视差效果。
transform.position不可以直接指定,需要用new Vector3
Mathf.Abs()
绝对值
使用public在unity中绑定可方便自己处理获取的问题
无限背景的详解:
首先打开图像平铺,平铺的足够长(要足够长)
背景中心点的起始位置:
想法:
当角色移动到移动到平铺图中第二个这样的起始位置时,背景图死心移到摄像机的x处(摄像机和角色绑定)
第二个这样的起始位置:
这样便可以实现无限背景。
问题:
offsetPositionX的作用是什么?
float offsetPositionX = (cameraTransform.position.x- transform.position.x) % textureUnitSizeX;
transform.position = new Vector3(cameraTransform.position.x+offsetPositionX, transform.position.y, transform.position.z)
因为update是每帧执行一次,所以在渲染的时间间隔内可能出现:
Mathf.Abs(cameraTransform.position.x - transform.position.x) != textureUnitSizeX
假设人物在间隔内走到了箭头所指的地方,然后执行
if (Mathf.Abs(cameraTransform.position.x - transform.position.x) >= textureUnitSizeX)
{
float offsetPositionX = (cameraTransform.position.x- transform.position.x) % textureUnitSizeX;
transform.position = new Vector3(cameraTransform.position.x+offsetPositionX, transform.position.y, transform.position.z);
}
图像的死心就定位到人物的x处,这样便会出现人物倒退的现象。
为什么最后一个背景会出现抖动的情况?
这个问题我也不太清楚,知道的朋友可以告诉我下。
已知:我把函数放在了fixedupdate中,如果我将时间调小则可以减轻抖动