Ошибка назначения точки стрельбы в Unity
Я пытаюсь сделать игру типа примитивного 2д шутера, как начал делать стрельбу так сразу все на перекосяк пошло, юнити думает, что я не указал позицию начала стрельбы, хотя она указана.
возможно как то пофиксить?
код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
public float speed;
private Vector2 moveVelocity;
public GameObject bullet;
public Transform shotPoint;
public Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Vector2 moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
moveVelocity = moveInput * speed;
Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
transform.eulerAngles = new Vector3(0, 0, Mathf.Rad2Deg * Mathf.Atan2(pos.y, pos.x));
}
void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime);
Instantiate(bullet, shotPoint.position, transform.rotation);
}
}
Ошибка: UnassignedReferenceException: The variable shotPoint of PlayerControler has not been assigned.
Ответы (2 шт):
Во-первых, это ооочень медленно! Запомни, что нельзя в FixedUpdate делать Instantiate из-за того, что это довольно тяжёлый вызов и ты его даже не каждый кадр пытаешься вызвать, а каждый такт!
Во-вторых, если ты хочешь, чтобы твоя пуля летела, на ней должен быть компонент rigidbody2D и коллайдер для столкновений.
В-третьих, пуля должна быть префабом и прокинута в инспектор, там же нужно установить начальную скорость, а в скипте уже непосредственно изменять импульс этой самой Пули созданной. Ты сейчас изменяешь Rigidbody2D своего персонажа, а не пули.
Если есть острая необходимость спаунить пули, то ты можешь выставить временной интервал, например, 1 раз в 60 кадров.
Вот переписанный пример, который я проверил на своей машине:
[SerializeField] private float speed;
[SerializeField] private Vector2 moveVelocity;
[SerializeField] private GameObject bullet;
[SerializeField] private Transform shotPoint;
[SerializeField] private Rigidbody2D rb = null;
// Start is called before the first frame update
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void Update()
{
Vector2 moveInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
moveVelocity = moveInput * speed;
Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
transform.eulerAngles = new Vector3(0, 0, Mathf.Rad2Deg * Mathf.Atan2(pos.y, pos.x));
if (Time.frameCount % 60 == 0)
{
CreateBullet();
}
}
private void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime);
}
private void CreateBullet()
{
var bulletRigidbody2D = Instantiate(this.bullet, shotPoint.position, transform.rotation).GetComponent<Rigidbody2D>();
bulletRigidbody2D.AddForce(bulletRigidbody2D.transform.up * 10, ForceMode2D.Impulse);
}
Ошибка: UnassignedReferenceException: The variable shotPoint of PlayerControler has not been assigned.
UnassignedReferenceException происходит когда объект не назначен полю компонента. Убедитесь что ссылка есть, перейдите в иерархии в сцене или в префабе на объект с PlayerController и назначьте пулю. Убедитесь также что ссылка имеет связь на объект пули из самой сцены(и пулю потом никто не уничтожает) или на префаб пули. Если же PlayerController находится в префабе то ссылка на пулю должна вести только на другой префаб или на объект внутри этого же префаба где и PlayerController.
Также убедитесь что вы не ставили ссылку на пулю в самом скрипте, выбрав файл скрипта и просмотрев инспектор - должно быть пусто во всех параметрах (это значения по умолчанию, вот такой инспектор https://docs.unity3d.com/Manual/class-MonoBehaviour.html#default-object-references)