protected virtual void UpdateTarget() { if (_controller == null || (!_isFireDown && EventSystem.current.IsPointerOverGameObject())) { return; } var camera = Camera.main; if (camera == null) { return; } var mouse = Input.mousePosition; mouse.z = camera.nearClipPlane; var near = camera.ScreenToWorldPoint(mouse); mouse.z = camera.farClipPlane; var far = camera.ScreenToWorldPoint(mouse); Vector3 lookNormal; var lookPosition = Util.GetClosestHitIgnoreSide(near, far, 1, _actor.Side, out lookNormal); var groundPosition = lookPosition; var targetActor = AIUtil.FindClosestActor(lookPosition, 0.7f, _actor); if (targetActor != null) { groundPosition = targetActor.transform.position; } var ground = _actor.transform.position.y + 1.5f; if (_motor.ActiveWeapon.Gun != null) { ground = _motor.GunOrigin.y; } var displayMarkerOnGround = MarkerAlwaysOnGround || targetActor != null; if (targetActor != null && targetActor.Side != _actor.Side) { lookPosition.y = Vector3.Lerp(targetActor.transform.position, targetActor.TopPosition, 0.75f).y; } else if (lookPosition.y > _actor.transform.position.y - 0.5f && lookPosition.y <= ground) { var plane = new Plane(Vector3.up, -ground); var direction = (far - near).normalized; var ray = new Ray(near, direction); float enter; if (plane.Raycast(ray, out enter)) { lookPosition = near + direction * enter; displayMarkerOnGround = MarkerAlwaysOnGround; } } if (Marker != null) { Vector3 up; if (displayMarkerOnGround) { up = targetActor == null ? lookNormal : Vector3.up; Marker.transform.position = groundPosition + GroundLift * up; } else { Marker.transform.position = lookPosition; up = -_motor.GunDirection; } Vector3 right; if (Vector3.Distance(up, Vector3.forward) > 0.01f) { right = Vector3.right; } else { right = Vector3.Cross(up, Vector3.forward); } var forward = Vector3.Cross(right, up); Marker.transform.LookAt(Marker.transform.position + forward, up); } { var axis = Util.HorizontalAngle(camera.transform.forward); var top = _actor.transform.position + 1.5f * Vector3.up; var vector = lookPosition - top; vector.y = 0; var angle = Util.HorizontalAngle(vector); var distance = vector.magnitude; if (distance < 2 && distance > float.Epsilon) { var height = lookPosition.y; if (distance < 1) { Util.LerpAngle(ref _angle, angle, distance * 2); } else { _angle = angle; } lookPosition = top + Util.HorizontalVector(_angle) * 2; lookPosition.y = height; } else { _angle = angle; } } { var axis = Util.HorizontalAngle(camera.transform.forward); for (int i = 0; i < _snaps.Length; i++) { _snapWork[i] = Mathf.Abs(Mathf.DeltaAngle(axis + _snaps[i], _angle)); } var angle = axis; for (int i = 0; i < _snaps.Length; i++) { var isOk = true; for (int j = i + 1; j < _snaps.Length; j++) { if (_snapWork[j] < _snapWork[i]) { isOk = false; break; } } if (isOk) { angle = axis + _snaps[i]; break; } } _controller.BodyTargetInput = _actor.transform.position + Util.HorizontalVector(angle) * 10; } _controller.AimTargetInput = lookPosition; if (!_isSprinting && Mathf.Abs(Mathf.DeltaAngle(Util.HorizontalAngle(_motor.transform.forward), Util.HorizontalAngle(_controller.BodyTargetInput - _motor.transform.position))) > 90) { _motor.InputPossibleImmediateTurn(); } }