【问题标题】:Unity - why getcomponent for script returns null when script is attached to game object in scene [duplicate]Unity-当脚本附加到场景中的游戏对象时,为什么脚本的getcomponent返回null [重复]
【发布时间】:2021-05-30 23:20:48
【问题描述】:

我创建了一个 TileMap。我的敌人是一个简单的圆柱体,附加了“EnemyMover.cs”脚本,并且在按下播放之前位于场景(层次结构)中。 (运行时不实例化)

在一个单独的对象上,我有一个“TargetLocator”脚本,它在运行时通过单击地图上的图块实例化时尝试利用 GetComponent 来查找圆柱体脚本组件。

    public class TargetLocator : MonoBehaviour
{
    [SerializeField] private Transform weapon;
    private Transform target;
    
    void Start()
    {
        target = GetComponent<EnemyMover>().transform;
    }
    
    void Update()
    {
        AimWeapon();
    }

    void AimWeapon()
    {
        weapon.LookAt(target);
    }
}

错误:

NullReferenceException:对象引用未设置为对象的实例 TargetLocator.Start()(在 Assets/Towers/TargetLocator.cs:12)

我应该提到我已经尝试过:

  1. 重置 Unity
  2. 移除转换并仅验证对象
  3. 为敌人(圆柱体)添加刚体
  4. 添加对撞机

除了刚体之外,所有都仍然返回 null,但这会导致项目从地板上掉下来,仍然不会瞄准敌人。


    public class EnemyMover : MonoBehaviour
    {
        [SerializeField] private List<Waypoint> path = new List<Waypoint>();
        [SerializeField] [Range(0f, 5f)] private float speed = 1f;
    
        void Start()
        {
            StartCoroutine(FollowPath());
        }
    
        IEnumerator FollowPath()
        {
            foreach (Waypoint waypoint in path)
            {
                Vector3 startPos = transform.position;
                Vector3 endPos = waypoint.transform.position;
                float travelPercent = 0f;
                
                // todo reintroduce when object can face
                // transform.LookAt(endPos);
    
                while (travelPercent < 1f)
                {
                    travelPercent += Time.deltaTime * speed;
                    transform.position = Vector3.Lerp(startPos, endPos, travelPercent);
                    yield return new WaitForEndOfFrame();
                }
            }
        }
    }

【问题讨论】:

  • 可能是一个简单的脚本执行顺序问题?要快速确认,您可以尝试在您的 AimWeapon 方法中将 weapon.LookAt(target); 更改为 weapon.LookAt(GetComponent&lt;EnemyMover&gt;().transform);

标签: c# unity3d


【解决方案1】:

尝试调用该脚本中的方法,而不是 transform ,这是对象的真实位置。 例如 EnemyMover

 public class EnemyMover: MonoBehaviour
{
    private Transform target;
    
    public Transform CalculateTarget()
    {
        target = GetComponent<Player>().transform;
        return target;
    }
}

然后在TargetLocator 你会打电话:

target = GetComponent<EnemyMover>().CalculateTarget();

【讨论】:

  • 是一个例子还是特定的?我的场景中没有任何可以指示玩家的东西。 EnemyMover.cs 位于我试图对其进行转换的敌人身上。我可以使用 target = GameObject... 或 GetComponent 或类似的东西吗?
  • 我试过你的代码,但我使用了:``` target = transform; ``` 仍然出现 NullReference 错误。
  • @thielr7 在编辑中将您的TargetLocator 脚本添加到问题中。 target = transform 不会做任何事情,因为 transform 是对象的属性,而不是实际值
  • 我假设您的意思是 EnemyMover 脚本,因为 TargetLocator 脚本在上面是完整的。我已附加另一个作为编辑。谢谢你看这个。奇怪的是,我正在观看并关注一个 Udemy 视频,其中我的原始代码适用于他们。
  • @thielr7 我的错,我的意思是使用target=GameObject.Find("Enemy").transform
【解决方案2】:

它看起来不像TargetLocatorEnemyMover 附加到相同 GameObject

你说你自己

在一个单独的对象上,我有一个“TargetLocator”脚本,它在运行时通过单击地图上的图块实例化时尝试利用 GetComponent 来查找圆柱体脚本组件。

Component.GetComponent 在给定的ComponentMonoBehaviour 继承自它)实例上查找组件。在您的情况下 this -> TargetLocator 本身的引用。

您宁愿使用例如FindObjectOfType 在场景层次结构中的任何对象上查找给定类型的组件。

target = FindObjectOfType<EnemyMover>().transform;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2022-10-18
    相关资源
    最近更新 更多