Unity中Transform无法实时更新射击位置问题求助
问题解决思路与代码修改
1. 射击位置不实时更新的原因及修复
你当前的代码直接在ScriptableObject(SO)中存储projectileSpawnPoint的Transform引用,若这个引用关联的是预制体而非场景中实例化的玩家对象,就会导致取到固定初始位置而非玩家实时位置。正确的做法是每次激活技能时,从传入的玩家parent对象中动态获取发射点:
- 移除SO中的
public Transform projectileSpawnPoint,改为通过名称/标签从玩家身上查找发射点 - 每次调用
Activate时,获取玩家身上最新的发射点位置与旋转
2. 子弹碰撞销毁的问题修复
你在Activate方法内部定义的OnCollisionEnter不会生效——这个方法是MonoBehaviour的回调,只有挂载在GameObject上的脚本才能触发。需要给子弹预制体单独添加处理碰撞的脚本:
修改后的Shoot脚本
using UnityEngine.InputSystem; using UnityEngine; namespace EO.ARPGInput { [CreateAssetMenu] public class Shoot : Ability { public GameObject projectilePrefab; public float bulletSpeed = 10f; public float bulletLife = 3f; public string spawnPointName = "ProjectileSpawnPoint"; // 玩家身上发射点的名称 public override void Activate(GameObject parent) { // 从玩家身上获取实时的发射点Transform Transform spawnPoint = parent.transform.Find(spawnPointName); if (spawnPoint == null) { Debug.LogError($"玩家{parent.name}上未找到名为{spawnPointName}的发射点!"); return; } // 实例化子弹,使用发射点当前的位置和旋转 GameObject projectile = Instantiate(projectilePrefab, spawnPoint.position, spawnPoint.rotation); // 设置子弹飞行速度 Rigidbody rb = projectile.GetComponent<Rigidbody>(); if (rb != null) { rb.velocity = spawnPoint.forward * bulletSpeed; } else { Debug.LogError("子弹预制体缺少Rigidbody组件!"); } // 初始化子弹的生命周期 projectile.GetComponent<Projectile>().Initialize(bulletLife); } } }
子弹碰撞处理脚本(Projectile.cs)
将此脚本挂载到子弹预制体上:
using UnityEngine; public class Projectile : MonoBehaviour { private float _lifeTime; public void Initialize(float lifeTime) { _lifeTime = lifeTime; // 设置自动销毁时间 Destroy(gameObject, _lifeTime); } private void OnCollisionEnter(Collision collision) { // 碰撞到任何物体时立即销毁子弹 Destroy(gameObject); // 若需要处理伤害逻辑,可在此添加,例如: // Health targetHealth = collision.gameObject.GetComponent<Health>(); // if (targetHealth != null) targetHealth.TakeDamage(10); } }
3. 关于Update函数的疑问
ScriptableObject本身没有Update方法,你的场景也不需要用Update:
- 射击逻辑只在技能激活时执行一次,不需要实时更新
- 子弹的运动由Rigidbody物理驱动,无需Update干预
- 碰撞与自动销毁逻辑已在子弹的专属脚本中处理
额外注意事项
- 确保玩家对象身上存在名为
ProjectileSpawnPoint的Transform(可根据实际修改名称) - 子弹预制体必须添加Rigidbody和碰撞体组件(如Sphere Collider),并开启碰撞检测
- 若需避免子弹与玩家自身碰撞,可在碰撞体设置中忽略玩家所在的图层
内容的提问来源于stack exchange,提问作者Ethan Ohmer
相关产品推荐
相关产品推荐

