Unity 2D:点击生成带上升动画的Prefab文本Y轴位置异常
问题
我的奖励文本粒子动画设置为X轴始终保持0,Y轴从0上升至1。但游戏运行时,点击屏幕生成粒子时,X轴能和手指点击位置对齐,Y轴却始终从0开始,不是点击的Y轴位置。我希望粒子能在点击的精确位置生成,怀疑是动画的问题,但不知道怎么修。
附带代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using BreakInfinity; using UnityEngine.Pool; public class GameManager : MonoBehaviour { [Header("Stats")] public static BigDouble notes = 0; public static BigDouble tap = 10; public static BigDouble auto = 0; [Header("Taps")] [SerializeField] private GameObject bonusParticlePrefab; float tapCooldown = 0.04f; float lastTapTime = 0f; private ObjectPool<GameObject> bonusParticlesPool; void Start() { bonusParticlesPool = new ObjectPool<GameObject>(CreateFunction, ActionOnGet, ActionOnRelease, ActionOnDestroy); } private GameObject CreateFunction() { return Instantiate(bonusParticlePrefab, transform); } private void ActionOnGet(GameObject bonusParticle) { bonusParticle.SetActive(true); } private void ActionOnRelease(GameObject bonusParticle) { bonusParticle.SetActive(false); } private void ActionOnDestroy(GameObject bonusParticle) { Destroy(bonusParticle); } void Update() { foreach(Touch touch in Input.touches) { if (touch.phase == TouchPhase.Began) { if (Time.time - lastTapTime > tapCooldown) { bool isOverUI = false; for (int i = 0; i < Input.touchCount; i++) { if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(i).fingerId)) { isOverUI = true; break; } } if (!isOverUI) // if not over UI elements { IncreasePoints(); Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position); touchPosition.z = 0; lastTapTime = Time.time; // Update the last tap time GameObject bonusParticleInstance = bonusParticlesPool.Get(); bonusParticleInstance.transform.position = touchPosition; LeanTween.delayedCall(1, ()=> bonusParticlesPool.Release(bonusParticleInstance)); } } } } } void IncreasePoints() { notes += tap; } }
解决方案
核心原因
问题出在粒子动画的初始位置硬编码:你的动画将Y轴起始值固定为0,覆盖了代码中设置的点击位置Y值。
修复方案
1. 修改动画剪辑(最直接)
- 打开粒子的动画剪辑,找到Y轴动画轨道
- 将Y轴的起始关键帧改为基于当前位置的相对偏移:
- 把动画类型设置为
Additive,或者将起始关键帧的Y值设为0、结束关键帧设为1,让动画从物体当前Y位置向上移动1单位 - 或者直接删除Y轴的初始固定关键帧,保留从当前位置到+1的动画曲线
- 把动画类型设置为
2. 代码中修正动画偏移
如果不想改动动画,可以在设置粒子位置后,强制修正动画的起始基准:
GameObject bonusParticleInstance = bonusParticlesPool.Get(); Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position); touchPosition.z = 0; bonusParticleInstance.transform.position = touchPosition; // 修正动画的Y轴起始基准 Animator anim = bonusParticleInstance.GetComponent<Animator>(); if(anim != null) { // 假设动画Y轴是从0到1的绝对移动,这里把动画根节点的Y偏移设为点击位置 anim.transform.localPosition = new Vector3(0, touchPosition.y, 0); } LeanTween.delayedCall(1, ()=> bonusParticlesPool.Release(bonusParticleInstance));
3. 用LeanTween替代内置动画
既然已经在使用LeanTween,完全可以用它直接控制粒子移动,彻底避免动画冲突:
GameObject bonusParticleInstance = bonusParticlesPool.Get(); Vector3 touchPosition = Camera.main.ScreenToWorldPoint(touch.position); touchPosition.z = 0; bonusParticleInstance.transform.position = touchPosition; // 直接用LeanTween实现从点击位置上升1单位的动画 LeanTween.moveY(bonusParticleInstance, touchPosition.y + 1, 1f).setOnComplete(() => { bonusParticlesPool.Release(bonusParticleInstance); });
内容的提问来源于stack exchange,提问作者Div
相关产品推荐
相关产品推荐

