protected override void Update() { base.Update(); if (!CombatHandler.Instance.DisableMovement && !SelfTank.DisableMovement) { SelfTank.HandleInput(); } }
protected override void Update() { base.Update(); if (CombatDebugHandler.Instance.MoveTestDebugOn) { Vector2 targetPos = CombatDebugHandler.Instance.TargetPosForMoveTest; Vector2 requestDir = targetPos - (Vector2)SelfTank.transform.position; requestDir = AvoidWalls(requestDir); SelfTank.PerformActuation(requestDir.normalized); } else { if (!CombatHandler.Instance.DisableMovement && !SelfTank.DisableMovement) { //TargetTank.MarkCurPositionAsBlockedOnMap(Map); updateGoalsAndPerformActions(); } CombatDebugHandler.Instance.RegisterObject("goal", curGoal); } }
public Vector2 AvoidWalls(Vector2 desiredDir) { Vector2 forwardVec = SelfTank.GetForwardVec(); Vector2 leftVec = forwardVec.Rotate(-90); Vector2 rightVec = forwardVec.Rotate(90); Vector2 backVec = forwardVec.Rotate(180); // If below 90, ray starting points should be in front of tank. Otherwise, behind tank. if (Mathf.Abs(Vector2.SignedAngle(forwardVec, desiredDir.normalized)) > 90) { Vector2 tmpVec = leftVec; leftVec = rightVec; rightVec = tmpVec; tmpVec = forwardVec; forwardVec = backVec; backVec = tmpVec; } float xAdd = SelfTank.Hull.Schematic.Size.x / 2f; float yAdd = SelfTank.Hull.Schematic.Size.y / 2f; Vector2 TopCenter = (Vector2)SelfTank.transform.position + forwardVec * yAdd; Vector2 TLCorner = (Vector2)SelfTank.transform.position + forwardVec * yAdd + leftVec * xAdd; Vector2 TRCorner = (Vector2)SelfTank.transform.position + forwardVec * yAdd + rightVec * xAdd; // If Collision, then take into account desired Dir and see if risk of collision const int WallBit = 8; const int PlayerBit = 9; const int LayerMask = 1 << WallBit | 1 << PlayerBit; const float DiagRatio = 0.8f; float fanRatio = Mathf.Clamp01((float)successiveCollisions / 100f); float maxDistance = Mathf.Max(SelfTank.Body.velocity.magnitude, 150f); RaycastHit2D[] hitResult = new RaycastHit2D[5]; hitResult[0] = Physics2D.Raycast(TopCenter, forwardVec, maxDistance, LayerMask); hitResult[1] = Physics2D.Raycast(TLCorner, forwardVec, maxDistance, LayerMask); hitResult[2] = Physics2D.Raycast(TRCorner, forwardVec, maxDistance, LayerMask); hitResult[3] = Physics2D.Raycast(TLCorner, (forwardVec * (1f - fanRatio) + leftVec * fanRatio).normalized, maxDistance * DiagRatio, LayerMask); hitResult[4] = Physics2D.Raycast(TRCorner, (forwardVec * (1f - fanRatio) + rightVec * fanRatio).normalized, maxDistance * DiagRatio, LayerMask); if (Application.isEditor && CombatDebugHandler.Instance.AvoidWallsDebugOn) { Debug.DrawLine(TopCenter, TopCenter + forwardVec.normalized * maxDistance, Color.blue); Debug.DrawLine(TLCorner, TLCorner + forwardVec.normalized * maxDistance, Color.blue); Debug.DrawLine(TRCorner, TRCorner + forwardVec.normalized * maxDistance, Color.blue); Debug.DrawLine(TLCorner, TLCorner + (forwardVec * (1f - fanRatio) + leftVec * fanRatio).normalized * maxDistance * DiagRatio, Color.blue); Debug.DrawLine(TRCorner, TRCorner + (forwardVec * (1f - fanRatio) + rightVec * fanRatio).normalized * maxDistance * DiagRatio, Color.blue); } bool centerHit = hitResult[0].collider != null; bool leftFordHit = hitResult[1].collider != null; bool rightFordHit = hitResult[2].collider != null; bool leftDiagHit = hitResult[3].collider != null; bool rightDiagHit = hitResult[4].collider != null; bool leftHit = leftFordHit || leftDiagHit; bool rightHit = rightFordHit || rightDiagHit; Vector2 newDesiredDir = desiredDir; const float MinBlend = 0.05f; const float MaxBlend = 1.0f; successiveCollisions += (centerHit || leftHit || rightHit) ? 1 : 0; if (leftHit && !rightHit) { float minHitDist = 9999; if (leftFordHit) { minHitDist = Mathf.Min(hitResult[1].distance, minHitDist); } if (leftDiagHit) { minHitDist = Mathf.Min(hitResult[3].distance, minHitDist); } float blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend); Vector2 dodgeVec = desiredDir.Rotate(90); newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized; } else if (rightHit && !leftHit) { float minHitDist = 9999; if (rightFordHit) { minHitDist = Mathf.Min(hitResult[2].distance, minHitDist); } if (rightDiagHit) { minHitDist = Mathf.Min(hitResult[4].distance, minHitDist); } float blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend); Vector2 dodgeVec = desiredDir.Rotate(-90); newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized; } else if (centerHit) { Vector2 obstCenterPos = hitResult[0].collider.transform.position; Vector2 diffVec = obstCenterPos - (Vector2)SelfTank.transform.position; float angle = Vector2.SignedAngle(forwardVec, diffVec); float minHitDist = hitResult[0].distance; if (angle > 0) { float blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend); Vector2 dodgeVec = desiredDir.Rotate(-90); newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized; } else { float blendRatio = Mathf.Clamp(minHitDist / maxDistance, MinBlend, MaxBlend); Vector2 dodgeVec = desiredDir.Rotate(90); newDesiredDir = (blendRatio * desiredDir + (1.0f - blendRatio) * dodgeVec).normalized; } } else { successiveCollisions = 0; } return(newDesiredDir); }