打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
unity3d 三分钟实现简单的赛车漂移

提到赛车游戏,大家最关心的应该就是漂移吧?!

从学unity开始,我就一直在断断续续的研究赛车

因为自己技术太烂、悟性太差等原因,我走了不少弯路

也许你会说,网上那么多资料,你不会查啊

是啊!网上一搜一大把unity赛车例程,还有好几篇被转发了很多次的赛车漂移实现思路

 

【wheelcollider:自己技术太烂搞不定】

赛车例程几乎都是用wheelcollider来实现的

我一直以为wheelcollider的参数简直就不是人能调的

直到上个星期我才听我好朋友 阿亮 说wheelcollider的参数不是随便调的

它是按照真实赛车来实现的,所以参数也要按照真实赛车来调

比如赛车车轮的间距、赛车重量、悬挂高度......

就好比小轿车使用了大货车的悬挂参数、大货车使用了小轿车的车轮参数

好吧,我承认我自己也是听得迷迷糊糊!

反正总而言之一句话:wheelcollider的参数的确是非常难调,但是懂的人还是能一下子就调好的(好像说的是废话,我是不懂的- -)

 

【实现思路的文章:自己悟性太差搞不定】

然后是关于赛车漂移实现思路的文章

有几篇被转发了很多次的文章,被转发了那么多次,那么漂移应该就是这个实现思路吧?可是大家的实现方式都不一样

我根本不知道漂移的实现是否有一个唯一的标准,如果有,那这个标准又是什么呢?

看了这些文章,漂移我还是没有研究出来,还是一点思路都没有

 

后来我偶然得到了一份商业赛车游戏的代码,然后漂移就实现出来了- -

听我说起来好像挺容易的!其实研究那份代码的过程特别煎熬!唉,不说了,都是泪啊

 

声明:下文中我要实现出来的漂移仅仅是个简单的漂移,非常简单!!!一个思路而已,并没有用到那份商业赛车游戏中的任何一句代码

注意:请使用Unity4.X版本,5.X版本的wheelcollider参数又变了,要哭了

 

准备工作:

1、下载CarWaypoint插件,使用插件中的demo。地址:http://www.cnblogs.com/shenggege/p/4295616.html

2、easytouch插件

 

导入CarWaypoint插件和easytouch插件

打开CarWaypoints/demo/Car Physics 场景,可以看到一辆车

Hierarchy面板除了前四项其余全部隐藏,运行起来跑一下,还是挺有漂移的感觉的,这是调wheelcollider参数调出来的

我们现在需要做的是用摇杆操作赛车,用另外一个思路让赛车转弯时会漂移

 

创建一个虚拟摇杆取名为:MoveJoystick,InteractionType选择Event Notification

新建一个C#脚本:RockerController,复制以下代码

  1 #region HeadComments  2 /* ========================================================================  3 * Copyright (C) 2015 ArthunGame  4 *  5 * 作    者:Arthun  6 * 文件名称:RockerController  7 * 功    能:摇杆控制器  8 *   9 * ========================================================================= 10 */ 11 #endregion 12  13 using UnityEngine; 14  15 public class RockerController : MonoBehaviour 16 { 17     public static RockerController Instance; 18  19     /// <summary> 20     /// 摇杆移动回调 21     /// </summary> 22     /// <param name="isMove"></param> 23     /// <param name="angle"></param> 24     /// <param name="move"></param> 25     public delegate void RockerMoveCallback(bool isMove, float angle, MovingJoystick move); 26     public RockerMoveCallback rockerMoveCallback; 27  28     void Awake() 29     { 30         if (Instance != null) 31             Debug.LogError("Instance RockerController x2"); 32  33         Instance = this; 34     } 35  36     /// <summary> 37     /// 当摇杆可用时注册事件(程序启动执行) 38     /// </summary> 39     void OnEnable() 40     { 41         EasyJoystick.On_JoystickMove += OnJoystickMove; 42         EasyJoystick.On_JoystickMoveEnd += OnJoystickMoveEnd; 43     } 44  45     /// <summary> 46     /// 当摇杆不可用时移除事件(程序关闭时执行)  47     /// </summary> 48     void OnDisable() 49     { 50         EasyJoystick.On_JoystickMove -= OnJoystickMove; 51         EasyJoystick.On_JoystickMoveEnd -= OnJoystickMoveEnd; 52     } 53  54     /// <summary> 55     /// 当摇杆销毁时移除事件 (程序关闭时执行)  56     /// </summary> 57     void OnDestroy() 58     { 59         EasyJoystick.On_JoystickMove -= OnJoystickMove; 60         EasyJoystick.On_JoystickMoveEnd -= OnJoystickMoveEnd; 61     } 62  63     /// <summary> 64     /// 移动摇杆结束 65     /// </summary> 66     /// <param name="move"></param> 67     void OnJoystickMoveEnd(MovingJoystick move) 68     { 69         OnRockerMoveInfo(false, -1f, move); 70     } 71  72     /// <summary> 73     /// 正在移动摇杆 74     /// </summary> 75     /// <param name="move"></param> 76     void OnJoystickMove(MovingJoystick move) 77     { 78         if (move.joystickAxis.x != 0 || move.joystickAxis.y != 0) 79         { 80             OnRockerMoveInfo(true, circularAngle(move), move); 81         } 82     } 83  84     /// <summary> 85     /// 获取摇杆全角度 0~360 86     /// </summary> 87     /// <param name="move"></param> 88     /// <returns> 左边0 上90 右180 下 270</returns> 89     float circularAngle(MovingJoystick move) 90     { 91         Vector2 pos = new Vector2 92         { 93             x = move.joystickAxis.x * 90f + 90f, 94             y = move.joystickAxis.y * 90f + 90f 95         }; 96  97         if (pos.y < 90f) 98         { 99             if (pos.x < 90f)100             {101                 return 270f + pos.y;102             }103             else if (pos.x > 90f)104             {105                 return 180f + (90f - pos.y);106             }107         }108 109         return pos.x;110     }111 112     /// <summary>113     /// 摇杆移动信息114     /// </summary>115     /// <param name="isMove"></param>116     /// <param name="angle">当前摇杆角度 取值范围0~360 -1为未操作</param>117     void OnRockerMoveInfo(bool isMove, float angle, MovingJoystick move)118     {119         if (rockerMoveCallback != null)120         {121             rockerMoveCallback(isMove, angle, move);122         }123     }124 }

 RockerController挂到MoveJoystick上

 

新建一个脚本:FollowCamera并复制以下代码

 1 #region HeadComments 2 /* ======================================================================== 3 * Copyright (C) 2016 ArthunGame 4 * 5 * 作    者:Arthun 6 * 文件名称:FollowCamera 7 * 功    能:跟随摄像机 8 * 创建时间:2016/03/11 19:38:35 9 * 10 * =========================================================================11 */12 #endregion13 14 using UnityEngine;15 16 public class FollowCamera : MonoBehaviour17 {18     static FollowCamera _instance;19     public static FollowCamera GetInstance()20     {21         return _instance;22     }23 24     public Transform Target;25     public float Distance = 10f;26     public float Height = 20f;27     public float HeightDamping = 2f;28 29     void Awake()30     {31         if (_instance != null)32             Debug.LogError("Instance FollowCamera x2");33 34         _instance = this;35     }36 37     void LateUpdate()38     {39         float currentHeight = Mathf.Lerp(transform.position.y, Target.position.y + Height, HeightDamping * Time.deltaTime);40 41         transform.position = Target.position;42         transform.position -= Vector3.forward * Distance;43         transform.position = new Vector3(transform.position.x, currentHeight, transform.position.z);44 45         transform.LookAt(Target);46     }47 48     public void SetTarget(Transform target)49     {50         Target = target;51     }52 53     public void SetParame(float dis, float height, float heightDamp)54     {55         Distance = dis;56         Height = height;57         HeightDamping = heightDamp;58     }59 }

将MainCamera上的SmoothFollowA脚本删除,替换为刚才新建的FollowCamera脚本

 

打开CarController脚本,添加几个变量

1     public float EngineTorque = 1500f;//引擎扭矩 2     public WheelCollider WheelBL;//后左轮3     public WheelCollider WheelBR;//后右轮4     public Vector3 CenterOfMass = Vector3.zero;//质量中心5 6     bool mRockerIsMove = false;//摇杆是否移动7     Vector3 mTargetBodyAngle = Vector3.zero;//目标车身角度8     float mBodyRotateSpeed = 3f;//旋转速度

在Start中设置赛车质量中心(越低越不容易翻车)和摇杆回调

 1     void Start() 2     { 3         rigidbody.centerOfMass = CenterOfMass; 4         RockerController.Instance.rockerMoveCallback += rockerMoveCallback; 5  6         //获取路标点数据 7         _WaypointsXML.GetXmlData(WaypointsModelAll, null, waypointsData.text); 8  9         Debug.Log("赛道总长度:" + CalcTotalDis().ToString());//计算赛道长度10     }11 12     /// <summary>13     /// 摇杆移动回调14     /// </summary>15     /// <param name="isMove"></param>16     /// <param name="angle"></param>17     /// <param name="move"></param>18     void rockerMoveCallback(bool isMove, float angle, MovingJoystick move)19     {20         if (move.joystickName != "MoveJoystick")21             return;22 23         mRockerIsMove = isMove;24         mTargetBodyAngle.y = move.Axis2Angle(true);25     }

 

最后,在FixedUpdate中加入三句代码

1         if (mRockerIsMove)2         {3             transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(mTargetBodyAngle), Time.fixedDeltaTime * mBodyRotateSpeed);4         }5 6         WheelBL.motorTorque = WheelBR.motorTorque = -EngineTorque * (mRockerIsMove ? 0.7f : 0f) * 5000f * Time.fixedDeltaTime;

看到这里,是不是吓了一跳,这漂移也太简单了吧!一句代码搞定漂移、一句代码搞定动力

原理是根据摇杆旋转的角度车身也相对应的旋转,加上动力有惯性,就产生圆弧形的漂移了

思路就是这么简单,也许你认为这实在是太简单得离谱了,可我却花费了一年多的时间才明白

现在,你只需要花几分钟看看这篇没什么高深技术的文章,就能知道漂移实现的思路

 

运行跑一下,有漂移效果,但是似乎不怎么明显,不够顺是不是?

解决方法很简单,在后面两个车轮处加一个向前推的力,在加一个目标方向侧推的力,就能每次都画出完美的漂移弧度

 

文章标题叫《三分钟实现简单的赛车漂移》,写的过程中才发现三分钟更本做不完

因为我自己在做的时候,很多代码都是之前写好了的,直接实现漂移部分的代码就可以了,所以感觉三分钟应该够了,就几句代码

好吧,我就当一次标题党吧!哈哈哈哈

 

原文链接:http://www.cnblogs.com/shenggege/p/5393815.html

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Unity3D 虚拟摇杆(之一)
param (C# Programming Guide)
cocos2dx三种定时器的使用
java采用递归算法求解汉诺塔问题(具有解决问题思路详解,具体代码,附有运行结果)
算法——K均值聚类算法(Java实现)
蚁群算法java实现以及TSP问题蚁群算法求解
更多类似文章 >>
生活服务
分享 收藏 导长图 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服