Скрипт на выстрел сферами, кубами и т.п.

Научился сам? Помоги начинающему.

Скрипт на выстрел сферами, кубами и т.п.

Сообщение orkons 25 авг 2019, 01:58




Скрипт, который позволяет стрелять различными примитивами, просто вешайте на камеру. В инспекторе можно выбрать тип снаряда и также тип полета (полет по физике или сразу появление снаряда в нужной точке). Также есть галочка с настройкой свечения (лапочка) у снарядов (просто по приколу).

Первый скрипт вешайте на камеру, больше ничего не нужно. Со вторым ничего делать не надо, просто положить в проект. Не забудьте назвать файлы по названию скриптов.

Код откомментирован, поэтому также может научить вас пользоваться выстрелами, создавать примитивы (без префабов), настраивать их немного в коде.

Первый. Скрипт выстрела

Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// стеляет снарядами из примитивов, учит создавать примитивы без префабов
/// и выбирать их через enum. тип снаряда выбирается в инспекторе,
/// вешается на камеру.
/// </summary>
public class FoamShootPrim : MonoBehaviour
{
    /// <summary>
    /// Все возможные снаряды
    /// </summary>
    enum TypeShell
    {
        Cube = PrimitiveType.Cube,
        Sphere = PrimitiveType.Sphere,
        Cylinder = PrimitiveType.Cylinder,
        Capsule = PrimitiveType.Capsule,
    }


    /// <summary>
    /// Какой снаряд выбран для стрельбы в данный момент
    /// </summary>
    [SerializeField]
    TypeShell typeShell = TypeShell.Cylinder;

    /// <summary>
    /// Все возможные типы стрельбы
    /// </summary>
    enum TypeShooting { Fly, Teleport }

    /// <summary>
    /// Какой тип стрельбы выбран сейчас (задается в редакторе)
    /// </summary>
    [SerializeField]
    TypeShooting typeShooting = TypeShooting.Fly;

    /// <summary>
    /// камера игрока, откуда пускаем луч (для типа стрельбы Teleport)
    /// </summary>
    private Camera cameraPlayer;

    /// <summary>
    /// Светиться ли снарядам
    /// </summary>
   [SerializeField]
    bool isLuminescent = false;

    void Start()
    {
        //найти камеру
        cameraPlayer = GetComponent<Camera>();
    }

    void Update()
    {
        //если нажата левая кнопка мышки
        if (Input.GetMouseButtonDown(0))
        {
            //стреляем
            Shooting();
        }
    }


    /// <summary>
    /// выстрел, создает объект (снаряд)
    /// </summary>
    private void Shooting()
    {

        //выбираем, какой снаряд создавать
        switch (typeShell)
        {
            case TypeShell.Cube:
                CreateShell(PrimitiveType.Cube);
                break;
            case TypeShell.Sphere:
                CreateShell(PrimitiveType.Sphere);
                break;
            case TypeShell.Cylinder:
                CreateShell(PrimitiveType.Cylinder);
                break;
            case TypeShell.Capsule:
                CreateShell(PrimitiveType.Capsule);
                break;
            default:
                Debug.Log("Поступил некорректный снаряд, выбрана Sphere");
                CreateShell(PrimitiveType.Sphere);
                break;
        }

    }

    /// <summary>
    /// Создает снаряд
    /// </summary>
    /// <param name="shell">тип примитива (снаряда)</param>
    void CreateShell(PrimitiveType shell)
    {

        //выбираем тип стрельбы
        if (typeShooting == TypeShooting.Fly)
        {
            Fly(shell);
        }
        if (typeShooting == TypeShooting.Teleport)
        {
            Teleport(shell);
        }
    }

    void Fly(PrimitiveType shell)
    {

        //создаем примитив снаряда
        GameObject shellInstantiate = GameObject.CreatePrimitive(shell);
        //выставляем ей позицию как у игрока, но на 1 метр вперед, чтобы не цеплялась за его коллайдер
        shellInstantiate.transform.position = transform.position + transform.forward;
        //выставляем градус направления
        shellInstantiate.transform.rotation = transform.rotation;
        //делаем объект физическим
        shellInstantiate.AddComponent<Rigidbody>();
        //добавляем на него скрипт с его поведением
        shellInstantiate.AddComponent<FoamShellPrim>();
        //если надо подсвечивать снаряд
        if (isLuminescent) OnLuminescent(shellInstantiate);
    }

    void Teleport(PrimitiveType shell)
    {
        //определяем центр экрана, откуда стрелять
        Vector3 point = new Vector3(cameraPlayer.pixelWidth / 2, cameraPlayer.pixelHeight / 2, 0);
        //пускаем луч оттуда
        Ray ray = cameraPlayer.ScreenPointToRay(point);
        //сюда сохраним инфу о попадании луча
        RaycastHit hit;
        //если луч куда-то попал
        if (Physics.Raycast(ray, out hit))
        {
            //создаем примитив
            GameObject shellInstantiate = GameObject.CreatePrimitive(shell);
            //переносим в нужное место
            shellInstantiate.transform.position = hit.point;
            //если надо подсвечивать снаряд
            if (isLuminescent) OnLuminescent(shellInstantiate);
        }
    }

    void OnLuminescent (GameObject shellInstantiate)
    {
        //делаем объект маленьким
        shellInstantiate.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
        //добавляем  свечение
        shellInstantiate.AddComponent<Light>();
    }
}

 


Второй (скрипт снаряда)

Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// скрипт для снаряда, прилипающего к коллайдерам, имеет импульс (выстрел)
/// учит пользоваться импульсом и всякой хрени
/// </summary>
public class FoamShellPrim : MonoBehaviour
{

    /// <summary>
    /// скорость полета снаряда
    /// </summary>
    private float speedShell = 15;

    void Start()
    {
        //придать импульс
        GetComponent<Rigidbody>().AddForce(transform.forward * speedShell, ForceMode.Impulse);
    }

    //при соприкосновении прилипнуть (заморозиться)
    private void OnCollisionEnter(Collision collision)
    {
        //игнорируем касания игрока (снаряд от него отскакивает, а не проходит сквозь)
        if (collision.transform.tag != "Player")
        {
            //замораживаем снаряд
            Destroy(gameObject.GetComponent<Rigidbody>());
        }
    }


    // Update is called once per frame
    void Update()
    {

    }
}
 


Новые версии скрипта и прочую инфу буду выкладывать на своем форуме. https://forum.orkons.ru/topic/355-unity ... -prefabov/

П.С. если кто решит проблему установки масштаба при делании снаряда дочерним от объекта, куда он попал (viewtopic.php?f=105&t=50835), то я смогу продолжить работу над кодом и сделать что-то вроде аналога пушки с пеной, как в Prey 2017.
Последний раз редактировалось orkons 25 авг 2019, 02:26, всего редактировалось 1 раз.
Мои заметки по Unity forum.orkons.ru/forum/56-unity-i-s/
Аватара пользователя
orkons
UNец
 
Сообщения: 37
Зарегистрирован: 14 май 2018, 11:09

Re: Скрипт на выстрел сферами, кубами и т.п.

Сообщение orkons 25 авг 2019, 02:00

Буду признателен, если более опытные напишут, как можно улучшить код - упростить или сделать более ООП. В общем за любые замечания по коду - спасибо.
Мои заметки по Unity forum.orkons.ru/forum/56-unity-i-s/
Аватара пользователя
orkons
UNец
 
Сообщения: 37
Зарегистрирован: 14 май 2018, 11:09


Вернуться в Уроки

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1