如果不是初次打开,File,OpenProject...,Open Other...
如果安装Unity时选择了SimpleProject,可以打开/Documents\Unity Projects\4-0_AngryBots工程。
可以直接在Project面板的Assets里找到AngryBots.unity文件打开
或者从File,OpenScene,找到工程目录的Assets目录里,打开AngryBots.unity文件
视图操作:
File,NewProject,CreateNewProject,
using UnityEngine; using System.Collections; public class HelloWorld : MonoBehaviour { /** 在屏幕显示 **/ void OnGUI() { // 标签文本尺寸 GUI.skin.label.fontSize = 100; // 标签(显示区域(x,y,w宽,h高),“显示文本”) GUI.Label(new Rect(10, 10, Screen.width, Screen.height), "HelloWorld!!!"); } }
在Assets中点住脚本文件,拖放到Hierarchy中的“MainCamera”主相机。
或者,先在Hierarchy里选中“MainCamera”主相机,然后从“Component”菜单的“Scripts”里选中脚本。
当主相机处于选中状态,从“Inspector”面板中可用看到用于相机的指令文件。
File,Build Settings...
然后从Project下的Assets面板,拖动HelloWorld.unity文件到弹出的BuildSettings窗口中,
或者点击BuildSettings窗口里的AddCurrent按钮选择场景文件。
MonoDevelop可能用起来不顺手,可用安装VS使之默认作为Unity的代码编辑器。
VS主程序:/MicrosoftVisualStudio12.0\Common7\IDE\devenv.exe
直接打开工程目录下的Assets文件夹。或在Assets面板的留空出右键,Show in Explorer,打开Assets目录,
然后将资源文件放入即可。
或者右键Assets面板,选择“Import New Asset...”,导入资源文件夹,
File,New Scene,然后保存为Level01.unity,
GameObject,Create Other,Plane,
根据需要,修改Shader类型。这里改为 Transparent,Cutout,Diffuse,
这一步可以直接从Assets中拖动材质球到Scene中的Plane上。
1)创建Plane,命名为Plane_Star,
2)创建材质球,
3)关联。
首先在Scene或Hierarchy中选中Plane_Star,然后Window,Animation,
然后,在新打开的Animation面板上,左键点击播放按钮下的条状区域,创建剪辑,
在Assets中生成一个.anim文件外,还生成一个.controller文件,
Edit,RenderSetting,
在Inspector面板,修改Ambient Light,
在Scene中修改视图到合适角度,点击Hierarchy中的主相机,GameObject,Align With View,
或者从属性面板手动修改主相机的参数,
GameObject,Create Other,Point Light。然后再Inspector面板配置参数,
修改属性,以和Plane_Star_Animation动画匹配,
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Player")] // 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名 public class Player : MonoBehaviour { /** * 构造函数不可用于初始化 **/ // 基速度 public float m_speed = 1; // public类型的变量可以在Inspector中配置 // 每渲染一帧动画,即调用一次 void Update () { float movev = 0; // 垂直方向速度 float moveh = 0; // 水平方向速度 // 向上箭头 if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime; } /** * Input包装输入功能,包括键盘、鼠标、触控 * Time.deltaTime表示每一帧被渲染的时刻,时长? **/ // 向下箭头 if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; } // 向左 if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; } // 向右 if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; } // this即Player this.transform.Translate(new Vector3(moveh, 0, movev)); /** * 物理转换器 * this.transform调用游戏体的Transform组件 * Transform包装移动、旋转、缩放 * Vector3(x, y, z) **/ } }
选择飞机,Component,MyGame,Player,
首先,将子弹的fbx文件拖入Hierarchy中,创建一个3D场景对象-游戏角色-游戏体,
打开子弹脚本,编辑代码,
using UnityEngine; using System.Collections; [AddComponentMenu ("MyGame/Rocket") ] /** * 子弹 **/ public class Rocket : MonoBehaviour { public float m_speed = 10; // 速度 public float m_liveTime = 1; // 生命 public float m_power = 1.0f; // 威力 void Update () { m_liveTime -= Time.deltaTime; // 没渲染一帧,生命值即减少一定时间 if (m_liveTime <= 0) { Destroy(this.gameObject); // 当生命值,销毁子弹对象 } // 速度越来越慢 this.transform.Translate(new Vector3(0, 0, - m_speed * Time.deltaTime)); } }
需要重复使用的游戏体,应将其只作为Prefab。
在Assets中右键创建一个Prefab,并修改为和子弹3D对象相同的名字,
从Hierarchy中拖放子弹对象到Assets中的Prefab上,
再修改飞机脚本
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Player")] // 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名 public class Player : MonoBehaviour { // 飞机基速度 public float m_speed = 1; // 子弹控制器 public Transform m_rocket; // 子弹速率 public float m_rocketRate = 0; // 每渲染一帧动画,即调用一次 void Update () { float moveh = 0; // 水平方向速度 float movev = 0; // 垂直方向速度 // 向上箭头 if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime; } // 向下箭头 if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; } // 向左 if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; } // 向右 if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; } // 子弹速率虽渲染帧数的增加而降低 m_rocketRate -= Time.deltaTime; // 空格,发射子弹 if (m_rocketRate <= 0) { m_rocketRate = 0.1f; if (Input.GetKey(KeyCode.Space)) { // 不能用new方法创建对象,只能是Instantiate Instantiate(m_rocket, this.transform.position, this.transform.rotation); } } this.transform.Translate(new Vector3(moveh, 0, movev)); } }
在Hierarchy中或从场景中选择飞机,然后切换到Inspector面板,在Player(Script)下找到Rocket属性,从Assets中拖放子弹的Prefab体到这里,
最后,测试即可。
空格键发射子弹。
从Assets中拖放敌人模型fbx文件到Hierarchy中,创建敌人游戏体。这时场景中也会默认添加敌人的游戏对象,
Enemy.cs文件,
using UnityEngine; using System.Collections; /** 由电脑控制敌人 **/ [AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour { // 速度 public float m_speed = 1; // 旋转速度 protected float m_rotSpeed = 60; // 变向间隔时间 protected float m_timer = 1.5f; // 当前游戏体的控制器 protected Transform m_transform; void Start() { m_transform = this.transform; } /** 每帧更新一次 **/ void Update() { m_timer -= Time.deltaTime; if (m_timer <= 0) { m_timer = 3; // 3秒旋转一次 // 改变旋转方向 m_rotSpeed = -m_rotSpeed; } // 旋转方向 m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World); // 前进 m_transform.Translate(new Vector3(m_speed * Time.deltaTime, 0, 0)); } }
同创建子弹预制体的步骤:
在Assets中右键创建Prefab-敌人预制体,并修改名称和敌人游戏体相同。然后从Hierarchy中拖动敌人游戏体到敌人预制体上,再把场景中的敌人3D对象删除即可。
首先从Assets中拖动敌人的Prefab预制体到场景中,然后选中敌人Prefab,Ctrl+D,多次复制,修改位置。
首先在Scene-场景中选择一个敌人游戏体,然后Component,Physics,Box Collider,
然后继续操作,打开Inspector面板,找到Box Collider模块,勾选Is Trigger,
紧接上一步,已经添加碰撞体的敌人游戏体被选择,Component,Physics,Rigidbody,
然后,打开Inspector面板,找到Rigidbody模块。去除勾选Use Gravity,选中Is Kinematic,
继续上面的操作,在设置完毕的游戏体选中的状态下,返回Inspector面板顶部,点击Prefab条目的Apply按钮,
上面3步可以直接在Assets中操作敌人的Prefab文件,这样就不用执行第3步的拷贝了,
在Assets中选中敌人的Prefab文件。
然后Component,Physics,Box Collider,
打开Inspector面板,找到Box Collider模块,勾选Is Trigger,
Component,Physics,Rigidbody,
打开Inspector面板,找到Rigidbody模块。去除勾选Use Gravity,选中Is Kinematic,
在Hierarchy中选择飞机的游戏体,执行同样的操作。
首先,创建tag。Edit,Project Setting,Tags and Layers,
自动打开属性面板。在Element*中填写标签,本例需要填写两个,“PlayerRocket”和“Enemy”,
然后为子弹和敌人游戏体添加标签。Enemy的tag是“Enemy”,Rocket的tag是“PlayerRocket”,
最后为飞机添加标签。Player这个标签是Unity预设的,
using UnityEngine; using System.Collections; /** 由电脑控制敌人 **/ [AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour { // 速度 public float m_speed = 1; // 旋转速度 protected float m_rotSpeed = 60; // 变向间隔时间 protected float m_timer = 1.5f; // 当前游戏体的控制器 protected Transform m_transform; // 生命值 public float m_life = 10; /** 物体发生碰撞时调用,继承自MonoBehaviour的函数。重写 **/ void OnTriggerEnter(Collider other) { /** other:碰撞体。如果当前敌人对象碰撞的是 子弹 */ if (other.tag.CompareTo("PlayerRocket") == 0) { // 当前当前碰撞体的标签,获取其所属游戏体 Rocket rocket = other.GetComponent<Rocket>(); // 获取到了 if (rocket != null) { // 当前敌人的生命值递减 m_life -= rocket.m_power; if (m_life <= 0) { Destroy(this.gameObject); } } } /** other:碰撞体。如果当前敌人对象碰撞的是 飞机 */ else if (other.tag.CompareTo("Player") == 0) { // 当前敌人对象之间销毁 m_life = 0; Destroy(this.gameObject); } } void Start() { m_transform = this.transform; } /** 每帧更新一次 **/ void Update() { m_timer -= Time.deltaTime; if (m_timer <= 0) { m_timer = 3; //改变旋转方向 m_rotSpeed = -m_rotSpeed; } // 旋转方向 m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World); // 前进 m_transform.Translate(new Vector3(m_speed * Time.deltaTime, 0, 0)); } }
using UnityEngine; using System.Collections; [AddComponentMenu ("MyGame/Rocket") ] /** * 子弹 **/ public class Rocket : MonoBehaviour { public float m_speed = 10; // 速度 public float m_liveTime = 1; // 生命 public float m_power = 1.0f; // 威力 /** 碰撞检测 other:与子弹发生碰撞的游戏体**/ void OnTriggerEnter (Collider other) { // 如果发生碰撞的 不是 敌人 if (other.tag.CompareTo("Enemy") != 0) { // 什么也不做,退出函数。 return; } // 碰撞的是敌人,销毁 子弹自身 Destroy(this.gameObject); } void Update () { m_liveTime -= Time.deltaTime; // 没渲染一帧,生命值即减少一定时间 if (m_liveTime <= 0) { Destroy(this.gameObject); // 当生命值,销毁子弹对象 } // 速度越来越慢 this.transform.Translate(new Vector3(0, 0, - m_speed * Time.deltaTime)); } }
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Player")] /** 飞机 * 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名 **/ public class Player : MonoBehaviour { // 飞机基速度 public float m_speed = 1; // 子弹控制器 public Transform m_rocket; // 子弹速率 public float m_rocketRate = 0; // 生命值 public float m_life = 3; /** 碰撞函数 **/ void OnTriggerEnter(Collider other) { // 如果和飞机发生碰撞的 不是自己发射的 子弹 if (other.tag.CompareTo("PlayerRocket") != 0) { m_life -= 1; if (m_life <= 0) { Destroy(this.gameObject); } } } // 每渲染一帧动画,即调用一次 void Update () { float moveh = 0; // 水平方向速度 float movev = 0; // 垂直方向速度 // 向上箭头 if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime; } // 向下箭头 if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; } // 向左 if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; } // 向右 if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; } // 子弹速率虽渲染帧数的增加而降低 m_rocketRate -= Time.deltaTime; if (m_rocketRate <= 0) { m_rocketRate = 0.1f; // 空格,发射子弹 if (Input.GetKey(KeyCode.Space)) { // 不能用new方法创建对象,只能是Instantiate Instantiate(m_rocket, this.transform.position, this.transform.rotation); } } this.transform.Translate(new Vector3(moveh, 0, movev)); } }
在Project的Assets目录创建Prefab,关联bound空游戏体。然后可以删除Hierarchy里的GameObject,
为预制体添加 BoxCollider-盒子碰撞体 和 Rigidbody-刚体 属性,
配置合适的大小和位置。还要记得为预制体添加“bound”标签,
using UnityEngine; using System.Collections; /** 由电脑控制敌人 **/ [AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour { // 速度 public float m_speed = 1; // 旋转速度 protected float m_rotSpeed = 60; // 变向间隔时间 protected float m_timer = 1.5f; // 当前游戏体的控制器 protected Transform m_transform; // 生命值 public float m_life = 10; /** 物体发生碰撞时调用,继承自MonoBehaviour的函数。重写 **/ void OnTriggerEnter(Collider other) { /** other:碰撞体。如果当前敌人对象碰撞的是 子弹 */ if (other.tag.CompareTo("PlayerRocket") == 0) { // 当前当前碰撞体的标签,获取其所属游戏体 Rocket rocket = other.GetComponent<Rocket>(); // 获取到了 if (rocket != null) { // 当前敌人的生命值递减 m_life -= rocket.m_power * 5; if (m_life <= 0) { Destroy(this.gameObject); } } } /** other:碰撞体。如果当前敌人对象碰撞的是 飞机 */ else if (other.tag.CompareTo("Player") == 0) { // 当前敌人对象之间销毁 m_life = 0; Destroy(this.gameObject); } /** 如果当前敌人对象碰撞的是 bound */ else if (other.tag.CompareTo("bound") == 0) { m_life = 0; Destroy(this.gameObject); } } void Start() { m_transform = this.transform; } /** 每帧更新一次 **/ void Update() { m_timer -= Time.deltaTime; if (m_timer <= 0) { m_timer = 3; //改变旋转方向 m_rotSpeed = -m_rotSpeed; } // 旋转方向 m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World); // 前进 m_transform.Translate(new Vector3(m_speed * Time.deltaTime, 0, 0)); } }
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour { public float m_speed = 1; protected float m_rotSpeed = 60; protected float m_timer = 1.5f; protected Transform m_transform; public float m_life = 10; void OnTriggerEnter(Collider other) { 略 } void Start() { m_transform = this.transform; } /** 每帧更新一次 **/ /** 供子类继承的方法 * virtual 子类必须被重新的 **/ protected virtual void Update() { 略 } }
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/SuperEnemy")] /** 继承自Enemy **/ public class SuperEnemy : Enemy { /** 重写 父类中的virtual方法 **/ protected override void Update() { /** 位移 * 继承自父类的属性 m_transform **/ m_transform.Translate(new Vector3(0, 0, - m_speed * Time.deltaTime)); } }
首先,在Project的Assets目录新建一个Prefab,命名为SuperEnemy,
然后,将Assets中的Boss敌人模型fbx文件拖放到Prefab预制体上,
接着,关联SuperEnemy.cs控制脚本到预制体上,
然后,为Boss敌人预制体添加盒子碰撞体、刚体属性并配置,
同时,修改Tag标签为“Enemy”,
拖放Boss敌机预制体到Scene中。
首先,使用子弹模型创建超级子弹游戏体,
从Assets中拖动子弹的fbx文件到Hierarchy中
其次,使用游戏体创建预制体
从Hierarchy中拖放子弹游戏体到Assets中的prefab上,并修改prefab文件的名称为SuperRocket,
创建好prefab文件后,删除Hierarchy中的子弹游戏体
再次,创建超级子弹使用的特殊材质球,
然后,修改超级子弹的材质,
选中Hierarchy中的超级子弹,切换到到Inspector面板,打开MeshRenderer项目,展开Materials子项目,点击Element*条目后的圆心点,选中材质球,
而后,Edit,ProjectSettings,TagsandLayers,添加“SuperRocket”标签,
接着,创建SuperRocket.cs控制脚本,
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/SuperRocket")] /** 继承自子弹 **/ public class SuperRocket : Rocket { /** 重写碰撞检测方法 **/ void OnTriggerEnter(Collider other) { // 如果发生碰撞的 不是 飞机 if (other.tag.CompareTo("Player") != 0) { // 什么也不做,退出函数。 return; } // 碰撞的是敌人,销毁 子弹自身 Destroy(this.gameObject); Debug.Log("超级子弹碰玩家====---"); } }
继而,为超级子弹预制体添加标签,添加盒子碰撞体、刚体属性,添加控制代码关联,
继续,修改Boss敌机的控制代码,
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/SuperEnemy")] /** 继承自Enemy **/ public class SuperEnemy : Enemy { // 超级子弹 public Transform m_rocket; // 发射时间间隔 public float m_fireTimer = 2; // 射击目标 protected Transform m_player; /** 初始化函数,在游戏开始时系统自动调用。 * 当一个脚本实例被载入时Awake被调用。 * Awake用于在游戏开始之前初始化变量或游戏状态。 * 在脚本整个生命周期内它仅被调用一次 * **/ void Awake() { // 获取 玩家 对象 GameObject obj = GameObject.FindGameObjectWithTag("Player"); if (obj != null) { // 初始化自己的射击目标 m_player = obj.transform; } } /** 重写 父类中的virtual方法 **/ protected override void Update() { // 发射速度越来越慢 m_fireTimer -= Time.deltaTime; if (m_fireTimer <= 0) { m_fireTimer = 2; if (m_player != null) { // 获取当前玩家的相对位置 Vector3 relativePos = m_transform.position - m_player.position; // 创建实例(实例对象-子弹,当前Boss敌机位置,朝向(玩家的位置)) Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos)); } } /** 位移 * 继承自父类的属性 m_transform **/ m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime * 0.5f)); Debug.Log("Boss敌机来袭............."); } }
在Project/Assets中右键,Import Package,Custom,Package....,
如果希望其他人或在其它项目方便使用自己的资源,可以右键Export Package...,导出为unitypackage文件:
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Player")] /** 飞机 * 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名 **/ public class Player : MonoBehaviour { // 飞机基速度 public float m_speed = 2; // 子弹控制器 public Transform m_rocket; // 子弹速率 public float m_rocketRate = 0; // 生命值 public float m_life = 2; public Transform m_transform; // 声音 public AudioClip m_shootClip; // 声音文件 protected AudioSource m_audio; // 爆炸效果 public Transform m_explosionFX; void Start() { m_transform = this.transform; m_audio = this.audio; } /** 碰撞函数 **/ void OnTriggerEnter(Collider other) { // 如果和飞机发生碰撞的 不是自己发射的 子弹 if (other.tag.CompareTo("PlayerRocket") != 0) { m_life -= 1; if (m_life <= 0) { // 实例化一个爆炸(实例对象,位置,四元素.身份) Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); Destroy(this.gameObject); Debug.Log("飞机坠毁 …… ……"); } } } // 每渲染一帧动画,即调用一次 void Update() { float moveh = 0; // 水平方向速度 float movev = 0; // 垂直方向速度 // 向上箭头 if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime; } // 向下箭头 if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; } // 向左 if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; } // 向右 if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; } // 子弹速率虽渲染帧数的增加而降低 m_rocketRate -= Time.deltaTime; if (m_rocketRate <= 0) { m_rocketRate = 0.1f; // 空格,发射子弹 if (Input.GetKey(KeyCode.Space)) { // 不能用new方法创建对象,只能是Instantiate Instantiate(m_rocket, this.transform.position, this.transform.rotation); // 播放声音 m_audio.PlayOneShot(m_shootClip); } } m_transform.Translate(new Vector3(moveh, 0, movev)); } }
1)分别选择敌人和Boss敌机的prefab文件,Component,Audio,Audio Source,
2)修改敌人的控制脚本,
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour { public float m_speed = 1; protected float m_rotSpeed = 60; protected float m_timer = 1.5f; protected Transform m_transform; public float m_life = 10; // 爆炸效果 public Transform m_explosionFX; // 声音 public AudioClip m_shootClip; // 声音文件 protected AudioSource m_audio; /** 物体发生碰撞时调用,继承自MonoBehaviour的函数。重写 **/ void OnTriggerEnter(Collider other) { if (other.tag.CompareTo("PlayerRocket") == 0) { Rocket rocket = other.GetComponent<Rocket>(); Debug.Log("PlayerRocket========="); if (rocket != null) { m_life -= rocket.m_power * 5; if (m_life <= 0) { /** 实例化一个爆炸(实例对象,位置,四元素.身份) **/ Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); Destroy(this.gameObject); } } } /** other:碰撞体。如果当前敌人对象碰撞的是 飞机 */ else if (other.tag.CompareTo("Player") == 0) { // 当前敌人对象之间销毁 m_life = 0; /** 如果碰到了飞机,发射爆炸 **/ Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); Destroy(this.gameObject); Debug.Log("敌人碰飞机===="); } else if (other.tag.CompareTo("bound") == 0) { 略 } } void Start() { m_transform = this.transform; m_audio = this.audio; } protected virtual void Update() { 略 } }
3)修改Boss的控制脚本,
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/SuperEnemy")] public class SuperEnemy : Enemy { public Transform m_rocket; public float m_fireTimer = 2; protected Transform m_player; void Awake() { 略 } protected override void Update() { m_fireTimer -= Time.deltaTime; if (m_fireTimer <= 0) { m_fireTimer = 2; if (m_player != null) { Vector3 relativePos = m_transform.position - m_player.position; Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos)); /*** 射击时播放声音 ***/ m_audio.PlayOneShot(m_shootClip); } } m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime * 0.5f)); } }
using UnityEngine; using System.Collections; public class EnemySpawn : MonoBehaviour { // 敌机类型 public Transform m_enemy; // 诞生时间间隔。速度:3秒生产一架 protected float m_timer = 3; // 当前生产设备 protected Transform m_transform; // 初始化生产设备 void Start () { m_transform = this.transform; } // 更新游戏 void Update () { // 间隔越来越短 m_timer -= Time.deltaTime; // 重新配置生产敌机的速度 if (m_timer <= 0) { m_timer = Random.value * 5.0f; // 最大为5 if (m_timer <= 3) { m_timer = 3; } // 创建敌机实例(敌机类型,敌机位置-当前生产设备的位置),相对于世界坐标或父坐标 Instantiate(m_enemy, m_transform.position, Quaternion.identity); } } }
从Assets中拖动脚本文件到Hierarchy中的空游戏体上,
右键Assets,Create,创建2个Prefab,
从Hierarchy中拖动空游戏体到预制体上,
最后删除空游戏体,
目前加入Scene中敌机生产设备默认是不显示的,不利于我们的设计制作。进行下面的操作可以在Scene中显现它们的位置,但最终发布的游戏以及测试中不会显示。
using UnityEngine; using System.Collections; public class EnemySpawn : MonoBehaviour { public Transform m_enemy; protected float m_timer = 3; protected Transform m_transform; void Start () { 略 } void Update () { 略 } // 在Scene中显示图标 void OnDrawGizmos() { Gizmos.DrawIcon(transform.position, "spawn.png", true); } }
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/GameManager")] public class GameManager : MonoBehaviour { public static GameManager Instance; // 得分 public int m_score = 0; // 历史最高得分 public static int m_hiscore = 0; // 主角 protected Player m_player; // 背景音乐 public AudioClip m_musicClip; // 声音源 protected AudioSource m_Audio; void Awake() { // 自身实例。单例 Instance = this; } // 初始化 void Start () { m_Audio = this.audio; // 获取主角 GameObject obj = GameObject.FindGameObjectWithTag("Player"); if (obj != null) { m_player = obj.GetComponent<Player>(); } } // 每帧渲染一次 void Update () { // 循环播放背景音乐 if (!m_Audio.isPlaying) { m_Audio.clip = m_musicClip; // 音乐文件 m_Audio.Play(); // 播放 } // 暂停游戏 // Time.timeScale 时间缩放,时间的速度 // 按下ESC键 if (Time.timeScale > 0 && Input.GetKeyDown(KeyCode.Escape)) { // 时间的速度为0,时间静止 Time.timeScale = 0; } } /** 专用绘制UI界面 **/ void OnGUI() { // 游戏暂停时显示------------------------------------- // 游戏暂停 --- 当时间静止 if (Time.timeScale == 0) { // 在屏幕绘制两个按钮 // 继续游戏按钮 // Buttom 按钮(区域,文字) // Rect 四方区域(x,y,w,h) if (GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.4f, 100, 30), "继续游戏")) { // 时间按原速度(正常速度)流失 Time.timeScale = 1; } // 退出游戏按钮 if (GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.6f, 100, 30), "退出游戏")) { // 退出游戏 Application.Quit(); } } // 以下当玩家创建后显示-------------------------------- int life = 0; if (m_player != null) { // 获得主角的生命值 life = (int)m_player.m_life; } else { // 游戏结束 GUI.skin.label.fontSize = 50; // 字号 GUI.skin.label.alignment = TextAnchor.LowerCenter; // 对齐 GUI.Label(new Rect(0, Screen.height * 0.2f, Screen.width, 60), "游戏失败"); // 标签 GUI.skin.label.fontSize = 20; // 字号 // 显示按钮 if (GUI.Button(new Rect(Screen.width*0.5f-50, Screen.height*0.5f, 100, 30), "再试一次")) { // 读取当前关卡 // Application.LoadLevel 读取下一个关卡,当前关卡的一切对象都被销毁 // Application.loadedLevelName 当前关卡 Application.LoadLevel(Application.loadedLevelName); } } // 以下一直显示--------------------------------------- GUI.skin.label.fontSize = 15; // 字号 GUI.skin.label.alignment = TextAnchor.LowerLeft; // 对齐位置 // 显示主角生命 GUI.Label(new Rect(5, 5, 100, 30), "生命值" + life); // 显示最高分 GUI.Label(new Rect(0, 5, Screen.width, 90), "历史最高得分 " + m_hiscore); // 显示当前得分 GUI.Label(new Rect(0, 125, Screen.width, 30), "得分" + m_score); } // 增加分数 // point即敌机控制类Enemy中的属性m_point public void AddScore( int point ) { m_score += point; // 更新高分纪录 if (m_hiscore < m_score) m_hiscore = m_score; } }
GameObject,Create Empty,空对象创建在Hierarchy面板中,将其重命名为“GameManager”。这个空游戏体会自动加入到Scene中。
选中GameManager,Component,Audio,Audio Source。
从Assets中拖放GM.cs到Hierarchy中的GM上。
首先,修改声音文件的立体声类型。2D声音和摄像机的距离无关,不会忽大忽小;3D声音会根据发声体与相机的距离而变大变小。
然后,打开GM的Inspector属性面板,Script项目,配置MusicClip,
做完这一步即可运行测试,
using UnityEngine; using System.Collections; [AddComponentMenu("MyGame/Enemy")] public class Enemy : MonoBehaviour { public float m_speed = 1; protected float m_rotSpeed = 60; protected float m_timer = 1.5f; protected Transform m_transform; public float m_life = 10; public Transform m_explosionFX; public AudioClip m_shootClip; protected AudioSource m_audio; // 分数值 public int m_point = 10; void OnTriggerEnter(Collider other) { if (other.tag.CompareTo("PlayerRocket") == 0) { Rocket rocket = other.GetComponent<Rocket>(); if (rocket != null) { m_life -= rocket.m_power * 5; if (m_life <= 0) { Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); Destroy(this.gameObject); // 调用游戏管理器的增加分数的方法 GameManager.Instance.AddScore(m_point); } } } else if (other.tag.CompareTo("Player") == 0) { 略 } else if (other.tag.CompareTo("bound") == 0) { 略 } } void Start() { 略 } protected virtual void Update() { 略 } }
using UnityEngine; using System.Collections; public class HelloWorld : MonoBehaviour { void OnGUI() { GUI.skin.label.fontSize = 100; GUI.Label(new Rect(10, 10, Screen.width, Screen.height), "HelloWorld!!!"); // 按钮(区域(x, y, w, h), 文字) if (GUI.Button(new Rect(Screen.width/2 - 100, Screen.height/2 - 50, 100, 30), "开始游戏")) { // Level01 关卡名称,.unity文件的名称 Application.LoadLevel("Level01"); } } }
首先,File,Save Scene,保存当前的关卡Level01,
然后,在Assets中双击打开之前的关卡HelloWorld,
接着,选择Assets中的一张图片,GameObject,Create Other,GUI Texture,
紧跟上一步点击“Player Setting...”,
或者,Edit,Project Settings,Player,
- end
资源:
本篇博文《Unity3D上路》: http://pan.baidu.com/s/1c0y5Cuk