public void DrawStates(HitCollisionHistory colliderCollection, Color color, float duration) { for (int i = 0; i < bufferSize; i++) { DrawStateAtIndex(i, colliderCollection, color, duration); } }
static bool IsRelevant(EntityManager entityManager, HitCollisionHistory hitCollHistory, int flagMask, Entity forceExcluded, Entity forceIncluded) { if (hitCollHistory.hitCollisionOwner == null) { GameDebug.LogError("HitCollisionHistory:" + hitCollHistory + " has a null hitCollisionOwner"); return(false); } if (hitCollHistory.colliders == null) { return(false); } Profiler.BeginSample("IsRelevant"); var hitCollisionOwner = entityManager.GetComponentObject <HitCollisionOwner>(hitCollHistory.hitCollisionOwner); var valid = (forceIncluded != Entity.Null && forceIncluded == hitCollHistory.hitCollisionOwner) || (hitCollisionOwner.collisionEnabled && (hitCollisionOwner.colliderFlags & flagMask) != 0 && !(forceExcluded != Entity.Null && forceExcluded == hitCollHistory.hitCollisionOwner)); Profiler.EndSample(); return(valid); }
protected override void OnUpdate() { for (var i = 0; i < RequestGroup.requests.Length; i++) { var request = RequestGroup.requests[i]; var forceIncluded = request.settings.ownerDamageFraction > 0 ? request.instigator : Entity.Null; HitCollisionHistory.PrepareColliders(ref ColliderGroup.hitCollisionArray, request.tick, request.collisionMask, Entity.Null, forceIncluded, primlib.sphere(request.center, request.settings.radius)); var hitColliderMask = 1 << m_hitCollisionLayer; var count = Physics.OverlapSphereNonAlloc(request.center, request.settings.radius, g_colliderBuffer, hitColliderMask); var colliderCollections = new Dictionary <HitCollisionOwner, ClosestCollision>(); GetClosestCollision(g_colliderBuffer, count, request.center, colliderCollections); foreach (var collision in colliderCollections.Values) { var collisionOwner = collision.hitCollision.owner; var ownerGameObjectEntity = collisionOwner.GetComponent <GameObjectEntity>(); var ownerEntity = ownerGameObjectEntity != null ? ownerGameObjectEntity.Entity : Entity.Null; var centerOfMass = collisionOwner.transform.position + Vector3.up * 1.2f; // TODO dont hardcode COM // Calc damage var damageVector = centerOfMass - (Vector3)request.center; var damageDirection = damageVector.normalized; var distance = damageVector.magnitude; if (distance > request.settings.radius) { continue; } var damage = request.settings.damage; var impulse = request.settings.impulse; if (distance > request.settings.falloffStartRadius) { var falloffFraction = (distance - request.settings.falloffStartRadius) / (request.settings.radius - request.settings.falloffStartRadius); damage -= (request.settings.damage - request.settings.minDamage) * falloffFraction; impulse -= (request.settings.impulse - request.settings.minImpulse) * falloffFraction; } if (request.instigator != Entity.Null && request.instigator == ownerEntity) { damage = damage * request.settings.ownerDamageFraction; } //GameDebug.Log(string.Format("SplashDamage. Target:{0} Inst:{1}", collider.hitCollision, m_world.GetGameObjectFromEntity(instigator) )); collisionOwner.damageEvents.Add(new DamageEvent(request.instigator, damage, damageDirection, impulse)); } PostUpdateCommands.DestroyEntity(RequestGroup.entities[i]); } }
public void DrawStateAtIndex(int stateIndex, HitCollisionHistory colliderCollection, Color color, float duration) { for (var i = 0; i < colliderCollection.colliders.Length; i++) { var bonePosition = buffer[stateIndex].bonePositions[i]; var boneRotation = buffer[stateIndex].boneRotations[i]; var worldPos = boneRotation * colliderCollection.colliders[i].localPosition + bonePosition; var worldRot = boneRotation * colliderCollection.colliders[i].localRotation; var capsuleCollider = colliderCollection.colliders[i].collider as CapsuleCollider; if (capsuleCollider != null) { DebugDraw.Capsule(worldPos, worldRot * Vector3.up, capsuleCollider.radius, capsuleCollider.height, color, duration); } } }
static void HandleRequests(EntityManager entityManager, int queryCount, Query[] queries, Result[] results, ComponentArray <HitCollisionHistory> hitCollisionArray, int environmentMask, int hitCollisionLayer, RaycastHit[] raycastHitBuffer) { // GameDebug.Log("HandleRequests id:" + startId + " to " + endId + " index:" + startId%c_bufferSize + " to " + endId%c_bufferSize); // First perform collision test against environment.New endpoint (if environment collision is found) is // used when testing agains hitcollision. If no hitcollision found damage will be applied to environment var rayTestCount = 0; for (var i = 0; i < queryCount; i++) { var query = queries[i]; if (query.testAgainsEnvironment == 0) { continue; } rayTestCount++; } Profiler.BeginSample("-create ray commands"); var rayCommands = new NativeArray <RaycastCommand>(rayTestCount, Allocator.TempJob); var rayResults = new NativeArray <RaycastHit>(rayTestCount, Allocator.TempJob); var rayTestIndex = 0; for (var i = 0; i < queryCount; i++) { var query = queries[i]; if (query.testAgainsEnvironment == 0) { continue; } rayCommands[rayTestIndex] = new RaycastCommand(query.origin, query.direction, query.distance, environmentMask); rayTestIndex++; } Profiler.EndSample(); Profiler.BeginSample("-excute ray commands"); var handle = RaycastCommand.ScheduleBatch(rayCommands, rayResults, 10); handle.Complete(); Profiler.EndSample(); // Test collision with hitCollision rayTestIndex = 0; for (var i = 0; i < queryCount; i++) { var query = queries[i]; // Handle raytest result var environmentHit = false; var environmentPoint = Vector3.zero; var environmentNormal = Vector3.zero; Collider environmentCollider = null; if (query.testAgainsEnvironment == 1) { environmentCollider = rayResults[rayTestIndex].collider; var impact = environmentCollider != null; if (impact) { environmentHit = true; environmentPoint = rayResults[rayTestIndex].point; environmentNormal = rayResults[rayTestIndex].normal; // query distance is adjusted so followup tests only are done before environment hit point query.distance = rayResults[rayTestIndex].distance; } if (showDebug.IntValue > 0) { Debug.DrawLine(query.origin, query.origin + query.direction * query.distance, impact ? Color.red : Color.green, debugDuration.FloatValue); } rayTestIndex++; } var result = new Result(); if (query.sphereCastRadius == 0) { HitCollisionHistory.PrepareColliders(entityManager, ref hitCollisionArray, query.hitCollisionTestTick, query.sphereCastMask, query.sphereCastExcludeOwner, Entity.Null, ray(query.origin, query.direction), query.distance); // HitCollision test var count = Physics.RaycastNonAlloc(query.origin, query.direction, raycastHitBuffer, query.distance, 1 << hitCollisionLayer); if (count > 0) { var closestIndex = GetClosestHit(raycastHitBuffer, count, query.origin); result.hit = 1; result.collider = raycastHitBuffer[closestIndex].collider; result.hitPoint = raycastHitBuffer[closestIndex].point; result.hitNormal = raycastHitBuffer[closestIndex].normal; } else { result.hitCollisionOwner = Entity.Null; } } else { HitCollisionHistory.PrepareColliders(entityManager, ref hitCollisionArray, query.hitCollisionTestTick, query.sphereCastMask, query.sphereCastExcludeOwner, Entity.Null, ray(query.origin, query.direction), query.distance, query.sphereCastRadius); var count = Physics.SphereCastNonAlloc(query.origin, query.sphereCastRadius, query.direction, raycastHitBuffer, query.distance, 1 << hitCollisionLayer); if (count > 0) { var closestIndex = GetClosestHit(raycastHitBuffer, count, query.origin); result.hit = 1; result.collider = raycastHitBuffer[closestIndex].collider; result.hitPoint = raycastHitBuffer[closestIndex].point; result.hitNormal = raycastHitBuffer[closestIndex].normal; } else { result.hitCollisionOwner = Entity.Null; } } // If no hitCollision found we use environment hit results if (result.hit == 0 && environmentHit) { result.hit = 1; result.hitPoint = environmentPoint; result.hitNormal = environmentNormal; result.collider = environmentCollider; } // Flag result as ready results[i] = result; } rayCommands.Dispose(); rayResults.Dispose(); }
protected override void OnUpdate() { var entityArray = RequestGroup.GetEntityArray(); var requestArray = RequestGroup.GetComponentDataArray <SplashDamageRequest>(); var hitCollisionArray = ColliderGroup.GetComponentArray <HitCollisionHistory>(); for (var i = 0; i < requestArray.Length; i++) { var request = requestArray[i]; var forceIncluded = request.settings.ownerDamageFraction > 0 ? request.instigator : Entity.Null; HitCollisionHistory.PrepareColliders(EntityManager, ref hitCollisionArray, request.tick, request.collisionMask, Entity.Null, forceIncluded, primlib.sphere(request.center, request.settings.radius)); var hitColliderMask = 1 << m_hitCollisionLayer; var count = Physics.OverlapSphereNonAlloc(request.center, request.settings.radius, g_colliderBuffer, hitColliderMask); var colliderCollections = new Dictionary <HitCollisionOwner, ClosestCollision>(); GetClosestCollision(g_colliderBuffer, count, request.center, colliderCollections); foreach (var collision in colliderCollections.Values) { var collisionOwner = collision.hitCollision.owner; var collisionOwnerEntity = collisionOwner.GetComponent <GameObjectEntity>().Entity; var centerOfMass = collision.closestPoint; // TODO (mogens) dont hardcode center of mass - and dont get from Character. Should be set on hitCollOwner by some other system if (EntityManager.HasComponent <Character>(collisionOwnerEntity)) { var charPredicedState = EntityManager.GetComponentData <CharPredictedStateData>(collisionOwnerEntity); centerOfMass = charPredicedState.position + Vector3.up * 1.2f; } // Calc damage var damageVector = centerOfMass - (Vector3)request.center; var damageDirection = damageVector.normalized; var distance = damageVector.magnitude; if (distance > request.settings.radius) { continue; } var damage = request.settings.damage; var impulse = request.settings.impulse; if (distance > request.settings.falloffStartRadius) { var falloffFraction = (distance - request.settings.falloffStartRadius) / (request.settings.radius - request.settings.falloffStartRadius); damage -= (request.settings.damage - request.settings.minDamage) * falloffFraction; impulse -= (request.settings.impulse - request.settings.minImpulse) * falloffFraction; } if (request.instigator != Entity.Null && request.instigator == collisionOwnerEntity) { damage = damage * request.settings.ownerDamageFraction; } //GameDebug.Log(string.Format("SplashDamage. Target:{0} Inst:{1}", collider.hitCollision, m_world.GetGameObjectFromEntity(instigator) )); collisionOwner.damageEvents.Add(new DamageEvent(request.instigator, damage, damageDirection, impulse)); } PostUpdateCommands.DestroyEntity(entityArray[i]); } }