赞
踩
卡车对象:
粒子系统:增加火焰、漂移轮胎上的火花等。
动画组件在StandartKart游戏对象(gameobject)上。
模型的中心轴不在模型中心,因此我们将模型添加到名为FrontLeft的父对象游戏对象中,FrontLeft游戏对象位于模型中心。当汽车运行时,我们将旋转FrontLeft游戏对象。
PlayerScripts.cs是此项目中最重要的脚本。如果您想知道每个函数的功能,首先请注释掉其他函数。如move()。
FixedUpdate() {
move();
//tireSteer();
//steer();
//groundNormalRotation();
//drift();
//boosts();
}
在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;
CurrentSpeed = Mathf.Lerp(CurrentSpeed, MaxSpeed, Time.deltaTime * 0.5f);
在这行代码中,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;
请注意,只有前轮可以左右旋转,后轮不行。
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); }
当汽车向前直行时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;
}
}
我们需要两个标志:向右漂移和向左漂移。
if(steerDirection > 0)
{
driftRight = true;
driftLeft = false;
}
else if(steerDirection < 0)
{
driftRight = false;
driftLeft = true;
}
steerDirection由左右输入轴控制。
steerDirection = Input.GetAxisRaw("Horizontal");
积累漂移时间:
if (Input.GetKey(KeyCode.V) && touchingGround && CurrentSpeed > 40 &&
Input.GetAxis("Horizontal") != 0)
{
driftTime += Time.deltaTime;
漂移条件:接触地面,速度>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;
}
在加速时,最大速度将设置为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;
}
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);
}
当卡车转向或漂移时,PlayerLookat游戏对象将逐渐朝着卡车旋转的方向旋转。因为我们想要看到汽车的侧面,所以我们使摄像机的旋转值逐渐接近卡车的转向旋转。
否则我们整个时间都只能看到汽车的后面:
如何在代码中实现这个功能:
CameraFollow.cs
transform.rotation = Quaternion.Slerp(transform.rotation, player.rotation, 3 *
Time.deltaTime);
相机的旋转慢慢地接近玩家的旋转。
额外的碰撞器在面板上方,该额外的碰撞器设置为Trigger。
PlayerScript.cs:
private void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "GliderPanel")
{
GLIDER_FLY = true;
gliderAnim.SetBool("GliderOpen", true);
gliderAnim.SetBool("GliderClose", false);
}
}
当退出触发器时,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);
}
}
当触地或离路时,我们将通过设置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;
}
此外,当滑翔时,卡车将围绕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
滑翔的动画:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。