- Тип игры: 2D-шутер с видом сверху.
- Цель: создавать эффекты именно в той точке, где луч попадает в коллайдер противника.
- Настройка:
Код: Выделить всё
1. Enemies have 2D colliders. 2. The player shoots rays using Physics2D.Raycast. 3. Effects are spawned using an ObjectPool.
Проблемы с обнаружением попаданий: Рейкаст не регистрирует попадание в том месте, где оно должно. Я проверил, что вражеский слой назначен правильно и что у врагов есть соответствующие 2D-коллайдеры.
Эффект создания: Функция InstantiateHitEffect помещает эффект удара в неправильную позицию (всегда создается в центре врага). Точка попадания теоретически должна быть точной точкой контакта на коллайдере, но кажется, что это не так.
Отладка и журналы: Я добавил журналы, чтобы проверить hit.point, вектор направления и маска слоя. Результат соответствует ожиданиям, но проблема остается.
Пул объектов: Настройка пула объектов проверена и работает, и я могу подтвердить, что все правильно. префабы создаются.
Рассмотрены потенциальные проблемы:
Проблемы с точностью: Интересно если есть проблема с точностью чисел с плавающей запятой, но расстояния довольно малы, поэтому это кажется маловероятным.
Настройка коллайдера: Может ли проблема быть связана с тем, как на врагов установлены коллайдеры? Это стандартные 2D-коллайдеры, и проблем с их обнаружением быть не должно.
Маска слоя: Вражеский слой настроен так, чтобы включать только вражеские коллайдеры, и Я проверял эту настройку несколько раз.
Скриншоты:
Я включил скриншоты, показывающие настройку сцены, настройки инспектора для соответствующих игровых объектов. и консоль регистрируется во время проблемы. Это обеспечит визуальный контекст, позволяющий лучше понять проблему.
Зеленая линия — это то место, куда я целюсь, а синяя линия — то место, где движок обнаруживает попадание и активирует эффекты частиц.
Пример установки вражеского коллайдера
Код: Выделить всё
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerShooting : MonoBehaviour
{
public GameObject hitEffectPrefab;
public GameObject bulletEffectPrefab;
public Transform particleSpawnPoint;
public float shootingRange = 5f;
public LayerMask enemyLayer;
public float fireRate = 1f;
public int damage = 10;
private Transform targetEnemy;
private float nextFireTime = 0f;
private ObjectPool objectPool;
private void Start()
{
objectPool = FindObjectOfType();
if (objectPool == null)
{
Debug.LogError("ObjectPool not found in the scene. Ensure an ObjectPool component is present and active.");
}
}
private void Update()
{
DetectEnemies();
if (targetEnemy != null)
{
if (Time.time >= nextFireTime)
{
ShootAtTarget();
nextFireTime = Time.time + 1f / fireRate;
}
}
}
private void DetectEnemies()
{
RaycastHit2D hit = Physics2D.Raycast(particleSpawnPoint.position, particleSpawnPoint.up, shootingRange, enemyLayer);
if (hit.collider != null)
{
targetEnemy = hit.collider.transform;
}
else
{
targetEnemy = null;
}
}
private void ShootAtTarget()
{
if (targetEnemy == null)
{
Debug.LogError("targetEnemy is null");
return;
}
Vector3 direction = (targetEnemy.position - particleSpawnPoint.position).normalized;
Debug.Log($"Shooting direction: {direction}");
RaycastHit2D hit = Physics2D.Raycast(particleSpawnPoint.position, direction, shootingRange, enemyLayer);
if (hit.collider != null)
{
BaseEnemy enemy = hit.collider.GetComponent();
if (enemy != null)
{
enemy.TakeDamage(damage);
}
// Debug log to check hit point
Debug.Log($"Hit point: {hit.point}, Enemy: {hit.collider.name}");
// Visual effect for bullet movement
InstantiateBulletEffect("BulletEffect", particleSpawnPoint.position, hit.point);
// Visual effect at point of impact
InstantiateHitEffect("HitEffect", hit.point);
}
else
{
Debug.Log("Missed shot.");
}
}
private void InstantiateBulletEffect(string tag, Vector3 start, Vector3 end)
{
GameObject bulletEffect = objectPool.GetObject(tag);
if (bulletEffect != null)
{
bulletEffect.transform.position = start;
TrailRenderer trail = bulletEffect.GetComponent();
if (trail != null)
{
trail.Clear(); // Clear the trail data to prevent old trail artifacts
}
bulletEffect.SetActive(true);
StartCoroutine(MoveBulletEffect(bulletEffect, start, end));
}
else
{
Debug.LogError($"{tag} effect is null. Check ObjectPool settings and prefab assignment.");
}
}
private void InstantiateHitEffect(string tag, Vector3 position)
{
GameObject hitEffect = objectPool.GetObject(tag);
if (hitEffect != null)
{
Debug.Log($"Setting hit effect position to: {position}");
hitEffect.transform.position = position;
hitEffect.SetActive(true);
}
else
{
Debug.LogError($"{tag} effect is null. Check ObjectPool settings and prefab assignment.");
}
}
private IEnumerator MoveBulletEffect(GameObject bulletEffect, Vector3 start, Vector3 end)
{
float duration = 0.1f; // Adjust this to match the speed of your bullet visual effect
float time = 0;
while (time < duration)
{
bulletEffect.transform.position = Vector3.Lerp(start, end, time / duration);
time += Time.deltaTime;
yield return null;
}
bulletEffect.transform.position = end;
bulletEffect.SetActive(false);
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, shootingRange);
Gizmos.color = Color.green;
Gizmos.DrawLine(particleSpawnPoint.position, particleSpawnPoint.position + particleSpawnPoint.up * shootingRange);
}
public void IncreaseDamage(int amount)
{
damage += amount;
}
public void IncreaseFireRate(float amount)
{
fireRate += amount;
}
public void IncreaseBulletRange(float amount)
{
shootingRange += amount;
}
}
Эффект создания: Функция InstantiateHitEffect помещает эффект удара в неправильную позицию (всегда создается в центре врага). Точка попадания теоретически должна быть точной точкой контакта на коллайдере, но кажется, что это не так.
Отладка и журналы: Я добавил журналы, чтобы проверить hit.point, вектор направления и маска слоя. Результат соответствует ожиданиям, но проблема остается.
Пул объектов: Настройка пула объектов проверена и работает, и я могу подтвердить, что все правильно. префабы создаются.
Подробнее здесь: https://stackoverflow.com/questions/788 ... ty-2d-game