我正在开发一个无限滚动条,其中玩家和摄像机是静止的,而平台和背景向它们移动。一旦一个物体第一次进入相机,它就会在 BoxCollider2D 的右边缘创建一个自己的副本,一旦它存在,它就会被销毁。
地板、天花板、天空、云彩和前景中的每一个都附有以下脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InfiniteScroller : MonoBehaviour
{
// Variables to control the parallax effect
// A value of 1 means the object will move at the same speed as the camera
// A value of 0 means the object will not move at all
public float parallaxCoefficient = 1;
// Variable to store the player controller script where the speed is stored
PlayerController playerController;
// Collider and its properties
BoxCollider2D col;
float colPositionX;
float colHalfWidth;
// Camera and its properties
Camera cam;
float camPositionX;
float camHalfWidth;
// Variables to control the state of the object
bool hasCreatedNewObject;
bool visibleFirstTime;
// Start is called before the first frame update
void Start()
{
// Fetch the collider and its properties
col = GetComponent<BoxCollider2D>();
colPositionX = col.transform.position.x;
colHalfWidth = col.size.x/2;
// Fetch the camera and its properties
cam = Camera.main;
camPositionX = cam.transform.position.x;
camHalfWidth = cam.aspect * cam.orthographicSize;
// fetch the player controller, we do it in start() because fetching the player controller in update() in every frame is expensive
playerController = GameObject.Find("Player").GetComponent<PlayerController>();
// set the state of the object to its initial state
hasCreatedNewObject = false;
visibleFirstTime = CheckIsVisible();
}
// Update is called once per frame
void Update()
{
// determine whether the object is visible
bool visible = CheckIsVisible();
// if the object is visible for the first time, create a new object
if (visible)
{
if (!hasCreatedNewObject) {
// create a new object
GameObject newObject = Instantiate(gameObject, new Vector2(colPositionX + colHalfWidth, transform.position.y), Quaternion.identity);
// set the state of the object to its initial state
hasCreatedNewObject = true;
}
if (!visibleFirstTime) visibleFirstTime = true;
}
else
{
// if the object is not visible, destroy it
if (visibleFirstTime) Destroy(gameObject);
}
}
// FixedUpdate is called once per physics update
void FixedUpdate()
{
// get the speed from the player controller
float speed = playerController.speed;
// // Move the object to the left
transform.Translate(Vector2.left * speed * parallaxCoefficient * Time.deltaTime);
}
// check if the object is visible by the camera
bool CheckIsVisible()
{
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(cam);
return GeometryUtility.TestPlanesAABB(planes, col.bounds);
}
}
结果并不是我真正想要的,因为生成的对象相互进入。这是结果(您可以看到碰撞盒重叠):
这是我的项目层次结构的样子: