码迷,mamicode.com
首页 > 编程语言 > 详细

Unity3D-第一视角射击游戏

时间:2014-12-07 17:45:52      阅读:1229      评论:0      收藏:0      [点我收藏+]

标签:des   http   io   ar   os   使用   sp   for   strong   

一。新建关卡

File,Save Scene,
File,New Scene,
File,Save Scene as... ,Level02.unity

1.建立场景

从Assets中拖放场景模型到Hierarchy中,
bubuko.com,布布扣

2.为游戏体添加多边形碰撞体

在Hierarchy中选择3个构造游戏空间的游戏体,
Component,Physics,Mesh Collider,
操作后,游戏空间游戏体可以用于物理碰撞检测。
bubuko.com,布布扣

3.创建灯光

现在游戏空间内光线不好,调整一下,

1)创建电光源

根据需求,创建若干。可使用Ctrl + D 快速复制,
bubuko.com,布布扣

2)调整亮度

bubuko.com,布布扣

二。创建玩家

1.创建空对象

GameObject,Create Empty,
在Hierarchy中将之命名为FPSPlayer,

2.设置标签

选择FPSPlayer,Inspector,Tag,修改为“Player”,
bubuko.com,布布扣

3.添加角色控制器

FPSPlayer仍旧被选中,
Component,Physics,Character Controller,
执行这一步后,玩家在场景中移动时,会和其它游戏体发生物理交互。
bubuko.com,布布扣

4.添加刚体属性

仍旧选中玩家,
Component,Physics,Rigidbody,
bubuko.com,布布扣

5.控制脚本

首先,创建FPSPlayer.cs脚本,

using UnityEngine;
using System.Collections;

[AddComponentMenu("MyGame/FPSPlayer")]
public class FPSPlayer : MonoBehaviour {

    private CharacterController m_ch;   // 玩家角色控制器
    public Transform m_transform;       // 玩家实例
    private float m_movSpeed = 3.0f;    // 玩家移动基速
    public int m_life = 5;              // 生命值

    private float m_gravity = 2.0f;     // 重力

    private Transform m_camTransform;   // 摄像机
    private Vector3 m_camRot;           // 摄像机姿势-旋转角度
    private float m_camHeight = 4.5f;   // 摄像机高度-玩家的眼睛

    void Start() {

        m_transform = this.transform;                       // 本角色实例
        m_ch = this.GetComponent<CharacterController>();    // 本角色的控制器

        m_camTransform = Camera.main.transform;// 获取摄像机

        /** 设置摄像机初始位置 **/
        Vector3 pos = m_transform.position; // 玩家位置
        pos.y += m_camHeight;               // 镜头高度
        m_camTransform.position = pos;                  // 初始化初始摄像机位置
        m_camTransform.rotation = m_transform.rotation; // 初始化摄像机姿势

        /**
         * eulerAngles的三个变量 z,x,y 表示三个绕坐标轴旋转的角度(世界坐标轴)
         * 顺序是z,x,y。如果角度超过360的话,要用Rotate来代替,用四元数来旋转
         * 这三个x,y,z的值对应Inspector上的transform/Rotation的三个值
         * 所绕角度是顺着坐标轴看,按逆时针旋转的角度
         **/
        m_camRot = m_camTransform.eulerAngles;      // 存储摄像机姿势

        Screen.lockCursor = true;       // 锁定鼠标

    }

    void Update() {

        if (m_life <= 0) return;                // 如果生命为0,什么也不做

        /**
         * Input.GetAxis(string name);
         * 根据坐标轴名称返回虚拟坐标系中的值。返回值类型:float
         * 参数:Horizontal, Vertial, Mouse X, Mouse Y
         * 其中Horizontal, Vertical 默认对应小键盘上的左右、上下键,返回值为-1或1
         * Mouse X, Mouse Y 对应鼠标位置,返回值不定
         * 以上都是在unity3d中预定义好的映射,可以通过 Edit->Project Settings->Input 来重新定义映射
         **/
        float rv = Input.GetAxis("Mouse Y");    // 鼠标 Y 轴移动距离,抬头角度
        float rh = Input.GetAxis("Mouse X");    // 鼠标 X 轴移动距离,转身角度

        m_camRot.x -= rv;                       // X轴 摄像机仰角-抬头
        m_camRot.y += rh;                       // Y轴 摄像机旋转
        m_camTransform.eulerAngles = m_camRot;  // 摄像机姿势修正

        // 使主角的面向方向与摄像机一致
        Vector3 camrot = m_camTransform.eulerAngles;    // 提取摄像机姿势
        camrot.x = 0; camrot.z = 0;                     // 防止后退
        m_transform.eulerAngles = camrot;               // 玩家姿势修正
         
        float xm = 0, ym = 0, zm = 0;

        // 重力运动
        ym -= m_gravity * Time.deltaTime * 10;

        // 前进/后退
        if (Input.GetKey(KeyCode.W))
            zm += m_movSpeed * Time.deltaTime * 3;
        else if (Input.GetKey(KeyCode.S))
            zm -= m_movSpeed * Time.deltaTime * 3;
        // 左移/右移
        if (Input.GetKey(KeyCode.A))
            xm -= m_movSpeed * Time.deltaTime * 3;
        else if (Input.GetKey(KeyCode.D))
            xm += m_movSpeed * Time.deltaTime * 3;
        
        // 移动
        m_ch.Move(m_transform.TransformDirection(new Vector3(xm, ym, zm)));

        // 使摄像机的位置与主角一致
        Vector3 pos = m_transform.position;
        pos.y += m_camHeight;
        m_camTransform.position = pos;

    }
    void OnDrawGizmos() {
        Gizmos.DrawIcon(transform.position, "pfsPlayer.png", true);
    }
}

然后,关联到玩家游戏体,
bubuko.com,布布扣

 

6.创建武器

1)设置主相机

可选操作,
bubuko.com,布布扣

2)创建武器游戏体

将已经做好的武器prefab文件加入场景,
bubuko.com,布布扣

3)建立父子关系

首先,拖动M16游戏体到MainCamera游戏体上松开鼠标即可,
bubuko.com,布布扣

然后,修改一下M16的参数,使之和主相机在一个位置,
bubuko.com,布布扣
 

三。创建僵尸

1.地形寻路设置

1)开启地形游戏体的寻路支持

首先,选中地形游戏体(可每次选一个,依次配置),
然后,在Inspector,Static,选中“Navigation Static”,
bubuko.com,布布扣

2)寻路计算

首先,Window,Navigation,
bubuko.com,布布扣

然后,在“Bake”标签页,配置参数
bubuko.com,布布扣

最后,点击“Bake”按钮,开始寻路计算,

计算结束后,可寻路的地形变色,
bubuko.com,布布扣

2.创建寻路者-僵尸

1)创建游戏体

从Assets中拖放僵尸模型资源到Hierarchy中,
bubuko.com,布布扣

2)添加寻路功能

bubuko.com,布布扣

3)寻路设置

bubuko.com,布布扣

3.僵尸控制脚本

1)脚本代码

using UnityEngine;
using System.Collections;

public class Zombie : MonoBehaviour {

    Transform m_transform;          // 僵尸实例
    FPSPlayer m_player;             // 玩家实例
    NavMeshAgent m_agent;           // 寻路器

    private float m_moveSpeed = 0.5f;   // 僵尸移动基速度

	void Start () {
        m_transform = this.transform;   // 初始化僵尸
        
        m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<FPSPlayer>();    // 玩家实例

        m_agent = this.GetComponent<NavMeshAgent>();                // 本僵尸的寻路器
        m_agent.SetDestination(m_player.transform.position);      // 寻路目标-玩家位置

        /**
         * UnassignedReferenceException: The variable m_transform of ‘FPSPlayer‘ has not been assigned.
         * You probably need to assign the m_transform variable of the FPSPlayer script in the inspector.
         **/
        //m_agent.SetDestination(m_player.m_transform.position);      // 出现上面的报错
	}
	
	void Update () {
        float speed = m_moveSpeed * Time.deltaTime;
        //m_transform.TransformDirection:从自身坐标到世界坐标变换方向。把一个具体的点坐标的三位向量转变成一个方向向量
        m_agent.Move(m_transform.TransformDirection(new Vector3(0, 0, speed))); // 寻路位置更新
	}
}

 

2)关联

点击Hierarchy中的僵尸游戏体,拖动Assets中的脚本到上面,
bubuko.com,布布扣

4.僵尸的动作

1)打开僵尸的动画管理器

在Hierarchy中选择僵尸游戏体,切换到Inspector面板,
打开Animator项目,(这个属性是游戏资源已经创建好的)
查看Controller条目,
Window,Animator,
bubuko.com,布布扣

2)添加角色属性

在“Parameters”子面板,点击“+”加号,选择“Bool”类型,
新建“idle、run、attack、death”4个属性,(对应4种动作)
bubuko.com,布布扣

3)设置动画切换

bubuko.com,布布扣

4)修改僵尸控制脚本

using UnityEngine;
using System.Collections;

public class Zombie : MonoBehaviour {

    public Transform m_transform;   // 僵尸实例
    FPSPlayer m_player;             // 玩家实例
    NavMeshAgent m_agent;           // 寻路器
    private float m_moveSpeed = 0.5f;   // 僵尸移动基速度

    Animator m_ani;     // 动画控制器
    float m_rotSpeed;   // 转身
    float m_timer = 0;  // 计时器。更新寻路的时间
    int m_life = 15;    // 生命值

	void Start () {
        m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<FPSPlayer>();    // 玩家实例
        m_transform = this.transform;                                                       // 初始化僵尸
        m_agent = this.GetComponent<NavMeshAgent>();                                        // 本僵尸的寻路器
        m_agent.SetDestination(m_player.m_transform.position);                              // 寻路目标(玩家的实例的位置)

        m_ani = this.GetComponent<Animator>();      // 动画控制器
	}

	void Update () {
        // 如果主角生命为0,什么也不做
        if (m_player.m_life <= 0) return;

        // 获取当前动画状态。AnimatorStateInfo:保存全部动作-动画类型(走、攻、立、死)
        AnimatorStateInfo stateInfo = m_ani.GetCurrentAnimatorStateInfo(0);

        // 如果处于静止状态。当前动画==动画控制器内定义的动作,且 不是过渡状态
        if (stateInfo.nameHash == Animator.StringToHash("Base Layer.idle") && !m_ani.IsInTransition(0)) {
            m_ani.SetBool("idle", false);

            // 静止一定时间
            m_timer -= Time.deltaTime;

            if (m_timer > 0) return;

            // 如果距离主角小于3米,进入攻击动画状态
            if (Vector3.Distance(m_transform.position, m_player. m_transform.position) < 3.0f) {
                m_ani.SetBool("attack", true);
            }
            else {
                // 重置定时器
                m_timer=0;

                // 设置寻路目标点
                m_agent.SetDestination(m_player. m_transform.position);

                // 进入跑步动画状态
                m_ani.SetBool("run", true);
            }
        }

        // 如果处于跑步状态
        if (stateInfo.nameHash == Animator.StringToHash("Base Layer.run") && !m_ani.IsInTransition(0)) {

            m_ani.SetBool("run", false);

            // 每隔1秒重新定位主角的位置
            m_timer -= Time.deltaTime;
            if (m_timer < 0) {
                m_agent.SetDestination(m_player. m_transform.position);

                m_timer = 1;
            }

            float speed = m_moveSpeed * Time.deltaTime;
            //m_transform.TransformDirection:从自身坐标到世界坐标变换方向。把一个具体的点坐标的三位向量转变成一个方向向量
            m_agent.Move(m_transform.TransformDirection(new Vector3(0, 0, speed))); // 寻路位置更新

            // 如果距离主角小于3米,向主角攻击
            if (Vector3.Distance(m_transform.position, m_player.m_transform.position) <= 3.0f) {
                //停止寻路	
                m_agent.ResetPath();
                // 进入攻击状态
                m_ani.SetBool("attack", true);
            }
        }

        // 如果处于攻击状态
        if (stateInfo.nameHash == Animator.StringToHash("Base Layer.attack") && !m_ani.IsInTransition(0)) {

            /** 面向主角 **/
            Vector3 oldangle = m_transform.eulerAngles; // 当前角度

            m_transform.LookAt(m_player.m_transform);   // 转身看着玩家
            float target = m_transform.eulerAngles.y;   // 保存当前朝向

            float speed = m_rotSpeed * Time.deltaTime;                          // 定义一个速度
            // MoveTowardsAngle:基于旋转速度,计算当前角度转向目标角度的旋转角度
            float angle = Mathf.MoveTowardsAngle(oldangle.y, target, speed);    // 要完成的动作角度
            m_transform.eulerAngles = new Vector3(0, angle, 0);                 // 转向目标角度

            /** 开启攻击模式 **/

            m_ani.SetBool("attack", false);

            // 如果攻击动画播完,重新进入待机状态
            if (stateInfo.normalizedTime >= 1.0f) {
                m_ani.SetBool("idle", true);

                // 重置计时器
                m_timer = 1;

            }
        }
	}
}

 

四。UI信息

1.图标

1)选择图片文件

bubuko.com,布布扣

2)创建纹理

CameObject,Create Other,GUI Texture,
bubuko.com,布布扣

3)设置纹理贴图

GUI对象的世界坐标原点在屏幕左下方;向右为x轴正方向,向上为y轴正方向;起点为0,最右边和最上边为1,
bubuko.com,布布扣

4)选择字体文件

bubuko.com,布布扣

5)创建文本控件

GameObject,Create Other,GUI Text,
bubuko.com,布布扣

6)设置文本控件

bubuko.com,布布扣

7)创建其它显示控件

bubuko.com,布布扣

2.控制脚本

1)创建UI管理器

首先,创建空游戏体。GameObject,Create Empty,更名为:Level3UI_Manager,
其次,将UI控件设为其子游戏体。注意修改合适的名称,
    bubuko.com,布布扣

2)管理器代码

using UnityEngine;
using System.Collections;

public class Level3UI_Manager : MonoBehaviour {
    //单例
    public static Level3UI_Manager Instance = null;

    public int        m_score = 0;      // 游戏得分
    public static int m_maxscore = 0;    // 游戏最高得分
    public int        m_ball = 100;     // 弹药数量
    FPSPlayer         m_player;         // 游戏主角

    // UI文字。对应Hierarchy中Level3UI_Manager空游戏体的子元素的名字
    GUIText text_Ball;      // 弹药
    GUIText text_Life;      // 生命值
    GUIText text_Score;     // 得分
    GUIText text_MaxScore;  // 最高分

    void Start() {

        Instance = this;

        // 获得玩家
        m_player = GameObject.FindGameObjectWithTag("Player").GetComponent<FPSPlayer>();

        // 获得UI控件
        text_Ball = this.transform.FindChild("text_Ball").GetComponent<GUIText>();
        text_Life = this.transform.FindChild("text_Life").GetComponent<GUIText>();
        text_Score = this.transform.FindChild("text_Score").GetComponent<GUIText>();
        text_MaxScore = this.transform.FindChild("text_MaxScore").GetComponent<GUIText>();

        text_Life.text = " 生命:" + m_player.m_life.ToString();
        text_Ball.text = "子弹:" + m_ball.ToString() + "/100";
        text_Score.text = " 得  分:" + m_score;
        text_MaxScore.text = " 最高分:" + m_maxscore;
    }

    // 更新分数
    public void SetScore(int score) {
        m_score += score;

        if (m_score > m_maxscore)
            m_maxscore = m_score;

        text_Score.text = "得分:" + m_score;
        text_MaxScore.text = "最高分:" + m_maxscore;
    }

    /**  更新弹药   **/
    public void SetBall(int ball) {
        m_ball -= ball;

        // 如果弹药为负数,重新填弹
        if (m_ball <= 0)
            m_ball = 100 - m_ball;

        text_Ball.text = "子弹:" + m_ball.ToString() + "/100";
    }
    // 更新生命
    public void SetLife(int life) {
        text_Life.text = "生命:" + life.ToString();
    }

    void OnGUI() {
        if (m_player.m_life <= 0) { // 居中显示文字
            GUI.skin.label.alignment = TextAnchor.MiddleCenter;
            GUI.skin.label.fontSize = 40;
            GUI.Label(new Rect(0, 0, Screen.width, Screen.height), "玩家已挂");

            // 重新游戏按钮
            GUI.skin.label.fontSize = 30;
            if (GUI.Button(new Rect(Screen.width * 0.5f - 150, Screen.height * 0.75f, 300, 40), "再来一次")) {
                Application.LoadLevel(Application.loadedLevelName);
            }
        }
    }
}

 

3)关联脚本

从Assets中拖放脚本文件到Hierarchy中的控制器游戏体上。
 

五。射击

1.修改玩家控制脚本

using UnityEngine;
using System.Collections;

[AddComponentMenu("Game/FPSPlayer")]
public class FPSPlayer : MonoBehaviour {

    private CharacterController m_ch;   // 玩家角色控制器
    public Transform m_transform;       // 玩家实例
    private float m_movSpeed = 3.0f;    // 玩家移动基速
    public int m_life = 5;              // 生命值
    private float m_gravity = 2.0f;     // 重力
    private Transform m_camTransform;   // 摄像机
    private Vector3 m_camRot;           // 摄像机姿势-旋转角度
    private float m_camHeight = 4.5f;   // 摄像机高度-玩家的眼睛

    private Transform m_muzzlepoint;    // 枪口
    public LayerMask m_layer;           // 碰撞层
    public Transform m_fx;              // 射中目标时的特效
    public AudioClip m_audio;           // 打枪声音
    private float m_shootTimer = 0;     // 射击间隔

    void Start() {
        m_transform = this.transform;                       // 本角色实例
        m_ch = this.GetComponent<CharacterController>();    // 本角色的控制器
        m_camTransform = Camera.main.transform;// 获取摄像机
        Vector3 pos = m_transform.position; // 玩家位置
        pos.y += m_camHeight;               // 镜头高度
        m_camTransform.position = pos;                  // 初始化初始摄像机位置
        m_camTransform.rotation = m_transform.rotation; // 初始化摄像机姿势
        m_camRot = m_camTransform.eulerAngles;      // 存储摄像机姿势

        // 枪口。这个是在3D软件中制作模型时创建的

bubuko.com,布布扣

        m_muzzlepoint = m_camTransform.FindChild("M16/weapon/muzzlepoint").transform; 

        Screen.lockCursor = true;       // 锁定鼠标
    }

    void Update() {
        if (m_life <= 0) return;                // 如果生命为0,什么也不做
        float rv = Input.GetAxis("Mouse Y");    // 鼠标 Y 轴移动距离,抬头角度
        float rh = Input.GetAxis("Mouse X");    // 鼠标 X 轴移动距离,转身角度
        m_camRot.x -= rv;                       // X轴 摄像机仰角-抬头
        m_camRot.y += rh;                       // Y轴 摄像机旋转
        m_camTransform.eulerAngles = m_camRot;  // 摄像机姿势修正
        Vector3 camrot = m_camTransform.eulerAngles;    // 提取摄像机姿势
        camrot.x = 0; camrot.z = 0;                     // 防止后退
        m_transform.eulerAngles = camrot;               // 玩家姿势修正
        float xm = 0, ym = 0, zm = 0;
        ym -= m_gravity * Time.deltaTime * 10;
        if (Input.GetKey(KeyCode.W))
            zm += m_movSpeed * Time.deltaTime * 3;
        else if (Input.GetKey(KeyCode.S))
            zm -= m_movSpeed * Time.deltaTime * 3;
        if (Input.GetKey(KeyCode.A))
            xm -= m_movSpeed * Time.deltaTime * 3;
        else if (Input.GetKey(KeyCode.D))
            xm += m_movSpeed * Time.deltaTime * 3;
        m_ch.Move(m_transform.TransformDirection(new Vector3(xm, ym, zm)));
        Vector3 pos = m_transform.position;
        pos.y += m_camHeight;
        m_camTransform.position = pos;

        m_shootTimer -= Time.deltaTime; // 射击时间间隔

        // 左键射击
        if (Input.GetMouseButton(0) && m_shootTimer <= 0) {

            m_shootTimer = 0.1f;
            this.audio.PlayOneShot(m_audio);    // 播放射击音效

            Level3UI_Manager.Instance.SetBall(1);   // 更新弹药

            RaycastHit info;    // 保存射线探测结果

            // 从m_muzzlepoint的位置,向摄像机面对的正方向射击一条射线
            // 射线只能与m_layer指定的层发生碰撞
            bool hit = Physics.Raycast(
                m_muzzlepoint.position,                                       // 发射点
                m_camTransform.TransformDirection(Vector3.forward),     // 方向
                out info,                                                        // 发生碰撞时保存光线投射信息
                100,                                                              // 射线长度
                m_layer);                                                        // 碰撞目标层

            if (hit) {
                // 如果碰撞-射击-到了标签为“Zombie”的游戏体
                if (info.transform.tag.CompareTo("Zombie") == 0) {
                    // 获取游戏体实例
                    Zombie zombie = info.transform.GetComponent<Zombie>();
                    // 更新被射中游戏角色的生命
                    zombie.OnDamage(1); // 此方法尚未添加
                }

                // 播放一个射击效果
                Instantiate(m_fx, info.point, info.transform.rotation);
            }
        }

    }

    void OnDrawGizmos() {
        Gizmos.DrawIcon(transform.position, "pfsPlayer.png", true);
    }

    // 修改玩家生命值
    public void OnDamage(int damage) {
        m_life -= damage;
        // 调用管理器实例的方法
        Level3UI_Manager.Instance.SetLife(m_life);
        // 如果没命了,释放鼠标
        if (m_life <= 0) Screen.lockCursor = false;
    }
}

 

2.添加碰撞层-身份

1)添加层(身份)

Edit,Project Settings,Tags and Layers,
bubuko.com,布布扣 

同时添加一个标签,
bubuko.com,布布扣

2)设置身份

空间游戏体:
bubuko.com,布布扣 

僵尸:
bubuko.com,布布扣

玩家(两个身份):
bubuko.com,布布扣

3.为玩家添加音源

首先,选择玩家游戏体,
然后,Component,Audio,Audio Source,

4.设置玩家的射击特效和声音

bubuko.com,布布扣

5.射击特效控制

1)添加脚本

选择Assets中的FX.prefab特效文件,打开Inspector属性面板,点击下方的“Add Component”,
bubuko.com,布布扣

2)控制代码

创建脚本后,关联,

using UnityEngine;
using System.Collections;

[AddComponentMenu("MyGame/AutoDestroy")]
public class AutoDestroy : MonoBehaviour {

    public float m_timer = 1.0f;

	void Update () {

        m_timer -= Time.deltaTime;
        if (m_timer <= 0)
            Destroy(this.gameObject);
	
	}
}

 

6.升级僵尸

1)添加碰撞体

首先,在Hierarchy中选择僵尸游戏体,
然后,Component,Physics,Capsule Collider-胶囊碰撞体,
bubuko.com,布布扣

2)升级僵尸控制脚本

添加OnDamage功能,在 五.1 升级的玩家代码中我们已经引用到了。

using UnityEngine;
using System.Collections;
public class Zombie : MonoBehaviour {
    public Transform m_transform;   // 僵尸实例
    FPSPlayer m_player;               // 玩家实例
    NavMeshAgent m_agent;             // 寻路器
    private float m_moveSpeed = 0.5f;   // 僵尸移动基速度
    Animator m_ani;     // 动画控制器
    float m_rotSpeed;   // 转身
    float m_timer = 0;  // 计时器。更新寻路的时间
    int m_life = 15;     // 生命值
	void Start () { 略 }
	void Update () {
        if (m_player.m_life <= 0) return;
        AnimatorStateInfo stateInfo = m_ani.GetCurrentAnimatorStateInfo(0);
        if (stateInfo.nameHash==Animator.StringToHash("Base Layer.idle") && !m_ani.IsInTransition(0)){
  略
         }
        if (stateInfo.nameHash == Animator.StringToHash("Base Layer.run") && !m_ani.IsInTransition(0)) {
			略
  }

        // 如果处于攻击状态
        if(stateInfo.nameHash==Animator.StringToHash("Base Layer.attack") && !m_ani.IsInTransition(0)){
            Vector3 oldangle = m_transform.eulerAngles; // 当前角度
            m_transform.LookAt(m_player.m_transform);   // 转身看着玩家
            float target = m_transform.eulerAngles.y;   // 保存当前朝向
            float speed = m_rotSpeed * Time.deltaTime;                          // 定义一个速度
            float angle = Mathf.MoveTowardsAngle(oldangle.y, target, speed);    // 要完成的动作角度
            m_transform.eulerAngles = new Vector3(0, angle, 0);                 // 转向目标角度
            m_ani.SetBool("attack", false);
            if (stateInfo.normalizedTime >= 1.0f) {
                m_ani.SetBool("idle", true);
                m_timer = 1;

                // 更新玩家的生命值
                m_player.OnDamage(1); 
            }
        }

        // 如果死亡动画播放
        if(stateInfo.nameHash==Animator.StringToHash("Base Layer.death") && !m_ani.IsInTransition(0)){
            if (stateInfo.normalizedTime >= 1.0f) {
                Level3UI_Manager.Instance.SetScore(10); // 给玩家加分
                Destroy(this.gameObject);
            }  
  } 
	}

    /** 修改生命值。已经在 五.1 中引用到 **/
    public void OnDamage(int damage) {
        m_life -= damage;

        if (m_life <= 0)
            m_ani.SetBool("death", true);   // 更新动画
    } 
}

 

六。僵尸生产设备

1.存储全功能僵尸

bubuko.com,布布扣

2.创建生产设备

GameObject,Create Empty,命名为“ZombieSpawn”,

3.控制代码

using UnityEngine;
using System.Collections;

[AddComponentMenu("MyGame/ZombieSpawn")]
public class ZombieSpawn : MonoBehaviour {
     
    public Transform m_enemy;     // 敌人的Prefab
    public int m_enemyCount = 0; // 生成的敌人数量
    public int m_maxEnemy = 3;    // 敌人的最大生成数量
    public float m_timer = 0;     // 生成敌人的时间间隔

    protected Transform m_transform;

	void Start () {
        m_transform = this.transform;
	}
	
	void Update () {
        // 如果生成敌人的数量达到最大值,停止生成敌人
        if (m_enemyCount >= m_maxEnemy)
            return;

        // 每间隔一定时间
        m_timer -= Time.deltaTime;
        if (m_timer <= 0) {
            m_timer = Random.value * 15.0f;
            if (m_timer < 5)
                m_timer = 5;

            // 生成敌人
            Transform obj=(Transform)Instantiate(m_enemy, m_transform.position, Quaternion.identity);

            // 获取敌人的角本
            Zombie enemy = obj.GetComponent<Zombie>();

            // 初始化敌人
            enemy.Init(this);   // 此功能尚未添加
        }
	}

  // Scene中可见图标
    void  OnDrawGizmos () {
        Gizmos.DrawIcon (transform.position, "spawn.png", true);
    }
}

 

4.关联并设置属性

bubuko.com,布布扣

5.僵尸升级

using UnityEngine;
using System.Collections;
public class Zombie : MonoBehaviour {
    public Transform m_transform;
    FPSPlayer m_player;
    NavMeshAgent m_agent;
    private float m_moveSpeed = 0.5f;
    Animator m_ani;
    float m_rotSpeed;
    float m_timer = 0;
    int m_life = 15;

    protected ZombieSpawn m_spawn;  // 生产设备

    /** 初始化僵尸的生产设备。实现 六.2 中引用的功能 **/
    public void Init(ZombieSpawn spawn) {
        m_spawn = spawn;
        m_spawn.m_enemyCount++; // 生产计数
  } 
  
	void Start () { 略 }
	void Update () {
        if (m_player.m_life <= 0) return;
        AnimatorStateInfo stateInfo = m_ani.GetCurrentAnimatorStateInfo(0);
        if(stateInfo.nameHash==Animator.StringToHash("Base Layer.idle")&& !m_ani.IsInTransition(0)){ 
  略 }
        if(stateInfo.nameHash==Animator.StringToHash("Base Layer.run")&& !m_ani.IsInTransition(0)){
  略 }
        if(stateInfo.nameHash==Animator.StringToHash("Base Layer.attack")&& !m_ani.IsInTransition(0)){
  略 }

        // 如果死亡动画播放
        if(stateInfo.nameHash==Animator.StringToHash("Base Layer.death")&& !m_ani.IsInTransition(0)){ 
            // 播放完成
            if (stateInfo.normalizedTime >= 1.0f) {
                m_spawn.m_enemyCount--; 

                Level3UI_Manager.Instance.SetScore(10); // 加分
                Destroy(this.gameObject);               // 销毁僵尸实例
            }
        }
	}
    public void OnDamage(int damage) { 略 }
}

 

七。地图

1.创建监控摄像机

1)创建摄像机

GameObject,Create Other,Camera,命名为“Scout Camera”,
bubuko.com,布布扣

2)调整视角和显示位置

bubuko.com,布布扣

2.创建游戏体替身

1)创建不同替身的材质

创建两种替身使用的材质,(Project,Create,Material)
bubuko.com,布布扣

2)创建2个球体-替身

GameObject,Create Other,Sphere,

 

3)为两种球体分别指定材质,

bubuko.com,布布扣 

4)创建Layer-替身身份

首先,创建“Avatar”替身身份,
bubuko.com,布布扣

然后,为替身指定身份,
bubuko.com,布布扣

5)将替身转为Prefab资源

bubuko.com,布布扣

3.设置替身为子元素

1)将全功能僵尸及替身放入Hierarchy

bubuko.com,布布扣

2)将两个替身设为正身的子元素

bubuko.com,布布扣

3)将设置好的资源用以替换

bubuko.com,布布扣

4)检查

bubuko.com,布布扣

4.调整摄像机

1)主相机

在Camera项目下,打开Culling Mask条目,去除“Avatar”身份,
bubuko.com,布布扣

2)监控相机

在Camera项目下,打开Culling Mask条目,只保留“Avatar”玩家身份,
bubuko.com,布布扣


- end

关卡关联

1.添加关卡到项目

File,Build Settings...,
bubuko.com,布布扣

2.修改关卡Level01的管理器

修改打开GameManager.cs文件

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() { 略 }
	void Start () { 略 }
	void Update () { 略 }

    /** 专用绘制UI界面 **/
    void OnGUI() {
        if (Time.timeScale == 0) { 略 }
        int life = 0;
        if (m_player != null) { 略 }
        else {  略 }
        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);

        /**       进入下一关      **/
        if (m_score >= 200) { // 居中显示文字
            GUI.skin.label.alignment = TextAnchor.MiddleCenter;
            GUI.skin.label.fontSize = 40;
            GUI.Label(new Rect(0, 0, Screen.width, Screen.height), "下一关,打僵尸");
            // 重新游戏按钮
            GUI.skin.label.fontSize = 30;
            if(GUI.Button(new Rect(Screen.width*0.5f-150, Screen.height*0.75f, 300, 40), "开始")) {
                // Application.LoadLevel(Application.loadedLevelName);  // 当前关卡
                Application.LoadLevel("Level02");   // 指定关卡
            }
        }
    }
    public void AddScore( int point ) { 略 }
}

 

效果图:

bubuko.com,布布扣

bubuko.com,布布扣

资源:
     本篇博文《Unity3D上路》: http://pan.baidu.com/s/1tQrmA 

Unity3D-第一视角射击游戏

标签:des   http   io   ar   os   使用   sp   for   strong   

原文地址:http://www.cnblogs.com/liuruitao/p/4149577.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!