如何修改Unity预制体重力?Spawner脚本修改寿司Prefab重力失效问题
问题原因分析
你的代码存在两个核心问题导致重力缩放修改不符合预期:
- 仅修改单次生成的寿司重力:当前逻辑只在刚好突破里程碑的那一次生成操作中,对当前创建的寿司修改重力,后续生成的寿司依然使用预制体的原始重力值,没有持续应用难度提升的效果。
- 触发条件逻辑缺陷:
sushiCreated > sushiMilestone的判断,在第一次突破10个后,sushiMilestone会被更新为20,后续生成的11-19个寿司都不会触发重力修改,直到第21个寿司才会再执行一次,依然只修改那一个寿司的重力。
修复方案
我们需要维护一个全局的重力缩放变量,每次生成寿司时都将该变量赋值给新寿司的重力属性;同时在突破里程碑时,更新这个全局变量,让后续所有新生成的寿司都应用提升后的重力。
修改后的完整代码
using UnityEngine; public class TargetSpawner : MonoBehaviour { [SerializeField] private BoxCollider2D cd; [SerializeField] private GameObject targetPrefab; [SerializeField] private float cooldown; [SerializeField] private float initialGravityScale = 1f; // 预制体默认重力缩放,可在Inspector调整 private float timer; private float currentGravityScale; public int sushiCreated; private int sushiMilestone = 10; void Awake() { // 初始化当前重力缩放为预制体默认值(或直接使用initialGravityScale) if (targetPrefab.TryGetComponent(out Rigidbody2D prefabRb)) { currentGravityScale = prefabRb.gravityScale; } else { currentGravityScale = initialGravityScale; Debug.LogWarning("预制体未挂载Rigidbody2D组件,使用默认重力缩放值"); } } void Update() { timer -= Time.deltaTime; if (timer < 0) { timer = cooldown; sushiCreated++; GameObject newTarget = Instantiate(targetPrefab); float randomX = Random.Range(cd.bounds.min.x, cd.bounds.max.x); newTarget.transform.position = new Vector2(randomX, transform.position.y); // 给每个新生成的寿司应用当前的重力缩放 if (newTarget.TryGetComponent(out Rigidbody2D targetRb)) { targetRb.gravityScale = currentGravityScale; } // 检查是否突破里程碑,更新难度参数 if (sushiCreated > sushiMilestone && cooldown > .5f) { sushiMilestone += 10; cooldown -= .3f; currentGravityScale += .3f; // 更新全局重力缩放变量 Debug.Log($"难度提升:冷却时间{cooldown:F2},重力缩放{currentGravityScale:F2}"); } } } }
关键优化点
- 新增
currentGravityScale变量存储当前生效的重力缩放值,确保所有新生成的寿司都使用统一的难度参数。 - 使用
TryGetComponent替代直接GetComponent,避免空引用报错,同时增加调试提示。 - 在
Awake中初始化重力缩放值,确保与预制体原始配置一致,或使用Inspector可配置的默认值。 - 每次生成寿司时都应用当前重力缩放,而不是仅在里程碑触发时修改单个寿司。
内容的提问来源于stack exchange,提问作者Mauro Carnesi
相关产品推荐
相关产品推荐

