using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; [System.Serializable] public class ParallaxLayerConfig { public GameObject layer; // 背景层的游戏对象 public float scrollSpeed; // 每层的滚动速度 public float scrollOffset; // 每层的滚动偏移量 } public class ParallaxManager : MonoBehaviour { public ParallaxLayerConfig[] layerConfigs; // 背景层配置数组 public ParallaxObjectCategoryConfig[] categoryConfigs; // 多种物体配置类别 public float speedMultiplier = 1; // 加速系数 private Dictionary> objectPools = new Dictionary>(); // 物体池 void Start() { // 初始化背景层滚动 foreach (var config in layerConfigs) { StartLayerScroll(config); } // 初始化物体池并启动物体生成逻辑 foreach (var category in categoryConfigs) { InitializeObjectPool(category); if (category.useIntervalGeneration) { StartCoroutine(ManageObjectGeneration(category)); } else { // 按照距离生成 StartCoroutine(ManageObjectGenerationByDistance(category)); } // category.SpawnObjects(this); // 启动物体生成 } } // 初始化物体池 private void InitializeObjectPool(ParallaxObjectCategoryConfig categoryConfig) { List pool = new List(); for (int i = 0; i < categoryConfig.objects.Length; i++) { GameObject prefab = categoryConfig.objects[i]; GameObject obj = Instantiate(prefab, prefab.transform.position, Quaternion.identity, transform); obj.SetActive(false); pool.Add(obj); } objectPools[categoryConfig.categoryName] = pool; Debug.Log($"为分类 {categoryConfig.categoryName} 初始化池子,池中物体数:{pool.Count}"); } // 开始背景层滚动 private void StartLayerScroll(ParallaxLayerConfig config) { Vector3 startPosition = config.layer.transform.position; float endPositionX = startPosition.x - config.scrollOffset; config.layer.transform.DOLocalMoveX(endPositionX, config.scrollSpeed * speedMultiplier) .SetEase(Ease.Linear) .OnKill(() => ResetLayerPosition(config)); } // 重置背景层位置 private void ResetLayerPosition(ParallaxLayerConfig config) { Vector3 currentPosition = config.layer.transform.position; config.layer.transform.position = new Vector3(currentPosition.x + config.scrollOffset * 2, currentPosition.y, currentPosition.z); StartLayerScroll(config); } // 管理物体生成(基于距离) public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig categoryConfig) { var pool = objectPools[categoryConfig.categoryName]; GameObject firstObject = pool[0]; if (!firstObject.activeInHierarchy) { firstObject.transform.position = categoryConfig.objects[0].transform.position; firstObject.SetActive(true); StartObjectMoveAnimation(firstObject, categoryConfig); Debug.Log($"生成了第一个物体: {firstObject.name}, 位置: {firstObject.transform.position}"); } GameObject lastObject = firstObject; //GameObject lastObject = null; while (true) { // 检查是否需要生成新物体 if (lastObject == null || lastObject.transform.position.x < categoryConfig.generationThreshold) { GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName); if (obj != null) { SpawnObject(obj, categoryConfig); lastObject = obj; } } yield return null; } } // 管理物体生成:按时间间隔生成 public IEnumerator ManageObjectGeneration(ParallaxObjectCategoryConfig categoryConfig) { if (!objectPools.ContainsKey(categoryConfig.categoryName)) { Debug.LogError($"没有为分类 {categoryConfig.categoryName} 初始化对象池!"); yield break; } var pool = objectPools[categoryConfig.categoryName]; // // 初始化生成第一个物体 // GameObject firstObject = pool.Find(o => !o.activeInHierarchy); // if (firstObject != null) // { // firstObject.SetActive(true); // StartObjectMoveAnimation(firstObject, categoryConfig); // //SpawnObject(firstObject, categoryConfig); // Debug.Log($"初始生成物体: {firstObject.name}, 位置: {firstObject.transform.position}"); // } // else // { // Debug.LogWarning($"对象池 {categoryConfig.categoryName} 没有可用的初始物体!"); // } // 持续生成物体 while (true) { yield return new WaitForSeconds(categoryConfig.spawnInterval); // 从池中查找未激活的对象 // GameObject obj = pool.Find(o => !o.activeInHierarchy); GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName); if (obj != null) { SpawnObject(obj, categoryConfig); Debug.Log($"生成物体: {obj.name}, 当前池大小: {pool.Count}"); } else { Debug.LogWarning($"对象池 {categoryConfig.categoryName} 中没有可用物体!可能需要增加池中物体数量。"); } } } // 获取池中未激活的物体 private GameObject GetInactiveObjectFromPool(string categoryName) { if (objectPools.TryGetValue(categoryName, out var pool)) { // 筛选出所有未激活的对象 var inactiveObjects = pool.FindAll(o => !o.activeInHierarchy); if (inactiveObjects.Count > 0) { // 从未激活的对象中随机选择一个 return inactiveObjects[Random.Range(0, inactiveObjects.Count)]; } } return null; // 如果没有未激活的对象 } // 生成物体逻辑 private void SpawnObject(GameObject obj, ParallaxObjectCategoryConfig categoryConfig) { float xStart = categoryConfig.xSpawnRange; //float yStart = obj.objects; // 可配置的随机高度范围 obj.transform.position = new Vector3(xStart, obj.transform.position.y, obj.transform.position.z); obj.SetActive(true); StartObjectMoveAnimation(obj, categoryConfig); } // 启动物体移动动画 private void StartObjectMoveAnimation(GameObject obj, ParallaxObjectCategoryConfig config) { float endX = -config.xSpawnRange; obj.transform.DOMoveX(endX, config.speed * speedMultiplier) .SetEase(Ease.Linear) .OnKill(() => { obj.SetActive(false); Debug.Log($"物体 {obj.name} 动画结束,回收到池中"); }); } }