Space Shooter

U3D官网教程之一,官网视频需要翻墙才能看,这里放上B站的视频链接(戳这里),这个up主有好几个翻译的官网教程。

设置方面,个人觉得不太懂的是灯光方面,虽然根据视频设置了相同的灯光,但是对一些什么主灯光,填充灯光的方向和灯光颜色设置不太了解。

①Main Camera设置Projection,这是一个雷电游戏,投射设置要改为Orthographic。正交投影从Y轴向下投影。

  (1) Perspective 透视:相机将用完全透视的方式来渲染对象。

  (2) Orthographic 正交:相机将用没有透视感的方式均匀地渲染对象。

②Player的Collider为Mesh Collider

③网格碰撞器利用一个网格资源并在其上构建碰撞器。对于复杂网状模型上的碰撞检测,它要比应用原型碰撞器精确的多。标记为凸起的(Convex )的网格碰撞器才能够和其他网格碰撞器发生碰撞。

④Player对象移动:

    private void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        Vector3 vr3 = new Vector3(moveHorizontal, 0.0f, moveVertical);
        Rigidbody rb = this.GetComponent<Rigidbody>();
        rb.velocity = vr3 * speed;
        rb.position = new Vector3;
            (
                Mathf.Clamp(rb.position.x, boundary._xMin, boundary._xMax),
                0.0f,
                Mathf.Clamp(rb.position.z, boundary._zMin, boundary._zMax)
            );
        rb.rotation = Quaternion.Euler(0.0f, 0.0f, rb.velocity.x * -tilt);
    }

此处移动是通过直接改变Rigidbody的position,移动对象还有这几种方式,transform.Translate,transform.Position 和 rigidbody.MovePosition。transform.Translate相当于直接改变物体的位置,可以参照自身坐标系或者世界坐标系,如果物体本身不是刚体,这个方法完全可以搞定,但如果物体是刚体,这个方法在刚体发生了碰撞后会发生不规则运动。而MovePosition方法考虑到了物理引擎的东西。但是MovePosition使用的时候也有坑,比如直接在Update里写rigidbody.MovePosition(vector3.forward)你会发现根本运动不了。这个方法需要在参数里加上自身的位置。比如写成rigidbody.MovePosition(transform.position + Vector3.forward),你会发现可以正常使用了,而且刚体间的碰撞不会影响接下来的移动。

⑤动态生成小行星之后的销毁问题,当有未被击中的小行星时,如果不对器进行销毁,就会产生小行星无限移动,且累计越来越多的情况,因此需要设置一个边界当小行星到达边界的时候被检测到同时销毁,此处是添加了一个cube,去除了Mesh Render,就相当与物体只有边框了 ,不需要计算物理碰撞的情况,所以勾选一下Is Trigger,检测碰撞销毁即可。

⑥Player击中小行星后的爆炸效果,其实就是在子弹和小行星的碰撞后再Instantiate一个Prefab,这个Prefab就是一个爆炸效果,同时又有一个问题,这个Prefab会一直停留在场景中,因此需要对这几个Prefab添加一个Destroy(),两个参数,第一个是对象,第二个可以给定一个时间。

⑦子弹射击,创建一个空对象放在Player前方,并让他成为Player的子对象,就会产生子弹从飞机射出。同时新创建出来的Prefab(子弹)需要设置rb.velocity = this.transform.forward ;即让子弹沿Z轴移动。(vector3.forward的值永远等于(0,0,1)。transform.forward的值则等于当前物体的自身坐标系z轴在世界坐标上指向,因此不一定等于(0,0,1),但是其magnitude长度是1。)

	void Update () {
        if (Input.GetButton("Fire1") && Time.time > nextFire)
        {
            nextFire = Time.time + fireRate;
            Instantiate(bolt, shotShawn.position, shotShawn.rotation);
            this.GetComponent<AudioSource>().Play();
        }
    }

此处在射击时设置nextFire和fireRate,负责就会出现子弹如同一条直线一样射击,这个fireRate就相当于硬直,后摇。同时还需要利用AudioSource添加射击音效。

⑧        this.GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere * tumble;小行星的旋转,下面这一部分时https://blog.csdn.net/hoxily/article/details/46299285的一部分:

如果这个空间体是一个球体(例如,当你想要一个距离坐标原点小于给定半径的随机点),你可以使用 Random.insideUnitSphere 乘上所需的半径。代码如下:

var randWithinRadius = Random.insideUnitSphere * radius;

请注意,如果你设置上面的球内随机坐标点的某个分量为零,那么你将不能正确地得到平面圆内的随机点。虽然这个点确实是随机的,并且落在正确的半径内,但是落点概率严重地偏向于圆的边缘,因此得到的点将会分布得很不均衡。你应该使用 Random.insideUnitCircle 来完成这项任务。代码如下:

var randWithinCircle = Random.insideUnitCircle * radius;

⑨协程

    IEnumerator MakePlantes()
    {
        yield return new WaitForSeconds(startWait);
        while (true)
        {
            for (int i = 0; i < plantesCount; i++)
            {
                Vector3 vr3 = new Vector3(Random.Range(-positionValue.x, positionValue.x), positionValue.y, positionValue.z);//行星位置 
                Quaternion qua = Quaternion.identity;
                Instantiate(hazard, vr3, qua);
                yield return new WaitForSeconds(spawnWait);//协程 暂时不太懂
            }
            yield return new WaitForSeconds(stopWait);
            if (isGameOver)
            {
                uiTextReStart.text = "Press 'R' to restart game";
                isReStart = true;
                break;
            }
        }

    }

Unity 5.x中使用StartCoroutine方法开启协程,其方式有以下几种.

//形式一 
StartCoroutine(CustomCorutineFn()); 
StartCoroutine(CustomCorutineFn(7));//向方法中传递参数 
//形式二 
StartCoroutine(“CustomCorutineFn”); 
StartCoroutine(“CustomCorutineFn”,7);//向方法中传递参数

在开发中可能会开启多个协程,如果你想停止其中某个协程,你可使用StopCoroutine.但在使用时,你需要注意一点,停止协程的方式要与开启协程的方式一致.StopCoroutine(“CustomCorutineFn”)必须与StartCoroutine(“CustomCorutineFn”)成对使用,与StartCoroutine(CustomCorutineFn())一起使用则完全无效. 

以下内容来自:https://www.cnblogs.com/InitialD/p/7348875.html

 协程的真正用途是分步做一个比较耗时的事情,比如游戏里面的加载资源,

比如我们加载的资源有30个(total),但是一次加载完毕会耗费大量的时间,不可能让玩家在start中等待这么久,这时候协程的作用就出现了,协程是每帧lateUpdate之前执行yield return之前的代码,lateupdate之后执行yield return之后的代码,相当于每帧循环一次(前提是你的协程有循环体,否则一帧就执行完了),具体可以复制我的代码看一下日志,这样就不会卡在这加载30个资源这里,而是你在update里面继续做你的事情,我每次只加载1个,加载1个耗时显然远远小于30个。

上面的例子具体可以对应进入一张地图加载NPC,当你进入一张地图后,如果一次性加载30个NPC,你可能就卡在进地图的地方,等待这30个NPC全部加载出来之后才能行动,但是用了协程,你可以移动,可能你移动一步(或者几步),加载一个NPC,实际上你根本感受不到移动过程中有停顿的现象。

 

我个人理解,某种程度上可以把它认为是异步加载,但是这和BS的异步是不太一样的,只是说可以这么去简单理解。

就总结这么多吧,个人理解,如果有不对的地方欢迎指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值