Unity定位与Update在功能上的不同

Unity Position Different in Function Compared to Update

在这段代码中,当我试图获得 transform.position_attackPoint.position 时。该值始终为 (0,0,0),但是当我在 Update 方法中进行转换时,它打印正常。

public class MeleeWeapon : Weapon
{
    [SerializeField] private Transform _attackPoint;
    [SerializeField] private float _attackRange;
    [SerializeField] private LayerMask _enemyLayers;

    private void Update()
    {
        Debug.Log(transform.position); // Prints right
    }

    public override void Attack()
    {
        Debug.Log(transform.position); // Prints 0,0,0

        Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(_attackPoint.position, _attackRange, _enemyLayers);
        Debug.Assert(hitEnemies.Length > 0); // Assertion failed
        foreach(Collider2D enemy in hitEnemies)
        {
            Debug.Log($"We hit {enemy.name}");

            CharacterStats stats = enemy.GetComponent<CharacterStats>();
            if (stats == null) continue;

            stats.ApplyDamage(damage);
        }
    }
}

Game View

我正在像下面那样实例化 MeleeWeapon

foreach (PivotToTransform pivot in pivotPoints)
{
    if (pivot.slot == item.initialSlot)
    {
        // Instantiate prefab
        GameObject it = Instantiate(item.prefab, pivot.point.position, Quaternion.identity);

        if (!item.isDisposable) // If item not disposable set parent transform
            it.transform.SetParent(pivot.point);

        // Set current prefab
        _currentPrefab = it;
    }
}

这里是支点:

Pivot Points

这是 MeleeWeapon 预制件:

MeleeWeapon Prefab

我用

攻击
try
{
    var equippedItems = EquipmentManager.Instance.equippedItems;
    var selectedSlot = EquipmentManager.Instance.selectedSlot;

    if (equippedItems.ContainsKey(selectedSlot))
    {
        // Try to get weapon
        Item equippedItem = equippedItems[selectedSlot];
        Weapon weapon = equippedItem.prefab.GetComponent<Weapon>();
        if (weapon == null) throw new System.Exception();

        // Actualy attack
        weapon.Attack();

        if (equippedItem.isDisposable)
        {
            RemoveState state = Inventory.Instance.RemoveItem(equippedItem, 1);
            // Unequip item if removed
            switch (state)
            {
                case RemoveState.Removed:
                    EquipmentManager.Instance.UnEquip(equippedItem.initialSlot);
                    break;
                case RemoveState.Error:
                    throw new System.Exception();
            }
        }

        // Set cooldown
        sm.StartCoroutine(Cooldown(equippedItem.cooldown));
    }
    else
    {
        sm.ChangeState(sm.IdleState);
    }
}
catch (System.Exception)
{
    sm.ChangeState(sm.IdleState);
}

您尝试过使用 transform.localPosition 吗?

gameObject 的父对象可能会导致这种情况。

看来育儿方面没什么问题。当我尝试攻击时,我使用的是未实例化的预制件。我像这样更改了攻击脚本并解决了。

EquipmentManager.Instance.currentPrefab.GetComponent<MeleeWeapon>().Attack();

您正在呼叫:

Weapon weapon = equippedItem.prefab.GetComponent<Weapon>();

当我读到这篇文章时,您似乎得到的是 PREFAB 而不是 INSTANCE。为什么不直接从 Item 中检索 Weapon 脚本?你得到:

Item equippedItem = equippedItems[selectedSlot];

而且我认为你需要从 equippedItem 而不是预制件上取下武器:

Weapon weapon = equippedItem.GetComponent<Weapon>();

当您从预制件中获取脚本时,您将获得一个未从尚未实例化的游戏对象中激活的脚本。