Unity官方 《Spaceshooter》学习笔记

       在写学习笔记之前,我先说说为什么会做这么一个游戏DEMO吧,目前是在一家互联网广告公司任职3D设计组长一职,主要内容是CG这块,因为对AR和VR很感兴趣,并且暂时选择了Unity这款游戏引擎做为我的敲门砖,因为CG是我的优势,所以对Unity这款软件不陌生,上手很快,唯一比较陌生的是程序代码这块,但因为大学的时候学过C和游戏编程,所以倒不止于看到程序就放弃,只是工作一两年完全没接触程序了。因此我决定在上手了Unity软件后,准备啃下Unity中编程这块硬骨头。我选择了C#这门语言来学习,因为市面上大多数AR和VR教程都是用C#来写的,这样学习起来方便一些。

       我先在在网上学习了一些Unity的C#基础知识,比如GameObject,Transform,枚举,方法等,对Unity中编程的基础知识有了一些了解,接着我觉得还得跟着一些教程做练习,理解消化,跟着官方教程是一个很不错的选择,接下来就进入我的Spaceshooter笔记。                                                  

一:教程的前5个课时讲述的是3D知识,比如相机灯光背景和特效等,表示毫无压力跳过

二:角色控制、发射子弹

代码如下:

using UnityEngine;

using System.Collections;

public class spaceshooter : MonoBehaviour {

             public float speed;

             public float rt;

             public float xMin;

             public float xMax;

             public float zMin;

            public float zMax;

    publicGameObjectshot;

    publicTransformshotspawn;

    publicfloatfirerate;

    privatefloatnextfire=0.0f;

voidUpdate(){

      if(Input.GetButton("Fire1")&&Time.time>nextfire){

      nextfire=Time.time+firerate;

     Instantiate(shot,shotspawn.position,shotspawn.rotation);

}

}

   void FixedUpdate()   {

           float mh = Input.GetAxis ("Horizontal");

            float mv =  Input.GetAxis ("Vertical");

            Rigidbody rigidbody =GetComponent();

            Vector3 movement = new Vector3 (mh, 0.0f, mv);

             rigidbody.velocity = movement*speed;

             transform.rotation= Quaternion.Euler (0.0f, 0.0f, rigidbody.velocity.x* rt);

              transform.position = new Vector3 (

             Mathf.Clamp (transform.position.x,xMin,xMax),

             0.0F,

             Mathf.Clamp(transform.position.z,zMin,zMax)

             );

    }

}

这段代码主要实现了以下功能

1:这段代码首先没有写在Unity默认的Update函数中,而是写在了FixedUpdate()函数中,在网上搜了一下Update和FixedUpdate的区别,Update()和FixedUpdate()在游戏中都会在更新的时候自动循环调用。但是Update是在每次渲染新的一帧的时候才会调用,也就是说,这个函数的更新频率和设备的性能有关以及被渲染的物体(可以认为是三角形的数量)。在性能好的机器上可能fps 30,差的可能小些。这会导致同一个游戏在不同的机器上效果不一致,有的快有的慢。因为Update的执行间隔不一样了。而FixedUpdate,是在固定的时间间隔执行,不受游戏帧率的影响。所以处理Rigidbody的时候最好用FixedUpdate。

PS:FixedUpdate的时间间隔可以在项目设置中更改,Edit->Project Setting->time找到Fixed timestep。就可以修改了。

2:关于Rigidbody调用的问题,官方案例是4.6版本,可以直接调用rigidbody,但5.0以后的版本中,Unity将C#规范了,要调用rigidbody必须要定义,比如Rigidbody r=GetComponent<Rigidebody>()来定义。

3:通过键盘上的"W" "A" "S" "D"或者方向键来控制飞船的前后左右的移动,左右是通过Input.GetAxis ("Horizontal")和Input.GetAxis ("Vertical")来实现,它们都是Vector3类型并且值范围都是在-1到1之间 ,此时定义一个访问修饰符为public且float类型的speed来控制飞船的速度;

4:用Math.Clamp方法来控制飞船移动边界,通过查阅官方文档知道,Math.Clamp返回的是一个float类型value的值,写法是Math.Clamp(float value,float min,float max)

5:设定飞船的旋转边界值,rotation是一个Quaternion类型的值,用Quaternion.Euler来表示物体的旋转,物体在x和y方向上的旋转为0 ,在z方向上的旋转跟物体的速度正负值挂钩,所以用rigidbody.velovity.x来表示,这样,按下方向键,向左或者向右时,飞船就能够发生“侧翻”效果.

6:Instantiat方法的使用,参照官方文档,Instancitate是用来实例化物体的,使用方法是Instantiate (Object Original,Vector3 position,Quaternion rotation),Object是要实例化的对象,Vector是要复制到的位置,Quaternion是设置物体的旋转。

7:Time.time方法用来获取游戏运行的时间,在本例中用来设置按下鼠标左键后间隔多少时间发射下一发子弹。

8:Input.GetButton("FIre1")代码块中,Fire1表示鼠标左键,Fire0表示鼠标中间,Fire2表示鼠标右键,而且Input.GetButton表示持续按下Fire1,同类型的还有Input.GetButtonDown和Input.GetButtonUp也表示按下按键,但是只能计算一次按下或者弹起。

二:边界

voidOnTriggerExit(Colliderother){

Destroy(other.gameObject);

}

调用了Trigger中的一个方法,即离开这个边界的物体都会被“杀死”,条件就是只要触碰到了边界物体的Collider就会调用这个方法,Destroy中的参数是other.gameobjet,表明只会杀死其他的物体,而不会把自身给销毁掉,跟后面要用到的碰撞方法有区别。

三 创建激光

void Start() 

{

Rigidbodyrigidbody=GetComponent();

rigidbody.velocity=transform.forward*speed;

rigidbody.angularVelocity=Random.insideUnitSphere*tumble;

}

1:这个代码是用来表示行星的产生方向和起始随机的旋转速度,transform.forward用来表示z轴方向上的速度,为(0,0,1)

2:rigidbody.angularVelocity用来表示物体的旋转角速度,是一个Vector3类型的,而随机的起始速度则由Random类中的insideUnitSphere来表示,它是一个半径为1的球,方向是-1到1,并且这个方法只能放在Start函数中只能调用一次,自己在做的时候,放在了Update()函数中,导致这个产生的行星都像发了疯似的旋转,因为每一帧都会更新它的角速度,而这个角速度又是随机产生的。

四 爆炸 

代码如下

publicGameObjectzidanbaozha;

publicGameObjectfeichuanbaozha;

publicGameObjectzidanbaozhashengyin;

publicGameObjectfeichuanbaozhashengyin;

voidOnTriggerEnter(Colliderother){

//自己的写法

if(other.tag=="Boundary")//这里的if是不让边界盒子跟行星发生碰撞

{

return;//这里的return是返回一个空的值,表示什么也不做,也可以不写这个return

}

if(other.tag=="Bolt")

{

Destroy(other.gameObject);

Destroy(gameObject);

Instantiate(zidanbaozha,transform.position,Quaternion.identity);

Instantiate(zidanbaozhashengyin,transform.position,Quaternion.identity);

}

if(other.tag=="Player")

{

Destroy(other.gameObject);

Destroy(gameObject);

Instantiate(feichuanbaozha,transform.position,Quaternion.identity);

Instantiate(feichuanbaozhashengyin,transform.position,Quaternion.identity);

}

if(other.tag=="xingxing")

{

Destroy(other.gameObject);

Destroy(gameObject);

Instantiate(zidanbaozha,transform.position,Quaternion.identity);

}

//官方教程的写法

/*if(other.tag=="Boundary")//这里的if是不让边界盒子跟行星发生碰撞

{

return;//这里的return是返回一个空的值,表示什么也不做,也可以不写这个return

}

Instantiate(zidanbaozha,transform.position,Quaternion.identity);

if(other.tag=="Player")

{

Instantiate(feichuanbaozha,transform.position,Quaternion.identity);

}

Destroy(other.gameObject);

Destroy(gameObject);*/

1:这里的代码是分类子弹的collider碰撞到不同的物体的时候,会有不同的爆炸特效,判断的一句是gameobject的Tag。我的写法相比官方的想法可能会更死板,不简练,但毕竟不是写代码的老手,这样写代码方便自己理解,以后代码量上去了我相信自己还是能够养成良好的代码习惯。

2:这里的Quaternion.identity表示物体没有旋转。

五 生成波

代码如下

publicGameObjecthazard;

publicVector3spawnwaves;

publicinthazardcount;

publicfloatwaittime;

publicfloatspawntime;

publicfloatjiangeshijian;

voidStart(){

StartCoroutine(SpawnWaves());

}

IEnumeratorSpawnWaves(){

yieldreturnnewWaitForSeconds(waittime);

while(true)

{

for(inti=0;i

{

floata=Random.Range(-4.76f,4.76f);

hazard.transform.position=newVector3(a,0.0f,14.0f);

hazard.transform.rotation=Quaternion.identity;

Instantiate(hazard,hazard.transform.position,hazard.transform.rotation);

yieldreturnnewWaitForSeconds(spawntime);

}

yieldreturnnewWaitForSeconds(jiangeshijian);

}

}

1:这里的代码是让“敌人”也就是行星能够一波一波地产生,并且在每次游戏开始之前,会过1s后才开始,让玩家做好游戏准备,并且“敌人”会一波一个产生,每一波之间也会有间隔时间。

2:这里用到了SpawnWaves()方法,其实我觉得有没有这个方法也是一样的,因为能够产生一波一波效果的主要是协同方法中的WaitForSeconds类来控制的,而且SpawnWaves()方法必须要在void Star()方法中手动调用才行。

3:能够实现一波一波效果的,最关键是用到了协同函数,来实现延迟的效果也就是StartCoroutine(method name)方法,查看官方文档知道,StartCoroutine(方法名)就能启用Coroutine方法,并且返回值的类型不再是void,而是IEnumerator,并且用关键字yield return new WaitForSeconds (float value)来标识WaitForSeconds类,这里的value是标识延迟的时间。(http://docs.unity3d.com/ScriptReference/WaitForSeconds.html)这里插入官方文档关于如何调用Coroutine,并且使用WaitForSeconds来实现延迟效果有很好的解释

六 结束游戏

在这一块中,主要困惑点是在重新加载当前游戏的api,因为官方教程用的是4.2的版本,用Application.loadlevel(Application.loadlevel) 来加载当前场景,当时在5.3版本中完全不能用,在5.3版本中使用SceneManager.LoadScene(scene name or index of the scene),并且在用这个类的时候,还必须引用Scene Management,在官网文档中其实也没解释清楚,在网上搜了好久才知道这个的用法,最终,在5.3中重新加载当前场景,我的代码是

usingUnityEngine;

usingSystem.Collections;

usingUnityEngine.SceneManagement;

publicclassGameController:MonoBehaviour{

void Update()

{

 if (gameover)

{

     if(Input.GetKeyDown(Keycode.R))
   {

      SceneManager.LoadScene(0);

   }

}

}

}

这样就当按下R键的时候,就会重新加载当前的场景,重新开始游戏

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容

  • 这是今天的成果吧,虽然还是没有全部完成,但是大致的功能已经实现,飞机的移动,限制移动范围,子弹的发射,消灭敌人,敌...
    Unity学习的路上阅读 2,831评论 1 2
  • // Unity学习笔记,自己会记录一些学习中遇到的问题,可以给自己看也可以给需要的人看,希望能帮助掉在同样坑里的...
    pirateH阅读 3,022评论 0 4
  • 111. [动画系统]如何将其他类型的动画转换成关键帧动画? 动画->点缓存->关键帧 112. [动画]Unit...
    胤醚貔貅阅读 12,956评论 3 90
  • 不知道你有没有喜欢上一个人,就是一眼见过后,就想跟她一起走完这一生的那种,不知道是什么样的动力让阿明做到了,不顾一...
    用心爱着你阅读 237评论 0 0
  • 最近一段时间关于李笑来的负面消息越来越多。 有说李笑来宣传的区块链投资是庞氏骗局的;有说李笑来没什么本事的;还有曝...
    且伴空山邀明月阅读 2,584评论 1 2