public override void tick(float dt) { if (target == null || body == null) { return; } Quaternion bestDirAbs = MUtil.qToAxes(target.position - transform.position, Vector3.up); Quaternion baseRotAbs = transform.parent.rotation * initialLocalRot; Quaternion difference = baseRotAbs.rotSub(bestDirAbs); differenceDegrees = MyMath.abs(MyMath.angleNormalizeSigned(MyMath.acos(difference.w) * 2)) * 180f / MyMath.PI; if (differenceDegrees > maxPrepareAngle) { bestDirAbs = baseRotAbs; //look forward if the angle is more than maxPrepareAngle } else { bestDirAbs = Quaternion.RotateTowards(baseRotAbs, bestDirAbs, maxAngle); //try to look to the target, but not more than maxAngle } body.targetRot = bestDirAbs; }
private Quaternion getRotation() { // Debug.Log("getRotation: " + O.v + " " + X.v + " " + Y.v); if (forcedRotationEnabled) { return(forcedRotation); } if (xz) { x = xIsNormalizedRay ? X.v : (X.v - O.v).normalized; y = (yIsNormalizedRay ? Y.v : (Y.v - O.v).normalized).crossProduct(x); z = x.crossProduct(y); } else { x = xIsNormalizedRay ? X.v : (X.v - O.v).normalized; z = x.crossProduct(yIsNormalizedRay ? Y.v : (Y.v - O.v).normalized); y = z.crossProduct(x); } return(MUtil.qToAxes(x, y, z)); // return MUtil.matrix2quaternion(x, y, z); }
public void FixedUpdate() { if (!enabled) { return; } if (bodyRigid == null) { return; } if (cam == null) { return; } bool grabInput = focusGrabber != null && focusGrabber.grab; if (Application.isPlaying) { calcUpByLegs(); } float h = 0; int dockedCount = 0; for (int i = 0; i < moveen.engine.steps.Count; i++) { Step2 step = moveen.engine.steps[i]; if (!step.dockedState) { h += step.bestTargetProgressiveAbs.y; //to rise sharper } else { dockedCount++; h += step.posAbs.y; } // h += step.bestTargetProgressiveAbs.y; } float targetHeightMultiplier = jumpPreparing ? jumpPrepareHeightMul : jumpInProgress ? jumpTargetHeightMul : 1; h = moveen.engine.steps.Count == 0 ? height : (h / moveen.engine.steps.Count + height * targetHeightMultiplier); float maxSpeed = speed; if (Input.GetKey(KeyCode.LeftShift)) { maxSpeed *= runSpeedMultiplier; moveen.engine.runJumpTime = runJumpTime;//it adds additional jump force on the step } else { moveen.engine.runJumpTime = 0; } moveen.engine.horizontalMotor.maxSpeed = maxSpeed; Vector3 add = new Vector3(); bool movePressed = false; if (jumpStrengthCurTime < jumpPrepareTime) { if (jumpStrengthCurTime > 0) { //set only after space was released (jump started), as while space is pressed jumpStrengthCurTime is 0 moveen.engine.verticalMotor.copyFrom(jumpMotor); jumpInProgress = true; } jumpStrengthCurTime += Time.deltaTime; //revert old value when jump is ended if (jumpStrengthCurTime >= jumpPrepareTime) { moveen.engine.verticalMotor.copyFrom(previousVerticalMotor); jumpInProgress = false; } } //remember value from editor when not jumping if (jumpStrengthCurTime >= jumpPrepareTime) { previousVerticalMotor.copyFrom(moveen.engine.verticalMotor); } if (grabInput) { if (Input.GetKey(KeyCode.Space)) { jumpStrengthCurTime = 0; jumpPreparing = true; } else { jumpPreparing = false; } Vector3 upDown = localWasd ? new Vector3(1, 0, 0) : new Vector3(0, 0, 1); Vector3 leftRight = localWasd ? new Vector3(0, 0, 1) : new Vector3(-1, 0, 0); if (Input.GetKey(KeyCode.W) || debugMoveForward) { add += upDown; movePressed = true; } if (Input.GetKey(KeyCode.S)) { add -= upDown; movePressed = true; } if (Input.GetKey(KeyCode.A)) { add += leftRight; movePressed = true; } if (Input.GetKey(KeyCode.D)) { add -= leftRight; movePressed = true; } add = add.normalized(); add *= maxSpeed / moveen.engine.horizontalMotor.distanceToSpeed; if (!localWasd) { add = bodyRigid.transform.rotation.conjug().rotate(add); //global -> body local } //limit forward, strafe, and rear speed if (add.x > 0) { add.x = Math.Min(add.x, maxSpeed); } if (add.x < 0) { add.x = Math.Max(add.x, -maxSpeed * rearSpeedMultiplyer); } if (add.z > 0) { add.z = Math.Min(add.z, maxSpeed * strafeSpeedMultiplyer); } if (add.z < 0) { add.z = Math.Max(add.z, -maxSpeed * strafeSpeedMultiplyer); } add = bodyRigid.transform.rotation.rotate(add); //body local -> global } Vector3 newBestTargetPos = moveen.engine.imCenter.add(add).withSetY(h); if (quantCenter) { if (dockedCount == 0 || movePressed || newBestTargetPos.dist(transform.position) > quantSize) { transform.position = newBestTargetPos; } } else { transform.position = newBestTargetPos; } wantedCamera = moveen.engine.imCenter.withSetY(h); RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Quaternion wantedRot = transform.rotation; Vector3 hitPoint = new Vector3(); bool wasHit = false; if (grabInput) { wasHit = Physics.Raycast(ray.origin, ray.direction, out hit); //TODO cached hitPoint = hit.point; if (wasHit) { //lower target, because we are looking from the top, but the actor will be aiming from a side // but we don't want correct height for walls and terrain if (hit.normal.y > 0.5f && hit.point.y > hit.collider.transform.position.y) { hitPoint.y = hit.collider.transform.position.y; } //Debug.DrawLine(new Vector3(-100, -100, -100), hitPoint, Color.red); if (moveen.engine.imCenter.dist(hitPoint) > 1) { wantedRot = MUtil.qToAxes(hitPoint - moveen.engine.imCenter, Vector3.up); } } } oldCam = oldCam.mix(wantedCamera, camApproachFactor); if (grabInput) { cam.transform.position = cam.transform.position.mix(oldCam + camPosition + wantedRot.rotate(new Vector3(maxSpeed * camAheadMul, 0, 0)), 0.1f); cam.transform.eulerAngles = camRotation; } // cam.transform.position = oldCam + camPosition + wantedRot.rotate(new Vector3(maxSpeed, 0, 0)); if (dockedCount > 0) { //rotate target only if at least one leg is touching ground float cosOfHalfAngle = (float)Math.Cos(bodyRotReactionSpeed / 2 / 180f * Math.PI); //TODO cache Quaternion rotDif = wantedRot.rotSub(transform.rotation); if (rotDif.w < 0) { rotDif = rotDif.scale(-1); } if (rotDif.w < cosOfHalfAngle) { rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle); } transform.rotation = transform.rotation * rotDif; } else { //get rotation from the body when in air // because else - body could accumulate rotation it will be looking weird after grounding transform.rotation = moveen.targetRot; } moveen.targetPos = transform.position; moveen.targetRot = transform.rotation; //must be after this transform pos/rot change as target can be child of this if (wasHit && aimTarget != null) { aimTarget.position = hitPoint; } }
public override void tick(float dt) { resultRot = MUtil.qToAxes(targetAbs.v - basisAbs.v, YAbs.v); }