Почему Instantiate иногда создаёт объект не в том месте?
Создаю шутер от первого лица, пули создаю как GameObjectы , не как RayCastы.
Есть строка :
GameObject BulletObj = Instantiate(Bullet, BulletSpawnPoint.position, Quaternion.identity) as GameObject;
Префаб Bullet с нулевой позицией, BulletSpawnPoint стоит там, где надо и никуда не съезжает , но пуля создаётся немного выше места, где должна бы , при этом периодически появляется там ,где надо, а периодически ещё выше , чем обычно(ровно в два раза выше обычно высокого места). Если персонаж идёт - пули снова на своём верном месте , по мере поворота камеры вверх пули будут появляться всё ближе к нужному месту( если смотреть точно в небо - пули будут там ,где и должны). Вся проблема была в скрипте с автоматом , а скрипт пистолета почти дублирует его, поэтому я решил осмотреть разницу - её нет, продублировал сам пистолет - и появилась точно та же проблема(возможно как-то случайно пофиксил её на пистолете раньше и забыл , но смысл в том,что существуют два идентичных пистолета, при этом один багованный, а один- нет). Какие-то манипуляции с положением автомата относительно персонажа не помогли, перемещение BulletSpawnPoint относительно автомата тоже не повлияли. Все строки, кроме instantiate закомментировал ( чтобы пуля просто оставалась на месте, где создалась) - всё равно появляется выше. Учитывая все эти факты, что может быть проблемой и что стоит попробовать?
Уверен, что проблема в том, что коллайдер пистолета выталкивает коллайдер пули. Это можно проверить в редакторе создав пулю в месте её спавна, а затем, выбрав одновременно пистолет и пулю, посмотреть, не сталкиваются ли их коллайдеры. Проблему можно решить двумя путями:
1) Переместить точку выстрела туда, где точно нет коллайдеров
2) Отменить коллизию. Для этого нужно создать два Layer - для пистолета и пули, затем в Edit/Project Settings/Physics в самом низу есть схема коллизий. Там нужно снять одну галочку, между слоем пули и слоем пистолета.
Если это не помогло, пришлите скрипт оружия и скрипт (если такой есть) пули в комментарий к этому сообщению, посмотрим, мб там что-то влияет.
У оружия коллайдера нет в принципе. К тому же при первом касании коллайдера пуля уничтожается.
У пули пытался полностью отключить скрипт - не повлияло ни на что, полностью комментировал и скрипт оружия( кроме строки Instantiate ) - эффекта тоже не было. Зато, как я уже писал чуть выше, проблема прошла, когда перезапустил unity , при этом при создании нового оружия - появляется на нём
Тут скрипт пистолета :
public class Pistol : MonoBehaviour
{
[SerializeField] private GameObject Bullet;
[SerializeField] private Camera PlayerCam;
[SerializeField] private bool AddBulletSpread = true;
private Vector3 BulletSpread = new Vector3(0.05f, 0.05f, 0.05f);
[SerializeField] private ParticleSystem ShootingParticle;
[SerializeField] private Transform BulletSpawnPoint;
private float Range = 10000f;
[SerializeField] private LayerMask IgnorePlayer;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (transform.parent != null)
{
if (transform.parent.gameObject.layer == 3)
{
Shoot();
}
}
}
}
private void Shoot()
{
Instantiate(ShootingParticle, BulletSpawnPoint);
Vector3 BulletDirection = PlayerCam.transform.forward;
BulletDirection = GetDirection();
Physics.Raycast(PlayerCam.transform.position, BulletDirection, out RaycastHit hit, Range, IgnorePlayer);
GameObject BulletObj = Instantiate(Bullet, BulletSpawnPoint.position, Quaternion.identity) as GameObject;
Debug.DrawRay(BulletSpawnPoint.position, BulletDirection * 100f, Color.red);
BulletObj.GetComponent().hit = hit;
BulletObj.GetComponent().BulletDirection = BulletDirection;
BulletObj.GetComponent().Shooter = gameObject;
BulletObj.GetComponent().StartPosition = PlayerCam.transform.position;
BulletObj.GetComponent().velocity = (hit.point - BulletSpawnPoint.position).normalized * 15;
}
public class Bullet : MonoBehaviour
{
public float BulletDamage = 10f;
public ParticleSystem ImpactParticle;
public RaycastHit hit;
public Vector3 StartPosition;
public Vector3 BulletDirection;
private int ShotObjectLayer=10;
private int NormalLayer;
[SerializeField] private LayerMask ShotObject;
public GameObject Shooter;
//public GameObject Shooter;
Ещё замечу, что делал DrawRay по совету человека повыше - опять же рисуется луч из точки, которая явно выше оружия. В самом коде пока что есть несколько временных костылей для простоты проверки работоспособности, поэтому сложно читаться будет, наверное
Cheezy_one, попробуйте создать новую пустую сцену, поместить туда оружие и затестить его работу там с выключенным скриптом Bullet на пуле. Если и так будут проблемы, нужно переписать код. Если всё ок, попробовать снова пострелять, но включив Bullet на пуле. Проблемы - смотрите там. Нет проблем - значит есть что-то на сцене, что может мешать.
PS. Мне сложно сказать по вашему коду что не так (явной причины быть пуле не там я не вижу), потому что там есть вещь, которая в принципе не должна давать возможность код запускать. Например, вот тут: BulletObj.GetComponent().hit = hit;
Проблема в том, что такой вызов GetComponent() вообще не поддерживается.
Там есть три варианта:
// норм
BulletObj.GetComponent<Bullet>().hit = hit;
// в принципе тоже норм
BulletObj.GetComponent(typeof(Bullet)).hit = hit;
// норм, но не очень
BulletObj.GetComponent("Bullet").hit = hit;
Я просто оставлю это здесь в надежде, что вам это пригодится:
Мимокрокодил, Насчёт нерабочего кода - я не заметил при копировании, почему-то просто пропала часть , хотя она там, естественно, везде есть. Спасибо за советы, попробую протестировать предложенные Вами варианты, если ничего не получится - постараюсь выкрутиться как-то иначе, но ,опять же, спасибо за уделённое время
Попробуй использовать отрисовку через RayCast и посмотри на поведение луча.
И вообще лучше делать подобные вещи через рейкаст чем спавнить объекты по сцене...
private Ray _ray;
Debug.DrawRay(_ray.origin, _ray.direction * _maxDistanceRay, Color.red);
Если я правильно понял, через RayCast придётся урон делать одновременно с выстрелом, что мне не особо понравилось, а ещё пули могут друг друга сбить, что я решил добавить к себе, поэтому делаю через GameObject. Насчёт совета - луч рисуется не из того места( а из того, где появляется пуля). Случайно выяснил, что перезапуск unity фиксит баг, но если создаю новый пистолет/автомат, то они снова будут багованные (до следующего перезапуска)
Как я уже написал - нулевая, при этом периодически спавнится там, где и должна , а также при любом движении её положение становится правильным( этого бы не происходило, будь у меня ошибка в префабе)