当前位置:   article > 正文

如何使用Unity制作马里奥卡丁车游戏unity3d开发教程_unity马里奥

unity马里奥

如何使用Unity制作马里奥卡丁车游戏unity3d开发教程

游戏预览:

在这里插入图片描述

卡车对象:
在这里插入图片描述

反射探针(reflection probe)用于为汽车提供漂亮的金属感。

在这里插入图片描述

粒子系统:增加火焰、漂移轮胎上的火花等。
在这里插入图片描述

动画组件在StandartKart游戏对象(gameobject)上。

轮胎:

gameobject

模型的中心轴不在模型中心,因此我们将模型添加到名为FrontLeft的父对象游戏对象中,FrontLeft游戏对象位于模型中心。当汽车运行时,我们将旋转FrontLeft游戏对象。
在这里插入图片描述

移动(前进和后退)

PlayerScripts.cs是此项目中最重要的脚本。如果您想知道每个函数的功能,首先请注释掉其他函数。如move()。

FixedUpdate() {
move();
//tireSteer();
//steer();
//groundNormalRotation();
//drift();
//boosts();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在move()函数中:

if (Input.GetKey(KeyCode.Space)) {
CurrentSpeed = Mathf.Lerp(CurrentSpeed, MaxSpeed, Time.deltaTime * 0.5f);
} else if (Input.GetKey(KeyCode.S)) {
CurrentSpeed = Mathf.Lerp(CurrentSpeed, -MaxSpeed / 1.75f, 1f * Time.deltaTime);
} else {
CurrentSpeed = Mathf.Lerp(CurrentSpeed, 0, Time.deltaTime * 1.5f);
}
Vector3 vel = transform.forward * CurrentSpeed;
vel.y = rb.velocity.y; //gravity
rb.velocity = vel;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
CurrentSpeed = Mathf.Lerp(CurrentSpeed, MaxSpeed, Time.deltaTime * 0.5f);
  • 1

在这行代码中,0.5f表示卡车将在1/0.5=2秒内达到最大速度。

不要忘记添加vel.y=rb.velocity.y分量。

显然我们不希望重力效应被抵消。

车体转向:

围绕y轴旋转。
在这里插入图片描述

在steer()函数中,
由于操纵应该在汽车移动较慢时更强,因此我们根据卡车的实际速度调整steerAmount,然后使用steerAmount在其y轴上旋转卡车。

steerAmount = RealSpeed > 30 ? RealSpeed / 4 * steerDirection : steerAmount =
RealSpeed / 1.5f * steerDirection;
  • 1
  • 2

轮胎转向和旋转:

在这里插入图片描述

请注意,只有前轮可以左右旋转,后轮不行。

if (Input.GetKey(KeyCode.LeftArrow))
{
frontLeftTire.localEulerAngles = Vector3.Lerp(frontLeftTire.localEulerAngles, new
Vector3(0, 155, 0), 5 * Time.deltaTime);
frontRightTire.localEulerAngles = Vector3.Lerp(frontLeftTire.localEulerAngles, new
Vector3(0, 155, 0), 5 * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.RightArrow))
{
frontLeftTire.localEulerAngles = Vector3.Lerp(frontLeftTire.localEulerAngles, new
Vector3(0, 205, 0), 5 * Time.deltaTime);
frontRightTire.localEulerAngles = Vector3.Lerp(frontLeftTire.localEulerAngles, new
Vector3(0, 205, 0), 5 * Time.deltaTime);
}
else
{
frontLeftTire.localEulerAngles = Vector3.Lerp(frontLeftTire.localEulerAngles, new
Vector3(0, 180, 0), 5 * Time.deltaTime); // when moving straight forward
frontRightTire.localEulerAngles = Vector3.Lerp(frontLeftTire.localEulerAngles, new
Vector3(0, 180, 0), 5 * Time.deltaTime);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

当汽车向前直行时y轴的默认旋转值为180。

地面正常旋转:

在这里插入图片描述
这里有一个小bug需要修复:

如上图所示,当在斜坡上时,车身并不平行于地面。我们需要旋转车身以实现车辆爬坡的效果。

只需将汽车旋转到射线命中点的法线方向的旋转即可。

private void groundNormalRotation()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.up, out hit, 0.75f))
{
transform.rotation = Quaternion.Lerp(transform.rotation,
Quaternion.FromToRotation(transform.up * 2, hit.normal) * transform.rotation, 7.5f *
Time.deltaTime);
touchingGround = true;
} else {
touchingGround = false;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

漂移:

我们需要两个标志:向右漂移和向左漂移。

if(steerDirection > 0)
{
driftRight = true;
driftLeft = false;
}
else if(steerDirection < 0)
{
driftRight = false;
driftLeft = true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

steerDirection由左右输入轴控制。

steerDirection = Input.GetAxisRaw("Horizontal");
  • 1

积累漂移时间:

if (Input.GetKey(KeyCode.V) && touchingGround && CurrentSpeed > 40 &&
Input.GetAxis("Horizontal") != 0)
{
driftTime += Time.deltaTime;
  • 1
  • 2
  • 3
  • 4

漂移条件:接触地面,速度>40,按住左或右键,按住V键进行漂移。在这里插入图片描述

根据漂移时间,为粒子系统设置不同的颜色。漂移时间越长,颜色越强。这样我们就给用户提供了视觉反馈。

在漂移之前,将有一个跳跃动画。

增压:

加速时间由漂移时间总和决定。

//give a boost
if (driftTime > 1.5 && driftTime < 4) {
BoostTime = 0.75f;
}
if (driftTime >= 4 && driftTime < 7)
{
BoostTime = 1.5f;
}
if (driftTime >= 7)
{
BoostTime = 2.5f;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在加速时,最大速度将设置为boostspeed:

if(BoostTime > 0) {
for(int i = 0; i < boostFire.childCount; i++)
{ // boost fire particles
if (! boostFire.GetChild(i).GetComponent<ParticleSystem>().isPlaying) {
boostFire.GetChild(i).GetComponent<ParticleSystem>().Play();
}
}
MaxSpeed = boostSpeed;
CurrentSpeed = Mathf.Lerp(CurrentSpeed, MaxSpeed, 1 * Time.deltaTime);
} else {
for (int i = 0; i < boostFire.childCount; i++) {
boostFire.GetChild(i).GetComponent<ParticleSystem>().Stop();
}
MaxSpeed = boostSpeed - 20;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

摄像机跟随:

在这里插入图片描述

CameraFollow.cs脚本附加在PlayerLookat游戏对象上。在这里插入图片描述

Main Camera游戏对象是PlayerLookat对象的子对象。

请注意,相对位置为0,0.95,-5.5,相对于X轴的旋转为10,以使其向下看一点。

另外,在游戏中,当我们获得提速时,相机会稍微后退。但实际上并不是PlayerLookat对象在向后移动,而是Main Camera游戏对象在向后移动。相关的代码如下:

In CameraFollow.cs:
if (playerScript.BoostTime > 0) {
transform.GetChild(0).localPosition =
Vector3.Lerp(transform.GetChild(0).localPosition, boostCamPos, 3 * Time.deltaTime);
} else {
transform.GetChild(0).localPosition =
Vector3.Lerp(transform.GetChild(0).localPosition, origCamPos, 3 * Time.deltaTime);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

当卡车转向或漂移时,PlayerLookat游戏对象将逐渐朝着卡车旋转的方向旋转。因为我们想要看到汽车的侧面,所以我们使摄像机的旋转值逐渐接近卡车的转向旋转。
在这里插入图片描述

否则我们整个时间都只能看到汽车的后面:在这里插入图片描述
如何在代码中实现这个功能:

CameraFollow.cs

transform.rotation = Quaternion.Slerp(transform.rotation, player.rotation, 3 *
Time.deltaTime);
  • 1
  • 2

相机的旋转慢慢地接近玩家的旋转。

滑翔:

如何触发滑翔:
预览:

在这里插入图片描述

额外的碰撞器在面板上方,该额外的碰撞器设置为Trigger。

PlayerScript.cs:

private void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "GliderPanel")
{
GLIDER_FLY = true;
gliderAnim.SetBool("GliderOpen", true);
gliderAnim.SetBool("GliderClose", false);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

当退出触发器时,GLIDER_FLY将为true。

private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Ground" || collision.gameObject.tag ==
"OffRoad")
{
GLIDER_FLY = false;
gliderAnim.SetBool("GliderOpen", false);
gliderAnim.SetBool("GliderClose", true);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当触地或离路时,我们将通过设置GLIDER_FLY = false来结束滑翔。

我们将使用GLIDER_FLY布尔标志来决定重力和速度因子:

在PlayerScript.cs的move()函数中:
if (!GLIDER_FLY) {
Vector3 vel = transform.forward * CurrentSpeed;
vel.y = rb.velocity.y; //gravity
rb.velocity = vel;
} else {
Vector3 vel = transform.forward * CurrentSpeed;
vel.y = rb.velocity.y * 0.6f; //滑翔时的重力
rb.velocity = vel;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

此外,当滑翔时,卡车将围绕z轴旋转,而不是围绕y轴旋转,该卡车在地面上旋转。

//glider movements
if (Input.GetKey(KeyCode.LeftArrow) && GLIDER_FLY) //left
{
transform.rotation = Quaternion.SlerpUnclamped(transform.rotation,
Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, 40), 2 *
Time.deltaTime);
} // left
else if (Input.GetKey(KeyCode.RightArrow) && GLIDER_FLY) //right
{
transform.rotation = Quaternion.SlerpUnclamped(transform.rotation,
Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, -40), 2 *
Time.deltaTime);
} //right
else //nothing
{
transform.rotation = Quaternion.SlerpUnclamped(transform.rotation,
Quaternion.Euler(transform.eulerAngles.x, transform.eulerAngles.y, 0), 2 *
Time.deltaTime);
} //nothing
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

滑翔的动画:
在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/109220
推荐阅读
相关标签
  

闽ICP备14008679号