想要挂接在Unity3D中的结点的脚本都得继承MonoBehaviour,State就是所有的状态的父类了,主要是三个函数,Init()用于这个状态的初始化,Update用于场景的更新,Exit()用于当离开当前状态时所进行的一些操作,比如隐藏当前界面等。
创建一个空的Object用来挂接我们游戏的主脚本,代码如下:
using UnityEngine;
using System.Collections;
// Use this for initialization
void Start () {
m_CurState.Init();
}
// Update is called once per frame
void Update ()
{
m_CurState.Update();
}
}
这样我们就可以轻松的在不同的状态中切换了。想要增加一个新的状态,就只需继承State类,然后在其中写这个状态所要的元素,在适当的地方ChangeState一下就好了。
脚本的层次结构如下:
例如我在按钮按下时切换到开始场景:
using System.Collections;
public class BeginGame : MonoBehaviour {
public StateRun m_RunState;
public Main_Script m_MainScript;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnMouseEnter()
{
print("enter");
}
void OnMouseUp()
{
m_MainScript.ChangeState(m_RunState);
}
void OnMouseExit()
{
print("exit");
}
}
这个脚本是挂在一个板上面的,点击它时就进入游戏的主场景了。下回说一下飞机的移动。
现在开始真正的游戏元素的编写了。
第一步,让飞机动起来。
首先是飞机的前进,通常2D中的做就是背景的循环滚动。
在3D中我们可以让摄像机移动,背景我们可以做超一个大地形。。在地形上摆一些固定的东西。
// Update is called once per frame
void Update () {
TurnLeft = false;
TurnRight = false;
if (Input.GetKey(KeyCode.W))
{
Vector3 screenPos = Camera.mainCamera.WorldToScreenPoint(this.transform.position);
//print(screenPos.y);
if (Screen.height > screenPos.y)
this.transform.Translate(Vector3.forward * Time.deltaTime * m_nMoveSpeed);
}
if (Input.GetKey(KeyCode.S))
{
Vector3 screenPos = Camera.mainCamera.WorldToScreenPoint(this.transform.position);
if (0 < screenPos.y)
this.transform.Translate(Vector3.forward * Time.deltaTime * -m_nMoveSpeed);
}
现在子弹出来了,但是我们没有加上子弹的消亡,这样子弹被创建出来后就一直存在于场景中不会消失,会越积越多,所以我们让子弹在移出屏幕时就把他销毁掉。
using UnityEngine;
using System.Collections;
public class BulletControl : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Vector3 screenPos = Camera.mainCamera.WorldToScreenPoint(this.transform.position);
//print(screenPos.y);
if (Screen.height < screenPos.y)
Destroy(transform.gameObject);
}
}
将这个脚本挂接在子弹的prefab上就可以实现效果了。
己方的飞机控制已经初步完成了,现在要加入敌机了。
理论上应该有两种方式:
1.预先设定,就是在编辑器里在你想要的位置上加上敌方的攻击单位
2.动态生成,根据游戏进行的时间来控制敌方攻击单位的产生。
这边采用第2个方式来产生,有一些地面单位倒是可以用第一种方式来产生。
我们首先要设置一个敌机的产生位置,用空的object可以随意的定一个坐标。
using UnityEngine;
using System.Collections;
public class EnemyManager : MonoBehaviour {
public GameObject m_EnemyPre;
public Transform m_CreatePoint;
//一波飞机的数量
public const int MAX_GROUP_ENEMYS = 4;
//两波飞机之间的时间间隔
public float GROUP_INTERVAL = 2.0f;
//同一波中两架飞机之间产生的间隔
public float CREATE_INTERVAL = 0.25f;
private float m_fTimeAfterOneGroup = 0.0f;
private float m_fTimeAfterCreate = 0.0f;
private int m_nEnemyNum = 0;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
m_fTimeAfterOneGroup +=Time.deltaTime;
m_fTimeAfterCreate += Time.deltaTime;
if (m_fTimeAfterOneGroup > 2.0f)
{
if (m_fTimeAfterCreate > 0.25f)
{
GameObject clone = (GameObject)Instantiate(m_EnemyPre,
m_CreatePoint.position, m_CreatePoint.rotation);
敌机的移动脚本,可自己再定义新的移动脚本,在创建新敌机时挂上去就好:
using UnityEngine;
using System.Collections;
public class MoveScript_Shake : MonoBehaviour {
//标志左右移动方向
private int m_nDir = 1;
//原始位置
private Vector3 m_OriginalPos;
//水平移动速度
public float m_HoriSpeed = 0.1f;
//翻转速度
public float m_RotSpeed = 1.0f;
//向前移动速度
public float m_MoveSpeed = 0.0005f;
public Vector3 curScreenPos;
public Vector3 LDPoint;
// Use this for initialization
void Start ()
{
m_OriginalPos = transform.position;
LDPoint = GameObject.Find("LDPoint").transform.position;
print (LDPoint);
}
// Update is called once per frame
void Update ()
{
float relativeOffset = transform.position.x - m_OriginalPos.x;
if (Mathf.Abs(relativeOffset) > 5)
{
m_nDir = -m_nDir;
}