//检测是否可以停到球 public static bool checkCatchingBall(FBActor actor) { if (actor.world.ball.owner != null || actor.world.ball.willBeCatched) { return(false); } //球速度不能为0也不能太大 var ballSquareSpeed = actor.world.ball.particleVelocity.squareLength; if (ballSquareSpeed == Fix64.Zero || ballSquareSpeed > actor.configuration.scb_maxBallSpeed.square) { //Debuger.Log("Speed too big " + (float)ballSquareSpeed); return(false); } //球员速度不能太快 if (actor.particle.velocity.squareLength > actor.configuration.scb_maxActorSpeed.square) { //Debuger.Log("Actor too quick to get ball" + (float)actor.particle.velocity.squareLength); return(false); } //求出足球方向和检测半径是否有交点 Fix64 ballSpeedLength = actor.world.ball.particleVelocity.length; FixVector2 ballActor = actor.world.ball.getPosition() - actor.getPosition(); Fix64 dot = FixVector2.dot(-ballActor, actor.world.ball.particleVelocity / ballSpeedLength); //方向相反 if (dot <= Fix64.Zero) { //Debuger.Log("Negative Direction to getBall" + (float)ballActor.length); return(false); } Fix64 d2 = ballActor.squareLength - dot.square; //无交点 if (d2 > actor.configuration.scb_maxRadius) { //Debuger.Log("no intersect point" + (float)ballActor.length); return(false); } Fix64 b2 = actor.configuration.scb_maxRadius.square - d2; if (b2 <= Fix64.Zero) { //Debuger.Log("D1"); return(false); } Fix64 s = dot - Fix64.Sqrt(b2); if (s < Fix64.Zero) { //Debuger.Log("Ball in Range???" + (float)ballActor.length); return(false); } FixVector2 normalizedBallActor = ballActor.normalized; FixVector2 bIntersectPoint = actor.world.ball.getPosition() + s * actor.world.ball.particleVelocity.normalized; #if UNITY_EDITOR LogicEvent.fire("setIntersectPoint", bIntersectPoint); #endif Fix64 t = Fix64.Zero; Fix64 dampingAcceleration = Fix64.Zero; bool canReachPoint = actor.world.ball.estimate(bIntersectPoint, out t, out dampingAcceleration); if (!canReachPoint) { //Debuger.Log("Can not read Point"); return(false); } if (t >= actor.configuration.scb_maxCathingTime) { //Debuger.Log("t > scb_maxCathingTime distance:" + (float)ballActor.length); return(false); } //弹跳次数>1不处理 EstimateHeightInfo heightInfo = actor.world.ball.estimateHeight(t); if (heightInfo.landedTimes > 0) { //Debuger.Log("heightInfo.landedTimes > 0"); return(false); } //脚下停球 if (heightInfo.destHeight <= actor.configuration.scb_catchingHeightLimit[0]) { ////动画时间太短 //if (t < actor.configuration.scb_catchingAniTime[0]) //{ // Debuger.Log("t < actor.configuration.scb_catchingAniTime :t=" + (float)t); // return false; //} //Debuger.Log("StandCatchingBall begin"); FixVector2 faceTo = (bIntersectPoint - actor.getPosition()).normalized; FixVector2 target = actor.getPosition() + faceTo * actor.configuration.scb_catchingOffset[0]; actor.world.ball.willCatchFreeBall(actor, target, t, actor.configuration.scb_catchingOffsetH[0], Fix64.FastAbs(dampingAcceleration)); actor.m_stateVector = faceTo; actor.m_stateValue = t; actor.m_nextState = StandCatchingBall.instance; return(true); } for (int i = 1; i < actor.configuration.scb_catchingHeightLimit.Length; ++i) { if (heightInfo.destHeight > actor.configuration.scb_catchingHeightLimit[i - 1] && heightInfo.destHeight <= actor.configuration.scb_catchingHeightLimit[i] ) { //if (t < actor.configuration.scb_catchingAniTime[i]) //{ // Debuger.Log("Air Cathing ball can not procced moveTime:t" + (float)t + " aniTime:" + (float)actor.configuration.scb_catchingAniTime[i]); // return false; //} FixVector2 cPoint = actor.getPosition() + actor.configuration.scb_catchingOffset[i] * ballActor.normalized; actor.world.ball.willCatchFreeBall(actor, cPoint, t, actor.configuration.scb_catchingOffsetH[i], Fix64.FastAbs(dampingAcceleration)); actor.m_stateVector = normalizedBallActor; actor.m_stateValue = t; actor.m_stateDataIndex = i; actor.m_nextState = AirCatchingBall.instance; return(true); } } //Debuger.Log("can not get ball heightInfo.destHeight" + (float)heightInfo.destHeight); return(false); }
void doorKeeperCathingBall(FBActor shooter, FBActor actor) { //球的轨迹和守门员的交点 FixVector2 intersectPoint = FixVector2.kZero; Fix64 intersectHeight = Fix64.One; Fix64 ballFlyTime = Fix64.Zero; bool canHit = ball.estimateHit(actor.direction, -FixVector2.dot(actor.getPosition(), actor.direction), out ballFlyTime, out intersectPoint, out intersectHeight); if (!canHit) { Debuger.Log("Can not fly to doorkeeper"); return; } #if UNITY_EDITOR LogicEvent.fire("onDoorKeeperCatchingBallView", actor, intersectPoint, intersectHeight); #endif FixVector2 toward = intersectPoint - actor.getPosition(); Fix64 distance = toward.length; int cathingZoneIndex = -1; if (distance < actor.configuration.dkcb_edgeLimit[0]) { if (intersectHeight < actor.configuration.dkcb_edgeLimit[1]) { //a区 cathingZoneIndex = 0; } else if (intersectHeight < actor.configuration.dkcb_edgeLimit[2]) { //b区 cathingZoneIndex = 1; } else if (intersectHeight < actor.configuration.dkcb_edgeLimit[3]) { //c区 cathingZoneIndex = 2; } else { //H区,直接返回,不处理 cathingZoneIndex = -1; } } else if (distance < actor.configuration.dkcb_edgeLimit[6]) { if (intersectHeight < actor.configuration.dkcb_edgeLimit[4]) { //fe区 cathingZoneIndex = 4; } else if (intersectHeight < actor.configuration.dkcb_edgeLimit[5]) { //gd区 cathingZoneIndex = 3; } else { cathingZoneIndex = -1; } } else { //H区,直接返回,不处理 cathingZoneIndex = -1; } bool pretendCatchingBall = false; if ((cathingZoneIndex == 3 || cathingZoneIndex == 4)) { //修改获取球的区域 Fix64 rightDoorV = shooter.team == FBTeam.kBlue ? new Fix64(1) : new Fix64(-1); FixVector2 doorPosition = new FixVector2(config.worldSize.x * rightDoorV, Fix64.Zero); Fix64 s = (shooter.getPosition() - doorPosition).length; if (s > shooter.configuration.maxGoalDistance) { s = shooter.configuration.maxGoalDistance; } Fix64 shootRate = ConstTable.ShootBall_GoalRate[(int)shooter.shootingType] * ball.getEnergy().goalRate *((Fix64)1.0f - s / shooter.configuration.maxGoalDistance); //失误计算 Fix64 randV = this.randomUnit; pretendCatchingBall = randV >= shootRate; Debuger.Log("ShootBall GoalRate:" + (float)shootRate + " random:" + (float)randV); if (pretendCatchingBall) { if (cathingZoneIndex == 3) { intersectHeight -= ConstTable.GoallKeeperPretendGetBallMissDistance; if (intersectHeight < actor.configuration.dkcb_edgeLimit[4]) { cathingZoneIndex = 4; } } if (cathingZoneIndex == 4) { intersectHeight += ConstTable.GoallKeeperPretendGetBallMissDistance; if (intersectHeight > actor.configuration.dkcb_edgeLimit[4]) { cathingZoneIndex = 3; } } } } if (cathingZoneIndex != -1) { actor.doCathingGoalBall(new FixVector2(intersectPoint.x, intersectPoint.y), intersectHeight, ballFlyTime, cathingZoneIndex, pretendCatchingBall); } }
public FBActor findTarget(FBActor src, FixVector2 direction, int index, int teamMask, FBActor exclude) { Fix64 maxRadius = src.configuration.passBallMaxR[index]; Fix64 minRadius = src.configuration.passBallMinR[index]; Fix64 theta = src.configuration.passBallFov[index]; Fix64 bestRadius = m_ball.owner.configuration.passBallBestR[index]; if (theta <= Fix64.Zero) { return(null); } var cosTheta = Fix64.Cos(theta); List <FBActor> preferTargets = new List <FBActor>(); var actorCount = m_actors.Count; for (int i = 0; i < actorCount; i++) { var actor = m_actors[i]; if (actor == exclude || ((int)actor.team & teamMask) == 0) { continue; } var d = actor.particle.position - src.getPosition(); var len = d.length; if (len < minRadius || len > maxRadius) { continue; } var cos = Fix64.Zero; if (len == Fix64.Zero) { cos = Fix64.One; } else { cos = FixVector2.dot(d.normalized, direction); } if (cos < cosTheta) { continue; } preferTargets.Add(actor); } FixVector2 preferPoint = src.getPosition() + direction * bestRadius; preferTargets.Sort(new FBActorTargetFindCompare(preferPoint)); FBActor destTarget = null; for (int i = 0; i < preferTargets.Count; ++i) { if (checkBlocked(src, preferTargets[i])) { continue; } destTarget = preferTargets[i]; break; } #if UNITY_EDITOR LogicEvent.fire("onMainCharacterPassingBall", src, direction, index, destTarget, preferTargets); #endif return(destTarget); }
public void endSample() { FixVector2 curPosition = getPosition(); var length = (curPosition - lastPosition).squareLength; var heightDelta = Fix64.Abs(height - lastHeight); if (forceCheck || length > (Fix64)0.0001f || height > Fix64.Zero) { if (height > Fix64.Zero) { world.fbGame.generateRenderAction <RAL.ActorMovingAction3D>(id, new FixVector3(curPosition.x, height, curPosition.y).toVector3(), ignorePositionSampleSlerp, (uint)defendMoveDirection); } else { world.fbGame.generateRenderAction <RAL.ActorMovingAction>(id, new FixVector2(curPosition.x, curPosition.y).toVector2(), ignorePositionSampleSlerp, (uint)defendMoveDirection); } if (endMove) { endMove = false; } } else { if (!endMove) { world.fbGame.generateRenderAction <RAL.ActorEndMoveAction>(id); endMove = true; } } if (checkMovingState() && particle.velocity != FixVector2.kZero && length <= (Fix64)1e-3) { world.fbGame.generateRenderAction <RAL.ChangeActorAnimatorSpeedAction>(id, (float)calculateAnimatorSpeedOfRun(0)); } if (ignorePositionSampleSlerp) { ignorePositionSampleSlerp = false; } bool sampleDirection = forceCheck || (!ignoreDirectionSample && FixVector2.dot(direction, lastDirection) < Fix64.One && direction != FixVector2.kZero); if (sampleDirection) { world.fbGame.generateRenderAction <RAL.TurningAction>(this.id, lastDirection.toVector2(), direction.toVector2(), ignoreDirectionSlerp); } if (ignoreDirectionSample) { ignoreDirectionSample = false; } if (ignoreDirectionSlerp) { ignoreDirectionSlerp = false; } if (forceCheck) { forceCheck = false; } }