首页 > 解决方案 > 脚本仅影响预制件的一个实例

问题描述

我有一个 Guard 预制件,它有两个子组件:一个用于检测目标是否在范围内,另一个用于检测目标是否在捕获范围内。捕获范围的 OnTriggerEnter 在 Prefab 的两个实例上工作。但是用于检测目标是否在范围内的方法仅适用于生成的 Prefab 的第一个实例。两个子对象都有一个设置为 Kinematic 的刚体,并且有自己的碰撞器来完成它们的任务。父级没有碰撞器。在我用于检测其是否在范围内的脚本中,我具有两个触发功能:

TGuardMovement mov;

void Start()
{
    mov = GameObject.FindGameObjectWithTag("Guard").GetComponent<TGuardMovement>();
}

public void OnTriggerEnter2D(Collider2D a_Collider2D)
{
    if (a_Collider2D.gameObject.CompareTag("Animal"))
    {
        //invoke chase
        mov.InvokeChase();
    } 
}


public void OnTriggerExit2D(Collider2D a_Collider2D)
{
    //cancel Invoke
    if (a_Collider2D.gameObject.CompareTag("Animal"))
    {
        mov.CancelInvokeChase();
    }
        
}

TGuardMovement 是处理 AI 运动的父脚本

 public void InvokeChase()
{
    InvokeRepeating("UpdatePath", 0f, .5f);
}

public void CancelInvokeChase()
{
    CancelInvoke("UpdatePath");
}

这些是子对象正在调用的函数。只需调用该函数即可分别开始追逐和停止追逐。这是 UpdatePath() 函数:

void UpdatePath()
{       
    if(m_GState == GuardState.PATROLING)
    {
        TriggerMovement();
    }

    else if (m_GState == GuardState.CHASING)
    {
        if (m_Seeker.IsDone())
        {
            m_Seeker.StartPath(m_Rb2D.position, targetGO.transform.position, OnPathComplete);
        }

    }
    if (targetGO == null)
    {
        m_Seeker.StartPath(m_Rb2D.position, m_objManager.m_goTGuardObject.transform.position, OnPathComplete);
    }
}

我有点想知道错误可能是什么。移动的触发事件由不移动的预制件触发,但它不会开始移动。即使只是传送实例也只会移动第一个生成的实例。

标签: c#unity3d

解决方案


您的问题很可能出现在显示的第一个脚本的 Start 函数中。GameObject.FindGameObjectWithTag(string)只返回一个GameObject,它找到的第一个。

一些可能的修复:

  • 您可以使用GameObject.FindGameObjectsWithTag(string), 请注意它说Objects而不是Object, 并将其存储在GameObjects[].

  • 如果守卫在运行时被实例化,你可以存储对守卫的引用,然后通过创建一个列表:

     public List<GameObject> guards = new List<GameObject>();
    

    然后在产卵功能中:

     guards.Add(Instantiate(guardPrefab));
    
  • 如果守卫可能会来来去去,而您只想获得该区域内您可以使用的所有守卫Physics.OverlapSphere(...);。除了获取区域内的所有对撞机外,它的使用与光线投射类似。您可以将它们存储在一个数组中,并在需要时访问它们的脚本。


推荐阅读