public static void drawSimpleSpiderGizmo(JunctionSimpleSpider junctionSimpleSpider, float size, Vector3 posAbs, Vector3 targetAbs) { UnityEditorUtils.cylinder(posAbs, MUtil.qToAxesXZ(junctionSimpleSpider.axisAbs, targetAbs), 1, 10, 0, 1 * size, 0.1f * size, 0.1f * size); UnityEditorUtils.cylinder(posAbs, MUtil.qToAxesXZ(junctionSimpleSpider.secondaryAxisAbs, junctionSimpleSpider.axisAbs), 1, 10, 0, 1 * size * 0.3f, 0.1f * size * 0.5f, 0.1f * size * 0.5f); }
private void Update() { if (ttl == -1) { return; } localTime += Time.deltaTime; speed += acceleration * Time.deltaTime; // angleSpeed += rotAccel * dt; Quaternion rot = transform.rotation; Quaternion rotForce = MUtil.toAngleAxis(angleSpeed.length() * Time.deltaTime, angleSpeed.normalized); rot = rotForce * rot; transform.SetPositionAndRotation(transform.position + speed * Time.deltaTime, rot); // scale += scaleSpeed * Time.deltaTime; // if (scale <= 0) Destroy(gameObject); // transform.localScale = new Vector3(scale, scale, scale); if (localTime >= ttl) { Destroy(gameObject); } }
//This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only). public override void OnValidate() { MUtil.logEvent(this, "OnValidate"); needsUpdate = true; if (!Application.isPlaying) { needsReset = true; } }
public void reset() { MUtil.logEvent(this, "reset"); //if (body == null) return; needsReset = false; engine.reset(transform.position, transform.rotation); targetPos = transform.position; targetRot = transform.rotation; }
protected override bool DoesPassCriteria(Player player) { if (!MUtil.TryGetStat <STAT_Happy>(player.gameObject, out StatItem stat)) { return(false); } return(stat.GetValue() > requiredAmount); }
public override void updateData() { base.updateData(); int newCount = transform.childCount; MUtil.madeCount(bonesDeltaPos, newCount); MUtil.madeCount(bonesDeltaRot, newCount); MUtil.madeCount(stepNumbers, newCount); }
private void updateBones() { MUtil.madeCount(bonesDeltaPos, bonesGeometry.Count); MUtil.madeCount(bonesDeltaRot, bonesGeometry.Count); for (int index = 0; index < bonesGeometry.Count; index++) { Bone bone = bones[index]; bone.attachedGeometry = bonesGeometry[index]; bone.deltaPos = bonesDeltaPos[index]; bone.deltaRot = bonesDeltaRot[index]; } }
//TODO call when needed only public override void updateData() { MUtil.logEvent(this, "updateData"); normalRel = normalRel.normalized; rotationJoint.axisRel = normalRel; elbowJoint.radius1 = r1; elbowJoint.radius2 = r2; bones[0].r = r1; bones[1].r = r2; maxLen = (r1 + r2) * 0.99f;//*0.99 because elbow junction "sticks" when it is close to the limit base.updateData(); }
public override void fixedTick(float dt) { base.fixedTick(dt); if (target == null) { if (transform.parent == null) { targetPos = initialLocalPos; } else { targetPos = transform.parent.TransformPoint(initialLocalPos); } } if (!Application.isPlaying) { return; } if (rotate) { Quaternion curRotAbs = transform.rotation; if (rb == null) { Vector3 rotAccel = Stepper5.torqueFromQuaternions(rotationMotor, curRotAbs, targetRot, angleSpeed, 1); angleSpeed += rotAccel * dt; Quaternion rotForce = MUtil.toAngleAxis(angleSpeed.length() * Time.deltaTime, angleSpeed.normalized); transform.rotation = rotForce * curRotAbs; } else { rb.AddTorque(Stepper5.torqueFromQuaternions(rotationMotor, curRotAbs, targetRot, rb.angularVelocity, 1), ForceMode.Acceleration); } } if (move) { Vector3 curPosAbs = transform.position; if (rb == null) { Vector3 accel = posMotor.getAccel(targetPos, curPosAbs, speed, 1); speed += accel * dt; transform.position = curPosAbs + speed * dt; } else { rb.AddForce(posMotor.getAccel(targetPos, curPosAbs, rb.velocity, 1), ForceMode.Acceleration); } } }
public override void OnEnable() { base.OnEnable(); MUtil.logEvent(this, "OnEnable"); needsUpdate = true; if (body != null) { bodyRigid = body.GetComponent <Rigidbody>(); } else { bodyRigid = GetComponent <Rigidbody>(); } }
public void fillOrigins(Vector3 xA1, float ar, Quaternion fromRot, Vector3 xB1, float br, Quaternion toRot, List <Vector3> poss, List <Quaternion> rots) { Vector3 vA = fromRot.rotate(new Vector3(ar, 0, 0)); Vector3 vB = toRot.rotate(new Vector3(-br, 0, 0)); Vector3 xA2 = xA1 + vA; Vector3 xB2 = xB1 + vB; poss[0] = xA1; Vector3 Z = fromRot.rotate(new Vector3(0, 0, 1)); // Vector3 Z = -vA.crossProduct(xB1 - xA1); Quaternion startRotDif = Quaternion.identity; Quaternion endRotDif = Quaternion.identity; if (simpleOrientation) { rots[0] = MUtil.qToAxesXZ(vA, Z); } else { startRotDif = fromRot.rotSub(MUtil.qToAxesXZ(vA, Z)); endRotDif = toRot.rotSub(MUtil.qToAxesXZ(-vB, Z)); rots[0] = fromRot; } Vector3 lastPos = poss[0]; for (int i = 1; i < poss.Count; i++) { float progress = (float)i / (poss.Count - 1); Vector3 bb = xA2.mix(xB2, progress); Vector3 currentPos = xA1.mix(bb, progress).mix(bb.mix(xB1, progress), progress); poss[i] = currentPos; rots[i] = MUtil.qToAxesXZ(currentPos - lastPos, Z); if (!simpleOrientation) { rots[i] = rots[i] * startRotDif.nlerp(endRotDif, progress); } lastPos = currentPos; } if (!simpleOrientation) { rots[rots.Count - 1] = toRot; } }
public override void updateData() { MUtil.logEvent(this, "updateData"); // rotJoint.axisRel = axis; rotJoint.axisRel = rotJoint.axisRel.normalized; rotJoint.secondaryAxisRel = rotJoint.secondaryAxisRel.normalized; elbowJoint.radius1 = r1; elbowJoint.radius2 = r2; bones[0].r = r1; bones[1].r = r2; bones[2].r = footPlatformHeight; minLen = Math.Abs(r1 - r2) * 1.1f; maxLen = r1 + r2; base.updateData(); }
// [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.Active)] // [DrawGizmo(GizmoType.InSelectionHierarchy | GizmoType.NonSelected | GizmoType.Active)] public static void OnDrawGizmos(MoveenSkelWithBones component) { if (!component.isActiveAndEnabled) { return; } Gizmos.color = BONE_COLOR; for (int i = 0; i < component.bones.Count; i++) { Bone bone = component.bones[i]; bone.origin.tick(); //TODO ensure tick in root if (bone.origin.getRot().magnitude() < 0.3f) { MUtil.log(component, "wrong quaternion: " + bone.origin.getRot()); //Debug.Log(" " + i); continue; } UnityEditorUtils.diamond(bone.origin.getPos(), bone.origin.getRot().normalized(), bone.r); } Type type = component.GetType(); Gizmos.color = Color.green; for (int index = 0; index < type.GetFields().Length; index++) { FieldInfo field = type.GetFields()[index]; if (field.FieldType == typeof(Vector3)) { if (field.GetCustomAttributes(typeof(CustomSkelResultAttribute), true).Length != 0) { Vector3 cur = (Vector3)field.GetValue(component); Gizmos.DrawWireSphere(cur, 0.04f); } } if (field.FieldType == typeof(P <Vector3>)) { if (field.GetCustomAttributes(typeof(CustomSkelResultAttribute), true).Length != 0) { P <Vector3> cur = (P <Vector3>)field.GetValue(component); Gizmos.DrawWireSphere(cur.v, 0.04f); } } } }
public virtual void reset(Vector3 pos, Quaternion rot) { MUtil.logEvent(this, ("reset " + pos)); this.comfortRadius = ((this.maxLen * 0.5f) * this.comfortRadiusRatio); this.bodyPos = pos; this.bodyRot = rot; this.bestTargetConservativeUnprojAbs = (Step2.toAbs(this.comfortPosRel, this.bodyPos, rot) + this.additionalDisplacement); this.bestTargetConservativeAbs = this.bestTargetConservativeUnprojAbs; this.bestTargetProgressiveAbs = this.bestTargetConservativeUnprojAbs; this.posAbs = this.bestTargetConservativeUnprojAbs; this.oldPosAbs = this.bestTargetConservativeUnprojAbs; this.speedAbs = new Vector3(); this.acceleration = new Vector3(); this.undockPauseCur = 0; this.airTime = 0; this.undockProgress = 100500; this.undockCurTime = 100500; this.footOrientation = rot; }
//This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only). public override void OnValidate() { MUtil.logEvent(this, "OnValidate"); base.OnValidate(); int targetBonesCount = bones.Count; if (bonesGeometry.Count != targetBonesCount) { Debug.LogWarning("Don't change array size!"); if (bonesGeometry.Count > targetBonesCount) { bonesGeometry.RemoveRange(targetBonesCount, bonesGeometry.Count - targetBonesCount); } while (bonesGeometry.Count < targetBonesCount) { bonesGeometry.Add(null); } } needsUpdate = true; }
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; }
public override void updateData() { MUtil.logEvent(this, "updateData"); rotJoint.axisRel = rotJoint.axisRel.normalized; rotJoint.secondaryAxisRel = rotJoint.secondaryAxisRel.normalized; //((SkelLeg2) legSkel).updateRadiuses(step.footPlatformHeight, rA + rC * style, rB + rC * (1 - style), rA, rB, rC); if (style) { r1 = rA + styleRatio * rB; r2 = maxLen - r1; visibleElbowJoint.radius1 = rB; visibleElbowJoint.radius2 = rC; } else { r2 = rC + styleRatio * rB; r1 = maxLen - r2; visibleElbowJoint.radius1 = rA; visibleElbowJoint.radius2 = rB; } maxLen = rA + rB + rC; // minLen = 0; minLen = Math.Abs(r1 - r2) * 1.1f; // minLen = Math.Max(rA, Math.Max(rB, Math.Max(rC, Math.Abs(r1 - r2)))); invisibleElbowJoint.radius1 = r1; invisibleElbowJoint.radius2 = r2; bones[0].r = rA; bones[1].r = rB; bones[2].r = rC; bones[3].r = footPlatformHeight; base.updateData(); }
public static void draw2DLeg(Vector3 X, Vector3 Y, Vector3 pos, float size) { // Vector3 Z = X.crossProduct(Y); // X = Y.crossProduct(Z).normalized; // Gizmos.DrawLine(h.transform.position, h.transform.position + X * 0.2f + Y * 0.2f); // Gizmos.DrawLine(h.transform.position + X * 0.2f + Y * 0.2f, h.transform.position + X * 0.4f); Quaternion rot = MUtil.qToAxesXZ(X, Y); GL.PushMatrix(); GL.LoadProjectionMatrix(Camera.current.projectionMatrix); GL.MultMatrix(Matrix4x4.TRS( pos, rot * Quaternion.AngleAxis(-45, Vector3.up), new Vector3(size, size, size))); diamond2d(); GL.MultMatrix(Matrix4x4.TRS( pos + rot.rotate(new Vector3(size * MyMath.cos(MyMath.PI / 4), 0, size * MyMath.cos(MyMath.PI / 4))), rot * Quaternion.AngleAxis(45, Vector3.up), new Vector3(size, size, size))); diamond2d(); GL.PopMatrix(); }
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 override void updateData() { base.updateData(); MUtil.madeCount(poss, stepsCount + 2); MUtil.madeCount(rots, stepsCount + 2); }
public override StatItem GetStat(GameObject source) { return(MUtil.GetStat <STAT_Balance>(source)); }
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; }
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 override StatItem GetStat(GameObject source) { return(MUtil.GetStat <STAT_MoveSpeed>(source)); }
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 void OnTransformChildrenChanged() { MUtil.logEvent(this, "OnTransformChildrenChanged"); needsUpdate = true; }
public override void tick(float dt) { resultRot = MUtil.qToAxes(targetAbs.v - basisAbs.v, YAbs.v); }
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; }
private void Create() { if (!this.deposit.DBManager.DynamicProperties.SupportVM()) { throw new ContractValidateException("vm work is off, need to be opened by the committee"); } CreateSmartContract contract = ContractCapsule.GetSmartContractFromTransaction(this.transaction); if (contract == null) { throw new ContractValidateException("Cannot get CreateSmartContract from transaction"); } SmartContract new_contract = contract.NewContract; if (!contract.OwnerAddress.Equals(new_contract.OriginAddress)) { Logger.Info("OwnerAddress not equals OriginAddress"); throw new VMIllegalException("OwnerAddress is not equals OriginAddress"); } byte[] contract_name = Encoding.UTF8.GetBytes(new_contract.Name); if (contract_name.Length > VMParameter.CONTRACT_NAME_LENGTH) { throw new ContractValidateException("contractName's length cannot be greater than 32"); } long percent = contract.NewContract.ConsumeUserResourcePercent; if (percent < 0 || percent > DefineParameter.ONE_HUNDRED) { throw new ContractValidateException("percent must be >= 0 and <= 100"); } byte[] contract_address = Wallet.GenerateContractAddress(this.transaction); if (this.deposit.GetAccount(contract_address) != null) { throw new ContractValidateException( "Trying to create a contract with existing contract address: " + Wallet.AddressToBase58(contract_address)); } new_contract.ContractAddress = ByteString.CopyFrom(contract_address); long call_value = new_contract.CallValue; long token_value = 0; long token_id = 0; if (VMConfig.AllowTvmTransferTrc10) { token_value = contract.CallTokenValue; token_id = contract.TokenId; } byte[] caller_address = contract.OwnerAddress.ToByteArray(); try { long fee_limit = this.transaction.RawData.FeeLimit; if (fee_limit < 0 || fee_limit > VMConfig.MAX_FEE_LIMIT) { Logger.Info(string.Format("invalid feeLimit {0}", fee_limit)); throw new ContractValidateException( "feeLimit must be >= 0 and <= " + VMConfig.MAX_FEE_LIMIT); } AccountCapsule creator = this.deposit.GetAccount(new_contract.OriginAddress.ToByteArray()); long energy_limit = 0; if (VMConfig.EnergyLimitHardFork) { if (call_value < 0) { throw new ContractValidateException("callValue must >= 0"); } if (token_value < 0) { throw new ContractValidateException("tokenValue must >= 0"); } if (new_contract.OriginEnergyLimit <= 0) { throw new ContractValidateException("The originEnergyLimit must be > 0"); } energy_limit = GetAccountEnergyLimitWithFixRatio(creator, fee_limit, call_value); } else { energy_limit = GetAccountEnergyLimitWithFloatRatio(creator, fee_limit, call_value); } CheckTokenValueAndId(token_value, token_id); byte[] ops = new_contract.Bytecode.ToByteArray(); this.root_internal_transaction = new InternalTransaction(this.transaction, this.transaction_type); long max_cpu_time_tx = this.deposit.DBManager.DynamicProperties.GetMaxCpuTimeOfOneTx() * DefineParameter.ONE_THOUSAND; long tx_cpu_limit = (long)(max_cpu_time_tx * GetCpuLimitInUsRatio()); long vm_start = Helper.NanoTime() / DefineParameter.ONE_THOUSAND; long vm_should_end = vm_start + tx_cpu_limit; IProgramInvoke invoke = this.invoke_factory.CreateProgramInvoke(TransactionType.TX_CONTRACT_CREATION_TYPE, this.executor_type, this.transaction, token_value, token_id, this.block.Instance, this.deposit, vm_start, vm_should_end, energy_limit); this.vm = new Vm(); this.program = new Program(ops, invoke, this.root_internal_transaction, this.block); byte[] tx_id = new TransactionCapsule(this.transaction).Id.Hash; this.program.RootTransactionId = tx_id; // TODO: EventPluginLoader is not Implementation //if (this.enable_listener // && (EventPluginLoader.getInstance().isContractEventTriggerEnable() // || EventPluginLoader.getInstance().isContractLogTriggerEnable()) // && IsCheckTransaction) //{ // logInfoTriggerParser = new LogInfoTriggerParser(this.block.getNum(), this.block.getTimeStamp(), txId, callerAddress); //} } catch (Exception e) { Logger.Info(e.Message); throw new ContractValidateException(e.Message); } this.program.Result.ContractAddress = contract_address; this.deposit.CreateAccount(contract_address, new_contract.Name, AccountType.Contract); this.deposit.CreateContract(contract_address, new ContractCapsule(new_contract)); byte[] code = new_contract.Bytecode.ToByteArray(); if (!VMConfig.AllowTvmConstantinople) { deposit.SaveCode(contract_address, ProgramPrecompile.GetCode(code)); } if (call_value > 0) { MUtil.Transfer(this.deposit, caller_address, contract_address, call_value); } if (VMConfig.AllowTvmTransferTrc10) { if (token_value > 0) { MUtil.TransferToken(this.deposit, caller_address, contract_address, token_id.ToString(), token_value); } } }
private void Call() { if (!this.deposit.DBManager.DynamicProperties.SupportVM()) { Logger.Info("vm work is off, need to be opened by the committee"); throw new ContractValidateException("VM work is off, need to be opened by the committee"); } TriggerSmartContract contract = ContractCapsule.GetTriggerContractFromTransaction(this.transaction); if (contract == null) { return; } if (contract.ContractAddress == null) { throw new ContractValidateException("Cannot get contract address from TriggerContract"); } byte[] contract_address = contract.ContractAddress.ToByteArray(); ContractCapsule deployed_contract = this.deposit.GetContract(contract_address); if (null == deployed_contract) { Logger.Info("No contract or not a smart contract"); throw new ContractValidateException("No contract or not a smart contract"); } long call_value = contract.CallValue; long token_value = 0; long token_id = 0; if (VMConfig.AllowTvmTransferTrc10) { token_value = contract.CallTokenValue; token_id = contract.TokenId; } if (VMConfig.EnergyLimitHardFork) { if (call_value < 0) { throw new ContractValidateException("callValue must >= 0"); } if (token_value < 0) { throw new ContractValidateException("tokenValue must >= 0"); } } byte[] caller_address = contract.OwnerAddress.ToByteArray(); CheckTokenValueAndId(token_value, token_id); byte[] code = this.deposit.GetCode(contract_address); if (code != null && code.Length > 0) { long fee_limit = this.transaction.RawData.FeeLimit; if (fee_limit < 0 || fee_limit > VMConfig.MAX_FEE_LIMIT) { Logger.Info(string.Format("invalid feeLimit {0}", fee_limit)); throw new ContractValidateException( "feeLimit must be >= 0 and <= " + VMConfig.MAX_FEE_LIMIT); } AccountCapsule caller = this.deposit.GetAccount(caller_address); long energy_limit = 0; if (this.is_static_call) { energy_limit = DefineParameter.ENERGY_LIMIT_IN_CONSTANT_TX; } else { AccountCapsule creator = this.deposit.GetAccount(deployed_contract.Instance.OriginAddress.ToByteArray()); energy_limit = GetTotalEnergyLimit(creator, caller, contract, fee_limit, call_value); } long max_cpu_time_tx = this.deposit.DBManager.DynamicProperties.GetMaxCpuTimeOfOneTx() * DefineParameter.ONE_THOUSAND; long tx_cpu_limit = (long)(max_cpu_time_tx * GetCpuLimitInUsRatio()); long vm_start = Helper.NanoTime() / DefineParameter.ONE_THOUSAND; long vm_should_end = vm_start + tx_cpu_limit; IProgramInvoke invoke = this.invoke_factory.CreateProgramInvoke(TransactionType.TX_CONTRACT_CALL_TYPE, this.executor_type, this.transaction, token_value, token_id, this.block.Instance, this.deposit, vm_start, vm_should_end, energy_limit); if (this.is_static_call) { invoke.IsStaticCall = true; } this.vm = new Vm(); this.root_internal_transaction = new InternalTransaction(this.transaction, this.transaction_type); this.program = new Program(code, invoke, this.root_internal_transaction, this.block); byte[] tx_id = new TransactionCapsule(this.transaction).Id.Hash; this.program.RootTransactionId = tx_id; // // TODO: EventPluginLoader is not Implementation //if (enableEventLinstener && // (EventPluginLoader.getInstance().isContractEventTriggerEnable() // || EventPluginLoader.getInstance().isContractLogTriggerEnable()) // && isCheckTransaction()) //{ // logInfoTriggerParser = new LogInfoTriggerParser(this.block.getNum(), this.block.getTimeStamp(), txId, callerAddress); //} } this.program.Result.ContractAddress = contract_address; if (call_value > 0) { MUtil.Transfer(this.deposit, caller_address, contract_address, call_value); } if (VMConfig.AllowTvmTransferTrc10) { if (token_value > 0) { MUtil.TransferToken(this.deposit, caller_address, contract_address, token_id.ToString(), token_value); } } }