UnityStandardAsset工程、源码分析_1_赛车游戏[玩家控制]_输入系统

前言

  好久没写博客了。最近在做demo,感觉在游戏架构设计方面遇到了瓶颈。在大学这几年里我基本是在全程造轮子,没有去阅读和分析别人写的源码,导致我缺少横向比较,甚至不知道自己的设计是否存在问题。这几天终于能沉下心来读一读别人的代码,查缺补漏,并且吸取一下别人的经验。
  不过好的unity开源项目还挺难找的,要么就是像这样设计得过于简陋,要么就是像OpenRA那样有点杂七杂八。最后还是选定了Unity的StandardAsset,简略看了一下,还是有点东西的。
  不知道能写到什么程度,反正写一点是一点吧。
  用到的素材

赛车[玩家控制]

 先来看看这游戏怎么玩。游戏提供了两种操作方式:

  • 通过硬件HardwareInput操作,也就是手柄,左摇杆向前加速,向后减速,左右转向。
  • 通过手机倾斜转向,虚拟按钮前进后退。

在这里插入图片描述
抽丝剥茧的首要任务就是找到线头,那我们就从最核心的车辆系统入手。
这是车辆prefab的内容:
在这里插入图片描述
在这里插入图片描述

  • Colliders是车辆总体的碰撞盒,分为三个部分,顶部,挡风玻璃,底盘,这很好理解。
  • WheelsHub是车辆的轮胎碰撞盒,分为四个,对应车辆的四个轮胎,均为WheelCollider。
  • Particles是车辆的尾烟,玩一下就可以知道在车辆的行驶过程中尾部会有烟尘飘起,就是这个粒子系统。
  • Helpers内WaypointTargetObject用于AI导航,这之后再说,玩家控制用不上。CameraFocusPoint是摄像机的瞄准点。
  • Light是车的两个前大灯,为聚光灯模式,设置为Active以后可以亮,否则就不亮。
  • SkyCar内是车辆的Mesh,各自独立,用途与其名字对应。

  在根节点Car上挂载有车辆的控制逻辑,此外,在四个轮胎上分别有各自的轮胎印控制器,用于模拟轮胎印,所以我们先看最核心的车辆控制逻辑。
在这里插入图片描述
CarController就是车辆的核心逻辑;CarUserControl是控制接口,为用户输入与CarController的中间件;CarAudioCarController调用,控制声音的播放。

我在CarController里找了一下,并没有发现有Update(),那逻辑是怎么运行的呢?答案就是CarUserControl

private void FixedUpdate()
        {
   
   
            // pass the input to the car!

            float h = CrossPlatformInputManager.GetAxis("Horizontal");  //本章重点
            float v = CrossPlatformInputManager.GetAxis("Vertical");

#if !MOBILE_INPUT
            float handbrake = CrossPlatformInputManager.GetAxis("Jump");
            //m_Car是CarController类型的变量,也就是当前车辆的核心控制脚本
            //他的Move方法定义为public void Move(float steering, float accel, float footbrake, float handbrake)
            //作用是通过几个变量的输入改变车辆速度,具体实现我放在下章分析,这章只考虑如何获取输入
            m_Car.Move(h, v, v, handbrake);
#else
            m_Car.Move(h, v, v, 0f);
#endif
        }

可以看出Unity做了平台适配,让不同的输入方式在不同的平台上得出较为一致的结果,而作为润滑剂的就是CrossPlatformInputManager类,接下来我分析一下他的原理,先放代码。

namespace UnityStandardAssets.CrossPlatformInput
{
   
   
	public static class CrossPlatformInputManager
	{
   
   
		public enum ActiveInputMethod
		{
   
   
			Hardware,
			Touch
		}
		private static VirtualInput activeInput;

		private static VirtualInput s_TouchInput;
		private static VirtualInput s_HardwareInput;

		static CrossPlatformInputManager()
		{
   
   
			s_TouchInput = new MobileInput();
			s_HardwareInput = new StandaloneInput();
			//在这里决定使用手机输入还是硬件输入
#if MOBILE_INPUT
            activeInput = s_TouchInput;
#else
			activeInput = s_HardwareInput;
#endif
		}
		//切换输入模式
		public static void SwitchActiveInputMethod(ActiveInputMethod activeInputMethod)
		{
   
   
			switch (activeInputMethod)
			{
   
   
				case ActiveInputMethod.Hardware:
					activeInput = s_HardwareInput;
					break;

				case ActiveInputMethod.Touch:
					activeInput = s_TouchInput;
					break;
			}
		}
		//接下来的方法均为静态调用
		public static bool AxisExists(string name)
		{
   
   
			return activeInput.AxisExists(name);
		}

		public static bool ButtonExists(string name)
		{
   
   
			return activeInput.ButtonExists(name);
		}

		public static void RegisterVirtualAxis(VirtualAxis axis)
		{
   
   
			activeInput.RegisterVirtualAxis(axis);
		}


		public static void RegisterVirtualButton(VirtualButton button)
		{
   
   
			activeInput.RegisterVirtualButton(button);
		}


		public static void UnRegisterVirtualAxis(string name)
		{
   
   
			if (name == null)
			{
   
   
				throw new ArgumentNullException("name");
			}
			activeInput.UnRegisterVirtualAxis(name);
		}


		public static void UnRegisterVirtualButton(string name)
		{
   
   
			activeInput.UnRegisterVirtualButton(name);
		}


		// returns a reference to a named virtual axis if it exists otherwise null
		public static VirtualAxis VirtualAxisReference(string name)
		{
   
   
			return activeInput.VirtualAxisReference(name);
		}


		// returns the platform appropriate axis for the given name
		public static float GetAxis(string name)
		{
   
   
			return GetAxis(name, false);
		}


		public static float GetAxisRaw(string name)
		{
   
   
			return GetAxis(name, true);
		}


		// private function handles both types of axis (raw and not raw)
		private static float GetAxis(string name, bool raw)
		{
   
   
			return activeInput.GetAxis(name, raw);
		}


		// -- Button handling --
		public static bool GetButton(string name)
		{
   
   
			return activeInput.GetButton(name);
		}


		public static bool GetButtonDown(string name)
		{
   
   
			return activeInput.GetButtonDown(name);
		}


		public static bool GetButtonUp(string name)
		{
   
   
			return activeInput.GetButtonUp(name);
		}


		public static void SetButtonDown(string name)
		{
   
   
			activeInput.SetButtonDown(name);
		}


		public static void SetButtonUp(string name)
		{
   
   
			activeInput.SetButtonUp(name);
		}


		public static void SetAxisPositive(string name)
		{
   
   
			activeInput.SetAxisPositive(name);
		}


		public static void SetAxisNegative(string name)
		{
   
   
			activeInput.SetAxisNegative(name);
		}


		public static void SetAxisZero(string name)
		{
   
   
			activeInput.SetAxisZero(name);
		}


		public static void SetAxis(string name, float value)
		{
   
   
			activeInput.SetAxis(name, value);
		}


		public static Vector3 mousePosition
		{
   
   
			get {
   
    return activeInput.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值