找回密码
 立即注册
查看: 649|回复: 0

[简易教程] Unity 3D教程:竞技游戏中汽车漂移的做法

[复制链接]
发表于 2021-4-12 09:42 | 显示全部楼层 |阅读模式
  Unity 3D是一个多平台的综合型游戏开发工具,是一个全面真格的专业游戏引擎,可以制作手游,也可制作端游。今天的Unity  3D教程主要是介绍一下竞技游戏中汽车漂移的做法。
  首先我们来分析一下现实生活中汽车漂移,在这个基础上进行游戏代码的开发。


  1.现实中的车不是那么好漂移的,漂移需要轮胎与地面的低摩擦和良好的悬挂系统配合。
  2.游戏里完全模拟力学引擎也是不现实的,因为漂移在现实中需要高超的技能,你不能指望玩家能有专业的技能水平去操控或者改装你的车吧,万一拐弯忘拉手刹,或者拉太久。而且完全的物理模拟,不仅费人脑去设计,也费电脑资源去运算。
  3.经过无数次的试验后发现高速移动的赛车突然地转弯是会侧翻的,这个不是游戏引擎问题,能漂移的汽车,需要有稳定精确的汽车架构,很低的底盘。
  4.侧翻不可避免,但游戏里不允许玩家稍微操控失误就侧翻,这会大大影响游戏性。
  经过多方位的研究与试验,丝路Unity 3D专业老师整理出3种方案,希望大家可以作为参考:
  方案一:整个赛车干脆都用translate做坐标移动,这个就是无视wheelcollider物理引擎的做法,新手适用,简单方便,但之后的开发上会有很多问题需要解决,个人认为不是最佳的方案。
  方案二:用wheelcollider的悬挂设置和摩擦力设置做。这个应该是最标准的,这个做法的移动是使用wheelcollider的motorTorque做移动的。
  方案三:轮子一样还用wheelCollider,但汽车移动的动力不使用轮子的motorTorque,而是在汽车的rigidbody上施加Force来传动。用Force有个好处,可以在拐弯的时候做受力分析,计算出最后侧滑的合力方向和大小,实时计算赛车动力方向和侧滑判定。唯一的问题就是汽车稳定性问题,在高速运动的汽车中很难保证他的稳定。
  方案四:用wheelcollider和translate混合处理。首先明白重要的一点,所有汽车移动,转弯都必须使用wheelcollider提供的函数,用wheelcollider方法可以保证车子正常运动,但不会漂移(要么过快车速侧翻,要么就直接转弯过去了),判断漂移只需要判断玩家点击手刹的时候,计算车子拉手刹一瞬间的转弯角和惯性方向,使用transform.translate来实现甩尾,有效规避掉不必要的摩擦判断和物理判断。
  由于手刹后前后轮抱死产生的摩擦和离心力的作用改变了整辆车合力的方向,所以导致汽车运动方向的改变,产生漂移。那我们假设他拉得不是手刹,而只是普通的制动闸,只有制动减速效果,所以先用wheelcollider做正常的拐弯减速运动,然后单独写一个traslate按预计漂移方向做物体移动,并判断当手刹按钮按下后再进行强行物体移动加以模拟减速移动来产生漂移的摩擦衰减效果(transform的坐标移动是不受物理引擎影响的,所以写起来就很简单。)
  这样最后综合起来的效果就能产生漂移效果的最初框架了。玩家操作简单,开发者开发也简单,何乐而不为。最后剩下的工作就是要去慢慢调试一些数据来改变用户体验了。
  [html] view plaincopyprint?
  var rearWheel1:WheelCollider;
  var rearWheel2:WheelCollider;
  var frontWheel1:WheelCollider;
  var frontWheel2:WheelCollider;
  var wheelFL : Transform;
  var wheelFR : Transform;
  var wheelRL : Transform;
  var wheelRR : Transform;
  var steer_max = 20;
  var motor_max = 10;
  var brake_max = 100;
  private var steer = 0;
  private var forward = 0;
  private var back = 0;
  private var motor = 0;
  private var brake = 0;
  private var reverse = false;
  private var speed = 0;
  function Start() {
  rigidbody.centerOfMass = Vector3(0, -0.05, 0);
  }
  function FixedUpdate () {
  speed = rigidbody.velocity.sqrMagnitude;
  steer = Mathf.Clamp(Input.GetAxis(“Horizontal”), -1, 1);
  forward = Mathf.Clamp(Input.GetAxis(“Vertical”), 0, 1);
  back = -1 * Mathf.Clamp(Input.GetAxis(“Vertical”), -1, 0);
  if(speed == 0) {
  if(back > 0) { reverse = true; }
  if(forward > 0) { reverse = false; }
  }
  if(reverse) {
  motor = -1 * back;
  brake = forward;
  } else {
  motor = forward;
  brake = back;
  }
  rearWheel1.motorTorque = motor_max * motor;
  rearWheel2.motorTorque = motor_max * motor;
  rearWheel1.brakeTorque = brake_max * brake;
  rearWheel2.brakeTorque = brake_max * brake;
  frontWheel1.steerAngle = steer_max * steer;
  frontWheel2.steerAngle = steer_max * steer;
  wheelFL.localEulerAngles.y = steer_max * steer;
  wheelFR.localEulerAngles.y = steer_max * steer;
  wheelFR.Rotate(frontWheel1.rpm * -6 * Time.deltaTime,0, 0);
  wheelFL.Rotate(frontWheel2.rpm * -6 * Time.deltaTime,0, 0);
  wheelRR.Rotate(rearWheel1.rpm * -6 * Time.deltaTime,0, 0);
  wheelRL.Rotate(rearWheel2.rpm * -6 * Time.deltaTime,0, 0);
  }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 16:49 , Processed in 0.106607 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表