void GenerateArgumentPermutations(StateData stateData, NativeList <ActionKey> argumentPermutations) { var AgentFilter = new NativeArray <ComponentType>(2, Allocator.Temp) { [0] = ComponentType.ReadWrite <Generated.AI.Planner.StateRepresentation.Agent>(), [1] = ComponentType.ReadWrite <Unity.AI.Planner.DomainLanguage.TraitBased.Location>(), }; var CollectibleFilter = new NativeArray <ComponentType>(2, Allocator.Temp) { [0] = ComponentType.ReadWrite <Unity.AI.Planner.DomainLanguage.TraitBased.Location>(), [1] = ComponentType.ReadWrite <Generated.AI.Planner.StateRepresentation.Collectible>(), }; var AgentObjectIndices = new NativeList <int>(2, Allocator.Temp); stateData.GetTraitBasedObjectIndices(AgentObjectIndices, AgentFilter); var CollectibleObjectIndices = new NativeList <int>(2, Allocator.Temp); stateData.GetTraitBasedObjectIndices(CollectibleObjectIndices, CollectibleFilter); var AgentBuffer = stateData.AgentBuffer; var CollectibleBuffer = stateData.CollectibleBuffer; for (int i0 = 0; i0 < AgentObjectIndices.Length; i0++) { var AgentIndex = AgentObjectIndices[i0]; var AgentObject = stateData.TraitBasedObjects[AgentIndex]; if (!(AgentBuffer[AgentObject.AgentIndex].Ammo < 5)) { continue; } for (int i1 = 0; i1 < CollectibleObjectIndices.Length; i1++) { var CollectibleIndex = CollectibleObjectIndices[i1]; var CollectibleObject = stateData.TraitBasedObjects[CollectibleIndex]; if (!(CollectibleBuffer[CollectibleObject.CollectibleIndex].Provides == Consumable.Ammo)) { continue; } if (!(CollectibleBuffer[CollectibleObject.CollectibleIndex].Active == true)) { continue; } var actionKey = new ActionKey(k_MaxArguments) { ActionGuid = ActionGuid, [k_AgentIndex] = AgentIndex, [k_CollectibleIndex] = CollectibleIndex, }; argumentPermutations.Add(actionKey); } } AgentObjectIndices.Dispose(); CollectibleObjectIndices.Dispose(); AgentFilter.Dispose(); CollectibleFilter.Dispose(); }
public static unsafe void CollideAndIntegrate( CharacterControllerStepInput stepInput, float characterMass, bool affectBodies, Unity.Physics.Collider *collider, ref RigidTransform transform, ref float3 linearVelocity, ref NativeStream.Writer deferredImpulseWriter, NativeList <StatefulCollisionEvent> collisionEvents = default, NativeList <StatefulTriggerEvent> triggerEvents = default) { // Copy parameters float deltaTime = stepInput.DeltaTime; float3 up = stepInput.Up; PhysicsWorld world = stepInput.World; float remainingTime = deltaTime; float3 newPosition = transform.pos; quaternion orientation = transform.rot; float3 newVelocity = linearVelocity; float maxSlopeCos = math.cos(stepInput.MaxSlope); const float timeEpsilon = 0.000001f; for (int i = 0; i < stepInput.MaxIterations && remainingTime > timeEpsilon; i++) { NativeList <SurfaceConstraintInfo> constraints = new NativeList <SurfaceConstraintInfo>(k_DefaultConstraintsCapacity, Allocator.Temp); // Do a collider cast { float3 displacement = newVelocity * remainingTime; NativeList <ColliderCastHit> triggerHits = default; if (triggerEvents.IsCreated) { triggerHits = new NativeList <ColliderCastHit>(k_DefaultQueryHitsCapacity / 4, Allocator.Temp); } NativeList <ColliderCastHit> castHits = new NativeList <ColliderCastHit>(k_DefaultQueryHitsCapacity, Allocator.Temp); CharacterControllerAllHitsCollector <ColliderCastHit> collector = new CharacterControllerAllHitsCollector <ColliderCastHit>( stepInput.RigidBodyIndex, 1.0f, ref castHits, world, triggerHits); ColliderCastInput input = new ColliderCastInput() { Collider = collider, Orientation = orientation, Start = newPosition, End = newPosition + displacement }; world.CastCollider(input, ref collector); // Iterate over hits and create constraints from them for (int hitIndex = 0; hitIndex < collector.NumHits; hitIndex++) { ColliderCastHit hit = collector.AllHits[hitIndex]; CreateConstraint(stepInput.World, stepInput.Up, hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, math.dot(-hit.SurfaceNormal, hit.Fraction * displacement), stepInput.SkinWidth, maxSlopeCos, ref constraints); } // Update trigger events if (triggerEvents.IsCreated) { UpdateTriggersSeen(stepInput, triggerHits, triggerEvents, collector.MinHitFraction); } } // Then do a collider distance for penetration recovery, // but only fix up penetrating hits { // Collider distance query NativeList <DistanceHit> distanceHits = new NativeList <DistanceHit>(k_DefaultQueryHitsCapacity, Allocator.Temp); CharacterControllerAllHitsCollector <DistanceHit> distanceHitsCollector = new CharacterControllerAllHitsCollector <DistanceHit>( stepInput.RigidBodyIndex, stepInput.ContactTolerance, ref distanceHits, world); { ColliderDistanceInput input = new ColliderDistanceInput() { MaxDistance = stepInput.ContactTolerance, Transform = transform, Collider = collider }; world.CalculateDistance(input, ref distanceHitsCollector); } // Iterate over penetrating hits and fix up distance and normal int numConstraints = constraints.Length; for (int hitIndex = 0; hitIndex < distanceHitsCollector.NumHits; hitIndex++) { DistanceHit hit = distanceHitsCollector.AllHits[hitIndex]; if (hit.Distance < stepInput.SkinWidth) { bool found = false; // Iterate backwards to locate the original constraint before the max slope constraint for (int constraintIndex = numConstraints - 1; constraintIndex >= 0; constraintIndex--) { SurfaceConstraintInfo constraint = constraints[constraintIndex]; if (constraint.RigidBodyIndex == hit.RigidBodyIndex && constraint.ColliderKey.Equals(hit.ColliderKey)) { // Fix up the constraint (normal, distance) { // Create new constraint CreateConstraintFromHit(world, hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, hit.Distance, stepInput.SkinWidth, out SurfaceConstraintInfo newConstraint); // Resolve its penetration ResolveConstraintPenetration(ref newConstraint); // Write back constraints[constraintIndex] = newConstraint; } found = true; break; } } // Add penetrating hit not caught by collider cast if (!found) { CreateConstraint(stepInput.World, stepInput.Up, hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, hit.Distance, stepInput.SkinWidth, maxSlopeCos, ref constraints); } } } } // Min delta time for solver to break float minDeltaTime = 0.0f; if (math.lengthsq(newVelocity) > k_SimplexSolverEpsilonSq) { // Min delta time to travel at least 1cm minDeltaTime = 0.01f / math.length(newVelocity); } // Solve float3 prevVelocity = newVelocity; float3 prevPosition = newPosition; SimplexSolver.Solve(remainingTime, minDeltaTime, up, stepInput.MaxMovementSpeed, constraints, ref newPosition, ref newVelocity, out float integratedTime); // Apply impulses to hit bodies and store collision events if (affectBodies || collisionEvents.IsCreated) { CalculateAndStoreDeferredImpulsesAndCollisionEvents(stepInput, affectBodies, characterMass, prevVelocity, constraints, ref deferredImpulseWriter, collisionEvents); } // Calculate new displacement float3 newDisplacement = newPosition - prevPosition; // If simplex solver moved the character we need to re-cast to make sure it can move to new position if (math.lengthsq(newDisplacement) > k_SimplexSolverEpsilon) { // Check if we can walk to the position simplex solver has suggested var newCollector = new CharacterControllerClosestHitCollector <ColliderCastHit>(constraints, world, stepInput.RigidBodyIndex, 1.0f); ColliderCastInput input = new ColliderCastInput() { Collider = collider, Orientation = orientation, Start = prevPosition, End = prevPosition + newDisplacement }; world.CastCollider(input, ref newCollector); if (newCollector.NumHits > 0) { ColliderCastHit hit = newCollector.ClosestHit; // Move character along the newDisplacement direction until it reaches this new contact { Assert.IsTrue(hit.Fraction >= 0.0f && hit.Fraction <= 1.0f); integratedTime *= hit.Fraction; newPosition = prevPosition + newDisplacement * hit.Fraction; } } } // Reduce remaining time remainingTime -= integratedTime; // Write back position so that the distance query will update results transform.pos = newPosition; } // Write back final velocity linearVelocity = newVelocity; }
private static void UpdateTriggersSeen <T>(CharacterControllerStepInput stepInput, NativeList <T> triggerHits, NativeList <StatefulTriggerEvent> currentFrameTriggerEvents, float maxFraction) where T : struct, IQueryResult { var world = stepInput.World; for (int i = 0; i < triggerHits.Length; i++) { var hit = triggerHits[i]; if (hit.Fraction > maxFraction) { continue; } var found = false; for (int j = 0; j < currentFrameTriggerEvents.Length; j++) { var triggerEvent = currentFrameTriggerEvents[j]; if ((triggerEvent.EntityB == hit.Entity) && (triggerEvent.ColliderKeyB.Value == hit.ColliderKey.Value)) { found = true; break; } } if (!found) { currentFrameTriggerEvents.Add(new StatefulTriggerEvent(world.Bodies[stepInput.RigidBodyIndex].Entity, hit.Entity, stepInput.RigidBodyIndex, hit.RigidBodyIndex, ColliderKey.Empty, hit.ColliderKey)); } } }
public static void DifferenceSorted <T>(this NativeArray <T> a, ref NativeArray <T> b, ref NativeList <T> resultCapacityOfA) where T : struct, IComparable <T> { var i = 0; var j = 0; while (i < a.Length && j < b.Length) { if (a[i].CompareTo(b[j]) < 0) { resultCapacityOfA.Add(a[i]); i++; } else if (b[j].CompareTo(a[i]) < 0) { j++; } else { i++; j++; } } while (i < a.Length) { resultCapacityOfA.Add(a[i]); ++i; } }
private void OnEnable() { RenderMeshes = new QuadTerrainRenderMesh[9]; Planes = new NativeArray <float4>(6, Allocator.Persistent); RenderNodes = new NativeList <RenderNode>(Allocator.Persistent); }
// Start is called before the first frame update void Start() { var areaMeasurement = new AreaMeasurement() { V0 = this.V0, V1 = this.V1, V2 = this.V2, V3 = this.V3 }; var measure = areaMeasurement.Measure(); _width = measure.x; _height = measure.y; var activeSamples = new NativeList <float2>(Allocator.TempJob); var results = new NativeList <float2>(Allocator.TempJob); var cellSize = _radius / math.sqrt(2); var gridWidth = (int)math.ceil(_width / cellSize); var gridHeight = (int)math.ceil(_height / cellSize); var gridArray = new NativeArray <float2>(gridWidth * gridHeight, Allocator.TempJob); for (var i = 0; i < gridArray.Length; i++) { gridArray[i] = new float2(float.MinValue, float.MinValue); } var poissonDiscSampler = new PoissonDiscSampler() { // Area Parameters Width = _width, Height = _height, Radius = _radius, CellSize = cellSize, RandomSeed = _randomSeed, // Grid Parameters GridWidth = gridWidth, GridHeight = gridHeight, GridArray = gridArray, // Origin and angle Origin = new float2(V0.position.x, V0.position.z), // Sample and Results ActiveSamples = activeSamples, Result = results }; var handle = poissonDiscSampler.Schedule(); handle.Complete(); Debug.Log($"Length of result is: {results.Length}"); for (int i = 0; i < results.Length; i++) { var sampleSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sampleSphere.transform.position = new Vector3(results[i].x, 0, results[i].y); sampleSphere.transform.localScale = Vector3.one * _sphereSize; } activeSamples.Dispose(); results.Dispose(); gridArray.Dispose(); }
internal PickupKeyAction(NativeList <StateEntityKey> statesToExpand, StateDataContext stateDataContext) { m_StatesToExpand = statesToExpand.AsDeferredJobArray(); m_StateDataContext = stateDataContext; }
public static unsafe void Solve( sfloat deltaTime, sfloat minDeltaTime, float3 up, sfloat maxVelocity, NativeList <SurfaceConstraintInfo> constraints, ref float3 position, ref float3 velocity, out sfloat integratedTime, bool useConstraintVelocities = true ) { // List of planes to solve against (up to 4) SurfaceConstraintInfo *supportPlanes = stackalloc SurfaceConstraintInfo[4]; int numSupportPlanes = 0; sfloat remainingTime = deltaTime; sfloat currentTime = sfloat.Zero; // Clamp the input velocity to max movement speed ClampToMaxLength(maxVelocity, ref velocity); while (remainingTime > sfloat.Zero) { int hitIndex = -1; sfloat minCollisionTime = remainingTime; // Iterate over constraints and solve them for (int i = 0; i < constraints.Length; i++) { if (constraints[i].Touched) { continue; } SurfaceConstraintInfo constraint = constraints[i]; float3 relVel = velocity - (useConstraintVelocities ? constraint.Velocity : float3.zero); sfloat relProjVel = -math.dot(relVel, constraint.Plane.Normal); if (relProjVel < k_Epsilon) { continue; } // Clamp distance to 0, since penetration is handled by constraint.Velocity already sfloat distance = math.max(constraint.Plane.Distance, sfloat.Zero); if (distance < minCollisionTime * relProjVel) { minCollisionTime = distance / relProjVel; hitIndex = i; } } // Integrate { currentTime += minCollisionTime; remainingTime -= minCollisionTime; position += minCollisionTime * velocity; } if (hitIndex < 0 || currentTime > minDeltaTime) { break; } // Mark constraint as touched { var constraint = constraints[hitIndex]; constraint.Touched = true; constraints[hitIndex] = constraint; } // Add the hit to the current list of active planes supportPlanes[numSupportPlanes] = constraints[hitIndex]; if (!useConstraintVelocities) { supportPlanes[numSupportPlanes].Velocity = float3.zero; } numSupportPlanes++; // Solve support planes ExamineActivePlanes(up, supportPlanes, ref numSupportPlanes, ref velocity); // Clamp the solved velocity to max movement speed ClampToMaxLength(maxVelocity, ref velocity); // Can't handle more than 4 support planes if (numSupportPlanes == 4) { break; } } integratedTime = currentTime; }
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { var renderEntities = new NativeList <RenderElement>(Allocator.Temp); var batchSpans = new NativeList <BatchedSpanElement>(Allocator.Temp); // Flat map the batch of render elements to a single array. int startIndex = 0; for (int i = 0; i < Batches.Length; i++) { var currentBatch = Batches[i].Elements; for (int j = 0; j < currentBatch.Length; j++) { var uiElement = currentBatch[j]; var uiEntity = conversionSystem.GetPrimaryEntity(uiElement); renderEntities.Add(new RenderElement { Value = uiEntity }); } batchSpans.Add(new int2(startIndex, currentBatch.Length)); startIndex += currentBatch.Length; } // Build the material property batch by only taking the first element of the BatchedElements. // This is due to the first elementing being representative of the entire batch. var propertyBatch = new MaterialPropertyBatch { Value = new MaterialPropertyBlock[Batches.Length] }; for (int i = 0; i < Batches.Length; i++) { var block = new MaterialPropertyBlock(); if (Batches[i].Elements[0].TryGetComponent(out Image image)) { var texture = image.sprite != null ? image.sprite.texture : Texture2D.whiteTexture; block.SetTexture(ShaderIDConstants.MainTex, texture); for (int k = 0; k < Batches[i].Elements.Length; k++) { var associativeEntity = conversionSystem.GetPrimaryEntity(Batches[i].Elements[k]); dstManager.AddComponentData(associativeEntity, new MaterialPropertyIndex { Value = (ushort)i }); } } propertyBatch.Value[i] = new MaterialPropertyBlock(); } dstManager.AddComponentData(entity, propertyBatch); unsafe { var renderBatches = dstManager.AddBuffer <RenderElement>(entity); var size = UnsafeUtility.SizeOf <RenderElement>() * renderEntities.Length; renderBatches.ResizeUninitialized(renderEntities.Length); UnsafeUtility.MemCpy(renderBatches.GetUnsafePtr(), renderEntities.GetUnsafePtr(), size); var renderSpans = dstManager.AddBuffer <BatchedSpanElement>(entity); size = UnsafeUtility.SizeOf <BatchedSpanElement>() * batchSpans.Length; renderSpans.ResizeUninitialized(batchSpans.Length); UnsafeUtility.MemCpy(renderSpans.GetUnsafePtr(), batchSpans.GetUnsafePtr(), size); } renderEntities.Dispose(); batchSpans.Dispose(); }
public StatisticsReport(int bucketSize) { BucketSize = bucketSize; Samples = new NativeList <SoakStatisticsPoint>(Allocator.Persistent); }
// Steps the simulation immediately on a single thread without spawning any jobs. public static void StepImmediate(SimulationStepInput input, ref SimulationContext simulationContext) { if (input.TimeStep < 0) { throw new ArgumentOutOfRangeException(); } if (input.NumSolverIterations <= 0) { throw new ArgumentOutOfRangeException(); } if (input.World.NumDynamicBodies == 0) { // No need to do anything, since nothing can move return; } // Inform the context of the timeStep simulationContext.TimeStep = input.TimeStep; // Find all body pairs that overlap in the broadphase var dynamicVsDynamicBodyPairs = new NativeStream(1, Allocator.Temp); var dynamicVsStaticBodyPairs = new NativeStream(1, Allocator.Temp); { var dynamicVsDynamicBodyPairsWriter = dynamicVsDynamicBodyPairs.AsWriter(); var dynamicVsStaticBodyPairsWriter = dynamicVsStaticBodyPairs.AsWriter(); input.World.CollisionWorld.FindOverlaps(ref dynamicVsDynamicBodyPairsWriter, ref dynamicVsStaticBodyPairsWriter); } // Create dispatch pairs var dispatchPairs = new NativeList <DispatchPairSequencer.DispatchPair>(Allocator.Temp); DispatchPairSequencer.CreateDispatchPairs(ref dynamicVsDynamicBodyPairs, ref dynamicVsStaticBodyPairs, input.World.NumDynamicBodies, input.World.Joints, ref dispatchPairs); // Apply gravity and copy input velocities Solver.ApplyGravityAndCopyInputVelocities(input.World.DynamicsWorld.MotionDatas, input.World.DynamicsWorld.MotionVelocities, simulationContext.InputVelocities, input.TimeStep * input.Gravity); // Narrow phase var contacts = new NativeStream(1, Allocator.Temp); { var contactsWriter = contacts.AsWriter(); NarrowPhase.CreateContacts(ref input.World, dispatchPairs.AsArray(), input.TimeStep, ref contactsWriter); } // Build Jacobians var jacobians = new NativeStream(1, Allocator.Temp); { var contactsReader = contacts.AsReader(); var jacobiansWriter = jacobians.AsWriter(); Solver.BuildJacobians(ref input.World, input.TimeStep, input.Gravity, input.NumSolverIterations, dispatchPairs.AsArray(), ref contactsReader, ref jacobiansWriter); } // Solve Jacobians { var jacobiansReader = jacobians.AsReader(); var collisionEventsWriter = simulationContext.CollisionEventDataStream.AsWriter(); var triggerEventsWriter = simulationContext.TriggerEventDataStream.AsWriter(); Solver.SolveJacobians(ref jacobiansReader, input.World.DynamicsWorld.MotionVelocities, input.TimeStep, input.NumSolverIterations, ref collisionEventsWriter, ref triggerEventsWriter); } // Integrate motions Integrator.Integrate(input.World.DynamicsWorld.MotionDatas, input.World.DynamicsWorld.MotionVelocities, input.TimeStep); // Synchronize the collision world if asked for if (input.SynchronizeCollisionWorld) { input.World.CollisionWorld.UpdateDynamicTree(ref input.World, input.TimeStep, input.Gravity); } }
static void NLClearer <T>(NativeList <T> list) where T : struct { list.Clear(); }
static void NLDisposer <T>(NativeList <T> list) where T : struct { list.Dispose(); }
private void Update() { if (_NumberOfBeamsInPropagation == 0 | _remodelling) { int beamPropagationSectionInteger; int discreteBeaminteger; _remodelling = false; ; if (CheckForSceneUpdates(out discreteBeaminteger, out beamPropagationSectionInteger)) { ; CutBeams(discreteBeaminteger, beamPropagationSectionInteger); } else { if (_separateObjectInteractions.Count != 0) { SendMultiBeams(); } return; } } var descreteBeamsTointeractIndeces = new List <int>(); for (int i = 0; i < _discreteBeams.Count; i++) { if (!ChechFloat3IsZero(_discreteBeams[i].DirectionOfPropagation)) { descreteBeamsTointeractIndeces.Add(i); } } var hit = new RaycastHit(); Ray ray = new Ray(); int layerMask = ~(1 << 8); var limitedBeamDirection = new NativeList <float3>(Allocator.TempJob); var limitedBeamPosition = new NativeList <float3>(Allocator.TempJob); var limitedBeamFinalPosition = new NativeList <float3>(Allocator.TempJob); var limitedBeamIndeces = new List <int>(); for (int i = 0; i < descreteBeamsTointeractIndeces.Count; i++) { ray.origin = _discreteBeams[descreteBeamsTointeractIndeces[i]].LastCoordinate; ray.direction = _discreteBeams[descreteBeamsTointeractIndeces[i]].DirectionOfPropagation; if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask)) { if (_ObjectOfInteractionPrevPosition.ContainsKey(hit.collider.gameObject)) { if (hit.collider.gameObject.transform.position != _ObjectOfInteractionPrevPosition[hit.collider.gameObject].Item1 | hit.collider.gameObject.transform.rotation != _ObjectOfInteractionPrevPosition[hit.collider.gameObject].Item2) { _remodelling = true; } } else { _ObjectOfInteractionPrevPosition.Add(hit.collider.gameObject, new Tuple <Vector3, Quaternion>(hit.collider.gameObject.transform.position, hit.collider.gameObject.transform.rotation)); } _collisionPositionsPerBeam[descreteBeamsTointeractIndeces[i]].Item2.Add(hit.point); if (_separateObjectInteractions.ContainsKey(hit.collider.gameObject)) { _separateObjectInteractions[hit.collider.gameObject].Item1.Add(descreteBeamsTointeractIndeces[i]); _separateObjectInteractions[hit.collider.gameObject].Item2.Add(hit); } else { _separateObjectInteractions.Add(hit.collider.gameObject, new Tuple <List <int>, List <RaycastHit> >( new List <int> { descreteBeamsTointeractIndeces[i] }, new List <RaycastHit> { hit } )); } } else { _NumberOfBeamsInPropagation--; limitedBeamDirection.Add(_discreteBeams[descreteBeamsTointeractIndeces[i]].DirectionOfPropagation); limitedBeamPosition.Add(_discreteBeams[descreteBeamsTointeractIndeces[i]].LastCoordinate); limitedBeamFinalPosition.Add(float3.zero); limitedBeamIndeces.Add(descreteBeamsTointeractIndeces[i]); } } var parallelLimitedPropagation = new ParallelLimitedPropagation(); parallelLimitedPropagation.discreteBeamsDirection = limitedBeamDirection; parallelLimitedPropagation.discreteBeamsPosition = limitedBeamPosition; parallelLimitedPropagation.discreteBeamsFinalPosition = limitedBeamFinalPosition; parallelLimitedPropagation.maxLengthOfPropagation = maxLengthOfPropagation; var handleLimitedPropagation = parallelLimitedPropagation.Schedule(limitedBeamDirection.Length, 1); var limitedBeamFinalPositionList = new List <float3>(); var limitedBeamIndecesList = new List <int>(); ; foreach (var el in _separateObjectInteractions.Keys) { var discreteBeamsForInteraction = new List <DiscreteBeam>(); foreach (var index in _separateObjectInteractions[el].Item1) { discreteBeamsForInteraction.Add(_discreteBeams[index]); } ; InteractionScriptI interactionScript; MultiBeamInteractionI multiBeamInteraction; if (el.TryGetComponent <InteractionScriptI>(out interactionScript)) { var result = interactionScript.InteractWithDescreteBeam(discreteBeamsForInteraction, _separateObjectInteractions[el].Item2); if (result.Count != _separateObjectInteractions[el].Item1.Count) { throw new ArgumentOutOfRangeException("The returned list size is out of range."); } for (int i = 0; i < _separateObjectInteractions[el].Item1.Count; i++) { AssignValuesAfterInteraction(_separateObjectInteractions[el].Item1[i], result[i][0].Item1, result[i][0].Item2, result[i][0].Item3, result[i][0].Item4); } _keysForClear.Add(el); ; } else { for (int i = 0; i < _separateObjectInteractions[el].Item1.Count; i++) { _NumberOfBeamsInPropagation--; limitedBeamFinalPositionList.Add(_separateObjectInteractions[el].Item2[i].point); limitedBeamIndecesList.Add(_separateObjectInteractions[el].Item1[i]); } if (!el.TryGetComponent <MultiBeamInteractionI>(out multiBeamInteraction)) { _keysForClear.Add(el); } ; } } handleLimitedPropagation.Complete(); for (int i = 0; i < limitedBeamFinalPosition.Length; i++) { limitedBeamFinalPositionList.Add(limitedBeamFinalPosition[i]); limitedBeamIndecesList.Add(limitedBeamIndeces[i]); } AssignValuesForLimitedPropagation(limitedBeamIndecesList, limitedBeamFinalPositionList); limitedBeamDirection.Dispose(); limitedBeamPosition.Dispose(); limitedBeamFinalPosition.Dispose(); Project(); ClearInteractionObjectKeys(); }
internal void MoveChunksFrom( NativeArray <ArchetypeChunk> chunks, NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping, EntityComponentStore *srcEntityComponentStore, ManagedComponentStore srcManagedComponentStore) { new MoveChunksJob { srcEntityComponentStore = srcEntityComponentStore, dstEntityComponentStore = EntityComponentStore, entityRemapping = entityRemapping, chunks = chunks }.Run(); var managedArrayChunks = new NativeList <IntPtr>(Allocator.Temp); int chunkCount = chunks.Length; var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob); for (int i = 0; i < chunkCount; ++i) { var chunk = chunks[i].m_Chunk; var archetype = chunk->Archetype; //TODO: this should not be done more than once for each archetype var dstArchetype = EntityComponentStore->GetOrCreateArchetype(archetype->Types, archetype->TypesCount); remapChunks[i] = new RemapChunk { chunk = chunk, dstArchetype = dstArchetype }; if (archetype->NumManagedArrays > 0) { managedArrayChunks.Add((IntPtr)chunk); } if (archetype->MetaChunkArchetype != null) { Entity srcEntity = chunk->metaChunkEntity; Entity dstEntity; EntityComponentStore->CreateEntities(dstArchetype->MetaChunkArchetype, &dstEntity, 1); var srcEntityInChunk = srcEntityComponentStore->GetEntityInChunk(srcEntity); var dstEntityInChunk = EntityComponentStore->GetEntityInChunk(dstEntity); ChunkDataUtility.SwapComponents(srcEntityInChunk.Chunk, srcEntityInChunk.IndexInChunk, dstEntityInChunk.Chunk, dstEntityInChunk.IndexInChunk, 1, srcEntityComponentStore->GlobalSystemVersion, EntityComponentStore->GlobalSystemVersion); EntityRemapUtility.AddEntityRemapping(ref entityRemapping, srcEntity, dstEntity); srcEntityComponentStore->DestroyEntities(&srcEntity, 1); } } var managedArrayDstIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob); var managedArraySrcIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob); EntityComponentStore->ReserveManagedObjectArrays(managedArrayDstIndices); var remapManaged = new RemapManagedArraysJob { chunks = managedArrayChunks, dstIndices = managedArrayDstIndices, srcIndices = managedArraySrcIndices, }.Schedule(managedArrayChunks.Length, 64); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker); k_ProfileMoveObjectComponents.Begin(); remapManaged.Complete(); m_ManagedComponentStore.MoveManagedObjectArrays(managedArraySrcIndices, managedArrayDstIndices, srcManagedComponentStore); k_ProfileMoveObjectComponents.End(); managedArrayDstIndices.Dispose(); managedArraySrcIndices.Dispose(); managedArrayChunks.Dispose(); k_ProfileMoveSharedComponents.Begin(); var remapShared = ManagedComponentStore.MoveSharedComponents(srcManagedComponentStore, chunks, Allocator.TempJob); k_ProfileMoveSharedComponents.End(); new ChunkPatchEntities { RemapChunks = remapChunks, EntityRemapping = entityRemapping, EntityComponentStore = EntityComponentStore }.Run(); var remapChunksJob = new RemapChunksJob { dstEntityComponentStore = EntityComponentStore, remapChunks = remapChunks, entityRemapping = entityRemapping }.Schedule(remapChunks.Length, 1); var moveChunksBetweenArchetypeJob = new MoveChunksBetweenArchetypeJob { remapChunks = remapChunks, remapShared = remapShared, globalSystemVersion = EntityComponentStore->GlobalSystemVersion }.Schedule(remapChunksJob); moveChunksBetweenArchetypeJob.Complete(); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); remapShared.Dispose(); remapChunks.Dispose(); }
public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { float3 up = math.up(); var chunkCCData = chunk.GetNativeArray(CharacterControllerComponentType); var chunkCCInternalData = chunk.GetNativeArray(CharacterControllerInternalType); var chunkPhysicsColliderData = chunk.GetNativeArray(PhysicsColliderType); var chunkTranslationData = chunk.GetNativeArray(TranslationType); var chunkRotationData = chunk.GetNativeArray(RotationType); var hasChunkCollisionEventBufferType = chunk.Has(CollisionEventBufferType); var hasChunkTriggerEventBufferType = chunk.Has(TriggerEventBufferType); BufferAccessor <StatefulCollisionEvent> collisionEventBuffers = default; BufferAccessor <StatefulTriggerEvent> triggerEventBuffers = default; if (hasChunkCollisionEventBufferType) { collisionEventBuffers = chunk.GetBufferAccessor(CollisionEventBufferType); } if (hasChunkTriggerEventBufferType) { triggerEventBuffers = chunk.GetBufferAccessor(TriggerEventBufferType); } DeferredImpulseWriter.BeginForEachIndex(chunkIndex); for (int i = 0; i < chunk.Count; i++) { var ccComponentData = chunkCCData[i]; var ccInternalData = chunkCCInternalData[i]; var collider = chunkPhysicsColliderData[i]; var position = chunkTranslationData[i]; var rotation = chunkRotationData[i]; DynamicBuffer <StatefulCollisionEvent> collisionEventBuffer = default; DynamicBuffer <StatefulTriggerEvent> triggerEventBuffer = default; if (hasChunkCollisionEventBufferType) { collisionEventBuffer = collisionEventBuffers[i]; } if (hasChunkTriggerEventBufferType) { triggerEventBuffer = triggerEventBuffers[i]; } // Collision filter must be valid if (!collider.IsValid || collider.Value.Value.Filter.IsEmpty) { continue; } // Character step input CharacterControllerStepInput stepInput = new CharacterControllerStepInput { World = PhysicsWorld, DeltaTime = DeltaTime, Up = math.up(), Gravity = ccComponentData.Gravity, MaxIterations = ccComponentData.MaxIterations, Tau = k_DefaultTau, Damping = k_DefaultDamping, SkinWidth = ccComponentData.SkinWidth, ContactTolerance = ccComponentData.ContactTolerance, MaxSlope = ccComponentData.MaxSlope, RigidBodyIndex = PhysicsWorld.GetRigidBodyIndex(ccInternalData.Entity), CurrentVelocity = ccInternalData.LinearVelocity, MaxMovementSpeed = ccComponentData.MaxMovementSpeed }; // Character transform RigidTransform transform = new RigidTransform { pos = position.Value, rot = rotation.Value }; NativeList <StatefulCollisionEvent> currentFrameCollisionEvents = default; NativeList <StatefulTriggerEvent> currentFrameTriggerEvents = default; if (ccComponentData.RaiseCollisionEvents != 0) { currentFrameCollisionEvents = new NativeList <StatefulCollisionEvent>(Allocator.Temp); } if (ccComponentData.RaiseTriggerEvents != 0) { currentFrameTriggerEvents = new NativeList <StatefulTriggerEvent>(Allocator.Temp); } // Check support CheckSupport(ref PhysicsWorld, ref collider, stepInput, transform, out ccInternalData.SupportedState, out float3 surfaceNormal, out float3 surfaceVelocity, currentFrameCollisionEvents); // User input float3 desiredVelocity = ccInternalData.LinearVelocity; HandleUserInput(ccComponentData, stepInput.Up, surfaceVelocity, ref ccInternalData, ref desiredVelocity); // Calculate actual velocity with respect to surface if (ccInternalData.SupportedState == CharacterSupportState.Supported) { CalculateMovement(ccInternalData.CurrentRotationAngle, stepInput.Up, ccInternalData.IsJumping, ccInternalData.LinearVelocity, desiredVelocity, surfaceNormal, surfaceVelocity, out ccInternalData.LinearVelocity); } else { ccInternalData.LinearVelocity = desiredVelocity; } // World collision + integrate CollideAndIntegrate(stepInput, ccComponentData.CharacterMass, ccComponentData.AffectsPhysicsBodies != 0, collider.ColliderPtr, ref transform, ref ccInternalData.LinearVelocity, ref DeferredImpulseWriter, currentFrameCollisionEvents, currentFrameTriggerEvents); // Update collision event status if (currentFrameCollisionEvents.IsCreated) { UpdateCollisionEvents(currentFrameCollisionEvents, collisionEventBuffer); } if (currentFrameTriggerEvents.IsCreated) { UpdateTriggerEvents(currentFrameTriggerEvents, triggerEventBuffer); } // Write back and orientation integration position.Value = transform.pos; rotation.Value = quaternion.AxisAngle(up, ccInternalData.CurrentRotationAngle); // Write back to chunk data { chunkCCInternalData[i] = ccInternalData; chunkTranslationData[i] = position; chunkRotationData[i] = rotation; } } DeferredImpulseWriter.EndForEachIndex(); }
internal void MoveChunksFrom( NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping, EntityComponentStore *srcEntityComponentStore, ManagedComponentStore srcManagedComponentStore) { var moveChunksJob = new MoveAllChunksJob { srcEntityComponentStore = srcEntityComponentStore, dstEntityComponentStore = EntityComponentStore, entityRemapping = entityRemapping }.Schedule(); JobHandle.ScheduleBatchedJobs(); int chunkCount = 0; for (var i = 0; i < srcEntityComponentStore->m_Archetypes.Length; ++i) { var srcArchetype = srcEntityComponentStore->m_Archetypes.Ptr[i]; chunkCount += srcArchetype->Chunks.Count; } var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob); var remapArchetypes = new NativeArray <RemapArchetype>(srcEntityComponentStore->m_Archetypes.Length, Allocator.TempJob); var managedArrayChunks = new NativeList <IntPtr>(Allocator.Temp); int chunkIndex = 0; int archetypeIndex = 0; for (var i = 0; i < srcEntityComponentStore->m_Archetypes.Length; ++i) { var srcArchetype = srcEntityComponentStore->m_Archetypes.Ptr[i]; if (srcArchetype->Chunks.Count != 0) { var dstArchetype = EntityComponentStore->GetOrCreateArchetype(srcArchetype->Types, srcArchetype->TypesCount); remapArchetypes[archetypeIndex] = new RemapArchetype { srcArchetype = srcArchetype, dstArchetype = dstArchetype }; for (var j = 0; j < srcArchetype->Chunks.Count; ++j) { var srcChunk = srcArchetype->Chunks.p[j]; remapChunks[chunkIndex] = new RemapChunk { chunk = srcChunk, dstArchetype = dstArchetype }; chunkIndex++; } if (srcArchetype->NumManagedArrays > 0) { for (var j = 0; j < srcArchetype->Chunks.Count; ++j) { var chunk = srcArchetype->Chunks.p[j]; managedArrayChunks.Add((IntPtr)chunk); } } archetypeIndex++; EntityComponentStore->IncrementComponentTypeOrderVersion(dstArchetype); } } moveChunksJob.Complete(); var managedArrayDstIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob); var managedArraySrcIndices = new NativeArray <int>(managedArrayChunks.Length, Allocator.TempJob); EntityComponentStore->ReserveManagedObjectArrays(managedArrayDstIndices); var remapManaged = new RemapManagedArraysJob { chunks = managedArrayChunks, dstIndices = managedArrayDstIndices, srcIndices = managedArraySrcIndices, }.Schedule(managedArrayChunks.Length, 64); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker); k_ProfileMoveObjectComponents.Begin(); remapManaged.Complete(); m_ManagedComponentStore.MoveManagedObjectArrays(managedArraySrcIndices, managedArrayDstIndices, srcManagedComponentStore); k_ProfileMoveObjectComponents.End(); managedArrayDstIndices.Dispose(); managedArraySrcIndices.Dispose(); managedArrayChunks.Dispose(); k_ProfileMoveSharedComponents.Begin(); var remapShared = ManagedComponentStore.MoveAllSharedComponents(srcManagedComponentStore, Allocator.TempJob); k_ProfileMoveSharedComponents.End(); new ChunkPatchEntities { RemapChunks = remapChunks, EntityRemapping = entityRemapping, EntityComponentStore = EntityComponentStore }.Run(); var remapAllChunksJob = new RemapAllChunksJob { dstEntityComponentStore = EntityComponentStore, remapChunks = remapChunks, entityRemapping = entityRemapping }.Schedule(remapChunks.Length, 1); var remapArchetypesJob = new RemapArchetypesJob { remapArchetypes = remapArchetypes, remapShared = remapShared, dstEntityComponentStore = EntityComponentStore, chunkHeaderType = TypeManager.GetTypeIndex <ChunkHeader>() }.Schedule(archetypeIndex, 1, remapAllChunksJob); ManagedComponentStore.Playback(ref EntityComponentStore->ManagedChangesTracker); remapArchetypesJob.Complete(); remapShared.Dispose(); remapChunks.Dispose(); }
public bool CastRay(RaycastInput input, ref NativeList <RaycastHit> allHits) => QueryWrappers.RayCast(ref this, input, ref allHits);
public TestBinaryReader(TestBinaryWriter writer) { content = writer.content; writer.content = new NativeList <byte>(); }
public bool CastCollider(ColliderCastInput input, ref NativeList <ColliderCastHit> allHits) => QueryWrappers.ColliderCast(ref this, input, ref allHits);
void GenerateArgumentPermutations(StateData stateData, NativeList <ActionKey> argumentPermutations) { var agentObjects = new NativeList <int>(4, Allocator.Temp); stateData.GetTraitBasedObjectIndices(agentObjects, s_AgentFilter); var keyObjects = new NativeList <int>(4, Allocator.Temp); stateData.GetTraitBasedObjectIndices(keyObjects, s_KeyFilter); var roomObjects = new NativeList <int>(4, Allocator.Temp); stateData.GetTraitBasedObjectIndices(roomObjects, s_RoomFilter); if (roomObjects.Length <= 0) { return; } var traitBasedObjectIds = stateData.TraitBasedObjectIds; var carriableBuffer = stateData.CarriableBuffer; var carrierBuffer = stateData.CarrierBuffer; var localizedBuffer = stateData.LocalizedBuffer; var firstRoom = traitBasedObjectIds[roomObjects[0]].Id; var agentKeyIndex = -1; for (var i = 0; i < keyObjects.Length; i++) { var keyIndex = keyObjects[i]; var keyObject = stateData.TraitBasedObjects[keyIndex]; if (carriableBuffer[keyObject.CarriableIndex].Carrier != ObjectId.None) { continue; } for (var j = 0; j < agentObjects.Length; j++) { var agentIndex = agentObjects[j]; var agentObject = stateData.TraitBasedObjects[agentIndex]; if (carrierBuffer[agentObject.CarrierIndex].CarriedObject == traitBasedObjectIds[keyIndex].Id) { agentKeyIndex = keyIndex; break; } } if (keyIndex >= 0) { break; } } // Get argument permutation and check preconditions for (var i = 0; i < keyObjects.Length; i++) { var keyIndex = keyObjects[i]; var keyObject = stateData.TraitBasedObjects[keyIndex]; if (carriableBuffer[keyObject.CarriableIndex].Carrier != ObjectId.None) { continue; } for (var j = 0; j < agentObjects.Length; j++) { var agentIndex = agentObjects[j]; var agentObject = stateData.TraitBasedObjects[agentIndex]; if (carrierBuffer[agentObject.CarrierIndex].CarriedObject == traitBasedObjectIds[keyIndex].Id) { continue; } if (localizedBuffer[agentObject.LocalizedIndex].Location != firstRoom) { continue; } argumentPermutations.Add(new ActionKey(k_MaxArguments) { ActionGuid = ActionGuid, [k_KeyIndex] = keyIndex, [k_AgentIndex] = agentIndex, [k_AgentKeyIndex] = agentKeyIndex }); } } agentObjects.Dispose(); keyObjects.Dispose(); roomObjects.Dispose(); }
public bool CalculateDistance(ColliderDistanceInput input, ref NativeList <DistanceHit> allHits) => QueryWrappers.CalculateDistance(ref this, input, ref allHits);
public void BuildMesh(int2 dir) { Mesh mesh = new Mesh(); NativeList <Vector3> verts = new NativeList <Vector3>(Allocator.Temp); NativeList <int> tris = new NativeList <int>(Allocator.Temp); List <Vector2> uvs = new List <Vector2>(); float3 blockPos = new float3(0, 0, 0); int numFaces = 0; //front if (dir.y < 0) { verts.Add(blockPos + new float3(0, 0, 0)); verts.Add(blockPos + new float3(0, 1, 0)); verts.Add(blockPos + new float3(1, 1, 0)); verts.Add(blockPos + new float3(1, 0, 0)); numFaces++; uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs()); } //right if (dir.x > 0) { verts.Add(blockPos + new float3(1, 0, 0)); verts.Add(blockPos + new float3(1, 1, 0)); verts.Add(blockPos + new float3(1, 1, 1)); verts.Add(blockPos + new float3(1, 0, 1)); numFaces++; uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs()); } //back if (dir.y > 0) { verts.Add(blockPos + new float3(1, 0, 1)); verts.Add(blockPos + new float3(1, 1, 1)); verts.Add(blockPos + new float3(0, 1, 1)); verts.Add(blockPos + new float3(0, 0, 1)); numFaces++; uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs()); } //left if (dir.x < 0) { verts.Add(blockPos + new float3(0, 0, 1)); verts.Add(blockPos + new float3(0, 1, 1)); verts.Add(blockPos + new float3(0, 1, 0)); verts.Add(blockPos + new float3(0, 0, 0)); numFaces++; uvs.AddRange(BlockTexture.Get(BlockType.BedRock, 0).sidePos.GetUVs()); } int tl = verts.Length - 4 * numFaces; for (int idx = 0; idx < numFaces; idx++) { NativeArray <int> range = new NativeArray <int>(6, Allocator.Temp); range[0] = tl + idx * 4; range[1] = tl + idx * 4 + 1; range[2] = tl + idx * 4 + 2; range[3] = tl + idx * 4; range[4] = tl + idx * 4 + 2; range[5] = tl + idx * 4 + 3; tris.AddRange(range); range.Dispose(); } mesh.vertices = verts.ToArray(); mesh.triangles = tris.ToArray(); mesh.uv = uvs.ToArray(); mesh.RecalculateNormals(); GetComponent <MeshFilter>().mesh = mesh; GetComponent <MeshCollider>().sharedMesh = mesh; verts.Dispose(); tris.Dispose(); }
public void Update(ref EntityArray array) { m_Entities.Clear(); EntitySpawnCount = 0; EntityReplaceCount = 0; EntityRemovalCount = 0; var defaultEntity = new Entity(); var length = array.Length; if (NeedEntitiesList) { UnityEngine.Profiling.Profiler.BeginSample("ForLoop #1 - With entities"); for (int i = 0; i != length; i++) { Entity entity; UnityEngine.Profiling.Profiler.BeginSample("Get entities and init var"); var checkedEntity = array[i]; UnityEngine.Profiling.Profiler.EndSample(); UnityEngine.Profiling.Profiler.BeginSample("TryGet()"); if (!m_CurrentEntities.FastTryGet(checkedEntity.Index, out entity)) { if (NeedEntitiesList) { m_Entities.Add(new EntityChangeItem() { entity = checkedEntity, wasCreated = true }); } m_CurrentEntities[checkedEntity.Index] = checkedEntity; EntitySpawnCount++; } else if (NeedToCheckReplacement) { UnityEngine.Profiling.Profiler.BeginSample("Check Version"); // The entity was replaced if (entity.Version != checkedEntity.Version) { EntityReplaceCount++; m_CurrentEntities[checkedEntity.Index] = checkedEntity; } UnityEngine.Profiling.Profiler.EndSample(); } UnityEngine.Profiling.Profiler.EndSample(); } UnityEngine.Profiling.Profiler.EndSample(); } else { UnityEngine.Profiling.Profiler.BeginSample("ForLoop #1 - Without entities"); EntitySpawnCount = length - m_LastLength; m_LastLength = length; UnityEngine.Profiling.Profiler.EndSample(); } UnityEngine.Profiling.Profiler.BeginSample("Check for removal"); if (NeedToCheckRemoval && array.Length != m_CurrentEntities.Count) { var toRemove = new NativeList <int>(Allocator.Temp); foreach (var entity in m_CurrentEntities.Values) { var exist = false; for (int i = 0; i != array.Length; i++) { if (array[i].Index == entity.Index) { exist = true; break; } } if (exist) { continue; } EntityRemovalCount++; m_Entities.Add(new EntityChangeItem() { entity = entity, wasCreated = false }); toRemove.Add(entity.Index); } for (int i = 0; i != toRemove.Length; i++) { m_CurrentEntities.Remove(toRemove[i]); } toRemove.Dispose(); } UnityEngine.Profiling.Profiler.EndSample(); }
public static unsafe void CheckSupport( ref PhysicsWorld world, ref PhysicsCollider collider, CharacterControllerStepInput stepInput, RigidTransform transform, out CharacterSupportState characterState, out float3 surfaceNormal, out float3 surfaceVelocity, NativeList <StatefulCollisionEvent> collisionEvents = default) { surfaceNormal = float3.zero; surfaceVelocity = float3.zero; // Up direction must be normalized Assert.IsTrue(Unity.Physics.Math.IsNormalized(stepInput.Up)); // Query the world NativeList <ColliderCastHit> castHits = new NativeList <ColliderCastHit>(k_DefaultQueryHitsCapacity, Allocator.Temp); CharacterControllerAllHitsCollector <ColliderCastHit> castHitsCollector = new CharacterControllerAllHitsCollector <ColliderCastHit>( stepInput.RigidBodyIndex, 1.0f, ref castHits, world); var maxDisplacement = -stepInput.ContactTolerance * stepInput.Up; { ColliderCastInput input = new ColliderCastInput() { Collider = collider.ColliderPtr, Orientation = transform.rot, Start = transform.pos, End = transform.pos + maxDisplacement }; world.CastCollider(input, ref castHitsCollector); } // If no hits, proclaim unsupported state if (castHitsCollector.NumHits == 0) { characterState = CharacterSupportState.Unsupported; return; } float maxSlopeCos = math.cos(stepInput.MaxSlope); // Iterate over distance hits and create constraints from them NativeList <SurfaceConstraintInfo> constraints = new NativeList <SurfaceConstraintInfo>(k_DefaultConstraintsCapacity, Allocator.Temp); float maxDisplacementLength = math.length(maxDisplacement); for (int i = 0; i < castHitsCollector.NumHits; i++) { ColliderCastHit hit = castHitsCollector.AllHits[i]; CreateConstraint(stepInput.World, stepInput.Up, hit.RigidBodyIndex, hit.ColliderKey, hit.Position, hit.SurfaceNormal, hit.Fraction * maxDisplacementLength, stepInput.SkinWidth, maxSlopeCos, ref constraints); } // Velocity for support checking float3 initialVelocity = maxDisplacement / stepInput.DeltaTime; // Solve downwards (don't use min delta time, try to solve full step) float3 outVelocity = initialVelocity; float3 outPosition = transform.pos; SimplexSolver.Solve(stepInput.DeltaTime, stepInput.DeltaTime, stepInput.Up, stepInput.MaxMovementSpeed, constraints, ref outPosition, ref outVelocity, out float integratedTime, false); // Get info on surface int numSupportingPlanes = 0; { for (int j = 0; j < constraints.Length; j++) { var constraint = constraints[j]; if (constraint.Touched && !constraint.IsTooSteep && !constraint.IsMaxSlope) { numSupportingPlanes++; surfaceNormal += constraint.Plane.Normal; surfaceVelocity += constraint.Velocity; // Add supporting planes to collision events if (collisionEvents.IsCreated) { var collisionEvent = new StatefulCollisionEvent(stepInput.World.Bodies[stepInput.RigidBodyIndex].Entity, stepInput.World.Bodies[constraint.RigidBodyIndex].Entity, stepInput.RigidBodyIndex, constraint.RigidBodyIndex, ColliderKey.Empty, constraint.ColliderKey, constraint.Plane.Normal); collisionEvent.CollisionDetails = new StatefulCollisionEvent.Details(1, 0, constraint.HitPosition); collisionEvents.Add(collisionEvent); } } } if (numSupportingPlanes > 0) { float invNumSupportingPlanes = 1.0f / numSupportingPlanes; surfaceNormal *= invNumSupportingPlanes; surfaceVelocity *= invNumSupportingPlanes; surfaceNormal = math.normalize(surfaceNormal); } } // Check support state { if (math.lengthsq(initialVelocity - outVelocity) < k_SimplexSolverEpsilonSq) { // If velocity hasn't changed significantly, declare unsupported state characterState = CharacterSupportState.Unsupported; } else if (math.lengthsq(outVelocity) < k_SimplexSolverEpsilonSq && numSupportingPlanes > 0) { // If velocity is very small, declare supported state characterState = CharacterSupportState.Supported; } else { // Check if sliding outVelocity = math.normalize(outVelocity); float slopeAngleSin = math.max(0.0f, math.dot(outVelocity, -stepInput.Up)); float slopeAngleCosSq = 1 - slopeAngleSin * slopeAngleSin; if (slopeAngleCosSq <= maxSlopeCos * maxSlopeCos) { characterState = CharacterSupportState.Sliding; } else if (numSupportingPlanes > 0) { characterState = CharacterSupportState.Supported; } else { // If numSupportingPlanes is 0, surface normal is invalid, so state is unsupported characterState = CharacterSupportState.Unsupported; } } } }
private void CreateRagdoll(float3 positionOffset, quaternion rotationOffset, float3 initialVelocity, int ragdollIndex = 1, bool internalCollisions = false, float rangeGain = 1.0f) { var entityManager = BasePhysicsDemo.DefaultWorld.EntityManager; var entities = new NativeList <Entity>(Allocator.Temp); var rangeModifier = new float2(math.max(0, math.min(rangeGain, 1))); // Head float headRadius = 0.1f; float3 headPosition = new float3(0, 1.8f, headRadius); Entity head; { CollisionFilter filter = internalCollisions ? layerFilter(layer.Head, layer.Torso) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> headCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(0, 0, 0), Vertex1 = new float3(0, 0, headRadius / 4), Radius = headRadius }, filter); head = CreateDynamicBody(headPosition, quaternion.identity, headCollider, float3.zero, float3.zero, 5.0f); } entities.Add(head); // Torso float3 torsoSize; float3 torsoPosition; Entity torso; { //UnityEngine.Mesh torsoMesh = (UnityEngine.Mesh)Resources.Load("torso", typeof(UnityEngine.Mesh)); torsoSize = torsoMesh.bounds.size; torsoPosition = headPosition - new float3(0, headRadius * 3.0f / 4.0f + torsoSize.y, 0); CollisionFilter filter = internalCollisions ? layerFilter(layer.Torso, layer.Thigh | layer.Head | layer.UpperArm | layer.Pelvis) : groupFilter(-ragdollIndex); NativeArray <float3> points = new NativeArray <float3>(torsoMesh.vertices.Length, Allocator.TempJob); for (int i = 0; i < torsoMesh.vertices.Length; i++) { points[i] = torsoMesh.vertices[i]; } BlobAssetReference <Unity.Physics.Collider> collider = ConvexCollider.Create( points, ConvexHullGenerationParameters.Default, CollisionFilter.Default ); points.Dispose(); collider.Value.Filter = filter; torso = CreateDynamicBody(torsoPosition, quaternion.identity, collider, float3.zero, float3.zero, 20.0f); } entities.Add(torso); // Neck { float3 pivotHead = new float3(0, -headRadius, 0); float3 pivotTorso = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(head), pivotHead)); float3 axisHead = new float3(0, 0, 1); float3 perpendicular = new float3(1, 0, 0); FloatRange coneAngle = new FloatRange(math.radians(0), math.radians(45)) * rangeModifier; FloatRange perpendicularAngle = new FloatRange(math.radians(-30), math.radians(+30)) * rangeModifier; FloatRange twistAngle = new FloatRange(math.radians(-5), math.radians(5)) * rangeModifier; var axisTorso = math.rotate(math.inverse(GetBodyTransform(torso).rot), math.rotate(GetBodyTransform(head).rot, axisHead)); axisTorso = math.rotate(quaternion.AxisAngle(perpendicular, math.radians(10)), axisTorso); var headFrame = new BodyFrame { Axis = axisHead, PerpendicularAxis = perpendicular, Position = pivotHead }; var torsoFrame = new BodyFrame { Axis = axisTorso, PerpendicularAxis = perpendicular, Position = pivotTorso }; PhysicsJoint.CreateRagdoll(headFrame, torsoFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1); CreateJoint(ragdoll0, head, torso); CreateJoint(ragdoll1, head, torso); } // Arms { float armLength = 0.25f; float armRadius = 0.05f; CollisionFilter armUpperFilter = internalCollisions ? layerFilter(layer.UpperArm, layer.Torso | layer.Forearm) : groupFilter(-ragdollIndex); CollisionFilter armLowerFilter = internalCollisions ? layerFilter(layer.Forearm, layer.UpperArm | layer.Hand) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> upperArmCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(-armLength / 2, 0, 0), Vertex1 = new float3(armLength / 2, 0, 0), Radius = armRadius }, armUpperFilter); BlobAssetReference <Unity.Physics.Collider> foreArmCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(-armLength / 2, 0, 0), Vertex1 = new float3(armLength / 2, 0, 0), Radius = armRadius }, armLowerFilter); float handLength = 0.025f; float handRadius = 0.055f; CollisionFilter handFilter = internalCollisions ? layerFilter(layer.Hand, layer.Forearm) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> handCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(-handLength / 2, 0, 0), Vertex1 = new float3(handLength / 2, 0, 0), Radius = handRadius }, handFilter); for (int i = 0; i < 2; i++) { float s = i * 2 - 1.0f; float3 upperArmPosition = torsoPosition + new float3(s * (torsoSize.x + armLength) / 2.0f, 0.9f * torsoSize.y - armRadius, 0.0f); Entity upperArm = CreateDynamicBody(upperArmPosition, quaternion.identity, upperArmCollider, float3.zero, float3.zero, 10.0f); float3 foreArmPosition = upperArmPosition + new float3(armLength * s, 0, 0); Entity foreArm = CreateDynamicBody(foreArmPosition, quaternion.identity, foreArmCollider, float3.zero, float3.zero, 5.0f); float3 handPosition = foreArmPosition + new float3((armLength + handLength) / 2.0f * s, 0, 0); Entity hand = CreateDynamicBody(handPosition, quaternion.identity, handCollider, float3.zero, float3.zero, 2.0f); entities.Add(upperArm); entities.Add(foreArm); entities.Add(hand); // shoulder { float3 pivotArm = new float3(-s * armLength / 2.0f, 0, 0); float3 pivotTorso = math.transform(math.inverse(GetBodyTransform(torso)), math.transform(GetBodyTransform(upperArm), pivotArm)); float3 axisArm = new float3(-s, 0, 0); float3 perpendicularArm = new float3(0, 1, 0); FloatRange coneAngle = new FloatRange(math.radians(0), math.radians(80)) * rangeModifier; FloatRange perpendicularAngle = new FloatRange(math.radians(-70), math.radians(20)) * rangeModifier; FloatRange twistAngle = new FloatRange(math.radians(-5), math.radians(5)) * rangeModifier; var axisTorso = math.rotate(math.inverse(GetBodyTransform(torso).rot), math.rotate(GetBodyTransform(upperArm).rot, axisArm)); axisTorso = math.rotate(quaternion.AxisAngle(perpendicularArm, math.radians(-s * 45.0f)), axisTorso); var armFrame = new BodyFrame { Axis = axisArm, PerpendicularAxis = perpendicularArm, Position = pivotArm }; var bodyFrame = new BodyFrame { Axis = axisTorso, PerpendicularAxis = perpendicularArm, Position = pivotTorso }; PhysicsJoint.CreateRagdoll(armFrame, bodyFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1); CreateJoint(ragdoll0, upperArm, torso); CreateJoint(ragdoll1, upperArm, torso); } // elbow { float3 pivotUpper = new float3(s * armLength / 2.0f, 0, 0); float3 pivotFore = -pivotUpper; float3 axis = new float3(0, -s, 0); float3 perpendicular = new float3(-s, 0, 0); var lowerArmFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotFore }; var upperArmFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotUpper }; var hingeRange = new FloatRange(math.radians(0), math.radians(100)); hingeRange = (hingeRange - new float2(hingeRange.Mid)) * rangeModifier + hingeRange.Mid; PhysicsJoint hinge = PhysicsJoint.CreateLimitedHinge(lowerArmFrame, upperArmFrame, hingeRange); CreateJoint(hinge, foreArm, upperArm); } // wrist { float3 pivotFore = new float3(s * armLength / 2.0f, 0, 0); float3 pivotHand = new float3(-s * handLength / 2.0f, 0, 0); float3 axis = new float3(0, 0, -s); float3 perpendicular = new float3(0, 0, 1); var handFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotHand }; var forearmFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotFore }; var hingeRange = new FloatRange(math.radians(0), math.radians(135)) * rangeModifier; PhysicsJoint hinge = PhysicsJoint.CreateLimitedHinge(handFrame, forearmFrame, hingeRange); CreateJoint(hinge, hand, foreArm); } } } // Pelvis float pelvisRadius = 0.08f; float pelvisLength = 0.22f; float3 pelvisPosition = torsoPosition - new float3(0, pelvisRadius * 0.75f, 0.0f); Entity pelvis; { CollisionFilter filter = internalCollisions ? layerFilter(layer.Pelvis, layer.Torso | layer.Thigh) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> collider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(-pelvisLength / 2, 0, 0), Vertex1 = new float3(pelvisLength / 2, 0, 0), Radius = pelvisRadius }, filter); pelvis = CreateDynamicBody(pelvisPosition, quaternion.identity, collider, float3.zero, float3.zero, 15.0f); } entities.Add(pelvis); // Waist { float3 pivotTorso = float3.zero; float3 pivotPelvis = math.transform(math.inverse(GetBodyTransform(pelvis)), math.transform(GetBodyTransform(torso), pivotTorso)); float3 axis = new float3(0, 1, 0); float3 perpendicular = new float3(0, 0, 1); FloatRange coneAngle = new FloatRange(math.radians(0), math.radians(5)) * rangeModifier; FloatRange perpendicularAngle = new FloatRange(math.radians(-5), math.radians(90)) * rangeModifier; FloatRange twistAngle = new FloatRange(-math.radians(-5), math.radians(5)) * rangeModifier; var pelvisFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotPelvis }; var torsoFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotTorso }; PhysicsJoint.CreateRagdoll(pelvisFrame, torsoFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1); CreateJoint(ragdoll0, pelvis, torso); CreateJoint(ragdoll1, pelvis, torso); } // Legs { float thighLength = 0.32f; float thighRadius = 0.08f; CollisionFilter thighFilter = internalCollisions ? layerFilter(layer.Thigh, layer.Pelvis | layer.Calf) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> thighCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(0, -thighLength / 2, 0), Vertex1 = new float3(0, thighLength / 2, 0), Radius = thighRadius }, thighFilter); float calfLength = 0.32f; float calfRadius = 0.06f; CollisionFilter calfFilter = internalCollisions ? layerFilter(layer.Calf, layer.Thigh | layer.Foot) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> calfCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(0, -calfLength / 2, 0), Vertex1 = new float3(0, calfLength / 2, 0), Radius = calfRadius }, calfFilter); float footLength = 0.08f; float footRadius = 0.06f; CollisionFilter footFilter = internalCollisions ? layerFilter(layer.Foot, layer.Calf) : groupFilter(-ragdollIndex); BlobAssetReference <Unity.Physics.Collider> footCollider = Unity.Physics.CapsuleCollider.Create(new CapsuleGeometry { Vertex0 = new float3(0), Vertex1 = new float3(0, 0, footLength), Radius = footRadius }, footFilter); for (int i = 0; i < 2; i++) { float s = i * 2 - 1.0f; float3 thighPosition = pelvisPosition + new float3(s * pelvisLength / 2.0f, -thighLength / 2.0f, 0.0f); Entity thigh = CreateDynamicBody(thighPosition, quaternion.identity, thighCollider, float3.zero, float3.zero, 10.0f); float3 calfPosition = thighPosition + new float3(0, -(thighLength + calfLength) / 2.0f, 0); Entity calf = CreateDynamicBody(calfPosition, quaternion.identity, calfCollider, float3.zero, float3.zero, 5.0f); float3 footPosition = calfPosition + new float3(0, -calfLength / 2.0f, 0); Entity foot = CreateDynamicBody(footPosition, quaternion.identity, footCollider, float3.zero, float3.zero, 2.0f); entities.Add(thigh); entities.Add(calf); entities.Add(foot); // hip { float3 pivotThigh = new float3(0, thighLength / 2.0f, 0); float3 pivotPelvis = math.transform(math.inverse(GetBodyTransform(pelvis)), math.transform(GetBodyTransform(thigh), pivotThigh)); float3 axisLeg = new float3(0, -1, 0); float3 perpendicularLeg = new float3(-s, 0, 0); FloatRange coneAngle = new FloatRange(math.radians(0), math.radians(60)) * rangeModifier; FloatRange perpendicularAngle = new FloatRange(math.radians(-10), math.radians(40)) * rangeModifier; FloatRange twistAngle = new FloatRange(-math.radians(5), math.radians(5)) * rangeModifier; var axisPelvis = math.rotate(math.inverse(GetBodyTransform(pelvis).rot), math.rotate(GetBodyTransform(thigh).rot, axisLeg)); axisPelvis = math.rotate(quaternion.AxisAngle(perpendicularLeg, math.radians(s * 45.0f)), axisPelvis); var upperLegFrame = new BodyFrame { Axis = axisLeg, PerpendicularAxis = perpendicularLeg, Position = pivotThigh }; var pelvisFrame = new BodyFrame { Axis = axisPelvis, PerpendicularAxis = perpendicularLeg, Position = pivotPelvis }; PhysicsJoint.CreateRagdoll(upperLegFrame, pelvisFrame, coneAngle.Max, perpendicularAngle, twistAngle, out var ragdoll0, out var ragdoll1); CreateJoint(ragdoll0, thigh, pelvis); CreateJoint(ragdoll1, thigh, pelvis); } // knee { float3 pivotThigh = new float3(0, -thighLength / 2.0f, 0); float3 pivotCalf = math.transform(math.inverse(GetBodyTransform(calf)), math.transform(GetBodyTransform(thigh), pivotThigh)); float3 axis = new float3(-1, 0, 0); float3 perpendicular = new float3(0, 0, 1); var lowerLegFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotCalf }; var upperLegFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotThigh }; var hingeRange = new FloatRange(math.radians(-90), math.radians(0)); hingeRange = (hingeRange - new float2(hingeRange.Mid)) * rangeModifier + hingeRange.Mid; PhysicsJoint hinge = PhysicsJoint.CreateLimitedHinge(lowerLegFrame, upperLegFrame, hingeRange); CreateJoint(hinge, calf, thigh); } // ankle { float3 pivotCalf = new float3(0, -calfLength / 2.0f, 0); float3 pivotFoot = float3.zero; float3 axis = new float3(-1, 0, 0); float3 perpendicular = new float3(0, 0, 1); var footFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotFoot }; var lowerLegFrame = new BodyFrame { Axis = axis, PerpendicularAxis = perpendicular, Position = pivotCalf }; var hingeRange = new FloatRange(math.radians(-5), math.radians(5)) * rangeModifier; PhysicsJoint hinge = PhysicsJoint.CreateLimitedHinge(footFrame, lowerLegFrame, hingeRange); CreateJoint(hinge, foot, calf); } } } // reposition with offset information if (entities.Length > 0) { for (int i = 0; i < entities.Length; i++) { var e = entities[i]; bool isTorso = (i == 1); SwapRenderMesh(e, isTorso); Translation positionComponent = entityManager.GetComponentData <Translation>(e); Rotation rotationComponent = entityManager.GetComponentData <Rotation>(e); PhysicsVelocity velocityComponent = entityManager.GetComponentData <PhysicsVelocity>(e); float3 position = positionComponent.Value; quaternion rotation = rotationComponent.Value; float3 localPosition = position - pelvisPosition; localPosition = math.rotate(rotationOffset, localPosition); position = localPosition + pelvisPosition + positionOffset; rotation = math.mul(rotation, rotationOffset); positionComponent.Value = position; rotationComponent.Value = rotation; velocityComponent.Linear = initialVelocity; entityManager.SetComponentData <PhysicsVelocity>(e, velocityComponent); entityManager.SetComponentData <Translation>(e, positionComponent); entityManager.SetComponentData <Rotation>(e, rotationComponent); } } }
private static unsafe void CalculateAndStoreDeferredImpulsesAndCollisionEvents( CharacterControllerStepInput stepInput, bool affectBodies, float characterMass, float3 linearVelocity, NativeList <SurfaceConstraintInfo> constraints, ref NativeStream.Writer deferredImpulseWriter, NativeList <StatefulCollisionEvent> collisionEvents) { PhysicsWorld world = stepInput.World; for (int i = 0; i < constraints.Length; i++) { SurfaceConstraintInfo constraint = constraints[i]; int rigidBodyIndex = constraint.RigidBodyIndex; float3 impulse = float3.zero; if (rigidBodyIndex < 0) { continue; } // Skip static bodies if needed to calculate impulse if (affectBodies && (rigidBodyIndex < world.NumDynamicBodies)) { RigidBody body = world.Bodies[rigidBodyIndex]; float3 pointRelVel = world.GetLinearVelocity(rigidBodyIndex, constraint.HitPosition); pointRelVel -= linearVelocity; float projectedVelocity = math.dot(pointRelVel, constraint.Plane.Normal); // Required velocity change float deltaVelocity = -projectedVelocity * stepInput.Damping; float distance = constraint.Plane.Distance; if (distance < 0.0f) { deltaVelocity += (distance / stepInput.DeltaTime) * stepInput.Tau; } // Calculate impulse MotionVelocity mv = world.MotionVelocities[rigidBodyIndex]; if (deltaVelocity < 0.0f) { // Impulse magnitude float impulseMagnitude = 0.0f; { float objectMassInv = GetInvMassAtPoint(constraint.HitPosition, constraint.Plane.Normal, body, mv); impulseMagnitude = deltaVelocity / objectMassInv; } impulse = impulseMagnitude * constraint.Plane.Normal; } // Add gravity { // Effect of gravity on character velocity in the normal direction float3 charVelDown = stepInput.Gravity * stepInput.DeltaTime; float relVelN = math.dot(charVelDown, constraint.Plane.Normal); // Subtract separation velocity if separating contact { bool isSeparatingContact = projectedVelocity < 0.0f; float newRelVelN = relVelN - projectedVelocity; relVelN = math.select(relVelN, newRelVelN, isSeparatingContact); } // If resulting velocity is negative, an impulse is applied to stop the character // from falling into the body { float3 newImpulse = impulse; newImpulse += relVelN * characterMass * constraint.Plane.Normal; impulse = math.select(impulse, newImpulse, relVelN < 0.0f); } } // Store impulse deferredImpulseWriter.Write( new DeferredCharacterControllerImpulse() { Entity = body.Entity, Impulse = impulse, Point = constraint.HitPosition }); } if (collisionEvents.IsCreated && constraint.Touched && !constraint.IsMaxSlope) { var collisionEvent = new StatefulCollisionEvent(world.Bodies[stepInput.RigidBodyIndex].Entity, world.Bodies[rigidBodyIndex].Entity, stepInput.RigidBodyIndex, rigidBodyIndex, ColliderKey.Empty, constraint.ColliderKey, constraint.Plane.Normal); collisionEvent.CollisionDetails = new StatefulCollisionEvent.Details( 1, math.dot(impulse, collisionEvent.Normal), constraint.HitPosition); // check if collision event exists for the same bodyID and colliderKey // although this is a nested for, number of solved constraints shouldn't be high // if the same constraint (same entities, rigidbody indices and collider keys) // is solved in multiple solver iterations, pick the one from latest iteration bool newEvent = true; for (int j = 0; j < collisionEvents.Length; j++) { if (collisionEvents[j].CompareTo(collisionEvent) == 0) { collisionEvents[j] = collisionEvent; newEvent = false; break; } } if (newEvent) { collisionEvents.Add(collisionEvent); } } } }
private void InitBoidBehaviourJob() { seenBoids = new NativeList <Boid_Blittable>(JOB_MAX_SEEN_BOIDS_ARRAYS_LENGTH, Allocator.Persistent); resultDir = new NativeArray <float3>(1, Allocator.Persistent); }
public static void ConvertRectTransformsRecursive(UnityEngine.RectTransform parent, Entity parentEntity, RectTransformToEntity rectTransformToEntity, EntityManager commandBuffer, ref DotsUIArchetypes archetypes, ref NativeList <LinkedEntityGroup> linkedGroup, bool isPrefab) { rectTransformToEntity.Add(parent, parentEntity); linkedGroup.Add(parentEntity); #if UNITY_EDITOR commandBuffer.SetName(parentEntity, parent.name); #endif m_PooledRectTransformList.Add(parent); int childCount = parent.childCount; for (int i = 0; i < childCount; i++) { if (parent.GetChild(i) is UnityEngine.RectTransform childTransform) { //if(!childTransform.gameObject.activeInHierarchy) // continue; Entity child = commandBuffer.CreateEntity(archetypes.GenericChildArchetype); SetRectTransform(commandBuffer, childTransform, child); commandBuffer.SetComponentData(child, new UIParent() { Value = parentEntity }); if (isPrefab) { commandBuffer.AddComponent(child, typeof(Prefab)); } ConvertRectTransformsRecursive(childTransform, child, rectTransformToEntity, commandBuffer, ref archetypes, ref linkedGroup, isPrefab); } } }
internal FindAmmo(Guid guid, NativeList <StateEntityKey> statesToExpand, StateDataContext stateDataContext) { ActionGuid = guid; m_StatesToExpand = statesToExpand.AsDeferredJobArray(); m_StateDataContext = stateDataContext; }