public void DrawStates(HitCollisionHistory colliderCollection, Color color, float duration)
 {
     for (int i = 0; i < bufferSize; i++)
     {
         DrawStateAtIndex(i, colliderCollection, color, duration);
     }
 }
Beispiel #2
0
    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);
            }
        }
    }
Beispiel #5
0
    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();
    }
Beispiel #6
0
    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]);
        }
    }