Unity -車輛控制效果的實現


前言:

  • 無論是專門的賽車游戲、還是像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);
        }*/
    }
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM