Dash技能作为ScriptableObject无横向作用力,仅向上推进问题排查
Dash技能改为ScriptableObject后仅纵向位移无横向位移问题排查与修复
核心问题诊断
从代码和现象来看,角色仅能向上移动说明upwardsSpeed生效,但横向位移失效,大概率是以下几个原因之一:
dashSpeed在Inspector中未设置有效数值(比如设为0)playerController.isFlipped的判断逻辑异常(包括playerController引用为空或isFlipped值错误)- CardAbility中缓存的玩家组件引用过期或未正确赋值
快速排查步骤
检查技能配置数值
打开Dash技能的ScriptableObject实例,确认dashSpeed字段设置了大于0的数值,不要留空或设为0。添加调试日志验证逻辑
修改Dash.CastDash()方法,添加日志确认关键参数:private void CastDash() { AssignComponents(); // 打印关键参数,确认逻辑分支 Debug.Log($"dashSpeed: {dashSpeed}, playerController: {playerController}, isFlipped: {playerController?.isFlipped}"); if (playerController == null) { Debug.LogError("PlayerController引用为空!"); return; } var horizontalSpeed = playerController.isFlipped ? dashSpeed : -dashSpeed; playerRb.velocity = new Vector2(horizontalSpeed, upwardsSpeed); }运行游戏释放技能,查看Console日志:
- 如果
dashSpeed为0:直接修正数值即可 - 如果
playerController为空:检查CardAbility基类的playerData是否在Inspector中正确拖入了PlayerData实例 - 如果
isFlipped值不符合角色当前朝向:检查PlayerController中isFlipped的切换逻辑是否正常
- 如果
验证PlayerData赋值流程
确认PlayerController的OnEnable方法已被调用,且playerData引用的是正确的实例:- 可以在
OnEnable中添加Debug.Log("PlayerData组件已赋值")验证执行时机 - 检查PlayerData的
playerController字段在运行时是否指向当前玩家对象
- 可以在
代码优化建议
1. 避免缓存运行时引用
ScriptableObject作为配置资产,不适合存储运行时的动态引用,直接通过PlayerData访问组件,避免引用失效:
// 修改CardAbility基类,移除缓存字段 public class CardAbility : ScriptableObject { [SerializeField] private string abilityName; public float abilityDuration; public PlayerData playerData; public virtual void CastAbility() { // 默认实现 } } // 修改Dash类,直接通过playerData访问组件 private void CastDash() { if (playerData == null || playerData.playerController == null || playerData.playerRb == null) { Debug.LogError("PlayerData或玩家组件未正确初始化!"); return; } var horizontalSpeed = playerData.playerController.isFlipped ? dashSpeed : -dashSpeed; playerData.playerRb.velocity = new Vector2(horizontalSpeed, upwardsSpeed); }
2. 改为参数传递PlayerData(更可靠的方案)
将PlayerData作为参数传入技能方法,彻底避免ScriptableObject存储运行时状态的问题:
// 修改CardAbility基类 public virtual void CastAbility(PlayerData playerData) { // 默认实现 } // 修改Dash类 public override void CastAbility(PlayerData playerData) { if (playerData == null || playerData.playerController == null || playerData.playerRb == null) { Debug.LogError("PlayerData或玩家组件未正确初始化!"); return; } var horizontalSpeed = playerData.playerController.isFlipped ? dashSpeed : -dashSpeed; playerData.playerRb.velocity = new Vector2(horizontalSpeed, upwardsSpeed); }
调用时从Deck脚本传入当前玩家的PlayerData实例即可。
3. 优化PlayerData赋值逻辑
将PlayerData的赋值改为初始化时完成,而非依赖OnEnable:
// PlayerController中 private void Awake() { if (playerData == null) { Debug.LogError("PlayerData未赋值!"); return; } playerData.player = gameObject; playerData.playerColl = GetComponent<BoxCollider2D>(); playerData.playerRb = GetComponent<Rigidbody2D>(); playerData.playerController = this; } private void OnDisable() { playerData?.ResetData(); }
内容的提问来源于stack exchange,提问作者EPiedrahita
相关产品推荐
相关产品推荐

