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) { !!falls through on BM2 as best target can be -100500 // 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; } if (Input.GetKey(KeyCode.W) || debugMoveForward) { add += new Vector3(1, 0, 0); movePressed = true; } if (Input.GetKey(KeyCode.S)) { add += new Vector3(-1, 0, 0); movePressed = true; } if (Input.GetKey(KeyCode.A)) { add += new Vector3(0, 0, 1); movePressed = true; } if (Input.GetKey(KeyCode.D)) { add += new Vector3(0, 0, -1); movePressed = true; } add = add.normalized(); add *= (maxSpeed / moveen.engine.horizontalMotor.distanceToSpeed); //cam local add = MUtil.toAngleAxis(camYaw, new Vector3(0, 1, 0)).rotate(add); //cam local -> global add = bodyRigid.transform.rotation.conjug().rotate(add); //global -> body local 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 = transform.rotation.rotate(add); //body local -> global add = bodyRigid.transform.rotation.rotate(add); //body local -> global // transform.position = body.transform.position + body.transform.rotation.rotate(add); } 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 = bodyRigid.position.withSetY(h); // wantedCamera = transform.position.limit(bodyRigid.position.withSetY(h), maxSpeed / 2).withSetY(h);//мерзко дрожит камера на больших скоростях if (grabInput) { float mx = Input.GetAxis("Mouse X") * 0.04f / Time.timeScale; float my = Input.GetAxis("Mouse Y") * -0.04f / Time.timeScale; camPitch = MyMath.clamp(camPitch + my, -1, 1); if (!debugFreezeRotation) { camYaw = MyMath.angleNormalizeSigned(camYaw + mx); //comment to stop reacting on mouse } if (debugRotateRight) { camYaw = MyMath.angleNormalizeSigned(camYaw + 0.3f * 0.05f); //uncomment to add constant rotation for test } } Quaternion yawRoll = MUtil.toAngleAxis(camYaw, new Vector3(0, 1, 0)); Quaternion rotForCameraLook = yawRoll * MUtil.toAngleAxis((float)(Math.PI / 2), new Vector3(0, 1, 0)) * MUtil.toAngleAxis(camPitch, new Vector3(1, 0, 0)); Quaternion rotForCameraPos = yawRoll; Quaternion rotForTarget; // 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); // } // } else { // hitPoint = ray.origin + ray.direction * 40; // wasHit = true; // } // } // // yawRoll = Quaternion.FromToRotation(moveen.transform.rotation.rotate(Vector3.right), hitPoint.sub(moveen.transform.position)); // rotForCameraPos = yawRoll; // // // //must be after this transform pos/rot change as target can be child of this // if (wasHit && aimTarget != null) aimTarget.position = hitPoint; if (inclineBodyToLegs) { rotForTarget = MUtil.qToAxesYX(Vector3.up.mix(upByLegs, inclineBodyToLegsRatio), yawRoll.rotate(new Vector3(1, 0, 0))); // rotForTarget = MUtil.qToAxes(yawRoll.rotate(new Vector3(1, 0, 0)), upByLegs); } else { rotForTarget = yawRoll * MUtil.toAngleAxis(camPitch * -0.5f, new Vector3(0, 0, 1)); } if (grabInput) { cam.transform.rotation = rotForCameraLook; oldCam = oldCam.mix(wantedCamera, camApproachFactor); cam.transform.position = oldCam + rotForCameraPos.rotate(camPosition); } // float reactionSpeed = bodyRotReactionSpeed; // if (bodyRigid != null) reactionSpeed /= Math.Max(1, bodyRigid.velocity.length() * bodyRotReactionSpeedSpeed); 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 = rotForTarget.rotSub(transform.rotation); if (rotDif.w < 0) { rotDif = rotDif.scale(-1); } if (rotDif.w < cosOfHalfAngle) { rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle); } transform.rotation = transform.rotation * rotDif; // transform.rotation = rotForTarget; } 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; }
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; } if (Input.GetKey(KeyCode.W) || debugMoveForward) { add += new Vector3(1, 0, 0); movePressed = true; } if (Input.GetKey(KeyCode.S)) { add += new Vector3(-1, 0, 0); movePressed = true; } if (Input.GetKey(KeyCode.A)) { add += new Vector3(0, 0, 1); movePressed = true; } if (Input.GetKey(KeyCode.D)) { add += new Vector3(0, 0, -1); movePressed = true; } add = add.normalized(); add *= (maxSpeed / moveen.engine.horizontalMotor.distanceToSpeed); //cam local // add = MUtil.toAngleAxis(camYaw, new Vector3(0, 1, 0)).rotate(add); //cam local -> global // add = bodyRigid.transform.rotation.conjug().rotate(add); //global -> body local 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 = transform.rotation.rotate(add); //body local -> global add = bodyRigid.transform.rotation.rotate(add); //body local -> global // transform.position = body.transform.position + body.transform.rotation.rotate(add); } 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; } float leftRight = 0; if (grabInput) { float my = Input.GetAxis("Mouse Y") * -0.02f / Time.timeScale; leftRight = (Input.mousePosition.x / Screen.width - 0.5f) * 2; if (debugFreezeRotation) { leftRight = 0; } if (debugRotateRight) { leftRight = 0.5f; } if (leftRight > 0) { leftRight = MyMath.smoothstep(0, 1, leftRight); } else { leftRight = -MyMath.smoothstep(0, 1, -leftRight); } camPitch = MyMath.clamp(camPitch + my, -1, 1); } // RaycastHit hit; // Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // Quaternion yawRoll = Quaternion.AngleAxis(leftRight * 10, Vector3.up) * transform.rotation; Quaternion yawRoll = Quaternion.AngleAxis(leftRight * 10, Vector3.up) * MUtil.qToAxesYX(Vector3.up, transform.rotation.rotate(Vector3.right)); // Quaternion yawRoll = Quaternion.FromToRotation(moveen.engine.realBodyRot.rotate(Vector3.right), hitPoint.sub(moveen.transform.position)); Quaternion rotForCameraPos = yawRoll * MUtil.toAngleAxis(-camPitch * 0.5f, new Vector3(0, 0, 1)); // Quaternion rotForCameraLook = rotForCameraPos; Quaternion rotForCameraLook = yawRoll * MUtil.toAngleAxis((float)(Math.PI / 2), new Vector3(0, 1, 0)) * MUtil.toAngleAxis(camPitch, new Vector3(1, 0, 0)); Vector3 wantedDir = yawRoll.rotate(new Vector3(1, 0, 0)); // if (wantedDir.scalarProduct(moveen.engine.inputWantedRot.rotate(Vector3.right)) > 0.95f) { // yawRoll = transform.rotation; // wantedDir = yawRoll.rotate(new Vector3(1, 0, 0)); // } Quaternion rotForTarget; if (inclineBodyToLegs) { rotForTarget = MUtil.qToAxesYX(Vector3.up.mix(upByLegs, inclineBodyToLegsRatio), wantedDir); // rotForTarget = MUtil.qToAxes(yawRoll.rotate(new Vector3(1, 0, 0)), upByLegs); } else { rotForTarget = yawRoll * MUtil.toAngleAxis(camPitch * -0.5f, new Vector3(0, 0, 1)); } if (grabInput) { Vector3 wantedCamera = moveen.engine.imCenter.withSetY(h); cam.transform.rotation = rotForCameraLook; oldCam = oldCam.mix(wantedCamera, camApproachFactor); cam.transform.position = oldCam + rotForCameraPos.rotate(camPosition); } // float reactionSpeed = bodyRotReactionSpeed; // if (bodyRigid != null) reactionSpeed /= Math.Max(1, bodyRigid.velocity.length() * bodyRotReactionSpeedSpeed); 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 = rotForTarget.rotSub(transform.rotation); if (rotDif.w < 0) { rotDif = rotDif.scale(-1); } if (rotDif.w < cosOfHalfAngle) { rotDif = rotDif.normalizeWithFixedW(cosOfHalfAngle); } transform.rotation = transform.rotation * rotDif; // transform.rotation = rotForTarget; } 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 void FixedUpdate() { if (!enabled) { return; } if (bodyRigid == null) { return; } if (Application.isPlaying) { calcUpByLegs(); } //calc h 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); moveen.engine.horizontalMotor.maxSpeed = speed; 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); } Vector3 add = moveDir.normalized; add *= speed / moveen.engine.horizontalMotor.distanceToSpeed; 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, speed); } if (add.x < 0) { add.x = Math.Max(add.x, -speed * rearSpeedMultiplyer); } if (add.z > 0) { add.z = Math.Min(add.z, speed * strafeSpeedMultiplyer); } if (add.z < 0) { add.z = Math.Max(add.z, -speed * strafeSpeedMultiplyer); } add = bodyRigid.transform.rotation.rotate(add); //body local -> global Vector3 newBestTargetPos = moveen.engine.imCenter.add(add).withSetY(h); if (quantCenter) { if (dockedCount == 0 || moveDir.length() > 0 || newBestTargetPos.dist(transform.position) > quantSize) { transform.position = newBestTargetPos; } } else { transform.position = newBestTargetPos; } Quaternion rotForTarget; if (inclineBodyToLegs) { Vector3 wantedForward = chassisRot.rotate(Vector3.right); Vector3 wantedUp = chassisRot.rotate(Vector3.up); Vector3 up = wantedUp.mix(upByLegs, inclineBodyToLegsRatio); rotForTarget = MUtil.qToAxesYX(up, wantedForward); } else { rotForTarget = chassisRot; } 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 = rotForTarget.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; }
private void Update() { mc3.aimTarget.position = lookPos; if (mc3 == null) { return; } if (mc3.moveen == null) { return; } thinkPause -= Time.deltaTime; idlePause -= Time.deltaTime; lookPause -= Time.deltaTime; if (thinkPause > 0) { return; } thinkPause += 0.1f; mc3.moveDir = Vector3.zero; //mc3.aimPos = Vector3.zero; if (lookPause < 0) { lookPause += Random.value * 2 + 1; if (mc3.aimTarget != null) { lookPos = mc3.moveen.transform.position + mc3.moveen.transform.rotation.rotate(Vector3.right) * 10 + (Random.insideUnitCircle * 2).withY(Random.value * 2 - 1); } } if (ci != null) { CharInfo closestToMe = ci.getClosestToMe(c => true); // CharInfo closestToMe = ci.getClosestToMe(c => !c.team.Equals(ci.team)); if (closestToMe != null) { Vector3 hisPos = closestToMe.transform.position; Vector3 myPos = transform.position; if (hisPos.dist(myPos) < 5) { placeToGo = new P <Vector3>(myPos + myPos.sub(hisPos) * 10 + Random.insideUnitCircle.withY(0) * 5); } } } if (placeToGo != null) { Vector3 dir = placeToGo.v.sub(mc3.moveen.engine.imCenter); mc3.chassisRot = MUtil.qToAxesYX(Vector3.up, dir); Vector3 dir0 = dir.withSetY(0); mc3.moveDir = dir0; if (dir0.length() < 1) { placeToGo = null; mc3.moveDir = Vector3.zero; } return; } if (idlePause > 0) { return; } chooseAction(); }