bool RaycastAllCollidables(float2 rayOrigin, float2 reciprocalHeading, out HitInfo hitInfo) { hitInfo = default(HitInfo); hitInfo.SetDefaults(); float minDistance = Mathf.Infinity; float tempDistance; for (int i = 0; i < this.Collidable.Length; i++) { if (this.RaycastCollidable(i, rayOrigin, reciprocalHeading, out tempDistance)) { if (tempDistance < minDistance) { minDistance = tempDistance; hitInfo.distanceToTarget = minDistance; hitInfo.hitEntity = this.CollidableEntities[i]; } } } hitInfo.hitPoint = rayOrigin + hitInfo.distanceToTarget / reciprocalHeading; return(hitInfo.hitEntity != Entity.Null); }
public void Execute(int index) { float remainingDistance = this.Distance[index]; Position2D position = this.SpearcasterPosition[index]; float2 center = position.Value; float2 leftPoint = center - this.SpearcastData[index].Offset.xy; float2 frontPoint = new float2(center.x, center.y + this.SpearcastData[index].Offset.z); float2 rightPoint = center + this.SpearcastData[index].Offset.xy; float2 heading = this.SpearcasterHeading[index].Value; float2 reciprocalHeading = math.rcp(heading); // TODO: Check if this handles heading of 0 correctly! HitInfo bestHitInfo = default(HitInfo); bestHitInfo.SetDefaults(); HitInfo tempHitInfo; while (remainingDistance > 0f) { if (this.RaycastAllCollidables(leftPoint, reciprocalHeading, out tempHitInfo) && tempHitInfo.distanceToTarget < bestHitInfo.distanceToTarget) { bestHitInfo = tempHitInfo; } if (this.RaycastAllCollidables(frontPoint, reciprocalHeading, out tempHitInfo) && tempHitInfo.distanceToTarget < bestHitInfo.distanceToTarget) { bestHitInfo = tempHitInfo; } if (this.RaycastAllCollidables(rightPoint, reciprocalHeading, out tempHitInfo) && tempHitInfo.distanceToTarget < bestHitInfo.distanceToTarget) { bestHitInfo = tempHitInfo; } float2 directionToMove = heading; float distanceToMove = remainingDistance; if (bestHitInfo.distanceToTarget <= remainingDistance && bestHitInfo.hitEntity != Entity.Null) // We hit something! { distanceToMove = bestHitInfo.distanceToTarget; float2 normal = this.CalculateNormal(index, bestHitInfo, center); heading = math.reflect(heading, normal); reciprocalHeading = math.rcp(heading); } position.Value = position.Value + distanceToMove * directionToMove; this.SpearcasterPosition[index] = position; remainingDistance -= distanceToMove; } }