Unity - A计划(永久有效期) 扫二维码继续学习 二维码时效为半小时

(196评价)
价格: 4019.00元
《逃离地球》 096控制主角的移动 主角无法移动
开发者微光发起了问答2017-12-12
3
回复
480
浏览

NullReferenceException: Object reference not set to an instance of an object
Forest.GetNextTagetPint () (at Assets/script/Forest.cs:111)
PlayMove.Update () (at Assets/PlayMove.cs:20)

通过PlayMove.Update () (at Assets/PlayMove.调用Forest.GetNextTagetPint ()方法但是无法移动主角并大量报错

错误代码在指向      111行 if ((WayPoint.Points[targetWayPointIndex].position.z - player.position.z)<100)

下附源码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Forest : MonoBehaviour
{
   public GameObject[] obstactes;
    //这里定义了一个数组,用来存储障碍物
    public float startLength = 50;
    //长歪武刚开始生成的位置
    public float minLength = 100;
    public float mixLength = 200;


     public Transform player;//角色
    private Waypoints WayPoint;//锚点集
    private int targetWayPointIndex;//目标点的索引

 


    private EverGenereratior envGentreator;//创建一个EverGenereratior的引用
    void Awake()
    {
        player = GameObject.FindGameObjectWithTag(Tags.player).transform;
        //这里通过查找标签的方式,获得了player,并获取了它的transform;属性
        WayPoint = transform.Find("waypoint").GetComponent<Waypoints>();
        //通过寻找子物体“waypoint”并获取Waypoints组件
        targetWayPointIndex = WayPoint.Points.Length - 2;
        //这里是角色要移动的第一个锚点
        //数组长度从零开始计算,第一个锚点在起始点所以不计算
        //减掉2,就是玩家要去的第一个点
        envGentreator = Camera.main.GetComponent<EverGenereratior>();
        //找到EverGenereratior方法


    }


    void Start()
    {

        GenerateObstacle();

    }


    void Update()
    {
        //这里的方法在里的功能在里实现有所以弃用了 GetNextTagetPint

        //如果player的z坐标大于当前场景的z坐标加100
        // if (player.position.z > (transform.position.z + 100))
        //{
        //则通知摄像机调用GenerateForest方法
        //   Camera.main.SendMessage("GenerateForest");
        //调用GenerateForest方法之后删除之前的场景
        //  GameObject.Destroy(this.gameObject);
        //   }
    }


    void GenerateObstacle()
    {//这个方法用来生成障碍物
        float startZ = transform.position.z - 3000;
        //地图的长度是300,所以开始的坐标等于当前的坐标-3000
        float endZ = startZ + 3000;
        float z = startZ + startLength;
        while (true)
        {
            z += Random.Range(100, 200);
            if (z > endZ)
            {
                break;
            }
            else
            {
                Vector3 position = GetWayPosByZ(z);
                //创建障碍物
                //障碍物已经有了
                //2。创建什么类型的障碍
                int obsindex = Random.Range(0, obstactes.Length);
                //通过随机数随机生成一个障碍物
                GameObject go = Instantiate(obstactes[obsindex], position, Quaternion.identity);
                go.transform.parent = this.transform;
            }
        }
    }
    Vector3 GetWayPosByZ(float z)
    {
        Transform[] points = WayPoint.Points;
        //创建一个数组存储瞄点,这里的锚点等于锚点类里的锚点
        int index = 0;
        for (int i = 0; i < points.Length - 1; i++)
        {
            if (z <= points[i].position.z && z >= points[i + 1].position.z)
            {
                index = i;
                break;
            }
        }
        //通过遍历数组里的瞄点来确定生成障碍物的位置在那两个瞄点之间

        return Vector3.Lerp(points[index + 1].position, points[index].position, (z - points[index + 1].position.z) / (points[index].position.z - points[index + 1].position.z));
        //通过调用Vector3.Lerp里的方法获取生成点的z值
        // return Vector3.Lerp(第一个锚点的position,相邻的瞄点的position,(z-第一个锚点的position的z值)除以(第一个锚点的position的z值  减  相邻的瞄点的position的z )

    }

    //角色前进的方向有锚点决定
    public Vector3 GetNextTagetPint()//获取角色前进的下一个点
    {
        while (true)//这里是一个死循环 一直做判断
        {
            if ((WayPoint.Points[targetWayPointIndex].position.z - player.position.z)<100)
            //玩家要去的第一个锚点的position与角色的position的 差,sqrMagnitude求差 小于100时,寻找下一个锚点
            {
                targetWayPointIndex--;
                //这里是根据锚点数组的长度所以 锚点的位置可能有关
                if (targetWayPointIndex < 0)//targetWayPointIndex为0时,这张地图完了
                {
                    envGentreator.GenerateForest();//所以从新加载新地图

                    Destroy(this.gameObject, 2);//两秒后删除旧地图
                    return envGentreator.forest1.GetNextTagetPint();//并且再次调用自身方法
                }
            }
            else//玩家要去的第一个锚点的position与角色的position的 差。不小于100,
            {
                return WayPoint.Points[targetWayPointIndex].position;//输出锚点位置
            }
        }

    }

 


}

所有回复
  • siki 2017-12-13

    这里报空指针,可能为空的对象可能是Waypoint,player,Waypoint.Points检查下这三个对象哪个为空。
    然后看下那个空对象的赋值是怎么赋值的

    还有-5条回复,点击查看
    你还没有登录,请先登录注册
  • 开发者微光 2017-12-13

      public Transform player;//角色

       通过player = GameObject.FindGameObjectWithTag(Tags.player).transform;找到,并在检视面板指定
     private Waypoints WayPoint;//锚点集

    Waypoint,  通过WayPoint = transform.Find("waypoint").GetComponent<Waypoints>();找到,并在检视面板指定。

    Waypoint.Points 通过 WayPoint = transform.Find("waypoint").GetComponent<Waypoints>();继承到并在检视面板指定。

    我检查了锚点的顺序。检查了在三个地图的检视面板,分别指定了 player,障碍物锚点

    仍然没找到错误。麻烦老师了

     

    还有-5条回复,点击查看
    你还没有登录,请先登录注册
  • siki 2017-12-13

    先通过输出(Debug.Log) Waypoint,player,Waypoint.Points确定哪一个对象为空,

    在空指针的那一行上面输出

    确定了哪个对象为空,再检查这个对象怎么赋值的

    还有-5条回复,点击查看
    你还没有登录,请先登录注册
发表回复
你还没有登录,请先 登录或 注册!