You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 2D:带动画组件的游戏对象Y轴移动时缩放失效问题求助

问题:Unity中沿Y轴移动时对象缩放无效果

刚接触Unity,希望让挂载了移动/动画脚本的游戏对象沿Y轴移动时同步缩放。采用父子对象结构:缩放脚本挂载在父对象,Sprite Renderer、Animator、Rigidbody2D、移动脚本挂载在子对象。目前动画正常运行,但缩放无视觉效果。尝试调换父子角色后,要么动画正常缩放失效,要么缩放正常动画失效。已确认脚本执行顺序(缩放脚本在动画之后),调试显示缩放代码在执行,但对象尺寸无变化。

提供的脚本

缩放脚本(ScalingCamera)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScalingCamera : MonoBehaviour
{
    public float minY = 290f;
    public float maxY = 320f;
    public float minScale = 0.5f;
    public float maxScale = 2.0f;

    private Transform childTransform;
    private SpriteRenderer childSpriteRenderer;

    private void Start()
    {
        childTransform = transform.GetChild(0);

        if (childTransform != null)
        {
            childSpriteRenderer = childTransform.GetComponent<SpriteRenderer>();

            if (childSpriteRenderer == null)
            {
                Debug.LogError("Child does not have a SpriteRenderer component.");
            }
        }
        else
        {
            Debug.LogError("No child found for scaling.");
        }
    }

    private void LateUpdate()
    {
        float yPos = transform.position.y;
        yPos = Mathf.Clamp(yPos, minY, maxY);
        float scale = Mathf.Lerp(minScale, maxScale, Mathf.InverseLerp(minY, maxY, yPos));

        childTransform.localScale = new Vector3(scale, scale, 1f);

        if (childSpriteRenderer != null)
        {
            childSpriteRenderer.size = new Vector2(childSpriteRenderer.size.x * scale, childSpriteRenderer.size.y * scale);
        }
    }
}

移动/动画脚本(movement)

using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[DebuggerDisplay("{ " + nameof(GetDebuggerDisplay) + "(),nq}")]
public class movement : MonoBehaviour
{
    [SerializeField] private int speed = 50;
    private Vector2 move;
    [SerializeField] private Animator animator;
    private Rigidbody2D rb;

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    private void OnMovement(InputValue value)
    {
        move = value.Get<Vector2>();
        if (move.x != 0 || move.y != 0)
        {
            animator.SetFloat("X", move.x);
            animator.SetFloat("Y", move.y);
            animator.SetBool("IsWalking", true);
        }
        else
            animator.SetBool("IsWalking", false);
    }

    private void FixedUpdate()
    {
        rb.MovePosition(rb.position + move * speed * Time.fixedDeltaTime);
    }

    private string GetDebuggerDisplay()
    {
        return ToString();
    }
}

解决方案

1. 排查Animator对Scale的覆盖

打开动画控制器,检查所有动画片段的属性列表:

  • 如果存在Transform > Scale曲线,会在播放时强制覆盖对象的localScale。要么删除该曲线,要么在动画片段的属性设置中将Scale权重设为0,或者用动画层遮罩排除Scale属性。

2. 修正缩放脚本逻辑

  • 删除重复缩放代码:同时修改Transform.localScale和SpriteRenderer.size会导致重复缩放,建议只保留Transform.localScale的修改,删掉SpriteRenderer.size相关代码。
  • 同步正确的Y位置:当前脚本获取的是父对象的Y位置,而实际移动的是子对象,需改为获取子对象的位置计算缩放:
    float yPos = childTransform.position.y;
    
  • 确认脚本执行顺序:在Edit > Project Settings > Script Execution Order中,确保ScalingCamera的执行顺序在Animator之后,避免动画覆盖缩放值。

3. 校验Y轴范围匹配度

检查minY(290f)和maxY(320f)是否与对象实际移动的Y轴范围一致。如果对象实际Y值超出该范围,scale会固定为minScale或maxScale,可添加调试代码确认:

Debug.Log($"当前Y位置: {yPos}, 计算缩放值: {scale}");

根据输出调整minY和maxY到对象实际移动区间。

4. 排查其他脚本干扰

检查项目中是否有其他脚本也在修改子对象的localScale(如动画事件、其他逻辑脚本),导致缩放值被覆盖。


内容的提问来源于stack exchange,提问作者Sato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:25:24