void UpdateCollisions() { if (velocity.magnitude * Time.deltaTime > MIN_CHECK_VELOCITY) { int count = myCollider.Cast(velocity / velocity.magnitude, contactFilter, hitBuffer, velocity.magnitude * Time.deltaTime + MIN_CHECK_RADIUS); Vector2 normalVector = new Vector2(velocity.y, -velocity.x); for (int i = 0; i < count; i++) { normalVector.Normalize(); Vector2 currentNormal = hitBuffer[i].normal; double currentdistance = hitBuffer[i].distance; float dangerousDistance = Mathf.Max(hitBuffer[i].distance, 0); float projection = Vector2.Dot(velocity, currentNormal); if (dangerousDistance < (-projection) * Time.deltaTime) { velocity -= currentNormal * (projection + dangerousDistance / Time.deltaTime); } } foreach (Vector2 vect in new Vector2[] { normalVector, -normalVector }) { count = myCollider.Cast(vect, contactFilter, hitBuffer, SHELL_RADIUS); for (int i = 0; i < count; i++) { transform.position += (Vector3)(hitBuffer[i].normal * SHELL_RADIUS); } } } }
public int CheckCollision(Vector2 position) { _contactFilter.useTriggers = false; CheckTriggerCollision(position); var res = _collider.Cast(position, _contactFilter, _results, 0); //position.magnitude); if (res > 0) { if (_results[0].collider.isTrigger) { res--; } else { if (_lastCollider != _results[0] && OnCollisionEnter != null) { OnCollisionEnter(_results[0]); } _lastCollider = _results[0]; } } else { _lastCollider = new RaycastHit2D(); } return(res); }
protected bool CastCollider(Vector2 _movement, out RaycastHit2D _hit) { bool _result = collider.Cast(_movement, contactFilter, castBuffer, _movement.magnitude) > 0; _hit = castBuffer[0]; return(_result); }
private void updateBlocked() { ContactFilter2D filter = new ContactFilter2D(); filter.ClearLayerMask(); int contactCount = collider.Cast(Vector2.down, filter, _contacts, movementSettings.minGroundDistance); for (int i = 0; i < contactCount; i++) { if (_contacts[i].collider != null && _contacts[i].transform != transform) { _isBlocked = true; if (_contacts[i].collider.tag == "Ground") { _isGrounded = true; } else { _isGrounded = false; } return; } } _isGrounded = false; _isBlocked = false; }
/* * * ==== AI UTILITY CODE ==== * Every AI entity sohuld "think" several times a second, but not necessarily every frame. * This is done with a coroutine: AI_Tick. AI_Tick does some pathing stuff, * calling methods depending on the case. Then, OnTickEnd is called, allowing inheritors * to do whatever else they might want to do in a tick. * * Most AI code should go into OnTickEnd rather than Update, as it's less performance-intensive, * and will also pause when the actor is frozen (or similiarly disabled). * * */ IEnumerator AI_Tick() { while (true) { if (this.IsActive()) { hasPathLOS = (0 == castCollider.Cast(directMove, tileFilter, castHits, directMove.magnitude)); hasFireLOS = (0 == castCollider.Cast(directMove, fireFilter, castHits, directMove.magnitude)); directMove = targetObject.transform.position - transform.position; //if we have line of sight, check if we are in hover range. if so, hover. if (hasFireLOS && directMove.magnitude <= hoverDistance) { OnInHoverDistance(); } else if (hasPathLOS) //else, if we can, run straight towards our target { OnDirectMove(); } //pathfinding; only if we must else { OnPathFind(); } AvoidObstacles(); OnTickEnd(); } yield return(new WaitForSeconds(tickTime)); } }
void Movement(Vector2 move) { /* im copying this over from the prototype, a lot of it is based on a * tutorial for a platformer so I will mostlikely need to change parts of * it later*/ float distance = move.magnitude; //int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + 0.01f); int count = entityCollider.Cast(move, contactFilter, hitBuffer, distance + 0.01f); hitBufferList.Clear(); for (int i = 0; i < count; i++) { bool add = true; //TODO: another way of checking that does not involve tags if (hitBuffer[i].collider.tag == "Entity" || hitBuffer[i].collider.tag == "Player") { if (!allowEntityCollision || (hitBuffer[i].collider.GetComponent <EntityControllerComp>() != null && !hitBuffer[i].collider.GetComponent <EntityControllerComp>().AllowEntityCollision)) { add = false; } } if (add) { hitBufferList.Add(hitBuffer[i]); } } for (int i = 0; i < hitBufferList.Count; i++) { Vector2 currentNormal = hitBufferList[i].normal; if (currentNormal.y > 0.65f) { EntityControllerComp ec = hitBufferList[i].transform.gameObject.GetComponent <EntityControllerComp>(); if (ec == null) { grounded = true; } } float projection = Vector2.Dot(velocity, currentNormal); if (projection < 0) { velocity -= projection * currentNormal; //corrections.x = velocity.x; corrections.x = -(projection * currentNormal.x); } float modifiedDistance = hitBufferList[i].distance - 0.01f; distance = modifiedDistance < distance ? modifiedDistance : distance; } rb2d.position = rb2d.position + move.normalized * distance; }
void VelocityUpdate() { velocity = playerRigidbody.velocity; //Donne la vélocité du rigidbody du player à une variable locale (velocity) pour pouvoir la modifier speedInfo = playerRigidbody.velocity.x; //Renvoie la vitesse du player pour pouvoir l'utiliser dans l'animation if (hKeyInput == 0) //supprime l'inertie { velocity.x = Mathf.MoveTowards(velocity.x, 0, 0.85f); playerRigidbody.velocity = velocity; } else if (enableMouv) { //Applique les changements voulus à la vélocité velocity += movementInput * Time.fixedDeltaTime * acceleration; movementInput = Vector2.zero;//L'input de mouvement a été consommé, on le réinitialise velocity.x = Mathf.Clamp(velocity.x, -maxSpeed, maxSpeed); //Tourne le sprite dans la direction vers laquelle on se dirige if (Input.GetAxis("Horizontal") < 0f) { gameObject.GetComponent <SpriteRenderer>().flipX = true; } else if (Input.GetAxis("Horizontal") > 0f) { gameObject.GetComponent <SpriteRenderer>().flipX = false; } //Smoothing collision with walls int numHits = playerCollider.Cast(-Vector2.left, rWallCast, 0.3f); if (numHits > 0) { velocity += new Vector2(-1.2f, 0); } int leftNumHits = playerCollider.Cast(Vector2.left, rWallCast, 0.3f); if (leftNumHits > 0) { velocity += new Vector2(1.2f, 0); } ; if (isFalling) { velocity.x = 0.85f * velocity.x; } //Rend la vélocité au rigidbody du player playerRigidbody.velocity = velocity; } }
void VerticalMovement(Vector2 move) { float distance = move.magnitude; if (distance > minMoveDistance) { int count = c2D.Cast(move, arenaFilter, hitBuffer, distance + shellRadius); hitBufferList.Clear(); for (int i = 0; i < count; i++) { hitBufferList.Add(hitBuffer [i]); } for (int i = 0; i < hitBufferList.Count; i++) { Vector2 currentNormal = hitBufferList [i].normal; if (currentNormal.y > minGroundNormalY) { grounded = true; groundNormal = currentNormal; currentNormal.x = 0; } float modifiedDistance = hitBufferList [i].distance - shellRadius; distance = modifiedDistance < distance ? modifiedDistance : distance; } if (!grounded) { count = c2D.Cast(move, fighterFilter, hitBuffer, distance + shellRadius); hitBufferList.Clear(); for (int i = 0; i < count; i++) { hitBufferList.Add(hitBuffer [i]); } for (int i = 0; i < hitBufferList.Count; i++) { Vector2 currentNormal = hitBufferList [i].normal; Vector2 pushVector = new Vector2(currentNormal.y, -currentNormal.x); move = move * pushVector; } } } rb2d.position = rb2d.position + move.normalized * distance; }
/// <summary> /// Pass in a collider to cast and get contacts with other collisions. /// </summary> /// <param name="collider"></param> /// <param name="direction"></param> /// <param name="distance"></param> /// <returns></returns> public static List <RaycastHit2D> CheckCollisions(Collider2D collider, Vector2 direction, float distance) { // setup collision filter to minimize contacts ContactFilter2D filter = new ContactFilter2D() { }; filter.useTriggers = false; filter.SetLayerMask(Physics2D.GetLayerCollisionMask(collider.gameObject.layer)); filter.useLayerMask = true; // prepare our hit storage RaycastHit2D[] hitBuffer = new RaycastHit2D[10]; List <RaycastHit2D> hits = new List <RaycastHit2D>(); // look for hits and store int hitCount = collider.Cast(direction, filter, hitBuffer, distance); for (int i = 0; i < hitCount; i++) { hits.Add(hitBuffer[i]); } return(hits); }
private void FixedUpdate() { float xVelocity = horizontalInput * speed; playerRigidbody.velocity = new Vector2(xVelocity, playerRigidbody.velocity.y); if ((isFacingRight && horizontalInput < 0) || (!isFacingRight && horizontalInput > 0)) { Flip(); } // Jump Logic // Check for landing on the ground. int numHits = collider.Cast(Vector2.down, hits, groundDistanceCheck); isOnGround = numHits > 0; // Debugging. Vector2 rayStart = new Vector2(collider.bounds.center.x, collider.bounds.min.y); Vector2 RayDirection = Vector2.down * groundDistanceCheck; Debug.DrawRay(rayStart, RayDirection, Color.red, 1f); // Jump only if on the ground. if (isJumpPressed && isOnGround) { playerRigidbody.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse); } //Update our animator system after updating the player's movement. animator.SetFloat("xSpeed", Mathf.Abs(playerRigidbody.velocity.x)); animator.SetFloat("yVelocity", playerRigidbody.velocity.y); animator.SetBool("isOnGround", isOnGround); ClearInputs(); }
void DetectCollisions() { stop = false; int nCollision = collider.Cast(Vector2.right * directionMultiplier, contactFilter, results, .2f); for (int i = 0; i < nCollision; i++) { var col = results[i]; if (col.collider.tag == "Player" || col.collider is TilemapCollider2D) { continue; } else { stop = true; StartCoroutine("DieIfStopped"); break; } } if (stop == false) { StopCoroutine("DieIfStopped"); } }
void updatePushingPlayers(bool pvMine) { teamCaptains.Clear(); int count = detectionColl.Cast(Vector2.zero, rch2ds, 0, true); for (int i = 0; i < count; i++) { RaycastHit2D rch2d = rch2ds[i]; GameObject rchGO = rch2d.collider.gameObject; if (rchGO.CompareTag("Player")) { TeamToken tt = TeamToken.getTeamToken(rchGO); HealthPool healthPool = rchGO.GetComponentInChildren <HealthPool>(); if (healthPool) { if (!teamCaptains.ContainsKey(tt.teamCaptain)) { teamCaptains.Add(tt.teamCaptain, 0); } float amount = healthPool.Health; //Add in distance to caravan float distance = (rchGO.transform.position - transform.position).magnitude; float distanceMultiplier = 1 + ((maxAllowedDistance - distance) / maxAllowedDistance); //Update team captains dict teamCaptains[tt.teamCaptain] += amount * distanceMultiplier; } } } updateDirection(pvMine); }
/// <summary> /// Returns a count and a list of colliders that collide with the given coll2d. /// NOTE: NOT thread safe /// </summary> /// <param name="coll2d"></param> /// <param name="direction"></param> /// <param name="distance"></param> /// <param name="ignoreSiblingColliders"></param> /// <returns></returns> public static RaycastAnswer CastAnswer(this Collider2D coll2d, Vector2 direction, float distance = 0, bool ignoreSiblingColliders = true) { int count = coll2d.Cast(direction, rch2dsNonAlloc, distance, ignoreSiblingColliders); checkMaxReturnedList("Utility.CastAnswer", count); return(new RaycastAnswer(rch2dsNonAlloc, count)); }
private void FixedUpdate() //O fixed update deve fazer os updates de física (rigidbody) - e é razoável pegar o input analógico aqui { //Run float horizontalInput = Input.GetAxis("Horizontal"); rb.AddForce(new Vector2(speed * horizontalInput, 0f)); //Adiciona força horizontal ao rigidbody if (horizontalInput > 0) { transform.eulerAngles = new Vector3(0, 0, 0); } else if (horizontalInput < 0) { transform.eulerAngles = new Vector3(0, 180, 0); } //Jump if (jump) { int hits = feet.Cast(Vector2.down, new RaycastHit2D[1], 0.1f); if (hits > 0) { rb.AddForce(jumpForce * Vector2.up); } jump = false; } }
public bool Shoot() // check for collisions with the scope, saves info about what it hit, and return whether or not the player actually shot { if (active && IsInBounds() && shotDelayTime < 0) { // if the shooter is enabled, it's in the shooting boundary, and the delay has been waited, the player can shoot if (Input.GetButtonDown("Fire1")) // if the player can shoot, did they actually press the fire button? (the LMB) { RaycastHit2D[] hits = new RaycastHit2D[1]; // if the player did shoot, cast the shooter's shootCollider.Cast(Vector3.forward, hits); // collider into the scene and store the RaycastHit2D hit = hits[0]; // collider hit in the 'hit' variable if (hit.transform != null && hit.transform.TryGetComponent(out Hitbox hitbox)) // if the hit isn't null, and there's a hitbox attached to what was hit { Debug.Log("Hit " + hit.transform); // debug what we hit audioManager.PlaySound("blast"); // play the blast and quack sounds audioManager.PlaySound("duck"); hitbox.hit = true; // set the hitbox as hit lastHit = hitbox; // save the info about that hitbox } else // otherwise, if nothing was hit { Debug.Log("Hit Nothing"); // debug that audioManager.PlaySound("miss"); // play the miss sound lastHit = null; // set last hit to nothing } shotDelayTime = shotDelay; return(true); // the shoot was shot, so reset it's cooldown & return true } } // if the player didn't fire, or couldn't fire, shotDelayTime -= Time.deltaTime; // remove time before next shot lastHit = null; // clear last hit return(false); // return false (wasn't shot) }
public void OnCollisionEnter2D(Collision2D collision) { if (_waitForNotBlocked || controller.movementController.IsGrounded) { return; } ContactFilter2D filter = new ContactFilter2D(); filter.layerMask = enemyLayerMask; int contacts = attackCollider.Cast(controller.movementController.Velocity.normalized, filter, _hits, 0.25f); for (int i = 0; i < contacts; i++) { if (_hits[i].collider.gameObject.tag == "Enemy") { Vulnerable consumer = _hits[i].collider.gameObject.GetComponent <Vulnerable>(); if (consumer) { consumer.RecieveAttack(_isSlamming ? AttackType.Slam : AttackType.Jump, attackCollider, _hits[i]); if (_isSlamming) { _waitForNotBlocked = true; } break; } } } _isSlamming = false; }
// This function tells you if a path between you and a target point is clear of obstacles. // Super useful for coding up some basic AI for tiles. // What counts as an "Obstacle?" That's where the optional "CanOverlapFunc" comes in. protected bool pathIsClear(Vector2 target, CanOverlapFunc canOverlapFunc = null) { if (canOverlapFunc == null) { canOverlapFunc = DefaultCanOverlapFunc; // Default function for checking overlaps. } Vector2 toTarget = target - (Vector2)transform.position; float distanceToTarget = toTarget.magnitude; toTarget.Normalize(); // Now we perform a collider "Cast" i.e. we simulate moving our collider forward along the path from us to our target. // Any objects that the physics engine detects as collider with this simulated collider will be stored in _maybeRaycastResults // This is a kinda weird way of handling this. The Cast function returns an int instead of just returning the array of results (i.e. the thing we actually care about). // Why is it like this? Short answer is for performance. int numCollisions = _collider.Cast(toTarget, _maybeRaycastResults, distanceToTarget); for (int i = 0; i < numCollisions && i < _maybeRaycastResults.Length; i++) { if (!canOverlapFunc(_maybeRaycastResults[i])) { return(false); } } // If we can overlap with all of the possible barriers, then the path is clear! return(true); }
void FixedUpdate() { float xVelocity = horizontalInput * speed; playerRigibody.velocity = new Vector2(xVelocity, playerRigibody.velocity.y); if ((isFacingRight && horizontalInput < 0) || (!isFacingRight && horizontalInput > 0)) { Flip(); } int numHits = collider.Cast(Vector2.down, hits, 1f); isOnGround = numHits > 0; Vector2 rayStart = new Vector2(collider.bounds.center.x, collider.bounds.min.y); Vector2 rayDirection = Vector2.down * groundDistanceCheck; //Debug.DrawRay(rayStart, rayDirection, Color.red, 1f); if (isJumpPressed && isOnGround) { playerRigibody.AddForce(Vector2.up * jumpforce, ForceMode2D.Impulse); } animator.SetFloat("xSpeed", Mathf.Abs(playerRigibody.velocity.x)); animator.SetFloat("yVelocity", playerRigibody.velocity.y); animator.SetBool("isOnGround", isOnGround); ClearInputs(); }
private void FixedUpdate() { xVelocity = horizontalInput * speed; velocityVector = new Vector2(xVelocity, playerRB.velocity.y); playerRB.velocity = velocityVector; if (isFacingRight && horizontalInput < 0 || !isFacingRight && horizontalInput > 0) { flip(); } int numHits = collider.Cast(Vector2.down, hits, distanceToCheck); isOnGround = numHits > 0; Vector2 rayStart = new Vector2(collider.bounds.center.x, collider.bounds.min.y); Vector2 rayDir = Vector2.down * distanceToCheck; if (isJumpPressed && isOnGround) { isJumping = true; jumpVector = Vector2.up * jumpForce; playerRB.AddForce(jumpVector, ForceMode2D.Impulse); } // updates animator system after updating player movement animator.SetBool("isOnGround", isOnGround); animator.SetFloat("xSpeed", Mathf.Abs(playerRB.velocity.x)); animator.SetFloat("yVelocity", playerRB.velocity.y); clearInputs(); }
private bool IsGrounded() { // Cast playerCollider2D down on 0.1f using contactFilter2D. // Results of casting are writing to raycastHit2DResults. playerCollider2D.Cast(Vector2.down, contactFilter2D, raycastHit2DResults, 0.1f); // If number of elements contained in the raycastHit2DResults higher 1, // then we consider that player is touching platform. if (raycastHit2DResults.Count > 0) { isTouchingPlatfrom = true; } else { isTouchingPlatfrom = false; } // If player is touching colliders on the "Platform" layer so it can do double jump. // If player not touching any platforms, so it can't do double jump. if (isTouchingPlatfrom) { canDoubleJump = true; } ; // Return result of checking return(isTouchingPlatfrom); }
//The creature moves in a random direction IEnumerator Wander() { //Choose a random direction transform.Rotate(Vector3.forward, Random.Range(0f, 360f)); //Move in that direction float time = 0; //Wander for the duration or until you hit a wall while (time < wanderTime && col.Cast(transform.up, collisionFilter, hits, wanderSpeed) == 0) { transform.Translate(transform.up * wanderSpeed * Time.deltaTime, Space.World); time += Time.deltaTime; yield return(null); } StartCoroutine(Ponder()); }
void DetectPlatform() { RaycastHit2D[] hits = new RaycastHit2D[10]; Colli.Cast(Vector2.down, hits, 0.5f); CheckSlope(hits); CheckPlatform(hits); }
public void HorizontalMovement(float value) { RaycastHit2D[] hits = new RaycastHit2D[1]; if (mainCollider.Cast(Vector2.right * value, floorDetectionFilter, hits, 0.05f) > 0) { rb2d.velocity = new Vector2(0, rb2d.velocity.y); } else if (value == 0 && rb2d.velocity.x != 0) { float velocityX = rb2d.velocity.x; int decelerationDirection = (int)(velocityX / Mathf.Abs(velocityX)) * -1; rb2d.velocity += Vector2.right * decelerationDirection * horizontalDeceleration; } else { rb2d.velocity = new Vector2(speed * value, rb2d.velocity.y); } }
private static bool checkCollision(Collider2D collider, Vector2 direction, float distance, ContactFilter2D filter) { if (collider != null) { return(collider.Cast(direction, filter, _holdingRaycast, distance, true) > 0); } return(false); }
Vector3 SlideWalls(Vector3 pos, Vector3 movement) { // Only slide when moving diagonally if (movement.x == 0 || movement.y == 0) { return(movement); } float magnitude = movement.magnitude; int collCount = collider_.Cast(movement.normalized, wallSlideFilter, slideHit, magnitude); // If no collision in this attempted move there is nothing to adjust if (collCount == 0) { return(movement); } // There is possibly something to adjust, try moving in X only. var moveX = new Vector3(Mathf.Sign(movement.x), 0, 0); collCount = collider_.Cast(moveX, wallSlideFilter, slideHit, movement.magnitude); if (collCount == 0) { // There is room when moving in the X direction. Try the full movement in X. var result = new Vector3(Mathf.Sign(movement.x) * magnitude, 0, 0); return(result); } // There is possibly something to adjust, try moving in Y only. var moveY = new Vector3(0, Mathf.Sign(movement.y), 0); collCount = collider_.Cast(moveY, wallSlideFilter, slideHit, movement.magnitude); if (collCount == 0) { // There is room when moving in the Y direction. Try the full movement in Y. var result = new Vector3(0, Mathf.Sign(movement.y) * magnitude, 0); return(result); } // There is collision in both X and Y, don't attempt to adjust anything. return(movement); }
/// <summary> /// Determines whether the player is on the ground. /// </summary> /// <returns><c>true</c> if the player is grounded; otherwise, <c>false</c>.</returns> public bool IsGrounded() { // Find all objects that are intersecting with the ground check RaycastHit2D[] raycastHits = new RaycastHit2D [10]; int numHits = groundCheck.Cast(Vector2.down, raycastHits, 0); // Return true if the groundCheck intersects with a non-trigger collider that doesn't belong to the player body. return(raycastHits.Take(numHits).Any((hit) => !hit.collider.isTrigger && hit.collider.gameObject != gameObject)); }
private void OnTriggerEnter2D(Collider2D collision) { int hitsCount = hitCollider.Cast(Vector2.one, hits); if (hitsCount > 0) { float angle = Vector2.Angle(Vector2.up, hits[0].normal); Instantiate(hitParticle, hits[0].point, Quaternion.Euler(0, 0, angle)); } }
private void FixedUpdate() { if (!thisVehicle || thisVehicle.transform == null || base.transform.parent == null) { return; } ContactFilter2D contactFilter = default(ContactFilter2D); int num = thisVehicle.hitMask | LayerMask.GetMask("EnemyTank", "EnemyTankMain"); num &= ~(1 << base.transform.parent.gameObject.layer); contactFilter.SetLayerMask(num); int num2 = damageCollider.Cast(Vector2.zero, contactFilter, result, 0f); Vehicle vehicle = null; for (int i = 0; i < num2; i++) { vehicle = result[i].collider.GetComponentInParent <Vehicle>(); if (vehicle != null) { break; } } if (vehicle != null) { vehicle.CurrentHealth -= base.Booster.GetValue() * Time.fixedDeltaTime; rotation.speed = 2f; particles.Emit(10); Transform airControlPointBack = thisVehicle.airControlPointBack; Rigidbody2D component = thisVehicle.transform.GetComponent <Rigidbody2D>(); if (component != null) { component.AddForceAtPosition(airControlPointBack.right * -30f + airControlPointBack.up * 10f, airControlPointBack.position); } if (!didStart) { startSound.Play(); endSound.Stop(); didEnd = false; didStart = true; } else if (!startSound.isPlaying && !damageSound.isPlaying) { damageSound.Play(); } } else if (!didEnd) { startSound.Stop(); damageSound.Stop(); endSound.Play(); didEnd = true; didStart = false; rotation.speed = 0.5f; } }
public bool CanClimbStairs(float movement) { if (movement == 0 || !BottomBumping(movement)) { return(false); } Vector2 dir = movement < 0 ? Vector2.left : Vector2.right; return(stairsCheck.Cast(dir, contactFilter, stairCheckHits, LedgeClimbCheckDistance) == 0); }
/// <summary> /// Returns a count and a list of colliders that collide with the given coll2d. /// NOTE: NOT thread safe /// </summary> /// <param name="coll2d"></param> /// <param name="direction"></param> /// <param name="distance"></param> /// <param name="ignoreSiblingColliders"></param> /// <returns></returns> public static RaycastAnswer CastAnswer(this Collider2D coll2d, Vector2 direction, float distance = 0, bool ignoreSiblingColliders = true) { int count = 0; count = coll2d.Cast(direction, rch2dsNonAlloc, distance, ignoreSiblingColliders); if (count > maxReturnedList) { maxReturnedList = count; Debug.Log("Utility.CastAnswer: max list count: " + maxReturnedList); } return(new RaycastAnswer(rch2dsNonAlloc, count)); }