本篇实现一个球体在固定区域移动撞击Cube的游戏。

首先有1个Plane当作地面,1个Sphere当作球体,4个Cube当作墙,12个Cube当作被撞击物体,另外还有球体的撞击计算,在撞击的过程适时显示撞击的球体数,12个Cube被撞击后提示游戏结束。

创建项目,创建背景和球

创建一个项目,名称为"MyRollBall",选择项目所在文件,选择"3D"项,点击"Create project"。

点击"File"菜单下的"Save Scene",在"MyRollBall"项目下的"Asserts"中创建一个自定义文件夹,名称是"_MyScene",然后把保存的Scene命名为"MiniGame",并保存到"_MyScene"文件夹中。创建完后,在"Project"窗口下的文件结构如下:

依次点击"GameObject"菜单下的"3D object","Plane",并在"Hierarchy"窗口中重命名为"Ground"。

点击"Hierarchy"窗口中的"Ground",在"Scene"窗口中,Ground自动调整到"Scene"窗口的中心;在"Inspector"窗口的"Transform"中有一个"Reset"按钮,点击它,会把这里的Ground恢复到初始状态;点击"Edit"菜单下的"Frame Selected"会看到"Scene"窗口的整个画面。

此时,"Scene"窗口的背景呈网格状,这里需要隐藏网格。点击"Scene"窗口"Gizmos"下拉项,把"Show Grid"的勾选去掉。

改变Ground的缩放比例,可以通过如下3种方式的一种来做:

1、点击"Hirarchy"窗口中的Ground,按快捷键R,通过拖动"Scene"窗口中Ground的x,z轴来实现。
2、点击"Hirarchy"窗口中的Ground,无需按哪个视图快捷键,把鼠标移上"Inspector"窗口中,"Transform"下的"Scale"中的"X"字母或"Z"字母上,通过鼠标的左右滑动来改变缩放。
3、直接修改"Inspector"窗口中,"Transform"下的"Scale"中"X"和"Z"的属性值。

注意:这里的Ground,即类型为"plane"的GameObject,沿y轴方向正向调整不会影响Ground的可见性,一旦拖动Y轴,让Y轴对应的值为负值,Ground随即不可见。这里给我们的启示是:如果一个GameObject不可见,我们可以调整该GameObject的Y值,来使其可见。

现在再增加一个球体。在"GameObject"菜单栏的"3D Object"中选择"Sphere",在"Hierarchy"窗口为Sphere重命名为"Player"。

在保证"Hierarchy"窗口为Sphere为选中状态下,点击"Edit"菜单下的"Frame Selected",Sphere在Scene窗口中出现在焦点位置,并呈选中状态。

但是,我们发现球体的位置不太对,所以要调整球体的位置。拖动"Scene"窗口中Sphere的y轴,使其往上移动,让整个球体在水平面之上。当然调整"Inspector"中的相关属性也是可以的。

在"Project"下的"Asserts"中添加名称为"Materials"的Folder。

选中"Mateirals"这个Folder,右键,依次选择"Create","Material",这样在"Mateirals"这个Folder中添加了一个名称为"New Mateiral"的Material,并重命名为"Background"。

修改名称为"Background"的"Inspector"窗口中的"Albedo"项,修改RGB属性值为"0,32,64",可以在"Inspector"窗口的最下方预览到效果。接着拖动这里的"Background"到"Scene"窗口的"Ground"上面,"Ground"因此有了Material。

点击"Hierarchy"窗口下的"Directional Light",修改"Inspector"窗口中"Rotation"的"Y"为60。

移动球

在"Hierarchy"窗口中选择名称为"Player"的GameObject。

为了能够让名称为"Player"的GameObject运动,需要为其添加"RigidBody"。

依次选择"Component"菜单、"Physics"、"RigidBody",之后,在"Inspector"窗口多了一个"Rigidbody"组件。当然,为GameObject添加组件Compnenet的方式不止这一种,可以点击"Inspector"窗口的"Add Component"按钮。还可以在"Inspector"窗口中调整各个组件的顺序。还可以折叠或展开各个组件面板。

选中"Project"下的"Asserts",添加一个"Scripts"文件夹。

再次选中"Hierarch"中的"Player",在其对应的"Inspector"窗口中点击"Add Component"按钮,点击"New Script",命名为"PlayerController"。按这种方式添加的脚本自动附加到GameObject上了。而在"Asserts"下也多了一个名称为"PlayerController"的脚本,为了把文件夹组织得更好,把该脚本拖入刚创建的"Scripts"文件夹。

双击脚本,在Visutal Studio中打开,编辑如下:

using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
    public float speed;
    private Rigidbody rb;
    void Start ()
    {
        rb = GetComponent<Rigidbody>();
    }
    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.AddForce(movement * speed);
    }

    // Update is called once per frame
    void Update () {

    }
}

可以在官网查看到所有的API:http://docs.unity3d.com/ScriptReference

再次点击"Hirarchy"下的"Player",在其对应的"Inspector"窗口下的"Player Controller"这个脚本中,调整Speed的属性值,设置为100。

运行。

按动键盘方向键,球以某种速度移动起来。

移动Camera

现在想把Camera附加到球体上。

首先设置Camera的位置。

在MainCamera对应的"Inspector"窗口中,在"Transform"下,调整"Position"的x,y,z分别为"0,10,-10",调整"Rotation"的x,y,z分别为"45,0,0",再在"Hierarchy"窗口中把"Main Camera"拖动到"Player"上,使其成为"Player"的一个子GameObject。这意味着当球体移动的时候,Camera也会跟着移动。

再次运行,这次看到球体移动非常快,这是因为Camera的位置相对于球体变化了。

在"Hierarch"窗口中,把"Main Camera"移动出"Player",不要让其成为球体的子GameObject。

为"Main Camera"添加一个名称为"CameraController"的脚本,编辑如下:

using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
    //说明这个Camera指向于某一个Gameobject,在这里是球体
    public GameObject player;
    //Camera的偏移量
    private Vector3 offset;
    void Start()
    {
        //Camera的位置-球体的位置
        offset = transform.position - player.transform.position;
    }
    void LateUpdate()
    {
        //让Camera根据球体的位置获得一个新位置
        transform.position = player.transform.position + offset;
    }
}

好,现在要把球体赋值给Camera。先打开"Main Camera"对应的"Inspector"窗口,然后拖动"Hierarchy"窗口下的名称为"Player"的球体到"Inspector"中"Camera Controller"中"Player"这个属性框上。

运行,这时,球在运动的时候有了一个很好的Camera角度。

设置球体运动区域

为了放置球体在移动过程中掉落,我们需要设置球体的运行区域。

创建一个空的"Game Object",并重命名为"Walls",并把之设置为默认值。

创建一个"Cube"类型的"Game Object",并重命名为"West Wall",并把之设置为默认值,拖动使其成为空"Game Object"的子项。

现在,"Scene"窗口中呈现出如下的位置关系。

这时需要调整Cube的位置,依次创建4个Cube,从4个方向挡住球体。

再次运行,球体被牢牢困在4个cube中间。

创建被球体撞击的物体

创建一个Cube类型的GameObject,重命名为"Pickup",设置其默认值,点击"Edit"菜单中的"Frame Selected"使其成为"Scene"窗口的焦点。

按如下设置"Pickup"的"Transform"。

现在想为其增加旋转效果。为其专门创建一个名称为"Rotator的脚本"。

using UnityEngine;
using System.Collections;
public class Rotator : MonoBehaviour {
    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {
        transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
    }
}

运行,"Pickup"会不停地旋转。

在"Project"窗口中,在"Asserts"下创建"Prefabs"文件夹。

把"Hierarchy"中的"Pickup"拖动到"Prefabs"文件夹中。

创建一个空的GameObject,重命名为"Pickups",设置默认值。

把"Asserts"中"Prefabs"中的"Pickup"拖动到"Pickups"中,作为子GameObject。

选中"Hierarchy"窗口中的"Pickup",选择左上角的"Local"模式,拖动"Pickup"到一个合适的位置。

复制"Pickup"12个,围成一个圈。

在"Project"窗口中的"Material"文件夹中再复制一个,重命名为"Pickup",改变其颜色为黄色。

把其拖动到"Scene"窗口中的各个"Pickup",这时,所有的"Pickup"呈现为黄色。

撞击物体

修改脚本"PlayerController"。

using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
    public float speed;
    private Rigidbody rb;
    void Start ()
    {
        rb = GetComponent<Rigidbody>();
    }
    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.AddForce(movement * speed);
    }
    //Collider表示被球体碰撞的其它物体
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Pick Up"))
        {
            other.gameObject.SetActive(false);
        }
    }

    // Update is called once per frame
    void Update () {

    }
}

回到Unity界面,选择"Project"界面上"Prefabs"文件夹内的"Pickup",在"Inspector"窗口加添加"Pick Up"标签。

运行,控制键盘方向键,当物体碰撞到Cube上的时候,Cube没有消失。这不是我们所期望的。

回到Unity界面,选择"Project"界面上"Prefabs"文件夹内的"Pickup",在"Inspector"窗口,在"Box Collider"中,勾选"Is Trigger"。

运行,控制键盘方向键,当物体碰撞到Cube上的时候,Cube消失。这正是我们所期望的。

所有的带Rigid Body的Game Object被Unity理解为dynamic,不带Rigid Body的Game Object被Unity理解成为static。如果没有把Game Object附加Rigid Body的话,Unity在每一帧都会统计这些static Game Object,这非常消耗资源。所以,我们应当为Game Object附加Rigid Body,让其变成dynamic。static是不可以移动的,而dynamic是可以移动的。

回到Unity界面,选择"Project"界面上"Prefabs"文件夹内的"Pickup",在"Inspector"窗口,点击"Add Component"按钮,为其添加Rigid Body组件。

再次运行,发现所有的Cube消失了,为什么?

回到Unity界面,选择"Project"界面上"Prefabs"文件夹内的"Pickup",在"Inspector"窗口,把"Rigid Body"中"Use Gravity"的勾选去掉。

再次运行,正常运行。

显示分数

在"Hierarch"窗口中添加Text,Text作为Canvas的子Game object出现,并重命名为"Counter Text"。选择Text,改变其字体颜色为白色,同时按住"alt"+"shift"键,改变Text的位置。

在"Hierarch"窗口中添加Text,Text作为Canvas的子Game object出现,并重命名为"Win Text"。选择Text,改变其字体颜色为白色。

修改"PlayerController"脚本。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
    public float speed;
    public Text countText;
    public Text winText;
    private Rigidbody rb;
    private int count;
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        count = 0;
        SetCountText();
        winText.text = "";
    }
    void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.AddForce(movement * speed);
    }
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Pick Up"))
        {
            other.gameObject.SetActive(false);
            count = count + 1;
            SetCountText();
        }
    }
    void SetCountText()
    {
        countText.text = "击中了: " + count.ToString() + "个";
        if (count >= 12)
        {
            winText.text = "成功!";
        }
    }
}

把"Hierarchy"窗口中,"Canvas"下的Text拖拽到"Player"球体对应的"Inspector"窗口内的"Counter Text"和"Win Text"属性值框上。

Build游戏

选择"File"菜单下的"Build Settings"。

点击"Add Current"按钮,把当前的"Scene"添加进来。

点击"Build"按钮。保存.exe文件保存到某个位置。

运行可执行文件,即看到与Unity软件中一样的效果。

参考资料:https://unity3d.com/learn/tutorials/projects/roll-a-ball/moving-the-camera

Unity3D实践系列06,球体撞击物体游戏相关推荐

  1. Unity3D实践系列03,使用Visual Studio编写脚本与调试

    在Unity3D中,只有把脚本赋予Scene中的GameObject,脚本才会得以执行. 添加Camera类型的GameObject. Unity3D默认使用"MonoDevelop&quo ...

  2. ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API

    本篇尝试在现有的ASP.NET MVC 4 项目上增加使用ASP.NET Web API. 新建项目,选择"ASP.NET MVC 4 Web应用程序". 选择"基本&q ...

  3. Unity3D中角色撞击物体弹出提示框或显示对象效果

    角色撞击物体弹出提示框或显示对象效果 刚开始使用的是调用SetActive方法 例: 在Start()函数中设置对象的SetActive属性为false,在函数 void start() {gameo ...

  4. Unity3D Shader系列之描边

    目录 1 引言 2 顶点沿法线外拓方式 2.1 法线外拓+ZTest Always 2.1.1 代码 2.1.2 问题点 2.2 法线外拓+Cull Front 2.2.1 代码 2.2.2 改进点 ...

  5. 【Unity3D 教程系列第 10 篇】Unity 脚本中的生命周期流程图

    这是[Unity3D 教程系列第 10 篇],如果觉得有用的话,欢迎关注专栏. 文章目录 一:生命周期流程图 二:常用的生命周期函数 三:脚本初始化和销毁 四:脚本的动态添加与静态添加 五:Awake ...

  6. Unity3D Shader系列之全息投影

    1 效果展示 2 实现原理 全息投影其实是几个效果的叠加:①半透明效果②上下条纹的扫描效果③边缘光效果④模拟信号传输不稳定的顶点偏移效果. 咱们依次来看看这几个效果背后的原理. ①半透明效果 在Uni ...

  7. 【Unity3D 教程系列第 19 篇】Unity 中根据长方体模型的尺寸添加碰撞盒 BoxCollider

    这是[Unity3D 教程系列第 19 篇],如果觉得有用的话,欢迎关注专栏. 前言: 给一个长方体模型添加碰撞盒 BoxCollider,即使手动拖拽也费不了多长时间,但手动拖动不仅显得 Low , ...

  8. 架构技术实践系列文章

    王晓宇:电商异步消息系统的实践 秦鹏:从应用到平台,云服务架构的演进过程 郭炜:从0到N建立高性价比的大数据平台 李智慧:宅米网技术变迁--初创互联网公司的技术发展之路 陶文质:分布式系统设计的求生之 ...

  9. unity3D期末大作业,坦克射击游戏

    unity3D期末大作业,坦克射击游戏 坦克射击游戏,可以发射子弹打击物体,坦克可以撞碎墙壁,树木,有背景音效详情如下动态图:(下载链接在文章末) 制作过程: 首先,从Asset Store中下载并i ...

最新文章

  1. 移位寄存器专题(verilog HDL设计)
  2. Trinity 1.1 发布,Linux 桌面环境
  3. 为什么被雷击中的大多是男性???
  4. python回复邮件_在Python中通过Outlook回复电子邮件
  5. RestQL:现代化的 API 开发方式
  6. 文件拖放的一种简洁方法
  7. 右侧按钮登录注册html,翻转式用户登录注册界面设计
  8. Unity List的拷贝
  9. Python爬取猫眼电影排行榜并写入MySQL
  10. CentOS 7 配置DHCP服务器
  11. OC语言之Protocol基本使用
  12. PR开场片头模板 恐怖惊悚电影侦探节目logo展示PR模板
  13. 接收微信支付通知php代码,微信支付开发告警通知实例
  14. 软件测试非功能性需求,什么是非功能测试?非功能测试包括哪些类型?
  15. 内部 CA 证书管理
  16. PHP:编写标准体重计算器
  17. 比较器应用一:滞回比较器
  18. 0.10版本后的kafka配置producer和comsumer的server参数
  19. 银河麒麟V10忘记密码
  20. 教你给大量视频快速调整色调的方法

热门文章

  1. 网络管理系统、网管、network manage system、运维系统
  2. 【STM32F407的DSP教程】第24章 DSP变换运算-傅里叶变换
  3. 建模常用的概念介绍1: WOE、IV
  4. 蚂蚁全媒体中心总编刘鑫炜:如何破解碎片化时代的营销困境
  5. 【纪中受难记】——Day10:逐渐自闭
  6. 【原创】怎样关联多个 Excel 档工作表(Sheet)中的数据
  7. 研究生毕业论文致谢导师,导师批注亮了!网友:哈哈哈哈哈哈
  8. CGB2105-Day16
  9. 数组的length属性和String的length()方法
  10. 软件测试工程师未来发展前景