protected override void Handle(CompensationWorld compensationWorld, IBulletEntityAgent bulletEntityAgent, RaycastHit hit, PlayerEntity srcPlayer) { if (srcPlayer.gamePlay.IsDead()) { BulletHitHandler._logger.ErrorFormat( "[Hit{1}]cant hit player entity with key {0} becase of srcplayer is dead", hitTargetPlayer.entityKey.Value, cmdSeq); return; } Vector3 pos; if (compensationWorld.TryGetEntityPosition(hitTargetPlayer.entityKey.Value, out pos)) { DoHitPlayer(srcPlayer, bulletEntityAgent, hit); } else { BulletHitHandler._logger.ErrorFormat("[Hit{1}]cant get player compensation position with key {0}", hitTargetPlayer.entityKey.Value, cmdSeq); DoHitPlayer(srcPlayer, bulletEntityAgent, hit); } bulletEntityAgent.HitType = EHitType.Player; }
public void AddShootPlayer(int cmdSeq, IBulletEntityAgent bulletEntityAgent, PrecisionsVector3 hitPoint, EntityKey targetKey, PrecisionsVector3 positionValue, EBodyPart part, float totalDamage) { StatisticsHitPlayerEvent hitPlayerEvent = (StatisticsHitPlayerEvent)EventInfos.Instance.Allocate(EEventType.HitPlayerStastics, false); hitPlayerEvent.cmdSeq = cmdSeq; // hitPlayerEvent.bulletRuntimeText = bulletEntityAgent.ToDynamicString(); // hitPlayerEvent.bulletBaseText = bulletEntityAgent.ToBaseDataString(); hitPlayerEvent.bodyPart = part; hitPlayerEvent.totalDamage = totalDamage; hitPlayerEvent.posValue = positionValue; hitPlayerEvent.hitPoint = hitPoint; hitPlayerEvent.serverTime = bulletEntityAgent.ServerTime; hitPlayerEvent.statisticStr = bulletEntityAgent.StatisticsInfo.ToString(); hitPlayerEvent.shootKey = string.Format("{0}_{1}_to_{2}", cmdSeq, bulletEntityAgent.OwnerEntityKey, targetKey); hitPlayerEvent.shootTarget = targetKey; // srcPlayer.localEvents.Events.AddEvent(e); AddShootPlayer(hitPlayerEvent); }
public virtual void OnHit(int cmdSeq, IBulletEntityAgent bulletEntityAgent, RaycastHit hit, CompensationWorld compensationWorld) { bulletEntityAgent.HitPoint = new PrecisionsVector3(hit.point, 3); Collider collider = hit.collider; if (collider == null) { _logger.ErrorFormat("[Hit{1}]bullet hit unknown collier {0}", bulletEntityAgent.OwnerEntityKey, cmdSeq); return; } PlayerEntity srcPlayer = playerContext.GetEntityWithEntityKey(bulletEntityAgent.OwnerEntityKey); if (srcPlayer == null) { _logger.WarnFormat("[Hit{3}]bullet from unkown {0} hit environment {1}, collier {2}", bulletEntityAgent.OwnerEntityKey, hit.point, collider.name, cmdSeq); return; } var comp = hit.collider.transform.gameObject.GetComponent <HitBoxOwnerComponent>(); foreach (var handler in hitTargetHandlers) { if (handler.ProcessHitTarget(comp, cmdSeq, compensationWorld, bulletEntityAgent, hit, srcPlayer)) { return; } } }
private void DoHitVehicle(PlayerEntity srcPlayer, IBulletEntityAgent bulletEntityAgent, RaycastHit hit) { if (srcPlayer.gamePlay.IsDead()) { return; } Collider collider = hit.collider; VehiclePartIndex partIndex; var hitBoxFactor = VehicleEntityUtility.GetHitFactor(hitTargetVehicle, collider, out partIndex); var totalDamage = GetBulletDamage(bulletEntityAgent, hitBoxFactor, Vector3.Distance(hit.point, bulletEntityAgent.GunEmitPosition)); var gameData = hitTargetVehicle.GetGameData(); gameData.DecreaseHp(partIndex, totalDamage, srcPlayer.entityKey.Value); srcPlayer.statisticsData.Statistics.TotalDamage += totalDamage; bulletEntityAgent.IsValid = false; srcPlayer.statisticsData.Statistics.ShootingSuccCount++; BulletHitHandler._logger.InfoFormat("[Hit{0}]bullet from {0} hit vehicle {1}, part {2}", bulletEntityAgent.OwnerEntityKey, hitTargetVehicle.entityKey.Value, collider.name, cmdSeq); ClientEffectFactory.AddHitVehicleEffectEvent(srcPlayer, hitTargetVehicle.entityKey.Value, hit.point, hit.point - hitTargetVehicle.position.Value, hit.normal); }
private void DoHitPlayer(PlayerEntity srcPlayer, IBulletEntityAgent bulletEntityAgent, RaycastHit hit) { Collider collider = hit.collider; bulletEntityAgent.SetAnimationAndColliderText(hitTargetPlayer.networkAnimator.ToStringExt(), GetCollidersDebugDatas(hitTargetPlayer)); EBodyPart part = BulletPlayerUtil.GetBodyPartByHitBoxName(collider); BulletHitHandler._logger.InfoFormat("[Hit{0}]HitPlayer in {1}", cmdSeq, part); float hitboxFactor = bulletEntityAgent.GetDamageFactor(part); float totalDamage = GetBulletDamage(bulletEntityAgent, hitboxFactor, Vector3.Distance(hit.point, bulletEntityAgent.GunEmitPosition)); bulletEntityAgent.IsValid = false; //由于动画放在客户端做了,服务器调用的命令会被忽视,需要发送事件到客户端 // if (hitTargetPlayer.hasStateInterface && hitTargetPlayer.stateInterface.State.CanBeenHit()) // { // hitTargetPlayer.stateInterface.State.BeenHit(); // } ClientEffectFactory.AddBeenHitEvent(srcPlayer, hitTargetPlayer, AttackUtil.GeneraterUniqueHitId(srcPlayer, cmdSeq), contexts.session.currentTimeObject.CurrentTime); //添加假红统计 if (hitTargetPlayer.gamePlay.IsAlive()) { srcPlayer.StatisticsController().AddShootPlayer(cmdSeq, bulletEntityAgent, hit.point, hitTargetPlayer.entityKey.Value, hitTargetPlayer.position.Value, part, totalDamage); } ClientEffectFactory.AddHitPlayerEffectEvent(srcPlayer, hitTargetPlayer.entityKey.Value, hit.point, (int)EAudioUniqueId.BulletHit, part); BulletHitHandler._logger.InfoFormat("[Hit{5}]bullet from {0} hit player {1}, part {2}, hitbox factor {3}, result damage {4}", bulletEntityAgent.OwnerEntityKey, hitTargetPlayer.entityKey.Value, collider, hitboxFactor, totalDamage, cmdSeq); if (!hitTargetPlayer.gamePlay.IsLastLifeState(EPlayerLifeState.Dead)) { //有效命中 if (hitTargetPlayer.gamePlay.IsLastLifeState(EPlayerLifeState.Alive)) { srcPlayer.statisticsData.Statistics.ShootingPlayerCount++; } srcPlayer.statisticsData.Statistics.ShootingSuccCount++; } BulletPlayerUtil.ProcessPlayerHealthDamage(contexts, damager, srcPlayer, hitTargetPlayer, new PlayerDamageInfo(totalDamage, (int)EUIDeadType.Weapon, (int)part, bulletEntityAgent.WeaponId, bulletEntityAgent.IsOverWall, false, false, bulletEntityAgent.HitPoint, bulletEntityAgent.Velocity)); DebugUtil.AppendShootText(cmdSeq, "[HitPlayer]hitPoint:{0},collider:{1},totalDamage:{2},part:{3}", hit.point, hit.collider, totalDamage, part); }
protected float GetBulletDamage(IBulletEntityAgent bulletEntityAgent, float hitboxFactor, float distance) { float baseHarm = bulletEntityAgent.BaseDamage; float distanceDecay = bulletEntityAgent.DistanceDecayFactor; // 武器基础伤害 * (距离系数 ^ (实际命中距离 / 1270)) * hitbox系数 * 防弹装备系数 * 穿透系数 float totalDamage = baseHarm * Mathf.Pow(distanceDecay, distance / 12.7f) * hitboxFactor; BulletHitHandler._logger.InfoFormat( "bullet damage baseHarm {0}, distance decay {1}, distance {2}, hitbox factor {3}, result damage {4}", baseHarm, distanceDecay, distance, hitboxFactor, totalDamage); return(totalDamage); }
public bool ProcessHitTarget(HitBoxOwnerComponent boxOwnerComponent, int cmdSeq, CompensationWorld compensationWorld, IBulletEntityAgent bulletEntityAgent, RaycastHit hit, PlayerEntity srcPlayer) { if (Filter(boxOwnerComponent, cmdSeq)) { try { profilerInfo.BeginProfileOnlyEnableProfile(); Handle(compensationWorld, bulletEntityAgent, hit, srcPlayer); } finally { profilerInfo.EndProfileOnlyEnableProfile(); } return(true); } return(false); }
protected abstract void Handle(CompensationWorld compensationWorld, IBulletEntityAgent bulletEntityAgent, RaycastHit hit, PlayerEntity srcPlayer);
protected override void Handle(CompensationWorld compensationWorld, IBulletEntityAgent bulletEntityAgent, RaycastHit hit, PlayerEntity srcPlayer) { DoHitVehicle(srcPlayer, bulletEntityAgent, hit); bulletEntityAgent.HitType = EHitType.Vehicle; }
private void DoHitEnvironment(PlayerEntity srcPlayer, IBulletEntityAgent bulletEntityAgent, RaycastHit hit) { if (srcPlayer.gamePlay.IsDead()) { BulletHitHandler._logger.InfoFormat("hit environment dead"); return; } subProfilerInfo.BeginProfileOnlyEnableProfile(); // BulletHitHandler._logger.InfoFormat("[Hit{0}] OwnerEntityKey {1}, point {2},collider:{3}", cmdSeq, // bulletEntityAgent.OwnerEntityKey, hit.point, hit.collider.name); ThicknessInfo thicknessInfo; /*profiler:热点项 考虑材质检测方式调整 * --GetColliderThickness * -- GetMaterialByHit * --GetEnvironmentTypeByMatName */ EnvironmentInfo info = BulletEnvironmentUtil.GetEnvironmentInfoByHitBoxName(hit, bulletEntityAgent.Velocity, out thicknessInfo); float damageDecayFactor = SingletonManager.Get <EnvironmentTypeConfigManager>().GetDamageDecayFactorByEnvironmentType(info.Type); float energyDecayFactor = SingletonManager.Get <EnvironmentTypeConfigManager>().GetEnergyDecayFactorByEnvironmentType(info.Type); // float oldThickNess = bulletEntityAgent.PenetrableThickness; // float oldDamage = bulletEntityAgent.BaseDamage; bulletEntityAgent.BaseDamage *= damageDecayFactor; bulletEntityAgent.PenetrableThickness = bulletEntityAgent.PenetrableThickness * energyDecayFactor - info.Thickness; bulletEntityAgent.PenetrableLayerCount -= info.LayerCount; if (bulletEntityAgent.PenetrableLayerCount <= 0 || bulletEntityAgent.PenetrableThickness <= 0) { //profiler:editor下热点项 -- Entity.AddComponent bulletEntityAgent.IsValid = false; } else { bulletEntityAgent.AddPenetrateInfo(info.Type); } subProfilerInfo.EndProfileOnlyEnableProfile(); var collider = hit.collider; var fracturedHittable = collider.GetComponent <FracturedHittable>(); if (fracturedHittable != null) { var fracturedChunk = HitFracturedHandler.HitFracturedObj(srcPlayer, hit, fracturedHittable); if (fracturedHittable.HasBulletHole && fracturedChunk != null) { // ClientEffectFactory.CreateHitFracturedChunkEffect( hit.point, srcPlayer.entityKey.Value, fracturedHittable.transform, fracturedChunk.ChunkId,hit.point - fracturedChunk.transform.position, hit.normal,info.Type); if (fracturedChunk.IsBroken()) { ChunkEffectBehavior.CleanupChunkEffectBehaviors(fracturedChunk.ChunkId); } else { ClientEffectFactory.CreateHitEnvironmentEffect(hit.point, hit.normal, info.Type, (int)EAudioUniqueId.BulletHit, true, fracturedChunk.ChunkId, fracturedChunk.transform); } } srcPlayer.statisticsData.Statistics.ShootingSuccCount++; if (fracturedHittable.HasBulletHole && fracturedChunk != null && bulletEntityAgent.IsValid && thicknessInfo.Thickness > 0) { ClientEffectFactory.CreateHitEnvironmentEffect(hit.point, hit.normal, info.Type, (int)EAudioUniqueId.BulletHit, true, fracturedChunk.ChunkId, fracturedChunk.transform); // ClientEffectFactory.CreateHitFracturedChunkEffect(_contexts.clientEffect, _entityIdGenerator, // thicknessInfo.OutPoint, srcPlayer.entityKey.Value, hittedObjectKey, fracturedChunk.ChunkId, // thicknessInfo.OutPoint - fracturedChunk.transform.position, thicknessInfo.Normal); } } else { //profiler:热点项 -- EventInfos.Instance.Allocate(EEventType.HitEnvironment, false); ClientEffectFactory.AdHitEnvironmentEffectEvent(srcPlayer, hit.point, hit.normal, info.Type, (int)EAudioUniqueId.BulletHit); if (bulletEntityAgent.IsValid && thicknessInfo.Thickness > 0) { ClientEffectFactory.AdHitEnvironmentEffectEvent(srcPlayer, thicknessInfo.OutPoint, thicknessInfo.Normal, info.Type, (int)EAudioUniqueId.BulletHit); } } // BulletHitHandler._logger.InfoFormat( // "bullet from {0} hit environment {1}, collier {2}, base damage {3}->{4}, penetrable thick {5}->{6}, env ({7}), remain layer {8}", // bulletEntityAgent.OwnerEntityKey, hit.point, hit.collider.name, oldDamage, bulletEntityAgent.BaseDamage, // oldThickNess, bulletEntityAgent.PenetrableThickness, info, bulletEntityAgent.PenetrableLayerCount); }
public void MoveBullet(IBulletEntityAgent bulletEntityAgent, int renderTime, List <DefaultBulletSegment> allBulletSegments, int cmdSeq) { if (renderTime < bulletEntityAgent.NextFrameTime) { return; } var origin = bulletEntityAgent.Position; var velocity = bulletEntityAgent.Velocity; var gravity = bulletEntityAgent.Gravity; var velocityDecay = bulletEntityAgent.VelocityDecay; var distance = bulletEntityAgent.Distance; float interval = (renderTime - bulletEntityAgent.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; // string rayInfo = string.Format("direction {0}, length {1},readInterval {2}, move {3} -> {4}, stepinterval {5}",direction,raySegment.Length, interval, oldOrigin, origin, _stepInterval); DefaultBulletSegment segment = DefaultBulletSegment.Allocate(renderTime, raySegment, bulletEntityAgent); allBulletSegments.Add(segment); if (Mathf.Approximately(v.magnitude, 0)) { bulletEntityAgent.IsValid = false; _logger.ErrorFormat("bullet velocity is zero, set to invalid"); DebugUtil.AppendShootText(cmdSeq, "[Bullet Move] bullet {0}invalid", bulletEntityAgent.OwnerEntityKey); } bulletEntityAgent.Position = origin; bulletEntityAgent.ServerTime = renderTime; bulletEntityAgent.Velocity = velocity; bulletEntityAgent.Distance = distance; bulletEntityAgent.NextFrameTime = renderTime + _stepInterval; // DebugUtil.AppendShootText(cmdSeq,"[Bullet Move]rayInfo :{0} //// bulletInfo :{1} ",rayInfo,bulletEntityAgent.ToMoveString()); }
protected override void OnCleanUp() { ServerTime = 0; BulletEntityAgent = null; ObjectAllocatorHolder <DefaultBulletSegment> .Free(this); }
public static DefaultBulletSegment Allocate(int serverTime, RaySegment raySegment, IBulletEntityAgent bulletEntityAgent) { var ret = ObjectAllocatorHolder <DefaultBulletSegment> .Allocate(); ret.ServerTime = serverTime; ret.RaySegment = raySegment; ret.BulletEntityAgent = bulletEntityAgent; return(ret); }