  .       Unity
 


     -       ? -   :     Pursuit (,  ,  ,    )      .   ,   - ,    ,   ,    .      ,  ,  ,    ;    ,    -       -.  -      ..       ,     -     .





 

  .       Unity



Table of Contents







    ,             .  -,    ,        ,    .

  :   ,       ,       ,  ,  .    . -   ,     SDK,      ,   .       :       , , ,   .

     ,    .   Pursuit (      Petrol Pursuit,         Pursuit)   :     ,  ,       ,      .       ,        .   :  https://sciencepub.ru/carcasual/ (https://sciencepub.ru/carcasual/)       .  ,    ,       ,  .








. .1. Pursuit  : , ,    .

       ? ,    ,    ,   .  Pursuit       :  ,    ,   ,     .           .

      :         Deep Space,       .       :   .                 ,      .

  :

     :  Unity,       .           .

    :        , , ,  .      .

    :     , ,     .   .

    : ,            ,   .

     :  ,         .

     :   ,       .

   :           .

      -: ,  , , -    ,     .

   :     , ,              .

     :    -,           ,  ,    .

   :   WebGL-,     .  ,         .

:        Pursuit      .              ;  :  https://sciencepub.ru/carcasual/ (https://sciencepub.ru/carcasual/)        .

:        Unity.    ,     :    .

,   ,     ,    . -   ,      ,        :   ,      .         , ,     .

!




 1.  : Unity   



     ,    .







     :          .   Unity,   Pursuit,     Play.        ,      ,   .




1.1  Unity Hub  


Unity    :  Unity Hub   -,       ,      .

 Unity Hub    https://unity.com/download (https://unity.com/download)   .



 Hub     Unity (     ).          Unity Personal.

  Installs  Install Editor     Unity 6 LTS         6000.3.18f1.      6000.3.x.

    WebGL Build Support          .     .

:        .          .




1.2  


 Pursuit   (               ,     ).

    .        ,  C:\Games\Pursuit  ~/Games/Pursuit.



 Unity Hub   Projects  Add ? Add project from disk    .    ,    Assets, Packages  ProjectSettings.

    .     : Unity    Library    .         .

:  Library, Temp  Logs   .     ,             : Unity   .




1.3   









. 1.1.  Unity   Pursuit:  Hierarchy,   Scene   ,  Inspector   ,  Project.

   Unity   :   ,   - .       ,       .         .

Hierarchy ()     .      : , , , , .      :   Unity      .

Scene ( )   .  ,       ,      .    ;      .

Game (   Scene)   :  ,    .         .

Inspector ()   .    Hierarchy          .     ,   :     ,     ,   .        .

Project ()    : , , , , .     Assets,   .

   ,     : Console (Window ? General ? Console).  ,      ,     .     ,  Play   ,           .

    Scene.    .      , ,   ,    WASD,   .          F,   . Alt         . ,      .

   ,  ,     .    Project  Assets/Scenes/Game.unity.

 Hierarchy   GameWorld    newRoads.  Inspector   Road Controller   ,    : Road Length 14, Despawn Offset 30, Spawn Offset 42, Despawn Distance 56.   Pursuit ,      ,    .        .



  carPrefab    player_purple    .     : Rigidbody (   , , ), Box Collider ( ,    ), Car Controller (  )  Obstacle (Script) ( ; ,         ).

 F   Scene   .    Game    Scene:     ,   .

    :   Hierarchy    Inspector.       ,     .

:      ,   ,     ,  .         ,    : Window ? Layouts ? Default.                .

:   Menu    Hierarchy  ButtonPlay (    play,   -).  ButtonPlay      Button,      On Click ().   ,   :     ,   Play     ,     .




1.4    


    Project      .      Assets:

Scenes    ,     ;       .

Scripts    :     C#.           .

Player, Road, Obstacle     ,   .

Meshtint Free City Lite Pack Mega Toon, 48 Particle Effect Pack, 2D Casual UI, Vehicle_Essentials   :  ,  ,        (         carSound.wav   Audio).    :     ,    .

Audio  : , , .

YandexGame  WebGLTemplates   PluginYG    .;      .

Editor     WebGL (   ).




1.5  


  .

  Project  Assets/Scenes/Menu.unity  .



  Play  .     (. 1.2).

 Play    .     WASD:   ,       .    :    ,   ,    .

          Game Over   .     .








. 1.2.   Pursuit: Play, Garage, Options.

:       .      ( Garage  )    .          .

:        Play.   ,  ,           Unity  .    :      Play     .







Unity   Unity Hub;      Unity 6 LTS   WebGL Build Support.

   Add project from disk;    Assets, Packages, ProjectSettings.

Library   ,        .

    : Hierarchy (   ), Scene ( ), Game ( ), Inspector ( ), Project ( );   Console    Window ? General ? Console.

         Assets/Scenes  Assets/Scripts;       .

        Play;    Play  .

:        ,     ,   .        Pursuit:             .




 2.  :   



     ,  .   ,  .







        , ,     Pursuit      .  Unity    :       ,   .           .




2.1   Pursuit


  Assets/Scenes:

Menu   :  Play, Garage, Options.

Game   :    .

HardGame   :     .

Garage      .

GameOver      .

SampleScene   -   Unity;    ,     (        ).

  :       ;     ;       (     );       .  .




2.2   : MenuController


       MenuController.cs      SceneManager  Menu:

using UnityEngine;



using UnityEngine.SceneManagement;





publicclass MenuController : MonoBehaviour



{



public void PlayGame()



{



SceneManager.LoadScene("Game"); //   "Game"



}





public void OpenGarage()



{



SceneManager.LoadScene("Garage"); //   "Garage"



}



public void OpenMenu()



{



SceneManager.LoadScene("Menu"); //   "Menu"



}



}

     : SceneManager.LoadScene("")      .  :    .    .       :  "Game"    ,   .           (File ? Build Profiles ? Scene List),       .

      ?           On Click ()  Button:      ,      .    UI  Unity:   ,   ,    .

         ,      .  ButtonGarage   MenuController.OpenGarage.    Play    MenuController:   On Click   GarageManager (,      )   StartGame   ,       :  ,   ,     .  MenuController.PlayGame(),     ,       ,     .   ButtonOptions    :       .        ;      .








. 2.1.   ButtonPlay:   On Click ()  MenuController  GarageManager.StartGame.

:       Hard,     .      MenuController  LoadScene("HardGame")    Play    On Click        MenuController ,  .         Options:      .




2.3    


        GameManager.cs.     :

publicclass GameManager : MonoBehaviour



{



publicstatic GameManager instance;





public Button PauseButton;



public Button ResumeButton;



public Button ExitButton;



private bool isPaused = false;





private void Awake()



{



instance = this;



}





public void PauseGame()



{



Time.timeScale = 0;



isPaused = true;



PauseButton.gameObject.SetActive(false);



ResumeButton.gameObject.SetActive(true);



}





public void ResumeGame()



{



Time.timeScale = 1;



isPaused = false;



PauseButton.gameObject.SetActive(true);



ResumeButton.gameObject.SetActive(false);



}



}

   .

.  public static GameManager instance   instance = this  Awake()     :         GameManager.instance,     .     ,  .

  . Time.timeScale = 0    :  , Time.deltaTime  , ,  ,  . timeScale = 1   .       .

: Time.timeScale   ,    .     (GameOver(), ExitMenu())    timeScale = 1:        .   ,      .




2.4   : GameUI


           .     GameUI.cs:

publicclass GameUI : MonoBehaviour



{



private void Awake()



{



GameManager gameManager = GameManager.instance;



Transform gameUI = transform;



gameManager.PauseButton = gameUI.Find("Button_Pause").GetComponent<Button>();



gameManager.ResumeButton = gameUI.Find("Button_Resume").GetComponent<Button>();



gameManager.ExitButton = gameUI.Find("Button_Exit").GetComponent<Button>();





//     



gameManager.PauseButton.onClick.AddListener(gameManager.PauseGame);



gameManager.ResumeButton.onClick.AddListener(gameManager.ResumeGame);



gameManager.ExitButton.onClick.AddListener(gameManager.ExitMenu);



}



}

transform.Find("")     ,  onClick.AddListener()        ,   On Click  ,   .   ,        .

      ,    . ,     GameUI.cs. :              .       Pause, Resume  ExitMenu     GameManager  ,    .     Button_Pause, Button_Resume, Button_Exit       :        NullReferenceException   Awake.   ,     ,       ,    .   ,   PlayGame():       ,     ,     .

:     (Find("Button_Pause"))   ,     :         ,    .         .







    ;     SceneManager.LoadScene("").

        (File ? Build Profiles ? Scene List).

GameManager  :      GameManager.instance.

   Time.timeScale = 0;    1   .

        On Click  ;   (AddListener)   GameUI.cs  -,    .

:        ,   .     :              ,      .




 3.  :  



          ,   .







CarController.cs        :    ,  ,    ,      .          .       ,  .      Unity-:   Start/Update,  Rigidbody   .




3.1 :  


publicclass CarController : MonoBehaviour



{



//  Rigidbody    



private Rigidbody rb;





//   



public float forwardSpeed = 10.0f;





//      Z



private float zLimitMin = 1.25f;



private float zLimitMax = 4.75f;





//    



private float fuelAmount = 40f;





//        



public TMPro.TextMeshProUGUI fuelText;



public TMPro.TextMeshProUGUI distanceText;





private Vector3 startPosition;



private float distanceTraveled = 0f;



private bool isMoving = false;



private bool isGameOver = false;



private AudioSource carSound;








. 3.1.     : Box Collider, Rigidbody (Collision Detection  Continuous Dynamic)  Car Controller       HUD.

     public  private.   Unity       ,   :  forwardSpeed      HUD    .    :  ,  , .

     ,     .   Pursuit    X ,   Z          zLimitMin  zLimitMax.      Z (   Unity),    X      (, , )   .    :              zLimitMin  zLimitMax,      .       .    :       +X,   Z. ,     .




3.2 Start: 


void Start()



{



rb = GetComponent<Rigidbody>();



fuelText.text = "Fuel: " + fuelAmount;



distanceText.text = "Distance: " + distanceTraveled;



startPosition = transform.position;





//     AudioSource



carSound = GameObject.Find("CarSound").GetComponent<AudioSource>();



}

Start()   ,     ,     .       Rigidbody (     ),           CarSound   .

: GameObject.Find("CarSound")       .         null,      carSound     NullReferenceException.         Unity-;      ,    API.




3.3 FixedUpdate: 


     Update(),   FixedUpdate():

void FixedUpdate()



{



//    



float horizontalAxis = Input.GetAxis("Horizontal");



float verticalAxis = Input.GetAxis("Vertical");





//   



Vector3 movement = new Vector3(verticalAxis, 0.0f, -horizontalAxis)



* forwardSpeed * Time.deltaTime;





//     Z ( )



float newPosZ = Mathf.Clamp(transform.position.z + movement.z,



zLimitMin, zLimitMax);



movement.z = newPosZ - transform.position.z;





//   



isMoving = (movement != Vector3.zero);





//    Rigidbody 



rb.MovePosition(rb.position + transform.TransformDirection(movement));

  .

 FixedUpdate? Update()      30,  144   ,  .    Unity     (  50   ),  ,   Rigidbody,    FixedUpdate()       .

 . Input.GetAxis("Vertical")      :    W  ,   S  .    "Horizontal"   /.  :     ,      ,  .

 .      X (/    ?),       Z ().   forwardSpeed  ,   Time.deltaTime       :    ,      .

  . Mathf.Clamp(, , )   Z   :       ,     .             .

  . rb.MovePosition(...)      :   ,  .       ,           transform.position,      .




3.4 :   


//      



Collider[] fuelCans = Physics.OverlapSphere(transform.position, 1.0f);



foreach (Collider fuelCan in fuelCans)



{



if (fuelCan.CompareTag("FuelCan"))



{



fuelAmount += 10f;



fuelText.text = "Fuel: " + fuelAmount;



Destroy(fuelCan.gameObject);



}



}





//       



if (isMoving)



{



fuelAmount -= Time.deltaTime;



fuelText.text = "Fuel: " + Mathf.Round(fuelAmount).ToString();



}

    Physics.OverlapSphere:        ,     ,  .    :        FuelCan,      +10    (Destroy).

   :   ,    Time.deltaTime        .    .    :  40    40  ,     10.

:     (  Tag   )    CompareTag     ,    fuelCan.tag == "FuelCan".




3.5    


//    



if ((fuelAmount <= 0 || isGameOver) && !isGameOver)



{



isGameOver = true;



carSound.Stop();





if (fuelAmount <= 0)



{



SceneManager.LoadScene("GameOver");



}



}





//   



if (isMoving)



{



Vector3 currentPos = transform.position;



float dx = currentPos.x - startPosition.x;



if (dx >= 0)



{



distanceTraveled += dx;



}



startPosition = currentPos;



distanceText.text = "Distance: " + Mathf.Round(distanceTraveled).ToString();



}

   (fuelAmount <= 0 || isGameOver) && !isGameOver:         isGameOver,    || isGameOver     . ? . ? .     ,      :        .    ,   ,   ,     if (fuelAmount <= 0 && !isGameOver).

  :    ,     X    (dx),          .  ,   ,  .

      ,    ?  PlayerPrefs      ,     ,   :

PlayerPrefs.SetFloat("lastPosX", distanceTraveled);

     FixedUpdate()       . ? . ?  :         . PlayerPrefs      ,       .        .

   :         ,    .  carSound.Stop()   ,       .







       X,     Z;   Mathf.Clamp.

,   Rigidbody,   FixedUpdate();    Time.deltaTime.

rb.MovePosition     ;    transform.position  .

 : Physics.OverlapSphere +   CompareTag + Destroy.

     PlayerPrefs;       .

GameObject.Find     :      .

:   ,     .     :           .        .




 4.  



   ,   .    .







      ,    ,     .    :    .    ,   ,           .       RoadController.cs,     .




4.1    


   Game:   GameWorld/roads        , ,     ,  .     .      newRoads   RoadController     ,  .

publicclass RoadController : MonoBehaviour



{



private Transform playerTransform;



public GameObject roadPrefab;



public float roadLength = 50f;



public float despawnOffset = -30f;



public float spawnOffset = 80f;



public float despawnDistance = 100f;



private List<GameObject> roads = new List<GameObject>();





private void Start()



{



playerTransform = GameObject.FindGameObjectWithTag("Player").transform;



Spawn();



}

 :  -,       ,   .      Unity:       .    roadLength = 50,       14     14.       ;    .       ,       .




4.2 Spawn:   


private void Spawn()



{



GameObject gameObject = Instantiate(roadPrefab);



gameObject.transform.position = roads.Count == 0



? Vector3.zero



: roads[roads.Count - 1].transform.position + Vector3.right * roadLength;



roads.Add(gameObject);



}

Instantiate()     :     .     ,      ,    roadLength  X (Vector3.right   (1, 0, 0);    = X?).       ,   ,     Instantiate     .




4.3 Update:  


private void Update()



{



//    



if (playerTransform.position.x >



roads[roads.Count - 1].transform.position.x - spawnOffset)



{



Spawn();



}





//  ,  



for (int i = 0; i < roads.Count; i++)



{



if (playerTransform.position.x - roads[i].transform.position.x



> despawnDistance)



{



Destroy(roads[i]);



roads.RemoveAt(i);



i--;



}



}



}

 ,  .

   .        ,   spawnOffset,   .      :      .

   . ,    ,   despawnDistance, .   ,    :      .    RemoveAt(i),              ,    .  i--  .         ,    C#.

:       :       ,  Unity    .  : ,     ,   .

 :    .   RoadController.cs          despawnOffset (   : -30).    :    despawnOffset  30,       ,   (  despawnDistance = 56)     .       ,   ,    ,   ,     ;       .




4.4    


      newRoads      :

roadLength   .      ,       .

spawnOffset    .        ,   ;       .

despawnDistance     .   20  ,  ( ), ,     .

:   spawnOffset = 5      .      .         :     ,  Subway Surfers  Temple Run.




4.5 :   


     ,     ,     .    CameraController.cs:

publicclass CameraController : MonoBehaviour



{



public Vector3 offset;



public float smoothSpeed = 0.125f;





void FixedUpdate()



{



GameObject player = GameObject.FindGameObjectWithTag("Player");



if (player != null)



{



Transform target = player.transform;



Vector3 desiredPosition = target.position + offset;



Vector3 smoothedPosition = Vector3.Lerp(transform.position,



desiredPosition, smoothSpeed);



transform.position = smoothedPosition;





transform.LookAt(target);



}



}



}

 :         offset ( :    ),  Vector3.Lerp       smoothSpeed   :   ,   . LookAt    .    :   smoothSpeed = 0.125,     0.9       .        0.10.2   .

:   GameObject.FindGameObjectWithTag     :          ,    .         Start()   ,   RoadController.      ,      .







    :     ,     .

Instantiate()    ;     .

       .

           (i--).

,    ,         .

   Lerp   ;        Start(),    .

:     .       ,  .        :  ,     .




 5. :   



        .







    .   :    ,  ,  .       ,     : ObstacleManager  , ObstacleMovement  ,     Collision.cs          .




5.1 ObstacleManager:   


publicclass ObstacleManager : MonoBehaviour



{



public GameObject[] obstaclePrefabs;



public float obstacleSpeed = 5f;



public float spawnDistance = 40f;



public float spawnOffset = 30f;



public float despawnDistance = 80f;





private GameObject player;



private float lastPlayerPosition;



private float currentDistance;





void Update()



{



currentDistance = player.transform.position.x - lastPlayerPosition;





if (currentDistance >= spawnDistance)



{



lastPlayerPosition = player.transform.position.x;





for (float spawnPosX = lastPlayerPosition + spawnOffset;



spawnPosX <= lastPlayerPosition + currentDistance;



spawnPosX += spawnDistance)



{



SpawnObstacle(new Vector3(spawnPosX, 1.4f, 1.7f));



}





DestroyObstacles(player.transform.position.x - despawnDistance);



}



}

         :       .   spawnDistance = 40,    Game   Obstacle  35 (  spawnOffset 25  30  despawnDistance 35  80)     ,       .   :     




  .


   .

   ,     (https://www.litres.ru/book/raznoe/gonka-kak-konstruktor-soberi-i-opublikui-svoiu-igru-na-unity-74323734/)  .

      Visa, MasterCard, Maestro,    ,   ,     ,  PayPal, WebMoney, ., QIWI ,       .


