/// <summary> /// Returns the current max speed of an agent /// </summary> public float MaxSpeed(NavAgent agent) { if (m_agentKinematics == null) { return(agent.configuration.movement.topSpeed); } movingAllAgents.Complete(); int archetypeIndex = archetypes.IndexOf(agent.configuration.archetype); return(m_agentKinematics[archetypeIndex][agent.index].maxSpeed); }
/// <summary> /// Changes the current max speed of an agent /// </summary> public void SetMaxSpeed(NavAgent agent, float maxSpeed) { movingAllAgents.Complete(); int archetypeIndex = archetypes.IndexOf(agent.configuration.archetype); AgentKinematics kinematics = m_agentKinematics[archetypeIndex][agent.index]; kinematics.maxSpeed = maxSpeed; NativeArray <AgentKinematics> agentKinematics = m_agentKinematics[archetypeIndex]; agentKinematics[agent.index] = kinematics; }
//------------------------------------------------- #region Public API /// <summary> /// Initializes the agent manager with an array of agent transforms /// </summary> public virtual void Initialize(Dictionary <NavAgentArchetype, List <Transform> > agents) { Dispose(); // clear any existing memory int configCount = configurations.Count; int archetypeCount = archetypes.Count; // initialize agent movement configurations m_movementTypes = new NativeArray <AgentMovement>(configCount, Allocator.Persistent); for (int i = 0; i < configCount; i++) { m_movementTypes[i] = configurations[i].movement; } // initialize job handle arrays m_updatingHandles = new NativeArray <JobHandle>(archetypeCount, Allocator.Persistent); m_movingByArchetype = new NativeArray <JobHandle>(archetypeCount, Allocator.Persistent); // initialize the agent properties m_agentMovementTypes = new List <NativeArray <int> >(archetypeCount); m_agentBehaviors = new List <NativeArray <AgentBehaviors> >(archetypeCount); m_agentKinematics = new List <NativeArray <AgentKinematics> >(archetypeCount); m_transformAccess = new List <TransformAccessArray>(archetypeCount); m_agentSteering = new List <NativeArray <float3> >(archetypeCount); m_totalAgents = new List <int>(archetypeCount); // initialize the flow field data structures int length = world.size.x * world.size.y * world.size.z; m_flowFields = new List <NativeArray <byte> >(archetypeCount); m_costFields = new List <NativeArray <byte> >(archetypeCount); m_intFields = new List <NativeArray <ushort> >(archetypeCount); m_openNodes = new List <NativeQueue <int3> >(archetypeCount); // cached data to build the flow fields m_targetPositions = new NativeList <int3>(Allocator.Persistent); // initialize each archetype for (int i = 0; i < archetypeCount; i++) { // initialize flow field data for each archetype m_openNodes.Add(new NativeQueue <int3>(Allocator.Persistent)); m_flowFields.Add(new NativeArray <byte>(length, Allocator.Persistent)); m_costFields.Add(new NativeArray <byte>(length, Allocator.Persistent)); m_intFields.Add(new NativeArray <ushort>(length, Allocator.Persistent)); // initialize agent data for each archetype Transform[] transforms = agents[archetypes[i]].ToArray(); int count = transforms.Length; TransformAccessArray transformAccess = new TransformAccessArray(transforms); NativeArray <int> movementTypes = new NativeArray <int>(count, Allocator.Persistent); NativeArray <float3> steering = new NativeArray <float3>(count, Allocator.Persistent); NativeArray <AgentKinematics> kinematics = new NativeArray <AgentKinematics>(count, Allocator.Persistent); NativeArray <AgentBehaviors> behaviors = new NativeArray <AgentBehaviors>(count, Allocator.Persistent); // read agent configuration for (int a = 0; a < count; a++) { NavAgent agent = transforms[a].GetComponent <NavAgent>(); int movementType = configurations.IndexOf(agent.configuration); AgentKinematics agentKinematics = new AgentKinematics(); agentKinematics.maxSpeed = agent.configuration.movement.topSpeed; movementTypes[a] = movementType; kinematics[a] = agentKinematics; } m_agentMovementTypes.Add(movementTypes); m_transformAccess.Add(transformAccess); m_agentKinematics.Add(kinematics); m_agentBehaviors.Add(behaviors); m_agentSteering.Add(steering); m_totalAgents.Add(count); } // initialize the agent spatial map m_spatialMap = new NativeMultiHashMap <int3, SpatialMapData>(m_totalAgents.Sum(), Allocator.Persistent); m_spatialMapWriter = m_spatialMap.AsParallelWriter(); // cache all directions m_directions = new NativeArray <int3>(27, Allocator.Persistent); for (int i = 0; i < 27; i++) { Vector3Int dir = Core.Direction3Int.Directions[i]; m_directions[i] = new int3(dir.x, dir.y, dir.z); } // cache directions for climbable check m_directionsNESW = new NativeArray <int>(4, Allocator.Persistent); m_directionsNESW[0] = 3; m_directionsNESW[1] = 5; m_directionsNESW[2] = 7; m_directionsNESW[3] = 9; // convert blocks to a struct and cache the data byte defaultCost = 1; int blockCount = blockManager.blocks.Count; m_blockTypes = new List <NativeArray <Block> >(); for (int a = 0; a < archetypeCount; a++) { NativeArray <Block> blocks = new NativeArray <Block>( blockCount, Allocator.Persistent); for (int i = 0; i < blockCount; i++) { BlockConfiguration block = blockManager.blocks[i]; int index = archetypes[a].movementCosts .FindIndex(x => x.block == block); Block navBlock = new Block(); if (index == -1) { navBlock.cost = defaultCost; } else { navBlock.cost = archetypes[a] .movementCosts[index].cost; } navBlock.solid = block.collidable; blocks[i] = navBlock; } m_blockTypes.Add(blocks); } }