C#我只是一个萌新,由于搞过Java,还是可以看懂C#的

偶然间得到赛车游戏Extreme Drift的源码

接下来我会花一段时间来解读,这是一个我学习的过程,记录在博客

等到我完全解读之后,我也许会考虑再加入联机功能等

 

当然,这个游戏用的是Unity引擎

首先,我先展示一下这个游戏的效果:

 

选车:

 

然后选图,进入比赛:

 

 

WASD,SHIFT氮气,空格漂移

不得不说,车辆的手感非常不错!

作为育碧的老玩家,讲真的,这个小游戏的手感比育碧的赛车手感好多了

甚至就我感觉,车辆除了一些参数感觉需要调整,整体来看,手感和GTA5的感觉有点像

 

不多说了,我打包出来一个Windows可运行的程序,双击就可以体验赛车游戏:

 

链接:https://pan.baidu.com/s/1kF61eguRJf1Gd7aGn4w5jg
提取码:ks1l

 

源码的地址:花钱买的,免费分享了!

 

链接:https://pan.baidu.com/s/1yiayLBXOBcSoJstHJQw33A
提取码:eyyq

 

下面正式开始查看源码:

导入之后目录结构:并且会自动导入Unity自带资源ImageEffects

 

打开Scenes的MainMenu场景,启动游戏:

然而第一次启动在加载地图的时候会报错,因为这一步:

  1. IEnumerator LoadLevelAsync()
  2. {
  3. yield return new WaitForSeconds(0.4f);
  4. sceneLoadingOperation = Application.LoadLevelAsync(currentLevelNumber + 1);
  5. sceneLoadingOperation.allowSceneActivation = false;
  6. while (!sceneLoadingOperation.isDone || sceneLoadingOperation.progress < 0.9f)
  7. {
  8. menuLoadTime += Time.deltaTime;
  9. yield return 0;
  10. }
  11. }

 

这里异步加载索引为currentLevelNumber+1的场景,然而,实际上不存在这个索引,所以,我们需要在Build Setting设置好这些场景:

 

然后在启动,就可以顺利游戏了!

 

有六个场景,那么就先从主菜单MainMenu场景来看:

负责UGUI的事件系统:

 

Standalone Input Module:专为鼠标/键盘/控制器输入而设计:

这里没有做什么多余操作,只是添加了这个组件,一个参数也没有改

 

Touch Input Module:为触摸屏设备而设计,暂时与我无关

 

接下来看UGUI部分:

 

一个Canvas,里面有八个对象

 

Top Panel是顶部的一个横条,右边有金币设置选项

观察金币,发现这只是一个简单的图片,而金币之内,包含GameScore对象,这个应该是处理金币的核心

猜错了,观察GameScore对象发现,这也是一个简单的Text,那么金币相关功能应该是find这个对象来处理的

然后看设置,是一个Button,绑定了MainMenu里面的一个函数,而且播放点击声音,另外有一个Shadow组件:作用是给按钮添加阴影轮廓

查看这个函数:

  1. public void SettingActive(bool activePanel)
  2. {
  3. menuPanels.Settings.gameObject.SetActive(activePanel);
  4. }

OK,只是使另一个UI对象active,可以理解为:点击设置按钮后跳转到另一个页面

 

MainMenu相当于是全屏幕,包含了左上的logo和底部的一个Panel:

标题Tilt:一个简单的图片,在它下面的Image有点意思,是一个较亮的矩形,反复从右到左位移,配合Logo实现发光的效果

实现机制:Image利用Aminator组件将自身和Tilt这个Logo绑定,实现循环动画

然后就是底部的Panel,里面有四个对象,退出,资源,油管,选车进行下一步

退出:绑定了Shadow、点击音效的一个按钮,以及一个MainMenu的函数:就是简单的退出

  1. public void ClickExitButton()
  2. {
  3. Application.Quit();
  4. }

资源和油管都是链接,本质一个按钮带Shadow和Audio,绑定OpenURL脚本的函数:传入URL,打开,简单

  1. public void OpenTab (string URL) {
  2. Application.OpenURL(URL);
  3. }

选车:一个简单的按钮,带Shadow,绑定MainMenu的一个函数:我在下面的注释中将会详细解释

  1. public void CurrentPanel(int current)
  2. {
  3. //这里为什么要传一个INT呢?因为开头有定义
  4. //public enum Panels { MainMenu = 0, SelectVehicle = 1, SelectLevel = 2, Settings = 3 }
  5. //activePanel默认为0,这里传入的是1,就是选车
  6. activePanel = (Panels)current;
  7. //PlayerPrefs是数据持久化,从存档取出数据验证
  8. if (currentVehicleNumber != PlayerPrefs.GetInt("CurrentVehicle"))
  9. {
  10. currentVehicleNumber = PlayerPrefs.GetInt("CurrentVehicle");
  11. //循环所有的车辆
  12. foreach (VehicleSetting VSetting in vehicleSetting)
  13. {
  14. //当前车激活状态,否则不激活
  15. if (VSetting == vehicleSetting[currentVehicleNumber])
  16. {
  17. VSetting.vehicle.SetActive(true);
  18. currentVehicle = VSetting;
  19. }
  20. else
  21. {
  22. VSetting.vehicle.SetActive(false);
  23. }
  24. }
  25. }
  26. //根据传入值做一些操作
  27. switch (activePanel)
  28. {
  29. case Panels.MainMenu:
  30. menuPanels.MainMenu.SetActive(true);
  31. menuPanels.SelectVehicle.SetActive(false);
  32. menuPanels.SelectLevel.SetActive(false);
  33. if (menuGUI.wheelColor) menuGUI.wheelColor.gameObject.SetActive(true);
  34. break;
  35. //这里传入的是1,进入选车
  36. case Panels.SelectVehicle:
  37. menuPanels.MainMenu.gameObject.SetActive(false);
  38. menuPanels.SelectVehicle.SetActive(true);
  39. menuPanels.SelectLevel.SetActive(false);
  40. break;
  41. case Panels.SelectLevel:
  42. menuPanels.MainMenu.SetActive(false);
  43. menuPanels.SelectVehicle.SetActive(false);
  44. menuPanels.SelectLevel.SetActive(true);
  45. break;
  46. case Panels.Settings:
  47. menuPanels.MainMenu.SetActive(false);
  48. menuPanels.SelectVehicle.SetActive(false);
  49. menuPanels.SelectLevel.SetActive(false);
  50. break;
  51. }
  52. }

 

 

VehicleGarage:车库情景,下面有五个对象

Top:顶部。左边一个logo:带有Outline的一个Text。中下是汽车的名字,也是一个Outline的Text

然后是三个车辆性能信息,速度,刹车,氮气,都是简单的Text+Slider

NextVehicle:绑定点击声音和MainMenu的一个函数:

  1. public void NextVehicle()
  2. {
  3. if (menuGUI.wheelColor) { menuGUI.wheelColor.gameObject.SetActive(false); }
  4. currentVehicleNumber++;
  5. //取模运算,防止越界
  6. currentVehicleNumber = (int)Mathf.Repeat(currentVehicleNumber, vehicleSetting.Length);
  7. foreach (VehicleSetting VSetting in vehicleSetting)
  8. {
  9. if (VSetting == vehicleSetting[currentVehicleNumber])
  10. {
  11. VSetting.vehicle.SetActive(true);
  12. //循环到下一辆车赋值给当前
  13. currentVehicle = VSetting;
  14. }
  15. else
  16. {
  17. VSetting.vehicle.SetActive(false);
  18. }
  19. }
  20. }

PreviousVehicle是类似的:

  1. public void PreviousVehicle()
  2. {
  3. if (menuGUI.wheelColor) { menuGUI.wheelColor.gameObject.SetActive(false); }
  4. currentVehicleNumber--;
  5. currentVehicleNumber = (int)Mathf.Repeat(currentVehicleNumber, vehicleSetting.Length);
  6. foreach (VehicleSetting VSetting in vehicleSetting)
  7. {
  8. if (VSetting == vehicleSetting[currentVehicleNumber])
  9. {
  10. VSetting.vehicle.SetActive(true);
  11. currentVehicle = VSetting;
  12. }
  13. else
  14. {
  15. VSetting.vehicle.SetActive(false);
  16. }
  17. }
  18. }

Bottom下有四个对象:

Back:一个按钮,返回上一场景,原理和上边的选车按钮一直,调用同一个函数

Next:下一步地图选择页面,也和上面的原理一样,都是调用一个函数CurrentPanel

CustomizeVehicle:自定义车辆,按钮绑定函数,点击后隐藏一些场景,开启自定义场景

BuyNewVehicle:买车,默认是不激活的,点击后激活下一个对象BuyConfirm

BuyConfirm:一个不激活的Panel,被激活后有两个选项,Yes的话掉MainMenu的函数,否则返回:

  1. public void BuyVehicle()
  2. {
  3. //金币足够或者车辆未买才会执行
  4. if ((gameScore >= vehicleSetting[currentVehicleNumber].price) && !vehicleSetting[currentVehicleNumber].Bought)
  5. {
  6. //数据持久化
  7. PlayerPrefs.SetInt("BoughtVehicle" + currentVehicleNumber.ToString(), 1);
  8. //减钱
  9. gameScore -= vehicleSetting[currentVehicleNumber].price;
  10. //防止负数
  11. if (gameScore <= 0) { gameScore = 1; }
  12. //保存金币数量
  13. PlayerPrefs.SetInt("GameScore", gameScore);
  14. //保存车辆购买状态
  15. vehicleSetting[currentVehicleNumber].Bought = true;
  16. }
  17. else
  18. {
  19. menuPanels.EnoughMoney.SetActive(true);
  20. }
  21. }

 

CustomizeVehicle:自定义车辆,下面有三个对象

Top:简单的一个顶部Logo,Colors里面有八个颜色对象,绑定了MainMenu的一个函数:

  1. public void ActiveCurrentColor(Image activeImage)
  2. {
  3. mainColor = activeImage.color;
  4. //根据传参持久化数据
  5. if (menuGUI.wheelColor.gameObject.activeSelf)
  6. {
  7. vehicleSetting[currentVehicleNumber].ringMat.SetColor("_Color", mainColor);
  8. PlayerPrefsX.SetColor("VehicleWheelsColor" + currentVehicleNumber, mainColor);
  9. }
  10. else if (menuGUI.smokeColor.gameObject.activeSelf)
  11. {
  12. vehicleSetting[currentVehicleNumber].smokeMat.SetColor("_TintColor", new Color(mainColor.r, mainColor.g, mainColor.b, 0.2f));
  13. PlayerPrefsX.SetColor("VehicleSmokeColor" + currentVehicleNumber, new Color(mainColor.r, mainColor.g, mainColor.b, 0.2f));
  14. }
  15. }

Bottom下面很多的对象,首先是一个返回,机制和函数上边提到了

WheelColor、SmokeColor和RandomColor都是绑定MainMenu几个函数,这几个函数不难:

  1. public void ActiveWheelColor(Image activeImage)
  2. {
  3. randomColorActive = false;
  4. activeImage.gameObject.SetActive(true);
  5. menuGUI.wheelColor = activeImage;
  6. menuGUI.smokeColor.gameObject.SetActive(false);
  7. }
  8. public void ActiveSmokeColor(Image activeImage)
  9. {
  10. randomColorActive = false;
  11. activeImage.gameObject.SetActive(true);
  12. menuGUI.smokeColor = activeImage;
  13. menuGUI.wheelColor.gameObject.SetActive(false);
  14. }
  1. public void RandomColor()
  2. {
  3. randomColorActive = true;
  4. menuGUI.wheelColor.gameObject.SetActive(false);
  5. menuGUI.smokeColor.gameObject.SetActive(false);
  6. //随机数函数
  7. vehicleSetting[currentVehicleNumber].ringMat.SetColor("_Color", new Color(Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f)));
  8. vehicleSetting[currentVehicleNumber].smokeMat.SetColor("_TintColor", new Color(Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), Random.Range(0.0f, 1.1f), 0.2f));
  9. //持久化
  10. PlayerPrefsX.SetColor("VehicleWheelsColor" + currentVehicleNumber, vehicleSetting[currentVehicleNumber].ringMat.GetColor("_Color"));
  11. PlayerPrefsX.SetColor("VehicleSmokeColor" + currentVehicleNumber, vehicleSetting[currentVehicleNumber].smokeMat.GetColor("_TintColor"));
  12. }

 

下面是EnoughMoney,明天再看

 

版权声明:本文为xuyiqing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xuyiqing/p/10022749.html