批量生成点

This commit is contained in:
2025-06-04 14:53:27 +08:00
parent 23e665f34c
commit c468c8b070
20 changed files with 294 additions and 310 deletions
@@ -47,7 +47,7 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 7c34fc3623b6a734d9a5968c521705a2
- m_GUID: 001714d99df8eb54fbf2bd671e6d557c
m_Address: "Sprite/\u7A97\u5916\u4F69\u4F69_Idle"
m_ReadOnly: 0
m_SerializedLabels: []
@@ -85,7 +85,7 @@ SpriteRenderer:
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
m_SpriteSortPoint: 1
--- !u!95 &6457534782112409331
Animator:
serializedVersion: 5
@@ -85,7 +85,7 @@ SpriteRenderer:
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
m_SpriteSortPoint: 1
--- !u!95 &5713582559052699558
Animator:
serializedVersion: 5
@@ -119,3 +119,17 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 01207e7e956b485d92b0112694380ce2, type: 3}
m_Name:
m_EditorClassIdentifier:
mobileObjectData:
itemName:
direction: {x: 0, y: 0}
speed: {x: 0, y: 0}
mobileType: 0
assetAddressArray: []
offset: {x: 0, y: 0}
sortingLayerId: 0
sortingOrder: 0
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 0
isFlip: 0
@@ -84,7 +84,7 @@ SpriteRenderer:
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
m_SpriteSortPoint: 1
--- !u!114 &4941759007155669797
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -84,7 +84,7 @@ SpriteRenderer:
m_SpriteTileMode: 0
m_WasSpriteAssigned: 0
m_MaskInteraction: 0
m_SpriteSortPoint: 0
m_SpriteSortPoint: 1
--- !u!114 &5190809509878527953
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -97,3 +97,17 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 74c3f049f89f4a70abbb5147c676bbb1, type: 3}
m_Name:
m_EditorClassIdentifier:
mobileObjectData:
itemName:
direction: {x: 0, y: 0}
speed: {x: 0, y: 0}
mobileType: 0
assetAddressArray: []
offset: {x: 0, y: 0}
sortingLayerId: 0
sortingOrder: 0
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 0
isFlip: 0
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7c34fc3623b6a734d9a5968c521705a2
guid: 001714d99df8eb54fbf2bd671e6d557c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
@@ -72,7 +72,7 @@ TextureImporter:
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
textureCompression: 2
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
+13 -9
View File
@@ -477,15 +477,19 @@ MonoBehaviour:
m_PostInfinity: 2
m_RotationOrder: 4
_filter:
- 0.007228916
- 0.043749984
- 0.12409639
- 0.20444278
- 0.24096388
- 0.20444278
- 0.12409639
- 0.043749984
- 0.007228916
- 0.0048309183
- 0.016401261
- 0.04532712
- 0.08293076
- 0.12053438
- 0.14946026
- 0.1610306
- 0.14946026
- 0.12053438
- 0.08293076
- 0.04532712
- 0.016401261
- 0.0048309183
--- !u!114 &-6101378415725230565
MonoBehaviour:
m_ObjectHideFlags: 3
@@ -797,7 +797,7 @@ Transform:
m_GameObject: {fileID: 3439365558513550950}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.38999987, y: 0.14, z: 0}
m_LocalPosition: {x: -8.71, y: -0.86, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
+22 -189
View File
@@ -174,32 +174,33 @@ MonoBehaviour:
mobileType: 2
assetAddressArray:
- "Mobile/\u5361\u8F66"
offset: {x: 0, y: 0}
sortingLayerId: 0
sortingOrder: 0
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 1
isFlip: 0
flipX: 1
flipY: 0
- itemName: "\u8F7F\u8F66"
direction: {x: 1, y: 0}
speed: {x: 7, y: 7}
mobileType: 2
assetAddressArray:
- "Mobile/\u8F7F\u8F66"
offset: {x: 0, y: 0}
sortingLayerId: 0
sortingOrder: 0
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 4
isFlip: 0
flip: 1
flipX: 1
flipY: 0
isDistanceMode: 1
existTime: 0
existDistance: 30
isFixedInterval: 0
fixedInterval: 0
intervalRange: {x: 7, y: 12}
--- !u!1001 &146077693
PrefabInstance:
@@ -527,20 +528,19 @@ MonoBehaviour:
mobileType: 1
assetAddressArray:
- "Mobile/\u76F8\u9519\u5217\u8F66\u50CF\u7D20\u7248"
offset: {x: 0, y: 0}
sortingLayerId: 941243827
sortingOrder: 1
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 1
isFlip: 0
flip: 0
flipX: 0
flipY: 0
isDistanceMode: 1
existTime: 0
existDistance: 50
isFixedInterval: 1
fixedInterval: 12
intervalRange: {x: 0, y: 0}
intervalRange: {x: 12, y: 12}
--- !u!1 &519420028
GameObject:
m_ObjectHideFlags: 0
@@ -1370,90 +1370,6 @@ MonoBehaviour:
- time: 2
weather: 0
sprite: {fileID: 21300000, guid: f3d7c9920c5ea194f95c24032be0f550, type: 3}
--- !u!1 &869492462
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 869492463}
- component: {fileID: 869492464}
m_Layer: 0
m_Name: "\u4F69\u4F69\u5929\u6865"
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!4 &869492463
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 869492462}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.595865, y: -0.13008846, z: 0.31335288}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1921397711}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &869492464
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 869492462}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 1905855335
m_SortingLayer: 2
m_SortingOrder: 0
m_Sprite: {fileID: 4145790568345934211, guid: aaa4b1e0109a1ea4389a36252af080b2, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 17.860466, y: 10.046512}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &979077029
GameObject:
m_ObjectHideFlags: 0
@@ -1616,19 +1532,18 @@ MonoBehaviour:
- "Mobile/\u8DEF\u4EBA\u4E2D_C"
- "Mobile/\u8DEF\u4EBA\u4E2D_D"
- "Mobile/\u8DEF\u4EBA\u4E2D_E"
offset: {x: 0, y: 0}
sortingLayerId: 941243827
sortingOrder: 15
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 1
isFlip: 0
flip: 1
flipX: 1
flipY: 0
isDistanceMode: 1
existTime: 0
existDistance: 22
isFixedInterval: 0
fixedInterval: 0
intervalRange: {x: 10, y: 12}
--- !u!1 &1131434708
GameObject:
@@ -7047,19 +6962,18 @@ MonoBehaviour:
- "Mobile/\u8DEF\u4EBA\u4E2D_C"
- "Mobile/\u8DEF\u4EBA\u4E2D_D"
- "Mobile/\u8DEF\u4EBA\u4E2D_E"
offset: {x: 0, y: 0}
sortingLayerId: 941243827
sortingOrder: 15
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 1
isFlip: 0
flip: 0
flipX: 0
flipY: 0
isDistanceMode: 1
existTime: 0
existDistance: 22
isFixedInterval: 0
fixedInterval: 0
intervalRange: {x: 10, y: 12}
--- !u!1 &1348121181
GameObject:
@@ -7112,32 +7026,33 @@ MonoBehaviour:
mobileType: 2
assetAddressArray:
- "Mobile/\u5361\u8F66"
offset: {x: 0, y: 0}
sortingLayerId: 0
sortingOrder: 0
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 1
isFlip: 0
flipX: 0
flipY: 0
- itemName: "\u8F7F\u8F66"
direction: {x: -1, y: 0}
speed: {x: 7, y: 7}
mobileType: 2
assetAddressArray:
- "Mobile/\u8F7F\u8F66"
offset: {x: 0, y: 0}
sortingLayerId: 0
sortingOrder: 0
isDistanceMode: 0
existTime: 0
existDistance: 0
weight: 4
isFlip: 0
flip: 0
flipX: 0
flipY: 0
isDistanceMode: 1
existTime: 0
existDistance: 30
isFixedInterval: 0
fixedInterval: 0
intervalRange: {x: 7, y: 12}
--- !u!1 &1475389257
GameObject:
@@ -8191,37 +8106,6 @@ Transform:
m_Children: []
m_Father: {fileID: 467680739}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1828825569
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1828825570}
m_Layer: 0
m_Name: Slot
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1828825570
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1828825569}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: -5, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1882541513
GameObject:
m_ObjectHideFlags: 0
@@ -8358,55 +8242,6 @@ Transform:
m_Children: []
m_Father: {fileID: 467680739}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1921397710
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1921397711}
- component: {fileID: 1921397712}
m_Layer: 0
m_Name: ActorManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1921397711
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1921397710}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -1.595865, y: 0.15334429, z: -0.31335288}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 869492463}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1921397712
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1921397710}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 40a5ab0dc89da0f469155caebeaf7383, type: 3}
m_Name:
m_EditorClassIdentifier:
slotList:
- {fileID: 1246487451}
- {fileID: 725363607}
- {fileID: 686675859}
--- !u!1 &1950680461
GameObject:
m_ObjectHideFlags: 0
@@ -9208,8 +9043,6 @@ SceneRoots:
- {fileID: 519420032}
- {fileID: 731494688}
- {fileID: 467680739}
- {fileID: 1921397711}
- {fileID: 370776970}
- {fileID: 1828825570}
- {fileID: 2057334823}
- {fileID: 1131434710}
+1 -64
View File
@@ -168,7 +168,6 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 239528928}
- component: {fileID: 239528929}
m_Layer: 0
m_Name: "\u4E2D\u666F\u623F\u5C4B\u751F\u6210\u70B9"
m_TagString: Untagged
@@ -191,26 +190,6 @@ Transform:
m_Children: []
m_Father: {fileID: 234809509}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &239528929
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 239528927}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 36a82fb65d2d45a8a6ce391835134c22, type: 3}
m_Name:
m_EditorClassIdentifier:
mobileObjectDatas: []
flip: 0
isDistanceMode: 1
existTime: 0
existDistance: 0
isFixedInterval: 1
fixedInterval: 0
intervalRange: {x: 0, y: 0}
--- !u!1 &419009314
GameObject:
m_ObjectHideFlags: 0
@@ -251,7 +230,6 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 571835745}
- component: {fileID: 571835746}
m_Layer: 0
m_Name: "\u524D\u666F\u623F\u5C4B\u751F\u6210\u70B9"
m_TagString: Untagged
@@ -274,26 +252,6 @@ Transform:
m_Children: []
m_Father: {fileID: 234809509}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &571835746
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 571835744}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 36a82fb65d2d45a8a6ce391835134c22, type: 3}
m_Name:
m_EditorClassIdentifier:
mobileObjectDatas: []
flip: 0
isDistanceMode: 1
existTime: 0
existDistance: 0
isFixedInterval: 1
fixedInterval: 0
intervalRange: {x: 0, y: 0}
--- !u!1 &858196761
GameObject:
m_ObjectHideFlags: 0
@@ -535,7 +493,6 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 1999162657}
- component: {fileID: 1999162658}
m_Layer: 0
m_Name: "\u680F\u6746\u751F\u6210\u70B9"
m_TagString: Untagged
@@ -558,26 +515,6 @@ Transform:
m_Children: []
m_Father: {fileID: 234809509}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1999162658
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1999162656}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 36a82fb65d2d45a8a6ce391835134c22, type: 3}
m_Name:
m_EditorClassIdentifier:
mobileObjectDatas: []
flip: 0
isDistanceMode: 1
existTime: 0
existDistance: 0
isFixedInterval: 1
fixedInterval: 0
intervalRange: {x: 0, y: 0}
--- !u!1 &78306667790355118
GameObject:
m_ObjectHideFlags: 0
@@ -1393,7 +1330,7 @@ Transform:
m_GameObject: {fileID: 4689508665021410824}
serializedVersion: 2
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.930233, y: -1.4883721, z: 0}
m_LocalPosition: {x: 1.930233, y: -1.5, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
@@ -4,13 +4,15 @@ using System.Linq;
namespace AibisDream.Framework
{
public class RandomSelector<T>
public class RandomSelector<T> : ISelector<T>
{
private readonly List<T> _items;
private readonly List<int> _prefixSums;
private readonly int _totalWeight;
private readonly Random _random;
public int Count => _items.Count;
public RandomSelector(IEnumerable<T> items, Func<T, int> weightSelector)
{
if (items == null) throw new ArgumentNullException(nameof(items));
@@ -70,4 +72,96 @@ namespace AibisDream.Framework
return left;
}
}
public class BatchSelector<T> : ISelector<T>
{
private readonly List<T> _items;
private readonly List<int> _batchWeight;
private readonly int _totalWeight;
private readonly Random _random;
private int _currentWeight;
private List<int> _curBatchWeight;
public int Count => _totalWeight;
public BatchSelector(IEnumerable<T> items, Func<T, int> weightSelector)
{
if (items == null) throw new ArgumentNullException(nameof(items));
if (weightSelector == null) throw new ArgumentNullException(nameof(weightSelector));
var itemList = items.ToList();
_items = new List<T>(itemList.Count);
int sum = 0;
foreach (var item in itemList)
{
int weight = weightSelector(item);
if (weight < 0)
throw new ArgumentException("Weights cannot be negative", nameof(items));
if (weight > 0)
{
sum += weight;
_batchWeight.Add(weight);
_items.Add(item);
}
}
_totalWeight = sum;
_currentWeight = sum;
_random = new Random();
if (_totalWeight == 0)
{
// 出错了
throw new InvalidOperationException("All weights are zero");
}
}
public T Select()
{
// 如果已经抽完就重置
if (_currentWeight == 0)
{
ResetSelector();
}
int randomValue = _random.Next(0, _currentWeight);
int index = BinarySearch(randomValue);
// 选择后减去权重
_currentWeight -= 1;
_curBatchWeight[index] -= 1;
return _items[index];
}
private void ResetSelector()
{
_currentWeight = _totalWeight;
_curBatchWeight = new List<int>(_batchWeight);
}
private int BinarySearch(int value)
{
var sum = 0;
for (var i = 0; i < _curBatchWeight.Count; i++)
{
sum += _curBatchWeight[i];
if (sum >= value)
{
return i;
}
}
return _curBatchWeight.Count - 1;
}
}
public interface ISelector<out T>
{
T Select();
int Count { get; }
}
}
@@ -20,7 +20,8 @@ namespace AibisDream
_spriteRenderer.sortingLayerID = mobileObjectData.sortingLayerId;
_spriteRenderer.sortingOrder = mobileObjectData.sortingOrder;
_spriteRenderer.flipX = mobileObjectData.isFlip;
_spriteRenderer.flipX = mobileObjectData.flipX;
_spriteRenderer.flipY = mobileObjectData.flipY;
}
protected override void Dispose()
@@ -0,0 +1,56 @@
using System.Collections;
using System.Collections.Generic;
using AibisDream.Framework;
using UnityEngine;
namespace AibisDream
{
public class BatchSpawner : Spawner
{
[SerializeField] private Vector2 batchInterval;
private bool _isSpawning;
protected override ISelector<MobileObjectData> CreateSelector(IEnumerable<MobileObjectData> datas)
{
return new BatchSelector<MobileObjectData>(datas, item => item.weight);
}
protected override void OnUpdate()
{
if (_isSpawning) return;
curInterval += Time.deltaTime;
// 按时间间隔生成物体
if (curInterval >= targetInterval)
{
Spawn();
curInterval = 0;
targetInterval = Random.Range(intervalRange.x, intervalRange.y);
}
}
protected override void Spawn()
{
StartCoroutine(SpawnCoroutine());
}
private IEnumerator SpawnCoroutine()
{
_isSpawning = true;
for (var i = 0; i < selector.Count; i++)
{
// 生成物体
var data = selector.Select();
var mobileObj = factory.CreateMobileObject(data);
mobileObjects.Add(mobileObj);
// 销毁时同样记录
mobileObj.OnDisposed += o => mobileObjects.Remove(o);
var interval = Random.Range(batchInterval.x, batchInterval.y);
yield return new WaitForSeconds(interval);
}
_isSpawning = false;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6f8dbbddeadc43158db470f2e9bb1a09
timeCreated: 1749011126
@@ -90,8 +90,9 @@ namespace AibisDream
[HideInInspector] public float existDistance;
public int weight;
public bool isFlip;
public bool flipX;
public bool flipY;
}
public enum MobileType
@@ -13,7 +13,9 @@ namespace AibisDream
var spriteAsset = ResourceKit.LoadAssetSync<GameObject>(RandomSelectAddress());
_childObject = Instantiate(spriteAsset, transform);
_childObject.transform.localScale = mobileObjectData.isFlip ? new Vector3(-1, 1, 1) : Vector3.one;
var scaleX = mobileObjectData.flipX ? -1 : 1;
var scaleY = mobileObjectData.flipY ? -1 : 1;
_childObject.transform.localScale = new Vector3(scaleX, scaleY, 1);
}
protected override void Dispose()
@@ -7,75 +7,99 @@ namespace AibisDream
public class Spawner : MonoBehaviour
{
[SerializeField] private MobileObjectData[] mobileObjectDatas;
[SerializeField] private bool flip;
[SerializeField] private bool isDistanceMode = true;
[SerializeField] private float existTime;
[SerializeField] private float existDistance;
[SerializeField] protected Vector2 intervalRange;
[SerializeField] private bool isFixedInterval = true;
[SerializeField] private float fixedInterval;
[SerializeField] private Vector2 intervalRange;
private RandomSelector<MobileObjectData> _selector;
private MobileObjectFactory _factory;
protected ISelector<MobileObjectData> selector;
protected MobileObjectFactory factory;
public readonly List<AbsMobileObject> mobileObjects = new();
private float _curInterval;
private float _targetInterval;
protected float curInterval;
protected float targetInterval;
public void Awake()
private void Awake()
{
Init();
}
private void Init()
{
// 先为Data赋一些公共值
var newMobileDatas = new List<MobileObjectData>();
var newMobileDatas = SetPublicVariable();
// 处理随机权重
selector = CreateSelector(newMobileDatas);
// 创建工厂
factory = new MobileObjectFactory(transform);
// 收集初始物体
CollectDefaultMobiles();
// 间隔归零
curInterval = 0;
targetInterval = Random.Range(intervalRange.x, intervalRange.y);
// 生成第一个物体
Spawn();
}
protected virtual ISelector<MobileObjectData> CreateSelector(IEnumerable<MobileObjectData> datas)
{
return new RandomSelector<MobileObjectData>(datas, data => data.weight);
}
private List<MobileObjectData> SetPublicVariable()
{
var res = new List<MobileObjectData>();
foreach (var temp in mobileObjectDatas)
{
var dataItem = temp;
dataItem.isFlip = flip;
dataItem.isDistanceMode = isDistanceMode;
dataItem.existTime = existTime;
dataItem.existDistance = existDistance;
newMobileDatas.Add(dataItem);
res.Add(dataItem);
}
// 处理随机权重
_selector = new RandomSelector<MobileObjectData>(newMobileDatas, data => data.weight);
// 创建工厂
_factory = new MobileObjectFactory(transform);
return res;
}
private void CollectDefaultMobiles()
{
// 为工厂收集一些初始物体
var initObjects = GetComponentsInChildren<AbsMobileObject>();
_factory.AddRecycleMobiles(initObjects);
factory.AddRecycleMobiles(initObjects);
foreach (var initObject in initObjects)
{
initObject.Init();
mobileObjects.Add(initObject);
initObject.OnDisposed += o => mobileObjects.Remove(o);
}
// 间隔归零
_curInterval = 0;
_targetInterval = isFixedInterval ? fixedInterval : Random.Range(intervalRange.x, intervalRange.y);
// 生成第一个物体
Spawn();
}
public void Update()
private void Update()
{
_curInterval += Time.deltaTime;
OnUpdate();
}
protected virtual void OnUpdate()
{
curInterval += Time.deltaTime;
// 按时间间隔生成物体
if (_curInterval >= _targetInterval)
if (curInterval >= targetInterval)
{
Spawn();
_curInterval = 0;
_targetInterval = isFixedInterval ? fixedInterval : Random.Range(intervalRange.x, intervalRange.y);
curInterval = 0;
targetInterval = Random.Range(intervalRange.x, intervalRange.y);
}
}
private void Spawn()
protected virtual void Spawn()
{
// 生成物体
var data = _selector.Select();
var mobileObj = _factory.CreateMobileObject(data);
var data = selector.Select();
var mobileObj = factory.CreateMobileObject(data);
mobileObjects.Add(mobileObj);
// 销毁时同样记录
mobileObj.OnDisposed += o => mobileObjects.Remove(o);
@@ -18,7 +18,8 @@ namespace AibisDream
_spriteRenderer.sortingLayerID = mobileObjectData.sortingLayerId;
_spriteRenderer.sortingOrder = mobileObjectData.sortingOrder;
_spriteRenderer.flipX = mobileObjectData.isFlip;
_spriteRenderer.flipX = mobileObjectData.flipX;
_spriteRenderer.flipY = mobileObjectData.flipY;
}
protected override void Dispose()