FMOD功能迁移
This commit is contained in:
@@ -10,7 +10,7 @@ using AibisDream;
|
||||
public class ParallaxLayerConfig
|
||||
{
|
||||
public GameObject layer; // 背景层的游戏对象
|
||||
[SerializeField, Range(0.01f, 1f)]public float scrollSpeed; // 每层的滚动速度
|
||||
[SerializeField, Range(0.01f, 1f)] public float scrollSpeed; // 每层的滚动速度
|
||||
public float scrollOffset; // 每层的滚动偏移量
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ParallaxManager : MonoBehaviour
|
||||
public float speedMultiplier = 1; // 加速系数
|
||||
public ParallaxLayerConfig[] layerConfigs; // 背景层配置数组
|
||||
public ParallaxObjectCategoryConfig[] categoryConfigs; // 多种物体配置类别
|
||||
|
||||
|
||||
public GameObject tunnelSprite; // 隧道的 Sprite 对象
|
||||
|
||||
public SpriteRenderer sisterSpriteRender; // 隧道的 Sprite 对象
|
||||
@@ -35,40 +35,42 @@ public class ParallaxManager : MonoBehaviour
|
||||
private float previousSpeedMultiplier; // 用于记录上一次的值
|
||||
|
||||
[YarnCommand("EnterTunnel")]
|
||||
public void EnterTunnel()
|
||||
public void EnterTunnel()
|
||||
{
|
||||
if (tunnelSprite != null && !isInTunnel)
|
||||
{
|
||||
tunnelSprite.transform.position=tunnelEnterPosition;
|
||||
tunnelSprite.transform.position = tunnelEnterPosition;
|
||||
isInTunnel = true;
|
||||
// 使用 DOTween 播放隧道进入动画
|
||||
sisterSpriteRender.DOFade(0.4f,tunnelDuration);
|
||||
sisterSpriteRender.DOFade(0.4f, tunnelDuration);
|
||||
tunnelSprite.transform.DOMove(tunnelKeepPosition, tunnelDuration)
|
||||
.SetEase(Ease.Linear)
|
||||
.OnStart(() => Debug.Log("开始进入隧道"))
|
||||
.OnKill(() => {
|
||||
Debug.Log("已完成进入隧道");
|
||||
ToggleCategoryVisibility("隧洞灯",true);
|
||||
|
||||
.OnKill(() =>
|
||||
{
|
||||
Debug.Log("已完成进入隧道");
|
||||
ToggleCategoryVisibility("隧洞灯", true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[YarnCommand("ExitTunnel")]
|
||||
public void ExitTunnel()
|
||||
{
|
||||
if (tunnelSprite != null && isInTunnel)
|
||||
{
|
||||
isInTunnel = false;
|
||||
ToggleCategoryVisibility("隧洞灯",false);
|
||||
sisterSpriteRender.DOFade(0,tunnelDuration);
|
||||
ToggleCategoryVisibility("隧洞灯", false);
|
||||
sisterSpriteRender.DOFade(0, tunnelDuration);
|
||||
// 使用 DOTween 播放隧道退出动画
|
||||
tunnelSprite.transform.DOMove(tunnelExitPosition, tunnelDuration)
|
||||
.SetEase(Ease.Linear)
|
||||
.OnStart(() => Debug.Log("开始退出隧道"))
|
||||
.OnKill(() => {
|
||||
Debug.Log("已完成退出隧道");
|
||||
ToggleCategoryVisibility("隧洞灯",false);
|
||||
tunnelSprite.transform.position=tunnelEnterPosition;
|
||||
.OnKill(() =>
|
||||
{
|
||||
Debug.Log("已完成退出隧道");
|
||||
ToggleCategoryVisibility("隧洞灯", false);
|
||||
tunnelSprite.transform.position = tunnelEnterPosition;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -82,9 +84,10 @@ public class ParallaxManager : MonoBehaviour
|
||||
previousSpeedMultiplier = speedMultiplier; // 记录当前值
|
||||
Debug.Log($"运行时修改 DOTween.timeScale 为 {speedMultiplier}");
|
||||
}
|
||||
if(Input.GetKeyDown(KeyCode.E))
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.E))
|
||||
{
|
||||
if(isInTunnel)
|
||||
if (isInTunnel)
|
||||
{
|
||||
ExitTunnel();
|
||||
}
|
||||
@@ -92,15 +95,15 @@ public class ParallaxManager : MonoBehaviour
|
||||
{
|
||||
EnterTunnel();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
// 当新速度值变化时,实时更新背景层和物体的速度
|
||||
foreach (var config in layerConfigs)
|
||||
{
|
||||
StartLayerScroll(config); // 重新启动背景层滚动
|
||||
StartLayerScroll(config); // 重新启动背景层滚动
|
||||
}
|
||||
|
||||
foreach (var category in categoryConfigs)
|
||||
@@ -117,15 +120,12 @@ public class ParallaxManager : MonoBehaviour
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Start()
|
||||
{
|
||||
AudioManager.PlayAmb1Audio("amb_subway");
|
||||
AudioManager.PlayAmb1Audio("music_subway");
|
||||
// 初始化记录的值
|
||||
Color color = sisterSpriteRender.color;
|
||||
color.a = 0;
|
||||
@@ -152,7 +152,7 @@ public class ParallaxManager : MonoBehaviour
|
||||
{
|
||||
// 按照距离生成
|
||||
StartCoroutine(ManageObjectGenerationByDistance(category));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ public class ParallaxManager : MonoBehaviour
|
||||
pool.Add(obj);
|
||||
obj.SetActive(false); // 初始时禁用物体
|
||||
}
|
||||
|
||||
objectPools[categoryConfig.categoryName] = pool;
|
||||
|
||||
Debug.Log($"为分类 {categoryConfig.categoryName} 初始化池子,池中物体数:{pool.Count}");
|
||||
@@ -176,11 +177,11 @@ public class ParallaxManager : MonoBehaviour
|
||||
private void StartLayerScroll(ParallaxLayerConfig config)
|
||||
{
|
||||
Vector3 startPosition = config.layer.transform.position;
|
||||
float endPositionX = - config.scrollOffset;
|
||||
|
||||
float endPositionX = -config.scrollOffset;
|
||||
|
||||
// 计算需要的时间,基于速度和距离
|
||||
float distance = Mathf.Abs(endPositionX - startPosition.x);
|
||||
float duration = distance / config.scrollSpeed; // 使用速度来计算时间
|
||||
float duration = distance / config.scrollSpeed; // 使用速度来计算时间
|
||||
|
||||
// 背景层滚动时不受 speedMultiplier 影响
|
||||
config.layer.transform.DOLocalMoveX(endPositionX, duration)
|
||||
@@ -198,87 +199,90 @@ public class ParallaxManager : MonoBehaviour
|
||||
}
|
||||
|
||||
// 管理物体生成:按时间间隔生成
|
||||
public IEnumerator ManageObjectGeneration(ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
if (!objectPools.ContainsKey(categoryConfig.categoryName))
|
||||
public IEnumerator ManageObjectGeneration(ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
Debug.LogError($"没有为分类 {categoryConfig.categoryName} 初始化对象池!");
|
||||
yield break;
|
||||
}
|
||||
|
||||
var pool = objectPools[categoryConfig.categoryName];
|
||||
int batchSize = categoryConfig.batchSize; // 每次生成的物体数量
|
||||
float batchInterval = categoryConfig.batchInterval; // 每个物体之间的生成间隔
|
||||
float delayAfterBatch = categoryConfig.delayAfterBatch; // 每组生成后的等待时间
|
||||
|
||||
// 启动首个物体
|
||||
GameObject firstObject = pool[0];
|
||||
if (!firstObject.activeInHierarchy)
|
||||
{
|
||||
|
||||
firstObject.transform.position = firstObject.transform.position; // 保持编辑器中的初始位置
|
||||
firstObject.SetActive(true); // 启用物体
|
||||
StartObjectMoveAnimation(firstObject, categoryConfig);
|
||||
Debug.Log($"初始化并激活首个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
|
||||
ToggleCategoryVisibility(categoryConfig.categoryName,categoryConfig.isEnabled);
|
||||
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 连续生成多个物体
|
||||
for (int i = 0; i < batchSize; i++)
|
||||
if (!objectPools.ContainsKey(categoryConfig.categoryName))
|
||||
{
|
||||
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
|
||||
if (obj != null)
|
||||
{
|
||||
SpawnObject(obj, categoryConfig);
|
||||
Debug.Log($"生成物体: {obj.name}, 当前池大小: {pool.Count}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"对象池 {categoryConfig.categoryName} 中没有可用物体!可能需要增加池中物体数量。");
|
||||
}
|
||||
|
||||
// 每个物体之间的间隔
|
||||
yield return new WaitForSeconds(Random.Range(batchInterval-1f,batchInterval+1f) / speedMultiplier); // 使用 speedMultiplier 来控制生成速率
|
||||
Debug.LogError($"没有为分类 {categoryConfig.categoryName} 初始化对象池!");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// 等待一段时间后再开始下一组生成
|
||||
yield return new WaitForSeconds(Random.Range(delayAfterBatch-1f,delayAfterBatch+1.5f) / speedMultiplier); // 使用 speedMultiplier 来控制生成间隔
|
||||
var pool = objectPools[categoryConfig.categoryName];
|
||||
int batchSize = categoryConfig.batchSize; // 每次生成的物体数量
|
||||
float batchInterval = categoryConfig.batchInterval; // 每个物体之间的生成间隔
|
||||
float delayAfterBatch = categoryConfig.delayAfterBatch; // 每组生成后的等待时间
|
||||
|
||||
// 启动首个物体
|
||||
GameObject firstObject = pool[0];
|
||||
if (!firstObject.activeInHierarchy)
|
||||
{
|
||||
firstObject.transform.position = firstObject.transform.position; // 保持编辑器中的初始位置
|
||||
firstObject.SetActive(true); // 启用物体
|
||||
StartObjectMoveAnimation(firstObject, categoryConfig);
|
||||
Debug.Log($"初始化并激活首个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
|
||||
ToggleCategoryVisibility(categoryConfig.categoryName, categoryConfig.isEnabled);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 连续生成多个物体
|
||||
for (int i = 0; i < batchSize; i++)
|
||||
{
|
||||
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
|
||||
if (obj != null)
|
||||
{
|
||||
SpawnObject(obj, categoryConfig);
|
||||
Debug.Log($"生成物体: {obj.name}, 当前池大小: {pool.Count}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"对象池 {categoryConfig.categoryName} 中没有可用物体!可能需要增加池中物体数量。");
|
||||
}
|
||||
|
||||
// 每个物体之间的间隔
|
||||
yield return
|
||||
new WaitForSeconds(Random.Range(batchInterval - 1f, batchInterval + 1f) /
|
||||
speedMultiplier); // 使用 speedMultiplier 来控制生成速率
|
||||
}
|
||||
|
||||
// 等待一段时间后再开始下一组生成
|
||||
yield return new WaitForSeconds(
|
||||
Random.Range(delayAfterBatch - 1f, delayAfterBatch + 1.5f) /
|
||||
speedMultiplier); // 使用 speedMultiplier 来控制生成间隔
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 管理物体生成(基于距离)
|
||||
public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
var pool = objectPools[categoryConfig.categoryName];
|
||||
GameObject firstObject = pool[0];
|
||||
if (!firstObject.activeInHierarchy)
|
||||
public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
firstObject.transform.position = categoryConfig.objects[0].transform.position;
|
||||
firstObject.SetActive(true); // 启用物体
|
||||
StartObjectMoveAnimation(firstObject, categoryConfig);
|
||||
ToggleCategoryVisibility(categoryConfig.categoryName,categoryConfig.isEnabled);
|
||||
Debug.Log($"生成了第一个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
|
||||
|
||||
}
|
||||
GameObject lastObject = firstObject;
|
||||
while (true)
|
||||
{
|
||||
// 检查是否需要生成新物体
|
||||
if (lastObject == null || lastObject.transform.position.x < -categoryConfig.generationThreshold)
|
||||
var pool = objectPools[categoryConfig.categoryName];
|
||||
GameObject firstObject = pool[0];
|
||||
if (!firstObject.activeInHierarchy)
|
||||
{
|
||||
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
|
||||
if (obj != null)
|
||||
firstObject.transform.position = categoryConfig.objects[0].transform.position;
|
||||
firstObject.SetActive(true); // 启用物体
|
||||
StartObjectMoveAnimation(firstObject, categoryConfig);
|
||||
ToggleCategoryVisibility(categoryConfig.categoryName, categoryConfig.isEnabled);
|
||||
Debug.Log($"生成了第一个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
|
||||
}
|
||||
|
||||
GameObject lastObject = firstObject;
|
||||
while (true)
|
||||
{
|
||||
// 检查是否需要生成新物体
|
||||
if (lastObject == null || lastObject.transform.position.x < -categoryConfig.generationThreshold)
|
||||
{
|
||||
SpawnObject(obj, categoryConfig);
|
||||
lastObject = obj;
|
||||
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
|
||||
if (obj != null)
|
||||
{
|
||||
SpawnObject(obj, categoryConfig);
|
||||
lastObject = obj;
|
||||
}
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取池中未激活的物体
|
||||
private GameObject GetInactiveObjectFromPool(string categoryName)
|
||||
@@ -294,32 +298,32 @@ public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig
|
||||
return inactiveObjects[Random.Range(0, inactiveObjects.Count)];
|
||||
}
|
||||
}
|
||||
|
||||
return null; // 如果没有未激活的对象
|
||||
}
|
||||
|
||||
// 生成物体逻辑
|
||||
private void SpawnObject(GameObject obj, ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
float xStart = categoryConfig.xSpawnRange;
|
||||
obj.transform.localPosition = new Vector3(xStart, obj.transform.localPosition.y, obj.transform.localPosition.z);
|
||||
obj.SetActive(true);
|
||||
ToggleCategoryVisibility(categoryConfig.categoryName, categoryConfig.isEnabled);
|
||||
StartObjectMoveAnimation(obj, categoryConfig);
|
||||
|
||||
float xStart = categoryConfig.xSpawnRange;
|
||||
obj.transform.localPosition = new Vector3(xStart, obj.transform.localPosition.y, obj.transform.localPosition.z);
|
||||
obj.SetActive(true);
|
||||
ToggleCategoryVisibility(categoryConfig.categoryName,categoryConfig.isEnabled);
|
||||
StartObjectMoveAnimation(obj, categoryConfig);
|
||||
|
||||
Debug.Log($"生成物体 {obj.name} 并开始移动, 初始位置: {obj.transform.position}");
|
||||
|
||||
Debug.Log($"生成物体 {obj.name} 并开始移动, 初始位置: {obj.transform.position}");
|
||||
}
|
||||
|
||||
// 启动物体移动动画
|
||||
private void StartObjectMoveAnimation(GameObject obj, ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
// 计算目标位置
|
||||
Vector3 targetPosition = new Vector3(-categoryConfig.xSpawnRange, obj.transform.position.y, obj.transform.position.z);
|
||||
|
||||
Vector3 targetPosition =
|
||||
new Vector3(-categoryConfig.xSpawnRange, obj.transform.position.y, obj.transform.position.z);
|
||||
|
||||
// 计算当前位置与目标位置的水平距离
|
||||
float distance = Mathf.Abs(obj.transform.position.x - targetPosition.x);
|
||||
|
||||
|
||||
// 计算动画的持续时间:距离 / 速度
|
||||
float duration = distance / categoryConfig.speed;
|
||||
|
||||
@@ -331,56 +335,54 @@ public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig
|
||||
// 物体移动完成后处理
|
||||
private void HandleObjectCompletion(GameObject obj, ParallaxObjectCategoryConfig categoryConfig)
|
||||
{
|
||||
obj.SetActive(false); // 隐藏物体
|
||||
obj.SetActive(false); // 隐藏物体
|
||||
Debug.Log($"物体 {obj.name} 移动完成,回收到池中");
|
||||
}
|
||||
|
||||
// 控制分类的显示与隐藏
|
||||
public void ToggleCategoryVisibility(string categoryName, bool isEnabled)
|
||||
{
|
||||
var category = System.Array.Find(categoryConfigs, config => config.categoryName == categoryName);
|
||||
if (category != null)
|
||||
{
|
||||
category.isEnabled = isEnabled;
|
||||
|
||||
// 遍历该分类的所有物体,并根据 isEnabled 控制它们的显示状态
|
||||
foreach (var obj in objectPools[categoryName])
|
||||
var category = System.Array.Find(categoryConfigs, config => config.categoryName == categoryName);
|
||||
if (category != null)
|
||||
{
|
||||
// 检查父物体是否有 SpriteRenderer
|
||||
var renderer = obj.GetComponent<SpriteRenderer>();
|
||||
|
||||
// 如果父物体没有 SpriteRenderer,检查所有子物体
|
||||
if (renderer == null)
|
||||
category.isEnabled = isEnabled;
|
||||
|
||||
// 遍历该分类的所有物体,并根据 isEnabled 控制它们的显示状态
|
||||
foreach (var obj in objectPools[categoryName])
|
||||
{
|
||||
var childRenderers = obj.GetComponentsInChildren<SpriteRenderer>();
|
||||
if (childRenderers.Length > 0)
|
||||
// 检查父物体是否有 SpriteRenderer
|
||||
var renderer = obj.GetComponent<SpriteRenderer>();
|
||||
|
||||
// 如果父物体没有 SpriteRenderer,检查所有子物体
|
||||
if (renderer == null)
|
||||
{
|
||||
// 如果找到子物体的 SpriteRenderer,修改它们的显示状态
|
||||
foreach (var childRenderer in childRenderers)
|
||||
var childRenderers = obj.GetComponentsInChildren<SpriteRenderer>();
|
||||
if (childRenderers.Length > 0)
|
||||
{
|
||||
childRenderer.enabled = isEnabled;
|
||||
// 如果找到子物体的 SpriteRenderer,修改它们的显示状态
|
||||
foreach (var childRenderer in childRenderers)
|
||||
{
|
||||
childRenderer.enabled = isEnabled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果父物体和子物体都没有 SpriteRenderer,输出警告
|
||||
Debug.LogWarning($"物体 {obj.name} 及其子物体均未找到 SpriteRenderer");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果父物体和子物体都没有 SpriteRenderer,输出警告
|
||||
Debug.LogWarning($"物体 {obj.name} 及其子物体均未找到 SpriteRenderer");
|
||||
// 如果父物体有 SpriteRenderer,直接修改父物体的显示状态
|
||||
renderer.enabled = isEnabled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果父物体有 SpriteRenderer,直接修改父物体的显示状态
|
||||
renderer.enabled = isEnabled;
|
||||
}
|
||||
|
||||
Debug.Log($"分类 {categoryName} 已{(isEnabled ? "启用" : "禁用")}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"未找到名为 {categoryName} 的分类");
|
||||
}
|
||||
|
||||
Debug.Log($"分类 {categoryName} 已{(isEnabled ? "启用" : "禁用")}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"未找到名为 {categoryName} 的分类");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user