【Unity3D】利用物体碰撞检测、键盘输入处理完成平衡球游戏

物体碰撞检测是游戏编程里面非常常用的功能,一旦碰到就怎么怎么样,比如掉血等。Unity3D直接就提供了物体碰撞检测的接口,实现起来很方便。借此功能,完成了一个平衡球游戏,同时说明Unity3D的物体碰撞检测、键盘输入处理的检测的使用。游戏如下图所示:

一、场景布置

1、UI方面布置如下所示,基本就是《【Unity3D】对话框、隐藏与显示、拖拽》(点击打开链接)的内容,不赘述了。StartModal和GameoverModal本质是Image,将他们重叠在一起,一会儿将用脚本隐藏GameoverModal。

2、大致上3D的场景布置如下图所示,基本上就《【Unity3D】物体、材质的设置、物体位移与旋转》(点击打开链接)的内容,也没什么难的。注意,此处的Cube的透明材质,不是默认的Diffuse,而是带透明的Transparent/Diffuse。

唯一需要注意的是,组成盒子的4个Cube,由于Plane的实际大小刚好是10x10,那么就应该分别在XOZ平面的(5,0),(-5,0),(0,5),(0,-5)的位置,且在(5,0)和(-5,0)平面的两个Cube,在X方面只延伸0.1,Z方面延伸10,高度Y方面延伸2,而在(0,5),(0,-5)的两个Cube,则刚好反之,在在X方面只延伸10,Z方面延伸0.1,高度Y方面同样延伸2个位置,刚好形成四堵墙。做好之后,将其余3堵墙拖到其中1个下面,构成一个整体,再同盒子底面的Cube共同拖到Plane之下。

3、我们还需要对作为盒子边缘墙体的父Cube赋予Tag,具体如下图操作:

4、同时还要创建一个空物体GameObject赋予脚本。

二、脚本设置

设置脚本也很简单,具体在《【Unity3D】Helloworld》(点击打开链接)提到过了,如下图所示,将设置如下脚本:

1、首先是Plane.cs

using UnityEngine;
using System.Collections;

public class Plane : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (Time.timeScale != 0)//如果游戏没有结束,将允许用户通过wasd或者上下左右操作
        {
            if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
            {
                transform.Rotate(Vector3.right * 1);
            }
            if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
            {
                transform.Rotate(-Vector3.right * 1);
            }
            if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
            {
                transform.Rotate(-Vector3.forward * 1);
            }
            if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
            {
                transform.Rotate(Vector3.forward * 1);
            }
        }
    }

}

此处是指出了Unity3D如何处理键盘输入的,和其余编程语言一样,只要得知键码,通过条件判断就好。

2、ui.cs

using UnityEngine;
using System.Collections;

public class ui : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {
    }

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

    }

    //就是开始游戏之时,游戏说明那个对话框中的确定按钮。
    public void onStart()
    {
        Destroy(GameObject.Find("StartModal"));//点击之后,将这个对话框销毁。
    }

    //就是Gameover的时候,“重新开始”的按钮
    public void onRestart()
    {
        Application.LoadLevel("BalanceBall");
    }
}

将ui.cs赋予给空物体GameObject之后,和《【Unity3D】场景切换、UGUI组件事件、开始游戏与关闭游戏》(点击打开链接)提到的方法一样,设置StartModal中的Button按钮的OnClick事件为onStart(),而GameoverModal中的Button按钮的OnClick事件为onRestart()。

3、Ball.cs

这脚本就是整个游戏的核心,同时展示如何使用Unity3D的物体碰撞检测。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Ball : MonoBehaviour
{
    int score = 0;//游戏分数
    GameObject GameoverModal;//结束游戏对话框

    void Awake()
    {
        Time.timeScale = 1;//打开时间结界
        GameoverModal = GameObject.Find("GameoverModal");//上来先获取结束游戏的对话框
    }

    void Start()
    {
        GameoverModal.SetActive(false);//隐藏结束游戏的对话框
    }

    void Update()
    {
        //此处判断小球是否飞离了箱子,通过坐标判断
        if (GameObject.Find("Sphere").transform.position.x > 6 ||
            GameObject.Find("Sphere").transform.position.z > 6 ||
            GameObject.Find("Sphere").transform.position.x < -6 ||
            GameObject.Find("Sphere").transform.position.z < -6 ||
            GameObject.Find("Sphere").transform.position.y < -6)
        {
            Time.timeScale = 0;//布置一个时间结界,相当于暂停游戏
        }

        if (Time.timeScale != 0)//如果时间结界不存在,那么就意味着游戏在进行中
        {
            score = System.Convert.ToInt32(GameObject.Find("Score").GetComponent<Text>().text);//获取Score那个文本,并转化为int整形
            score += System.Convert.ToInt32(rigidbody.velocity.magnitude);//加上此刚体,也就是这个球的速度
            GameObject.Find("Score").GetComponent<Text>().text = score.ToString();//刷新Score那个文本
        }
        else//如果时间结界存在,就意味着游戏结束了
        {
            GameoverModal.SetActive(true);//显示重新开始游戏的对话框
            GameObject.Find("GameoverText").GetComponent<Text>().text = "你的得分:" + score;//更新对话框中的文本
        }
    }

    // 碰撞开始
    void OnCollisionEnter(Collision collision)//也就是如果一旦球和四面墙,也就是任意一个Cube发生碰撞
    {
        if (collision.collider.tag == "Cube1")//碰撞的是Cube1,而不是Plane
        {
            Time.timeScale = 0;//打开时间结界
        }
    }

    /*碰撞检测还可以这样用*/
    // 碰撞结束
    void OnCollisionExit(Collision collision)
    {
    }
    // 碰撞持续中
    void OnCollisionStay(Collision collision)
    {
    }
}

此脚本注意在初始化的时候要重新打开时间结界,虽然Time.timeScale默认是等于1的,但因为下面一些列的操作会导致Time.timeScale=0,在ui.cs的重新载入场景不会更新这个Time.timeScale,并同时注意获取这个GameModal实例。这是必要的,不是画蛇添足,具体原因在《【Unity3D】SetActive的NullReferenceException与LoadLevel的初始化》(点击打开链接)说过了。

至此,整个游戏做完,编译,发布,则得到一个平衡球的游戏。

这里不设置4个cube围着plane,直接用碰撞结束OnCollsionExit判断游戏是否结束是不行的,因为小球在滚动过程中,是会跳动的,在某几个没有滑出Plane的瞬间,是会因Plane的旋转产生的跳动,而偶尔离开这个Plane的。

时间: 2024-12-25 02:28:52

【Unity3D】利用物体碰撞检测、键盘输入处理完成平衡球游戏的相关文章

java利用Scanner获取键盘输入

在运行一个java程序的时候,可能我们需要在运行的时候传递一些参数进去...咋办呢... java提供了一个Scanner类,利用这个类,我们可以很方便的获取键盘输入的参数... Scanner是一个基于正则表达式的文本扫描器~~可以从文件,输入流,字符串中解析出基本类型和字符串类型的值.Scanner类提供了多个构造器,不同的构造器可以接受文件,输入流,字符串作为数据源,用于从文件,输入流字符串中解析数据.(摘自<疯狂java讲义>李刚) 代码示例: import java.util.Sca

unity3d小小白之代码控制物体通过键盘输入移动

我通过键盘wsad来控制物体运动,代码如下: 这里说明一下我的代码. 这里面的back,forward,right,left 都是以你要控制移动的物体的自身坐标移动的. 我的代码是左右移动是在Z轴上,上下移动是X轴上,按理来讲,按下a,物体应该是Vector.left 而不是Vector.right.这是因为我在放物体的时候将物体绕Y轴旋转了180° ,如果我还按照按下a对应left,那么我按下a会向右走.因此我就调成按下a向右走了. 至于判断条件里的数字,是这样得到的:把你要移动的物体移到Ga

Unity3D 控制物体移动、旋转、缩放

Transform基本移动函数: transform.Translate(Vector3.forward *TranslateSpeed); transform.Translate(xSpeed,0,zSpeed); transform.position = Vector3(xPostion,0,zPostion); 1.输入指定按键: if(Input.GetKey ("up")) print("Up!"); if(Input.GetKey(KeyCode.W);

企业发放奖金根据利润提成,从键盘输入当月利润I,求应发放奖金总数?

题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%:20万到40万之间时,高于20万元的部分,可提成5%:40万到60万之间时高于40万元的部分,可提成3%:60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 程序分析:请利用数轴来分界,定位. 程序源代码: #

[自制简单操作系统] 5、杂七杂八(高分辨率和键盘输入)

前言: >_<" 这几天正在研究一个好玩的,准备写<软硬结合第三篇——科班的还是可以修电脑的>,可是当前遇到个技术难点——WHDI,所以操作系统这里就慢了好大一节啦!但是以操作系统多任务的思路,感觉还是把这个优先级并不是太低的进程拿出来做一下吧!毕竟技术难点有时候需要灵感的哈~(不过有大神知道VGA接口的通信原理吗?求给个好一点的链接看看!).回到正题上来,这次学的东西有点杂,主要就是高分辨率和键盘输入相关~对于前者和汇编及硬件联系较多(具体可以查VBE Video El

virt-manager 解决kvm 不能键盘输入的问题

virt-manager  解决kvm 不能键盘输入的问题

Java键盘输入的几种方式,大爱Scanner

1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStreamReader; 4 import java.util.Scanner; 5 6 public class EnterTest { 7 8 public static void main(String[] args) { //主方法 9 CharTest(); //调用System.in方法 10 ReadTest()

通过VNC连接远程服务器,然后登陆服务器上的虚拟机,出现键盘输入问题的解决方法

前几天由于要在服务器上装一个虚拟机,然后就选择了vmware workstation,装好之后,进入虚拟机中的centOS系统,发现键盘上的Cpas Lock键不起作用,按下之后还是输入小写,而且按住shift + ,不会出现 ‘<' 而是出现 ‘>',这怎么可以,这完全没法在虚拟机中使用呀. 因为我是通过VNC连接到服务器,原先一直认为是vmware软件的问题,然后就换vmware的版本,结果还是不行:后来我就直接试了下直接在服务器上链接一个屏幕,然后使用vmware,发现完全没有这个问题:

10、使用TCP协议完成一个客户端一个服务器。客户端从键盘输入读取一个字符串,发送到服务器。 服务器接收客户端发送的字符串,反转之后发回客户端。客户端接收并打印。

/**10.使用TCP协议完成一个客户端一个服务器.客户端从键盘输入读取一个字符串,发送到服务器. 服务器接收客户端发送的字符串,反转之后发回客户端.客户端接收并打印. * 客户端*/ import java.io.*; import java.net.*; public class Test10_Client { public static void main(String[] args) throws Exception { Socket s = new Socket("192.168.0.