Implement EntitySpawnerZone override system
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- Создан скрипт EntitySpawnerZone.cs для выделения зон замены префабов в Unity Editor. - Модифицирован EntitySpawner.cs для поддержки зон при выборе префаба на основе координат точки спавна.
This commit is contained in:
parent
3d1772af15
commit
28f5409187
@ -4937,7 +4937,7 @@ GameObject:
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!4 &314704398255972110
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -4989,7 +4989,7 @@ VisualEffect:
|
||||
- m_Value: {x: 2, y: 0.019583605, z: 0, w: 1}
|
||||
m_Name: ParticleColor
|
||||
m_Overridden: 1
|
||||
- m_Value: {x: 4, y: 0.20000002, z: 0, w: 1}
|
||||
- m_Value: {x: 766.9961, y: 275.83508, z: 0, w: 1}
|
||||
m_Name: ShaderColor
|
||||
m_Overridden: 1
|
||||
m_Uint:
|
||||
@ -5014,7 +5014,7 @@ VFXRenderer:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4081737046539047411}
|
||||
m_Enabled: 1
|
||||
m_Enabled: 0
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
@ -5187,7 +5187,7 @@ VisualEffect:
|
||||
- m_Value: {x: 1, y: 0, z: 0, w: 1}
|
||||
m_Name: ParticleColor
|
||||
m_Overridden: 0
|
||||
- m_Value: {x: 2, y: 0.06666667, z: 0, w: 1}
|
||||
- m_Value: {x: 32, y: 1.0666667, z: 0, w: 1}
|
||||
m_Name: ShaderColor
|
||||
m_Overridden: 1
|
||||
m_Uint:
|
||||
|
||||
@ -227,16 +227,16 @@ namespace RR.Game2D.Behaviour
|
||||
if (!CanSpawn())
|
||||
return null;
|
||||
|
||||
GameObject prefab = PickPrefab();
|
||||
if (prefab == null)
|
||||
return null;
|
||||
|
||||
if (!TryPickSpawnPoint(usedSpawnPointIndices, out Transform spawnPoint))
|
||||
return null;
|
||||
|
||||
Vector3 spawnPosition = spawnPoint != null ? spawnPoint.position : transform.position;
|
||||
Quaternion spawnRotation = spawnPoint != null ? spawnPoint.rotation : transform.rotation;
|
||||
|
||||
GameObject prefab = PickPrefab(spawnPosition);
|
||||
if (prefab == null)
|
||||
return null;
|
||||
|
||||
float zAngle = UnityEngine.Random.Range(randomZRotation.x, randomZRotation.y);
|
||||
spawnRotation *= Quaternion.Euler(0f, 0f, zAngle);
|
||||
|
||||
@ -261,16 +261,31 @@ namespace RR.Game2D.Behaviour
|
||||
return true;
|
||||
}
|
||||
|
||||
private GameObject PickPrefab()
|
||||
private GameObject PickPrefab(Vector3 spawnPosition)
|
||||
{
|
||||
// Проверка, находится ли эта точка спавна внутри какой-либо активной зоны переопределения
|
||||
SpawnPrefabEntry[] activePrefabs = prefabs;
|
||||
for (int i = 0; i < EntitySpawnerZone.ActiveZones.Count; i++)
|
||||
{
|
||||
EntitySpawnerZone zone = EntitySpawnerZone.ActiveZones[i];
|
||||
if (zone != null && zone.IsPointInside(spawnPosition))
|
||||
{
|
||||
activePrefabs = zone.Prefabs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (activePrefabs == null || activePrefabs.Length == 0)
|
||||
return null;
|
||||
|
||||
int totalWeight = 0;
|
||||
|
||||
for (int i = 0; i < prefabs.Length; i++)
|
||||
for (int i = 0; i < activePrefabs.Length; i++)
|
||||
{
|
||||
if (prefabs[i].prefab == null)
|
||||
if (activePrefabs[i].prefab == null)
|
||||
continue;
|
||||
|
||||
totalWeight += Mathf.Max(1, prefabs[i].weight);
|
||||
totalWeight += Mathf.Max(1, activePrefabs[i].weight);
|
||||
}
|
||||
|
||||
if (totalWeight <= 0)
|
||||
@ -279,17 +294,17 @@ namespace RR.Game2D.Behaviour
|
||||
int randomValue = UnityEngine.Random.Range(0, totalWeight);
|
||||
int currentWeight = 0;
|
||||
|
||||
for (int i = 0; i < prefabs.Length; i++)
|
||||
for (int i = 0; i < activePrefabs.Length; i++)
|
||||
{
|
||||
if (prefabs[i].prefab == null)
|
||||
if (activePrefabs[i].prefab == null)
|
||||
continue;
|
||||
|
||||
currentWeight += Mathf.Max(1, prefabs[i].weight);
|
||||
currentWeight += Mathf.Max(1, activePrefabs[i].weight);
|
||||
if (randomValue < currentWeight)
|
||||
return prefabs[i].prefab;
|
||||
return activePrefabs[i].prefab;
|
||||
}
|
||||
|
||||
return prefabs[prefabs.Length - 1].prefab;
|
||||
return activePrefabs[activePrefabs.Length - 1].prefab;
|
||||
}
|
||||
|
||||
private bool TryPickSpawnPoint(HashSet<int> usedSpawnPointIndices, out Transform spawnPoint)
|
||||
|
||||
83
Assets/Scripts/Behaviour/EntitySpawnerZone.cs
Normal file
83
Assets/Scripts/Behaviour/EntitySpawnerZone.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RR.Game2D.Behaviour
|
||||
{
|
||||
[RequireComponent(typeof(Collider2D))]
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class EntitySpawnerZone : MonoBehaviour
|
||||
{
|
||||
[Header("Override Prefabs")]
|
||||
[Tooltip("Список префабов, которые будут спавниться вместо оригинальных префабов спавнера внутри этой зоны.")]
|
||||
[SerializeField] private EntitySpawner.SpawnPrefabEntry[] prefabs;
|
||||
|
||||
private Collider2D _collider;
|
||||
|
||||
// Статический список всех активных зон на сцене для быстрого поиска
|
||||
public static readonly List<EntitySpawnerZone> ActiveZones = new();
|
||||
|
||||
public EntitySpawner.SpawnPrefabEntry[] Prefabs => prefabs;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_collider = GetComponent<Collider2D>();
|
||||
// Убеждаемся, что коллайдер является триггером, чтобы не вызывать физических коллизий с персонажами
|
||||
if (_collider != null)
|
||||
{
|
||||
_collider.isTrigger = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
ActiveZones.Add(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
ActiveZones.Remove(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет, находится ли мировая точка внутри коллайдера зоны.
|
||||
/// </summary>
|
||||
public bool IsPointInside(Vector3 point)
|
||||
{
|
||||
if (_collider == null)
|
||||
{
|
||||
_collider = GetComponent<Collider2D>();
|
||||
}
|
||||
|
||||
return _collider != null && _collider.OverlapPoint(point);
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
if (_collider == null)
|
||||
{
|
||||
_collider = GetComponent<Collider2D>();
|
||||
}
|
||||
|
||||
if (_collider == null) return;
|
||||
|
||||
// Рисуем оранжевую рамку зоны замены в редакторе
|
||||
Gizmos.color = new Color(1f, 0.5f, 0f, 0.2f);
|
||||
|
||||
if (_collider is BoxCollider2D box)
|
||||
{
|
||||
Vector3 position = transform.TransformPoint(box.offset);
|
||||
Vector3 size = Vector3.Scale(box.size, transform.lossyScale);
|
||||
|
||||
Gizmos.DrawCube(position, size);
|
||||
Gizmos.color = new Color(1f, 0.5f, 0f, 0.8f);
|
||||
Gizmos.DrawWireCube(position, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Для других типов коллайдеров рисуем сферу в центре объекта
|
||||
Gizmos.DrawSphere(transform.position, 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Behaviour/EntitySpawnerZone.cs.meta
Normal file
2
Assets/Scripts/Behaviour/EntitySpawnerZone.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5c91a3a7ea71314e9c60d5e48b397d4
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user