Unity 4 3D开发实战详解
上QQ阅读APP看书,第一时间看更新

3.6 C#脚本综合案例

上一节的案例中所使用的脚本语言是JavaScript脚本,本节将根据上一节的案例,使用C#脚本语言来开发该案例,两个案例只是在球纹理的选择场景和文件名称上做了一些小的改变,同时,对脚本做了一些优化,使用更少的代码实现相同的功能。

3.6.1 立方体旋转场景实现

在本场景中具体的设计目的就是实现立方体的转动,为了在视觉上呈现出不同的效果,进而设计了6个具有不同纹理贴图的立方体,并且都具有一定的自转效果,当选中某个立方体时,立方体反向旋转同时转速加快,变得与众不同,在此默认第一个立方体为选中状态,并将此时选中的立方体的纹理记录下来。运行效果如图3-19、图3-20和图3-21所示。

▲图3-19 最终运行效果图1

▲图3-20 最终运行效果图2

▲图3-21 最终运行效果图3

1.场景搭建的具体过程

(1)在开发前首先要对案例开发需要的资源进行收集,主要需要的资源如表3-14所示。

表3-14 立方体旋转场景实现所需的资源

续表

(2)~(5)的操作步骤和3.5节所对应的(2)~(5)操作步骤类似,具体的可以参考3.5节所对应的步骤来操作,这里由于篇幅的限制就不再赘述了。

(6)单击GameObject→Create Other→Cube菜单,在场景中创建一个球体,在此改名为Cube1,并在属性编辑器中设置具体的参数,然后依次创建其他5个立方体,命名为Cube2~Cube6,摆放位置如图 3-22所示。

▲图3-22 创建的 6个立方体

(7)此后的操作步骤请参考3.5节中所对应的第(4)~(6)步骤来操作,这里不再赘述。

2.立方体旋转的实现以及GUI组件的应用

(1)GUI组件的应用,即创建一个名字为“StartGame.cs”的脚本,将此脚本挂载到摄像机上,即可实现GUI组件的应用,脚本的代码如下。

代码位置:见随书光盘中源代码/第3章目录下的CubeBal /Assets/Script / StartGame.cs。

1 using UnityEngine;

2 using System.Collections;      //引入系统包

3 public class StartGame : MonoBehaviour {

4   public Texture quedingTexture;   //确定按钮纹理图引用

5   public Texture tuichuTexture;    //退出按钮纹理图引用

6   public Texture anlibiaotiTexture;   //案例标题按钮纹理图引用

7   public GUIStyle MyStyle;     //定义自己的GUIStyle

8   public static bool isTouched = false;  //是否有Cube被触摸

9   public static string touchedCube = null; //被触摸Cube的名字

10  void Start(){        //重写Start函数

11    PlayerPrefs.SetString("Tex","Tex1"); //默认保存第一个Cube的纹理图

12  }

13  void Update () {       //重写Update函数

14    foreach (Touch touch in Input.touches)//对当前触控事件循环

15   {        //声明一条由屏幕触控点发出垂直于屏幕的射线

16     Ray ray = Camera.main.ScreenPointToRay(touch.position);

17    RaycastHit hit;//声明一个RaycastHit型变量hit

18     if (Physics.Raycast (ray, out hit)) //判断此物理事件

19    {

20      isTouched = true ; //当射线碰撞到Cube时将isTouched设为true

21      //获得射线碰撞Cube的名称

22     touchedCube = hit.transform.root.transform.name;

23      SetTex(touchedCube);   //调用SetTex函数

24    }}

25 if (Application.platform == RuntimePlatform.Android)//判断运行平台是否为Android平台

26   {

27    if (Input.GetKeyUp(KeyCode.Home) ) //判断当前按键是否为Android设备的Home键

28    {

29     Application.Quit();   //退出项目

30    }

31   if (Input.GetKeyUp(KeyCode.Escape))//判断当前按键是否为Android设备的Escape键

32    {

33     Application.Quit();   //退出项目

34    }}}

35  void OnGUI()       //重写OnGUI函数

36  {

37 float ratioScaleTempH=Screen.height/960.0f;//为了进行屏幕自适应而声明的纵向缩放比变量

38 float ratioScaleTemp=Screen.width/540.0f;//为了进行屏幕自适应而声明的横向缩放比变量

39    //在自定义的屏幕位置绘制案例标题的纹理图片

40    GUI.DrawTexture(new Rect(45*ratioScaleTemp,50*ratioScaleTempH,450*ratioScaleTemp,

41     100*ratioScaleTempH), anlibiaotiTexture, ScaleMode.ScaleToFit,true, 450.0f/100.0f);

42 if(GUI.Button(newRect(70*ratioScaleTemp,800*ratioScaleTempH,150*ratioScaleTemp,

43     80*ratioScaleTempH),quedingTexture,MyStyle)){//在自定义的屏幕位置//绘制一个确定按钮,并判断是否被按下

44    Application.LoadLevel("StartBall"); //若按下,跳转到Start场景

45    Destroy(this);     //并销毁这个按钮

46   }

47    //在自定义的屏幕位置绘制一个退出按钮,并判断是否被按下

48 if (GUI.Button(new Rect(320*ratioScaleTemp,800*ratioScaleTempH,150*ratioScaleTemp,

49     80*ratioScaleTempH),tuichuTexture,MyStyle)){

50    Application.Quit();    //若按下,退出项目

51   }}

52  void SetTex(string cubeName){    //声明SetTex函数

53    switch(cubeName){

54    case "Cube1":     //当触摸到Cube1,修改Tex记录为Tex1

55     PlayerPrefs.SetString("Tex","Tex1");

56     break;

57    case "Cube2":     //当触摸到Cube2,修改Tex记录为Tex2

58     PlayerPrefs.SetString("Tex","Tex2");

59     break;

60    case "Cube3":     //当触摸到Cube3,修改Tex记录为Tex3

61     PlayerPrefs.SetString("Tex","Tex3");

62     break;

63    case "Cube4":     //当触摸到Cube4,修改Tex记录为Tex4

64     PlayerPrefs.SetString("Tex","Tex4");

65     break;

66    case "Cube5":     //当触摸到Cube5,修改Tex记录为Tex5

67     PlayerPrefs.SetString("Tex","Tex5");

68     break;

69    case "Cube6":     //当触摸到Cube6,修改Tex记录为Tex6

70     PlayerPrefs.SetString("Tex","Tex6");

71     break;

72    }}}

● 第4-9行的主要功能为变量声明,在开发环境下的属性查看器中可以为各个参数指定资源或者取值。

● 第10-12行为实现了Start方法的重写,主要是在初始化时默认记录第一个纹理图。

● 第13-34行为实现了Update方法的重写,主要为了判断是否有Cube被触摸,然后获得触摸的Cube名称并记录对应的纹理图,以及给Android设备的按键添加控制方法。

● 第35-51行为实现了OnGUI方法的重写,主要为了创建确定和退出按钮,以及执行跳转界面和退出项目的操作。

● 第 13-34 行为实现了定义一个 SetTex 方法,主要实现了根据立方体的名称记录相对应的纹理图。

(2)立方体旋转的实现,即创建一个名字为“RotateCube.cs”的脚本,分别挂载到 Cube1~Cube6,脚本“RotateCube.cs”的代码如下。

代码位置:见随书光盘中源代码/第3章目录下的CubeBal /Assets/Script / RotateCube.cs。

1 using UnityEngine;

2 using System.Collections;//引入系统包

3 public class RotateCube : MonoBehaviour {

4   void Update () {//重写Update函数

5    //如果没有Cube被触摸到同时本脚本挂在了Cube1上,Cube1就以较快的速度反向旋转

6    if(!StartGame.isTouched && this.transform.name == "Cube1"){

7     this.transform.Rotate(-Time.deltaTime * 200,-Time.deltaTime * 200,-Time.deltaTime * 200);

8    }

9    //如果有Cube被触摸到同时被触摸到的Cube和本脚本挂载的Cube同名,被触摸到的Cube

//就以较快的速度反向旋转

10    if(StartGame.isTouched && this.transform.name == StartGame.touchedCube){

11     this.transform.Rotate(-Time.deltaTime * 200,-Time.deltaTime * 200,-Time.deltaTime * 200);

12    }

13    else{//其他情况下,立方体正常旋转

14     this.transform.Rotate(Time.deltaTime * 50,Time.deltaTime * 50,Time.deltaTime * 50);

15    }}}

● 第4-15行是实现了Update方法的重写,主要功能是为了控制各个立方体的旋转速度,使被触摸的立方体改变速度。

3.6.2 球走场景实现

本场景中的所有操作都与3.2.2小节所对应的操作相同,具体的操作步骤读者可参考3.2.2小节所对应的部分,只是本场景中所使用的文件名有所改变,将中文改成了英文,再者就是将上一节中的“Init.js”脚本改成了“Init.cs”脚本,具体的脚本代码如下所示。

代码位置:见随书光盘中源代码/第3章目录下的CubeBal /Assets/Script / Init.cs。

1 using UnityEngine;

2 using System.Collections;//引入系统包

3 public class Init : MonoBehaviour {

4   public Rigidbody ballTemplete;//球模板引用

5   public Texture fanhuiTexture;//返回按钮纹理图引用

6   public GUIStyle MyStyle;//自定义GUIStyle

7   void Start () {//重写Start函数

8    Rigidbody ball;//新建实例球对象的引用

9    //在(0,0.7f,4.0f)位置实例化一个ball对象

10 ball=Instantiate(ballTemplete, new Vector3(0,0.7f,4.0f), ballTemplete.rotation) as Rigidbody;

11    string ballTex;//球纹理名引用

12    ballTex=PlayerPrefs.GetString("Tex");//获得对应的纹理图名称

13    //将球的纹理设置成对应的纹理

14    ball.renderer.material.mainTexture = (Texture2D)Resources.Load(ballTex,typeof(Texture2D));

15    ball.velocity= new Vector3(-8,0,-15);//给球加一个初始速度

16  }

17  void Update () {//重写Update函数

18 if (Application.platform == RuntimePlatform.Android)//判断运行平台是否为Android平台

19   {

20    if (Input.GetKeyUp(KeyCode.Home) ) //判断当前按键是否为Android设备的Home键

21    {

22     Application.Quit();   //退出项目

23    }

24   if (Input.GetKeyUp(KeyCode.Escape))//判断当前按键是否为Android设备的Escape键

25    {

26     Application.Quit();   //退出项目

27    }}}

28  void OnGUI()

29  {

30    float ratioScaleTempH=Screen.height/960.0f;

31    float ratioScaleTemp=Screen.width/540.0f; //自适应屏幕时的长、宽缩放比

32    if (GUI.Button(new Rect(380*ratioScaleTemp,850*ratioScaleTempH,

33     150*ratioScaleTemp,80*ratioScaleTempH),fanhuiTexture,MyStyle)){

34     StartGame.isTouched = false;//返回到ChangeTex场景后恢复初始状态

35    Application.LoadLevel("ChangeTex");//加载ChangeTex场景

36   }}}

● 第4-6行的主要功能为变量声明,在开发环境下的属性查看器中可以为各个参数指定资源或者取值。

● 第7-16行实现了的Start方法的重写,在场景中实例化了一个球,并为球添加了纹理贴图以及赋予了初速度。

● 第17-27行为实现了的Update方法的重写,主要为了给Android设备的按键添加控制方法。

● 第28-36行为实现了的OnGUI方法的重写,主要为了创建返回按钮,执行跳转界面的操作,以及声明横纵向缩放比变量,进而实现GUI组件的屏幕自适应特性。