private ICompensationWorld CreateWorld(DefaultBulletSegment segment) { var serverTime = segment.ServerTime; ICompensationWorld world; if (!_compensationWorlds.ContainsKey(serverTime)) { world = _compensationWorldFactory.CreateCompensationWorld(serverTime); if (world == null) { _logger.ErrorFormat("create compensation world at time {0}, FAILED", segment.ServerTime); segment.BulletEntity.IsValid = false; } else { _logger.DebugFormat("create compensation world at time {0}, SUCC", serverTime); _compensationWorlds[serverTime] = world; _compensationWorldList.Add(world); } } else { world = _compensationWorlds[serverTime]; } if (world == null) { return(null); } world.Self = segment.BulletEntity.OwnerEntityKey; world.ExcludePlayerList = segment.BulletEntity.ExcludePlayerList; return(world); }
private void OldBulletHit(int cmdSeq, DefaultBulletSegment segment, ICompensationWorld world) { RaycastHit camDirHit; if (world.Raycast(segment.RaySegment, out camDirHit, _hitboxLayerMask)) { _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, camDirHit, world); } }
public void MoveBullet(IBulletEntity bulletEntity, int renderTime, List <DefaultBulletSegment> allBulletSegments) { if (renderTime < bulletEntity.NextFrameTime) { return; } var origin = bulletEntity.Origin; var velocity = bulletEntity.Velocity; var gravity = bulletEntity.Gravity; var velocityDecay = bulletEntity.VelocityDecay; var distance = bulletEntity.Distance; float interval = (renderTime - bulletEntity.ServerTime) / 1000.0f; Vector3 oldOrigin = origin; // O(1) = O(0) + V(0) * t; origin.x = origin.x + velocity.x * interval; origin.y = origin.y + velocity.y * interval; origin.z = origin.z + velocity.z * interval; if (DebugConfig.DrawBulletLine) { RuntimeDebugDraw.Draw.DrawLine(oldOrigin, origin, Color.blue, 60f); Debug.DrawLine(oldOrigin, origin, Color.red, 60f); } // V(1) = V(0) + a * t Vector3 v = velocity; v.y = v.y - gravity * interval; v = v * Mathf.Pow(velocityDecay, interval); velocity = v; RaySegment raySegment = new RaySegment(); raySegment.Ray.origin = oldOrigin; var direction = origin - oldOrigin; raySegment.Ray.direction = direction; raySegment.Length = direction.magnitude; distance += raySegment.Length; _logger.DebugFormat("move bullet velocity {0}, direction {1}, distance {2}, total distance {3}, interval {4}, move {5} -> {6}, stepinterval {7}", velocity, direction, raySegment.Length, distance, interval, oldOrigin, origin, _stepInterval); DefaultBulletSegment segment = DefaultBulletSegment.Allocate(renderTime, raySegment, bulletEntity); allBulletSegments.Add(segment); if (Mathf.Approximately(v.magnitude, 0)) { bulletEntity.IsValid = false; _logger.ErrorFormat("bullet velocity is zero, set to invalid"); } bulletEntity.Origin = origin; bulletEntity.ServerTime = renderTime; bulletEntity.Velocity = velocity; bulletEntity.Distance = distance; bulletEntity.NextFrameTime = renderTime + _stepInterval; }
private void NewBulletHit(int cmdSeq, DefaultBulletSegment segment, ICompensationWorld world) { RaycastHit camDirHit; segment.BulletEntity.IsNew = false; RaycastHit gunDirHit; var camRaySegment = segment.RaySegment; bool checkGunDirObstacle = false; while (segment.BulletEntity.IsValid && world.Raycast(camRaySegment, out camDirHit, _hitboxLayerMask)) { if (!checkGunDirObstacle) { checkGunDirObstacle = true; //如果击中物体,从枪口向击中位置做检测,如果有物体,则使用枪口方向的结果 var startPosition = segment.BulletEntity.GunEmitPosition; var target = camDirHit.point; var dir = target - startPosition; var blockCheckSegment = new RaySegment() { Length = Vector3.Distance(target, startPosition) - RaycastStepOffset, Ray = new Ray(startPosition, dir.normalized), }; while (segment.BulletEntity.IsValid && world.Raycast(blockCheckSegment, out gunDirHit, _hitboxLayerMask)) { _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, gunDirHit, world); blockCheckSegment.Ray.origin = gunDirHit.point + blockCheckSegment.Ray.direction * RaycastStepOffset; } } if (segment.BulletEntity.IsValid) { _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, camDirHit, world); camRaySegment.Ray.origin = camDirHit.point + camRaySegment.Ray.direction * RaycastStepOffset; } } if (segment.BulletEntity.IsValid) { if (!checkGunDirObstacle) { //如果没有击中物体,从枪口向第一帧末子弹到达的位置做检测,如果有物体,使用枪口方向的结果 var startPosition = segment.BulletEntity.GunEmitPosition; var target = segment.RaySegment.Ray.direction * segment.RaySegment.Length + segment.RaySegment.Ray.origin; var dir = target - startPosition; var blockCheckSegment = new RaySegment() { Length = Vector3.Distance(target, startPosition) - RaycastStepOffset, Ray = new Ray(startPosition, dir.normalized), }; while (segment.BulletEntity.IsValid && world.Raycast(blockCheckSegment, out gunDirHit, _hitboxLayerMask)) { checkGunDirObstacle = true; _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, gunDirHit, world); blockCheckSegment.Ray.origin = gunDirHit.point + blockCheckSegment.Ray.direction * RaycastStepOffset; } } } }