124 lines
4.1 KiB
C#
124 lines
4.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Unity.Collections;
|
|
using Unity.Burst;
|
|
using Unity.Jobs;
|
|
using Unity.Mathematics;
|
|
|
|
public class Game : MonoBehaviour
|
|
{
|
|
[SerializeField] private int numBlues;
|
|
[SerializeField] private int numReds;
|
|
[SerializeField] private GameObject bluePrefab;
|
|
[SerializeField] private GameObject redPrefab;
|
|
[SerializeField] private Rect[] areasOfTheMap;
|
|
|
|
private int maxQuadTreeSize;
|
|
private Transform[] blueTransforms;
|
|
private Transform[] redTransforms;
|
|
private NativeArray<float2> bluePositions;
|
|
private NativeArray<float2> redPositions;
|
|
private NativeArray<float4> quadTree;
|
|
private NativeArray<long> nearestEnemyOfBlueIndex;
|
|
private NativeArray<long> nearestEnemyOfRedIndex;
|
|
|
|
public void Start()
|
|
{
|
|
blueTransforms = new Transform[numBlues];
|
|
redTransforms = new Transform[numReds];
|
|
int nearestPowerOf2(int n)
|
|
{
|
|
int a = (int)(Math.Log(n) / Math.Log(2));
|
|
return (int)Math.Pow(2, a) == n
|
|
? n
|
|
: (int)Math.Pow(2, a + 1);
|
|
}
|
|
|
|
maxQuadTreeSize = nearestPowerOf2(numBlues + numReds);
|
|
|
|
// This is actually the size of the max subdivisions
|
|
int maxSubDivisions = 5;
|
|
maxQuadTreeSize = (int)Math.Pow(4, maxSubDivisions);
|
|
|
|
Debug.Log(maxQuadTreeSize);
|
|
void InstantiatePrefabs(int amount, GameObject prefab, Transform[] transforms, Rect area) {
|
|
for (int i = 0; i < amount; i++) {
|
|
var go = GameObject.Instantiate(prefab);
|
|
transforms[i] = go.transform;
|
|
float randX = UnityEngine.Random.Range(area.x, area.x + area.width);
|
|
float randY = UnityEngine.Random.Range(area.y, area.y + area.height);
|
|
go.transform.localPosition = new Vector3(randX, 0, randY);
|
|
}
|
|
};
|
|
InstantiatePrefabs(numBlues, bluePrefab, blueTransforms, areasOfTheMap[0]);
|
|
InstantiatePrefabs(numReds, redPrefab, redTransforms, areasOfTheMap[1]);
|
|
|
|
bluePositions = new NativeArray<float2>(numBlues, Allocator.Persistent);
|
|
redPositions = new NativeArray<float2>(numReds, Allocator.Persistent);
|
|
quadTree = new NativeArray<float4>(maxQuadTreeSize, Allocator.Persistent);
|
|
nearestEnemyOfBlueIndex = new NativeArray<long>(numBlues, Allocator.Persistent);
|
|
nearestEnemyOfRedIndex = new NativeArray<long>(numReds, Allocator.Persistent);
|
|
}
|
|
|
|
float2 Vec3ToF2(Vector3 v) => new float2(v.x, v.z);
|
|
|
|
public void Update()
|
|
{
|
|
int i = 0;
|
|
int min = numBlues > numReds ? numBlues : numReds;
|
|
while (i < min)
|
|
{
|
|
bluePositions[i] = Vec3ToF2(blueTransforms[i].localPosition);
|
|
redPositions[i] = Vec3ToF2(redTransforms[i].localPosition);
|
|
i++;
|
|
}
|
|
while (i < numBlues)
|
|
{
|
|
bluePositions[i] = Vec3ToF2(blueTransforms[i].localPosition);
|
|
i++;
|
|
}
|
|
while (i < numReds)
|
|
{
|
|
redPositions[i] = Vec3ToF2(redTransforms[i].localPosition);
|
|
i++;
|
|
}
|
|
|
|
var constructJob = new ConstructQuadTreeJob
|
|
{
|
|
positions = bluePositions,
|
|
quadTree = quadTree,
|
|
};
|
|
|
|
var constructHandle = constructJob.Schedule(maxQuadTreeSize, 100);
|
|
constructHandle.Complete();
|
|
|
|
var findEnemyJob = new FindNearestEnemyQuadTreeJob
|
|
{
|
|
bluePositions = bluePositions,
|
|
redPositions = redPositions,
|
|
quadTree = quadTree,
|
|
nearestEnemyOfBlueIndex = nearestEnemyOfBlueIndex,
|
|
nearestEnemyOfRedIndex = nearestEnemyOfRedIndex,
|
|
};
|
|
|
|
var findRedsHandle = findEnemyJob.Schedule(numBlues, 100);
|
|
// We don't have a dependency on findRedsHandle, but we do have to wait for both
|
|
// findReds and findBlues to finish
|
|
findRedsHandle.Complete();
|
|
var findBluesHandle = findEnemyJob.Schedule(numReds, 100);
|
|
|
|
findBluesHandle.Complete();
|
|
}
|
|
|
|
public void OnDestroy()
|
|
{
|
|
bluePositions.Dispose();
|
|
redPositions.Dispose();
|
|
quadTree.Dispose();
|
|
}
|
|
|
|
|
|
}
|