哪家做网站的公司,婚礼网站怎么做的,html5网站开发环境的搭建,企业网站建设目的是什么最终效果 【制作100个unity游戏之31】用unity制作一个爬坡2d赛车小游戏 前言 
今天用unity制作一个简单的爬坡2d赛车小游戏 
素材 
https://www.spriters-resource.com/mobile/hillclimbracing/ 
拼装车素材 车身添加碰撞体#xff0c;摩檫力0 轮胎添加碰撞体和刚体#xff0…最终效果 【制作100个unity游戏之31】用unity制作一个爬坡2d赛车小游戏 前言 
今天用unity制作一个简单的爬坡2d赛车小游戏 
素材 
https://www.spriters-resource.com/mobile/hillclimbracing/ 
拼装车素材 车身添加碰撞体摩檫力0 轮胎添加碰撞体和刚体摩檫力设置为2 整个车加刚体修改质量为2 车新增两个Wheel Joint 2组件分别绑定前后两个车轮刚体 将锚点移动到车车轮中心  
修改参数  
运行效果高频会让你的悬架保持紧密  
让车开起来 
新增DriveCar 代码 
public class DriveCar : MonoBehaviour
{[SerializeField] private Rigidbody2D _frontTireRB; // 前轮刚体[SerializeField] private Rigidbody2D _backTireRB; // 后轮刚体[SerializeField] private float _speed  150f; // 车辆速度private float _moveInput; // 移动输入值// 每帧更新private void Update(){_moveInput  Input.GetAxisRaw(Horizontal); // 获取水平输入}// 固定帧更新private void FixedUpdate(){// 给前轮和后轮施加扭矩控制车辆运动_frontTireRB.AddTorque(-_moveInput * _speed * Time.fixedDeltaTime);_backTireRB.AddTorque(-_moveInput * _speed * Time.fixedDeltaTime);}
} 
配置  效果 我们还希望当汽车在空中时能够控制它的旋转 
修改DriveCar 
[SerializeField] private Rigidbody2D _carRB; // 车刚体
[SerializeField] private float _rotationSpeed  500f; // 旋转速度// 固定帧更新
private void FixedUpdate()
{//..._carRB.AddTorque(-_moveInput * _rotationSpeed * Time.fixedDeltaTime);
}配置  
效果  
让我们把司机的头弄得摇摇晃晃的 
在身体上添加一个2d碰撞体  
给头添加碰撞体 添加Hinge Joint 2D 链接组件链接车锚点设置在脖子处 并开启限制Use Limits使用限制 限制头在一定范围内摆动  
效果  
添加 
添加Sprite Shape Profile图片形状轮廓  其实效果就是地面旋转超过一定角度后草地就消失了  
应用Sprite Shape Profile图片形状轮廓配置 
场景添加ClosedShape组件  配置  可以看到草默认没有露出来我们需要编辑样条使左上角点和右上角点立即线性   
绘制地形 
我们可以手动绘制地形但是工作量太大  
我们可以选择用代码控制生成新增EnvironmentGenerator 
using UnityEngine;
using UnityEngine.U2D;[ExecuteInEditMode]
public class EnvironmentGenerator : MonoBehaviour
{[SerializeField] private SpriteShapeController _spriteShapeController; // Sprite Shape 控制器[SerializeField, Range(3f, 100f)] private int _levelLength  50; // 环境长度[SerializeField, Range(1f, 50f)] private float _xMultiplier  2f; // X 倍增量[SerializeField, Range(1f, 50f)] private float _yMultiplier  2f; // Y 倍增量[SerializeField, Range(0f, 1f)] private float _curveSmoothness  0.5f; // 曲线平滑度[SerializeField] private float _noiseStep  0.5f; // 噪声步长[SerializeField] private float _bottom  10f; // 底部高度private Vector3 _lastPos; // 上一个位置public void OnValidate(){_spriteShapeController.spline.Clear(); // 清空曲线for (int i  0; i  _levelLength; i){_lastPos  transform.position  new Vector3(i * _xMultiplier, Mathf.PerlinNoise(0, i * _noiseStep) * _yMultiplier, 0f); // 计算当前位置_spriteShapeController.spline.InsertPointAt(i, _lastPos); // 在曲线中插入点if (i ! 0  i ! _levelLength - 1){_spriteShapeController.spline.SetTangentMode(i, ShapeTangentMode.Continuous); // 设置切线模式为连续_spriteShapeController.spline.SetLeftTangent(i, Vector3.left * _xMultiplier * _curveSmoothness); // 设置左切线_spriteShapeController.spline.SetRightTangent(i, Vector3.right * _xMultiplier * _curveSmoothness); // 设置右切线}}_spriteShapeController.spline.InsertPointAt(_levelLength, new Vector3(_lastPos.x, transform.position.y - _bottom, 0f)); // 在最后添加底部左侧点_spriteShapeController.spline.InsertPointAt(_levelLength  1, new Vector3(transform.position.x, transform.position.y - _bottom, 0f)); // 在最后添加底部右侧点}
}配置调整参数配置绘制地形  
地面添加碰撞体 
新增Edge Collider 2D碰撞体  
可以看到默认是一条线点击Sprite Shape Controller组件的更新碰撞体取消勾选再打开就刷新了  这样碰撞就与地面匹配了  
但是我们不希望碰撞体在草地之上可以点击细微调整碰撞体  
效果  
添加虚拟相机摄像头跟随 效果  
添加燃料条 
绘制UI   
新增FuelController 
using UnityEngine;
using UnityEngine.UI;public class FuelController : MonoBehaviour
{public static FuelController instance;[SerializeField] private Image _fuelImage; // 显示燃料的图像[SerializeField, Range(0.1f, 5f)] private float _fuelDrainSpeed  1f; // 燃料消耗速度范围[SerializeField] private float _maxFuelAmount  100f; // 最大燃料量private float _currentFuelAmount; // 当前燃料量private void Awake(){if (instance  null)instance  this; // 单例模式确保只有一个实例}private void Start(){_currentFuelAmount  _maxFuelAmount; // 初始时燃料量等于最大燃料量UpdateUI(); // 更新UI显示}private void Update(){_currentFuelAmount - Time.deltaTime * _fuelDrainSpeed; // 每帧消耗燃料UpdateUI(); // 更新UI显示}private void UpdateUI(){_fuelImage.fillAmount  (_currentFuelAmount / _maxFuelAmount); // 更新燃料图像的填充量}
}配置  
效果  
按颜料剩余量显示不同的颜色变化 
修改FuelController 
[SerializeField] private Gradient _fueleGradient;//颜色参数private void UpdateUI()
{_fuelImage.fillAmount  (_currentFuelAmount / _maxFuelAmount); // 更新燃料图像的填充量_fuelImage.color  _fueleGradient.Evaluate(_fuelImage.fillAmount);//修改颜色变化
}配置  效果  
燃料耗尽结束游戏和重新开始游戏 
简单绘制游戏结束UI  
新增GameManager 
using UnityEngine;
using UnityEngine.SceneManagement;public class GameManager : MonoBehaviour
{public static GameManager instance;[SerializeField] private GameObject _gameOverCanvas; // 游戏结束时显示的画布private void Awake(){if (instance  null)instance  this; // 单例模式确保只有一个实例Time.timeScale  1f; // 时间缩放设为正常时间}public void GameOver(){_gameOverCanvas.SetActive(true); // 显示游戏结束画布Time.timeScale  0f; // 暂停游戏时间}public void RestartGame(){SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); // 重新加载当前场景}
}配置  
配置重新开始游戏按钮事件  修改FuelController调用游戏结束事件 
private void Update()
{//...//燃料耗尽结束游戏if(_currentFuelAmount  0f){GameManager.instance.GameOver();}
}效果  
玩家头部撞地结束游戏 
添加在头上脚本记得配置地面标签 
public class DriverDeathFromHead : MonoBehaviour
{private void OnCollisionEnter2D(Collision2D other) {if(other.gameObject.CompareTag(Ground)){GameManager.instance.GameOver();}}
}配置  效果  
加油 
修改FuelController 
//加油
public void FillFuel(){_currentFuelAmount  _maxFuelAmount;UpdateUI();
}新增CollectFuel 油脚本 
public class CollectFuel : MonoBehaviour
{private void OnTriggerEnter2D(Collision2D other) {if(other.gameObject.CompareTag(Player)){FuelController.instance.FillFuel();Destroy(gameObject);}}
}配置  
效果  
显示行驶距离 
新增DisplayDistanceText 
public class DisplayDistanceText : MonoBehaviour
{[SerializeField] private Text _distanceText; // 显示距离的TextMeshProUGUI组件[SerializeField] private Transform _playerTrans; // 玩家的Transform组件private Vector2 _startPosition; // 起始位置private void Start(){_startPosition  _playerTrans.position; // 记录玩家的初始位置}private void Update(){Vector2 distance  (Vector2)_playerTrans.position - _startPosition; // 计算玩家相对于起始位置的距离distance.y  0f; // 只关心水平方向的距离if (distance.x  0){distance.x  0; // 距离不会为负数最小为0}_distanceText.text  distance.x.ToString(F0)  m; // 更新显示距离的文本保留0位小数并添加单位“m”}
}配置  
效果  
轮胎凹陷问题 
比如这样  你可以选择修改阻尼比和增大频率的值使其更加稳定比如这里改成0.3和5  
把轮胎往下移  
别忘记重新定位锚点到中心  
最终效果 
参考 
https://www.youtube.com/watch?vE8lR59Yb2A0 
源码 很遗憾源码我并不想免费分享我也建议大家能自己手动去敲代码逐步实现和理解每一块功能。项目实现所涉及的主要功能思路和代码我也已经毫无保留的分享在文章中了当然如果你真的需要的话源码我也放出来了收个辛苦费就当作你对我不断创作的支持。力量随微心暖人。您的每一次支持都是我创作的最大动力 https://gf.bilibili.com/item/detail/1106249120 
完结 
赠人玫瑰手有余香如果文章内容对你有所帮助请不要吝啬你的点赞评论和关注以便我第一时间收到反馈你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法也欢迎评论私信告诉我哦 
好了我是向宇https://xiangyu.blog.csdn.net 
一位在小公司默默奋斗的开发者出于兴趣爱好最近开始自学unity闲暇之余边学习边记录分享站在巨人的肩膀上通过学习前辈们的经验总是会给我很多帮助和启发php是工作unity是生活如果你遇到任何问题也欢迎你评论私信找我 虽然有些问题我也不一定会但是我会查阅各方资料争取给出最好的建议希望可以帮助更多想学编程的人共勉~