unity使用jobsystem获取最近的物体

 

using System.Collections.Generic;
using UnityEngine;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;

public class DistanceCheck : MonoBehaviour {
    public List<Transform> monsterList;
    public Transform player;
    
    void Update() {
        var x = JobSystemUtil.FindNearestMonster(monsterList, player.position, 3);
        Debug.Log($"最近的怪物索引: {string.Join(", ", x)}");
    }
}

public class JobSystemUtil {
    
    // 距离结果 + 原始索引
    public struct DistIdx : System.IComparable<DistIdx>
    {
        public float distSq;
        public int index;
        public int CompareTo(DistIdx other) => distSq.CompareTo(other.distSq);
    }

    [BurstCompile]
    public struct ComputeDistJob : IJobFor
    {
        [ReadOnly] public NativeArray<float3> positions;
        public float3 playerPos;
        public NativeArray<DistIdx> outDistIdx;

        public void Execute(int i)
        {
            float3 d = positions[i] - playerPos;
            outDistIdx[i] = new DistIdx
            {
                distSq = math.lengthsq(d), // 用平方距离更快
                index = i
            };
        }
    }
    
    /// <summary>
    /// 获取最近的怪物
    /// </summary>
    public static int[] FindNearestMonster(List<Transform> monsterPosList, Vector3 playerPos, int num)
    {
        int count = monsterPosList.Count;
        if (count == 0 || num <= 0) return System.Array.Empty<int>();
        num = math.min(num, count);

        // 拷贝到 NativeArray(TempJob 适合短生命周期、仅此帧用完的内存)
        var positions = new NativeArray<float3>(count, Allocator.TempJob);
        for (int i = 0; i < count; i++) {
            positions[i] = monsterPosList[i].position;
        }

        var distIdx = new NativeArray<DistIdx>(count, Allocator.TempJob);

        // 1) 并行计算平方距离
        var job = new ComputeDistJob
        {
            positions = positions,
            playerPos = playerPos,
            outDistIdx = distIdx
        };

        // 2) 排序
        job.ScheduleParallel(count, 128, default).Complete();
        distIdx.Sort(); // 单线程、同步

        // 3) 取前 N 个索引
        var result = new int[num];
        for (int i = 0; i < num; i++) result[i] = distIdx[i].index;

        // 释放
        positions.Dispose();
        distIdx.Dispose();

        return result;
    }
}

 

posted @ 2025-08-21 15:33  三页菌  阅读(16)  评论(0)    收藏  举报