/// <summary> /// moves the entity taking collisions into account /// </summary> /// <returns><c>true</c>, if move actor was newed, <c>false</c> otherwise.</returns> /// <param name="motion">Motion.</param> /// <param name="collisionResult">Collision result.</param> public bool move(Vector2 motion, out CollisionResult collisionResult) { collisionResult = new CollisionResult(); // no collider? just move and forget about it if (entity.getComponent <Collider>() == null || _triggerHelper == null) { entity.transform.position += motion; return(false); } // 1. move all non-trigger Colliders and get closest collision var colliders = entity.getComponents <Collider>(); for (var i = 0; i < colliders.Count; i++) { var collider = colliders[i]; // skip triggers for now. we will revisit them after we move. if (collider.isTrigger) { continue; } // fetch anything that we might collide with at our new position var bounds = collider.bounds; bounds.x += motion.X; bounds.y += motion.Y; var neighbors = Physics.boxcastBroadphaseExcludingSelf( collider, ref bounds, collider.collidesWithLayers); foreach (var neighbor in neighbors) { // skip triggers for now. we will revisit them after we move. if (neighbor.isTrigger) { continue; } if (collider.collidesWith(neighbor, motion, out collisionResult)) { // hit. back off our motion motion -= collisionResult.minimumTranslationVector; } } } ListPool <Collider> .free(colliders); // 2. move entity to its new position if we have a collision else move the full amount. motion is updated when a collision occurs entity.transform.position += motion; // 3. do an overlap check of all Colliders that are triggers with all broadphase colliders, triggers or not. // Any overlaps result in trigger events. _triggerHelper.update(); return(collisionResult.collider != null); }
/// <summary> /// caculates the movement modifying the motion vector to take into account any collisions that will /// occur when moving /// </summary> /// <returns><c>true</c>, if movement was calculated, <c>false</c> otherwise.</returns> /// <param name="motion">Motion.</param> /// <param name="collisionResult">Collision result.</param> public bool calculateMovement(ref Vector2 motion, out CollisionResult collisionResult) { collisionResult = new CollisionResult(); // no collider? just move and forget about it if (entity.getComponent <Collider>() == null || _triggerHelper == null) { entity.transform.position += motion; return(false); } // 1. move all non-trigger Colliders and get closest collision var colliders = entity.getComponents <Collider>(); for (var i = 0; i < colliders.Count; i++) { var collider = colliders[i]; // skip triggers for now. we will revisit them after we move. if (collider.isTrigger) { continue; } // fetch anything that we might collide with at our new position var bounds = collider.bounds; bounds.x += motion.X; bounds.y += motion.Y; var neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, ref bounds, collider.collidesWithLayers); foreach (var neighbor in neighbors) { // skip triggers for now. we will revisit them after we move. if (neighbor.isTrigger) { continue; } if (collider.collidesWith(neighbor, motion, out collisionResult)) { // hit. back off our motion motion -= collisionResult.minimumTranslationVector; } } } ListPool <Collider> .free(colliders); return(collisionResult.collider != null); }
/// <summary> /// update should be called AFTER Entity is moved. It will take care of any ITriggerListeners that the Collider overlaps. /// </summary> public void update() { // 3. do an overlap check of all entity.colliders that are triggers with all broadphase colliders, triggers or not. // Any overlaps result in trigger events. var colliders = _entity.getComponents <Collider>(); for (var i = 0; i < colliders.Count; i++) { var collider = colliders[i]; // fetch anything that we might collide with us at our new position var neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); foreach (var neighbor in neighbors) { // we need at least one of the colliders to be a trigger if (!collider.isTrigger && !neighbor.isTrigger) { continue; } if (collider.overlaps(neighbor)) { var pair = new Pair <Collider>(collider, neighbor); // if we already have this pair in one of our sets (the previous or current trigger intersections) dont call the enter event var shouldReportTriggerEvent = !_activeTriggerIntersections.Contains(pair) && !_previousTriggerIntersections.Contains(pair); if (shouldReportTriggerEvent) { notifyTriggerListeners(pair, true); } _activeTriggerIntersections.Add(pair); } // overlaps } // end foreach } ListPool <Collider> .free(colliders); checkForExitedColliders(); }