前言:
- 無論是專門的賽車游戲、還是像GTA5、絕地求生這樣的游戲。都有開車這樣的功能,如何做出好的車輛控制手感,讓玩家感受開車的樂趣呢,今天就來學習一個最簡單的方式吧
首先需要設計車輛的控制邏輯,為了更真實的模擬車輛的運動方式,采用速度控制效果。主要的速度參數為:
//車輛控制速度參數
private float speedOne = 0f; //車輛實時速度
private float speedMax = 120f; //車輛最大速度
private float speedMin = -20f; //車輛最小速度(倒車最大速度)
private float speedUpA = 2f; //車輛加速加速度(A鍵控制)
private float speedDownS = 4f; //車輛減速加速度(S鍵控制)
private float speedTend = 0.5f; //無操作實時速度趨於0時加速度
private float speedBack = 1f; //車輛倒車加速度
整個車輛控制系統核心在於對speedOne的調整,具體設計方式如下:
車輛的加速減速:
當玩家按下W鍵並且車輛沒有達到最大速度時,則車輛加速,若達到最大速度,則車輛速度保持不變。
當玩家按下S鍵並且車輛速度沒有達到最小時,則車輛減速,並且減速速率大於加速,具體代碼為:
//按下W鍵並且速度沒達到最大,則速度增加
if (Input.GetKey(KeyCode.W) && speedOne < speedMax)
{
speedOne = speedOne + Time.deltaTime * speedUpA;
}
//按下S鍵並且速度沒達到零,則速度減小
if (Input.GetKey(KeyCode.S) && speedOne > 0f)
{
speedOne = speedOne - Time.deltaTime * speedDownS;
}
車輛的倒車剎車:
車輛的倒車與車輛的減速相似,只是需要判斷車輛是否可倒車狀態,就是車輛的速度是否小於等於零,且大於最大的倒車速度,通過增加判斷來實現的減速效果。
而車輛的剎車系統則采用空格來直接控制,首先就是采用Lerp獲得平滑的效果:
//按下S鍵並且速度沒有達到倒車速度最大時,且車輛處於可以倒車狀態時車輛倒車
if (Input.GetKey(KeyCode.S) && speedOne > speedMax && speedOne<=0)
{
speedOne = speedOne - Time.deltaTime * speedBack;
}
//按下空格,則汽車停止
if (Input.GetKey(KeyCode.Space) && speedOne != 0)
{
speedOne = Mathf.Lerp(speedOne, 0, 0.4f);
if (speedOne < 5) speedOne = 0;
}
玩家未執行操作:
當玩家沒有執行操作時 ,則車輛速度speedOne逐漸回歸到零,這樣可以保證汽車慢慢的停下來,模擬阻力的效果:
//沒有執行速度操作並且速度大於最小速度,則緩慢操作
if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S) && speedOne > 0f)
{
speedOne = speedOne - Time.deltaTime * speedTend;
}
if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S) && speedOne < 0f)
{
speedOne = speedOne + Time.deltaTime * speedTend;
}
車輛轉彎:
車輛的轉彎效果,當有了一定的基本速度后,則可以實現轉彎效果,防止原地打轉的效果出現:
//使用A和D來控制物體左右旋轉
if(speedOne>1f) //為了區分邏輯,直接數值表示
{
y = Input.GetAxis("Horizontal") * 60f * Time.deltaTime;
transform.Rotate(0, y, 0);
}
該系統存在問題:
很明顯,車輛轉彎沒有漂移效果,需要進行相應的改進
- 最后附上可執行腳本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarCtrl : MonoBehaviour
{
private float y;
//車輛控制速度參數
private float speedOne = 0f; //車輛實時速度
private float speedMax = 120f; //車輛最大速度
private float speedMin = -20f; //車輛最小速度(倒車最大速度)
private float speedUpA = 2f; //車輛加速加速度(A鍵控制)
private float speedDownS = 4f; //車輛減速加速度(S鍵控制)
private float speedTend = 0.5f; //無操作實時速度趨於0時加速度
private float speedBack = 1f; //車輛倒車加速度
// Update is called once per frame
void Update()
{
//鼠標隱藏
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
//按下W鍵並且速度沒達到最大,則速度增加
if (Input.GetKey(KeyCode.W) && speedOne < speedMax)
{
speedOne = speedOne + Time.deltaTime * speedUpA;
}
//按下S鍵並且速度沒達到零,則速度減小
if (Input.GetKey(KeyCode.S) && speedOne > 0f)
{
speedOne = speedOne - Time.deltaTime * speedDownS;
}
//沒有執行速度操作並且速度大於最小速度,則緩慢操作
if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S) && speedOne > 0f)
{
speedOne = speedOne - Time.deltaTime * speedTend;
}
if (!Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S) && speedOne < 0f)
{
speedOne = speedOne + Time.deltaTime * speedTend;
}
//按下S鍵並且速度沒有達到倒車速度最大時,且車輛處於可以倒車狀態時車輛倒車
if (Input.GetKey(KeyCode.S) && speedOne > speedMax && speedOne<=0)
{
speedOne = speedOne - Time.deltaTime * speedBack;
}
//按下空格,則汽車停止
if (Input.GetKey(KeyCode.Space) && speedOne != 0)
{
speedOne = Mathf.Lerp(speedOne, 0, 0.4f);
if (speedOne < 5) speedOne = 0;
}
transform.Translate(Vector3.forward * speedOne * Time.deltaTime);
//使用A和D來控制物體左右旋轉
if(speedOne>1f)
{
y = Input.GetAxis("Horizontal") * 60f * Time.deltaTime;
transform.Rotate(0, y, 0);
}
/* if (transform.eulerAngles.z != 0)
{
transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0);
}*/
}
}