Скрипт, который позволяет стрелять различными примитивами, просто вешайте на камеру. В инспекторе можно выбрать тип снаряда и также тип полета (полет по физике или сразу появление снаряда в нужной точке). Также есть галочка с настройкой свечения (лапочка) у снарядов (просто по приколу).
Первый скрипт вешайте на камеру, больше ничего не нужно. Со вторым ничего делать не надо, просто положить в проект. Не забудьте назвать файлы по названию скриптов.
Код откомментирован, поэтому также может научить вас пользоваться выстрелами, создавать примитивы (без префабов), настраивать их немного в коде.
Первый. Скрипт выстрела
Синтаксис:
Используется 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>();
}
}
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()
{
}
}
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.