예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
                    }
                }
            }
        }