/// <summary> /// Create a rotation velocity that rotates the character based on input /// </summary> /// <param name="rInputFromAvatarAngle"></param> /// <param name="rDeltaTime"></param> protected virtual void RotateActorToTarget(Transform rTarget, float rSpeed) { // Get the forward looking direction Vector3 lForward = (rTarget.position - mActorController._Transform.position).normalized; // We do the inverse tilt so we calculate the rotation in "natural up" space vs. "actor up" space. Quaternion lInvTilt = QuaternionExt.FromToRotation(mActorController._Transform.up, Vector3.up); // Character's forward direction of the actor in "natural up" Vector3 lActorForward = lInvTilt * mActorController._Transform.forward; // Target forward in "natural up" Vector3 lTargetForward = lInvTilt * lForward; // Ensure we don't exceed our rotation speed float lActorToTargetAngle = NumberHelper.GetHorizontalAngle(lActorForward, lTargetForward); if (rSpeed > 0f && Mathf.Abs(lActorToTargetAngle) > rSpeed * Time.deltaTime) { lActorToTargetAngle = Mathf.Sign(lActorToTargetAngle) * rSpeed * Time.deltaTime; } // Add the rotation to our character Quaternion lRotation = Quaternion.AngleAxis(lActorToTargetAngle, Vector3.up); if (mActorController._UseTransformPosition && mActorController._UseTransformRotation) { _Transform.rotation = _Transform.rotation * lRotation; } else { mActorController.Rotate(lRotation, Quaternion.identity); } }
/*public CollisionType GetTheSafestCallision() * { * return ((CollisionType)WhatKindOfNormalIsIt(DefineWhichNormalToChose())); * }*/ /// <summary> /// ici défini la normal de la somme des 4 collisions, /// et le type de collision que cela implique /// </summary> private void DefineNormalAndCollision() { //set new normal / collision normalSumCollide = QuaternionExt.GetMiddleOfXVector(colliderNormalArray); if (normalSumCollide == Vector3.zero) { //Debug.Log("PUTAIN POURQUOI C'4EST ZERO"); // normalSumCollide = Vector3.up; } //save previous collision / normal Vector3 normalToChose = DefineWhichNormalToChose(); CollisionType tmpCollision = (CollisionType)WhatKindOfNormalIsIt(normalToChose); if (tmpCollision == CollisionType.InAir && collisionType != CollisionType.InAir) { lastCollisionTypePersist = collisionType; normalSumCollidePrevious = normalSumCollide; } if (tmpCollision == CollisionType.Ground) { //Debug.Log("normalToCHose: " + normalToChose); for (int i = 0; i < colliderNormalArray.Length; i++) { //Debug.Log(colliderNormalArray[i]); } //Debug.Break(); } collisionType = tmpCollision; }
/// <summary> /// Allows the motor to process after the camera and controller have completed /// </summary> public override void PostRigLateUpdate() { Transform lAnchor = Anchor; if (lAnchor != null) { mWasAnchorRotating = !QuaternionExt.IsEqual(mAnchorLastRotation, lAnchor.rotation); mAnchorLastPosition = lAnchor.position; mAnchorLastRotation = lAnchor.rotation; } mFocusLastPosition = GetFocusPosition(RigController._Transform.rotation); // Reset our internal rotation targets if (Mathf.Abs(_EulerTarget.y - _Euler.y) < EPSILON) { _Euler.y = LocalYaw; _EulerTarget.y = _Euler.y; mViewVelocityY = 0f; } // Reset our internal rotation targets if (Mathf.Abs(_EulerTarget.x - _Euler.x) < EPSILON) { _Euler.x = LocalPitch; _EulerTarget.x = _Euler.x; mViewVelocityX = 0f; } base.PostRigLateUpdate(); }
/// <summary> /// gère le saut depuis le sol /// </summary> private void JumpFromGround() { //si on ne bouge pas if (playerInput.NotMoving()) { SimpleJumpMoving(); //JumpFromNormal(); //saute par rapport à la normal au sol } //ici la corde n'est pas tendu else if (!ropeHandler.IsTenseForJump) { SimpleJumpMoving(); //jump normalement en faisant le milieu de vecteur up & direction input } else { //ici la corde est tendu, appliquer le jump normalisé par rapport à la corde //appliquer un boost de puissance par rapport à playerJump setting Vector3 dir = GetTheGoodAngleWhenRopeTense(); //divisé par 2 ? dir = QuaternionExt.GetMiddleOf2Vector(dir, ropeHandler.GetVectorFromPlayer(playerController.IdPlayer)); dir = QuaternionExt.GetMiddleOf2Vector(dir, ropeHandler.GetVectorFromPlayer(playerController.IdPlayer)); //dir = QuaternionExt.GetMiddleOf2Vector(dir, playerPenduleMove.GetDirRopeFromPivot()); //dir = QuaternionExt.GetMiddleOf2Vector(dir, playerPenduleMove.GetDirRopeFromPivot()); //playerPenduleMove.GetDirRopeFromPivot(); playerControlledAirJump.ControlledAirJumpSetup(true, dir, true, playerJump.JumpTenseFromGroundRatio); //Jump(dir, false, 0, boost); } }
public override MultiAimInverseConstraintJob Create(Animator animator, ref T data, Component component) { var job = new MultiAimInverseConstraintJob(); job.driven = ReadOnlyTransformHandle.Bind(animator, data.constrainedObject); job.drivenParent = ReadOnlyTransformHandle.Bind(animator, data.constrainedObject.parent); job.drivenOffset = Vector3Property.Bind(animator, component, data.offsetVector3Property); job.aimAxis = data.aimAxis; WeightedTransformArray sourceObjects = data.sourceObjects; WeightedTransformArrayBinder.BindReadWriteTransforms(animator, component, sourceObjects, out job.sourceTransforms); WeightedTransformArrayBinder.BindWeights(animator, component, sourceObjects, data.sourceObjectsProperty, out job.sourceWeights); job.sourceOffsets = new NativeArray <Quaternion>(sourceObjects.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); for (int i = 0; i < sourceObjects.Count; ++i) { if (data.maintainOffset) { var aimDirection = data.constrainedObject.rotation * data.aimAxis; var dataToSource = sourceObjects[i].transform.position - data.constrainedObject.position; var rot = QuaternionExt.FromToRotation(dataToSource, aimDirection); job.sourceOffsets[i] = Quaternion.Inverse(rot); } else { job.sourceOffsets[i] = Quaternion.identity; } } job.weightBuffer = new NativeArray <float>(sourceObjects.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); return(job); }
/// <summary> /// renvoi vrai si on peut se déplacer vers la où on veut en tense /// </summary> /// <returns></returns> public Vector3 GetTheGoodAngleWhenTenseInAirMove(Vector3 dirPlayer) { //si on est grounded, faire gaffe à pas bouger si on vise le mur ! Vector3 dirInversePlayer = -dirPlayer; //une fois que j'ai mon vecteur, prendre l'inverse Vector3 dirNormal = worldCollision.GetSumNormalSafe(); //prend la normal Debug.DrawRay(transform.position, dirPlayer * 2, Color.green, 1f); Debug.DrawRay(transform.position, dirInversePlayer * 2, Color.red, 1f); //float anglePlayer = QuaternionExt.GetAngleFromVector(dirPlayer); float angleInverse = QuaternionExt.GetAngleFromVector(dirInversePlayer); float angleNormal = QuaternionExt.GetAngleFromVector(dirNormal); float diffAngleNormalInverse; bool isCLose = QuaternionExt.IsAngleCloseToOtherByAmount(angleNormal, angleInverse, playerAirMove.DiffAngleWhenWeCantMoveThisWay, out diffAngleNormalInverse); //Debug.Log("Diff angleNormal/angleInverse: " + diffAngleNormalInverse); if (!isCLose) { return(dirPlayer); } //Debug.Break(); return(Vector3.zero); }
/// <summary> /// Determines if we'll treat input as if we're strafing /// </summary> protected void SimulateStrafeInput() { // Direction we need to travel in Vector3 lDirection = mWaypointVector; lDirection.y = lDirection.y - _PathHeight; lDirection.Normalize(); // Determine our view Vector3 lVerticalDirection = Vector3.Project(lDirection, _Transform.up); Vector3 lLateralDirection = (lDirection - lVerticalDirection).normalized; mInputFromAvatarAngle = Vector3Ext.SignedAngle(_Transform.forward, lLateralDirection); // Determine our movement if (mTargetDistance > _StopDistance) { // Calculate our own slowing float lRelativeMoveSpeed = 1f; if (mIsInSlowDistance && _SlowFactor > 0f) { float lSlowPercent = (mTargetDistance - _StopDistance) / (_SlowDistance - _StopDistance); lRelativeMoveSpeed = ((1f - _SlowFactor) * lSlowPercent) + _SlowFactor; } // TRT 4/5/2016: Force the slow distance as an absolute value if (mIsInSlowDistance && _SlowFactor > 0f) { lRelativeMoveSpeed = _SlowFactor; } lLateralDirection = _Transform.InverseTransformDirection(lLateralDirection); mMovementX = lLateralDirection.x * lRelativeMoveSpeed; mMovementY = lLateralDirection.z * lRelativeMoveSpeed; } // Grab extra input information if we can if (mMotionController._CameraTransform == null) { mInputFromCameraAngle = mInputFromAvatarAngle; } else { Vector3 lInputForward = new Vector3(mMovementX, 0f, mMovementY); // We do the inverse tilt so we calculate the rotation in "natural up" space vs. "actor up" space. Quaternion lInvTilt = QuaternionExt.FromToRotation(_Transform.up, Vector3.up); // Camera forward in "natural up" Vector3 lCameraForward = lInvTilt * mMotionController._CameraTransform.forward; // Create a quaternion that gets us from our world-forward to our camera direction. Quaternion lToCamera = Quaternion.LookRotation(lCameraForward, lInvTilt * _Transform.up); // Transform joystick from world space to camera space. Now the input is relative // to how the camera is facing. Vector3 lMoveDirection = lToCamera * lInputForward; mInputFromCameraAngle = NumberHelper.GetHorizontalAngle(lCameraForward, lMoveDirection); } }
/// <summary> /// ici effectue la force au sol /// </summary> /// <param name="dirForce"></param> public void ChooseIfAccelerateOrVelocityChange(Vector3 dirForce, float ratio) { //Debug.Log("la ?"); MoveOnWallWhenAirMove(dirForce.normalized * Mathf.Abs(previousInput), ratio); return; Vector3 rigidbodyVelocity = rb.velocity; float dotResult = QuaternionExt.DotProduct(Vector3.right, rigidbodyVelocity); if ((QuaternionExt.DotProduct(Vector3.right, rigidbodyVelocity) >= 0 && playerInput.Horiz > 0) || (QuaternionExt.DotProduct(Vector3.right, rigidbodyVelocity) <= 0 && playerInput.Horiz < 0)) { //dans le sens MoveOnWallWhenAirMove(dirForce.normalized * Mathf.Abs(previousInput), ratio); } else { //inverse Vector3 addForce = dirForce.normalized * speedAcceleration * ratio * Mathf.Abs(previousInput) * Time.fixedDeltaTime; rb.AccelerateTo(addForce, maxSpeedConstante, ForceMode.Acceleration); } }
/// <summary> /// Use this for initialization /// </summary> protected override void Awake() { base.Awake(); if (_Anchor != null && this.enabled) { ICharacterController lController = InterfaceHelper.GetComponent <ICharacterController>(_Anchor.gameObject); if (lController != null) { IsInternalUpdateEnabled = false; IsFixedUpdateEnabled = false; lController.OnControllerPostLateUpdate += OnControllerLateUpdate; } mTilt = QuaternionExt.FromToRotation(_Transform.up, _Anchor.up); mToCameraDirection = _Transform.position - _Anchor.position; mToCameraDirection.y = 0f; mToCameraDirection.Normalize(); if (mToCameraDirection.sqrMagnitude == 0f) { mToCameraDirection = -_Anchor.forward; } } // Object that will provide access to the keyboard, mouse, etc if (_InputSourceOwner != null) { mInputSource = InterfaceHelper.GetComponent <IInputSource>(_InputSourceOwner); } // Default the speed we'll use to rotate mDegreesPer60FPSTick = _RotationSpeed / 60f; }
/// <summary> /// ici effectue les mouvements en l'air (selon la corde tendu ?) /// </summary> private void AirMove() { Vector3 dirRope = ropeHandler.GetVectorFromPlayer(playerController.IdPlayer); Vector3 dirReference = playerInput.GetDirInput(); dirPlayerAirMove = QuaternionExt.GetTheGoodRightAngleClosest(dirRope, dirReference, 10f); if (dirPlayerAirMove == Vector3.zero) { return; } if (!ForceGroundedInCoolDown()) { return; } if (WeJustInversePendule()) { //Debug.LogWarning("ici on a inversé !"); SetInverse(); } //ici on est bon ! DoNewPenduleForce(); }
/// <summary> /// Direction arrow /// </summary> private void ChangeDirectionArrow() { if (!(PlayerInputScript.Horiz == 0 && PlayerInputScript.Verti == 0)) { dirArrow.rotation = QuaternionExt.DirObject(dirArrow.rotation, PlayerInputScript.Horiz, -PlayerInputScript.Verti, turnRateArrow, QuaternionExt.TurnType.Z); } }
/// <summary> /// Ground, //0 Wall, //1 Ceilling //2 /// /// Ground, //0 /// GroundLeft, //1 /// GroundRight, //2 /// WallLeft, //3 /// WallRight, //4 /// CeilingLeft, //5 /// CeilingRight, //6 /// Ceilling, //7 /// /// <param name="normal">direction de la normal de collision</param> /// <returns>retourne un type de collision ( explicite)</returns> private int WhatKindOfNormalIsIt(Vector3 normal) { if (normal == Vector3.zero) { //Debug.Log("return -1, la normal fourni est 0"); return(-1); } float angleNormal = QuaternionExt.GetAngleFromVector(normal); //angle normal collision //si la normal de contact est proche de 0 ou 180, à 20° près, alors on est en mode wallJump... float diffAngle = 0; for (int i = 0; i < angleReference.Length; i++) { bool groundType = QuaternionExt.IsAngleCloseToOtherByAmount(angleNormal, angleReference[i], angleDifference, out diffAngle); if (groundType) { //Debug.Log(angleReferenceDisplay[i] + ", angleNormal: " + angleNormal + "(diff:" + diffAngle + ")"); return(i); } } //Debug.Log("return -1"); return(-1); }
/// <summary> /// Allow the joint to render it's own GUI. This GUI is used /// for displaying and manipulating the joint itself. /// </summary> /// <returns>Reports if the object's value was changed</returns> public override bool OnInspectorManipulatorGUI(IKBoneModifier rModifier) { #if UNITY_EDITOR // Determine if the swing is changing if (mBone != null) { Vector3 lSwing = rModifier.Swing.eulerAngles; Vector3 lNewSwing = InspectorHelper.Vector3Fields("Swing", "Euler angles to swing the bone.", lSwing, true, true, false); if (lNewSwing != lSwing) { // Grab the amount that was just rotated by based on the current rotation. // We do this so the change is relative to the current swing rotation Vector3 lDeltaRotations = lNewSwing - lSwing; rModifier.Swing = rModifier.Swing * Quaternion.Euler(lDeltaRotations); rModifier.IsDirty = true; } // Determine if the twist is changing //float lTwist = mBone.Twist.eulerAngles.y; float lTwist = Vector3Ext.SignedAngle(Vector3.up, rModifier.Twist * Vector3.up, Vector3.forward); float lNewTwist = EditorGUILayout.FloatField("Twist", lTwist); if (_AllowTwist && lNewTwist != lTwist) { rModifier.Twist = Quaternion.AngleAxis(lNewTwist, Vector3.forward); rModifier.IsDirty = true; } // Reset the values if needed if (GUILayout.Button("reset rotation", EditorStyles.miniButton)) { rModifier.Swing = Quaternion.identity; rModifier.Twist = (_AllowTwist ? Quaternion.identity : mBone._Twist); rModifier.IsDirty = true; mBone._Transform.localRotation = mBone._BindRotation; } if (rModifier.IsDirty) { // Before we go to far, see if we are within the joint limits. If not, // we need to go back to a good position. bool lIsInLimits = ApplyLimits(ref rModifier.Swing, ref rModifier.Twist); if (lIsInLimits || QuaternionExt.IsEqual(rModifier.Swing, Quaternion.identity)) { mLastSwing = rModifier.Swing; mLastTwist = rModifier.Twist; } else { rModifier.Swing = mLastSwing; rModifier.Twist = mLastTwist; } } } #endif return(rModifier.IsDirty); }
/// <summary> /// ici renvoi vrai si le sens du mouvement va vers le haut /// </summary> /// <returns></returns> private bool IsVelocityIsInGoodSide(PosQuadran posInSpace) { float dirRigidbody = 0; switch (posInSpace) { case PosQuadran.upLeft: dirRigidbody = QuaternionExt.DotProduct(-Vector3.right, rb.velocity); if (dirRigidbody > 0) { return(true); } else { return(false); } case PosQuadran.upRight: dirRigidbody = QuaternionExt.DotProduct(Vector3.right, rb.velocity); if (dirRigidbody > 0) { return(true); } else { return(false); } case PosQuadran.downLeft: dirRigidbody = QuaternionExt.DotProduct(Vector3.right, rb.velocity); if (dirRigidbody > 0) { return(true); } else { return(false); } case PosQuadran.downRight: dirRigidbody = QuaternionExt.DotProduct(-Vector3.right, rb.velocity); if (dirRigidbody > 0) { return(true); } else { return(false); } case PosQuadran.ambigous: default: return(false); } }
public override void ProcessFrame(Playable playable, FrameData info, object playerData) { Transform binding = playerData as Transform; if (binding == null) { return; } int inputCount = playable.GetInputCount(); if (inputCount == 0) { return; } float totalWeight = 0; Vector3 position = new Vector3(); Quaternion rotation = new Quaternion(); Vector3 scale = new Vector3(); for (int i = 0; i < inputCount; i++) { var inputPlayable = (ScriptPlayable <EZTransformConstraintBehaviour>)playable.GetInput(i); var inputBehaviour = inputPlayable.GetBehaviour(); if (inputBehaviour.target == null) { continue; } float inputWeight = playable.GetInputWeight(i); if (inputWeight == 0) { continue; } totalWeight += inputWeight; position += inputBehaviour.target.position * inputWeight; rotation = QuaternionExt.Cumulate(rotation, inputBehaviour.target.rotation.Scale(inputWeight)); scale += inputBehaviour.target.lossyScale * inputWeight; } if (totalWeight < 1e-5) { return; } if (positionConstraint) { binding.position = position / totalWeight; } if (rotationConstraint) { binding.rotation = rotation; } if (scaleConstraint) { binding.localScale = scale / totalWeight; } }
/// <summary> /// le jump de base, millieu de direction horizontal, Vecteur up /// </summary> private Vector3 GetVelocityAndUpDirection() { Vector3 dirInputPlayer = rb.velocity; dirInputPlayer.y = dirInputPlayer.z = 0; //ne garder que l'horizontal Vector3 dir = QuaternionExt.GetMiddleOf2Vector(Vector3.up, dirInputPlayer); return(dir); }
/// <summary> /// retourne l'angle correct /// </summary> /// <returns></returns> public Vector3 GetTheGoodAngleWhenRopeTense() { Vector3 dirRope = ropeHandler.GetVectorFromPlayer(playerController.IdPlayer); //Vector3 dirRope = playerPenduleMove.GetDirRopeFromPivot(); Vector3 dirReference = worldCollision.GetSumNormalSafe(); return(QuaternionExt.GetTheGoodRightAngleClosest(dirRope, dirReference, 10f)); }
private void WallJumpSimple() { Debug.Log("ici jump wall selon wallLeft/right et Up"); Vector3 horiz = new Vector3(((worldCollision.GetCollisionSafe() == CollisionType.WallLeft) ? 1 : -1), 0, 0); Vector3 dir = QuaternionExt.GetMiddleOf2Vector(Vector3.up, horiz); float boost = playerJump.JumpBoostFromWall; Jump(dir, false, 0, boost); }
/// <summary> /// le jump de base, millieu de direction horizontal, Vecteur up /// </summary> private Vector3 GetInputAndUpDirection() { Vector3 dirInputPlayer = playerInput.GetDirInput(); //input du player dirInputPlayer.y = dirInputPlayer.z = 0; //ne garder que l'horizontal Vector3 dir = QuaternionExt.GetMiddleOf2Vector(Vector3.up, dirInputPlayer); return(dir); }
static public int Normalized_s(IntPtr l) { try { UnityEngine.Quaternion a1; checkType(l, 1, out a1); var ret = QuaternionExt.Normalized(a1); pushValue(l, ret); return(1); } catch (Exception e) { return(error(l, e)); } }
/// <summary> /// est-ce que l'input est dans le sens du mouvement ? /// </summary> /// <returns></returns> private bool IsGoodInputToVelocy() { float dirinput = QuaternionExt.DotProduct(playerInput.GetDirInput(), rb.velocity); if (dirinput > 0) { return(true); } else { return(false); } }
/// <summary> ///checker l'angle Vector.down & player - pivot ///si angle inférieur à 20, alors on est au début de la monté, autoriser (++force) /// </summary> /// <returns></returns> private bool IsAngleDownOk(float angleAccepted) { Vector3 dirDown = -Vector3.up; Vector3 dirPivot = transform.position - pointPivot; float diffAngle = QuaternionExt.GetDiffAngleBetween2Vectors(dirDown, dirPivot); if (diffAngle <= angleAccepted) { return(true); } return(false); }
/// <summary> /// Provides a place to set the properties of the animator /// </summary> /// <param name="rInput">Vector3 representing the input</param> /// <param name="rMove">Vector3 representing the amount of movement taking place (in world space)</param> /// <param name="rRotate">Quaternion representing the amount of rotation taking place</param> protected override void SetAnimatorProperties(Vector3 rInput, Vector3 rMovement, Quaternion rRotation) { if (mInputSource == null || !mInputSource.IsEnabled) { return; } // Jump based on space bool lIsInJump = !mActorController.State.IsGrounded; if (mInputSource.IsJustPressed("Jump")) { if (!lIsInJump && !mIsInJumpToWall) { lIsInJump = true; // We need to check if we're actually jumping towards a wall RaycastHit lHitInfo; if (RaycastExt.SafeRaycast(transform.position + (transform.up * JumpToWallHeight), transform.forward, out lHitInfo, JumpToWallDistance)) { mIsInJumpToWall = true; mJumpToWallPoint = lHitInfo.point; mJumpToWallNormal = lHitInfo.normal; mJumpToWallElapsedTime = 0f; mSavedOrientToGroundSpeed = mActorController.OrientToGroundSpeed; mActorController.OrientToGroundSpeed = JumpToWallOrientSpeed; } // Perform the jump mActorController.AddImpulse(transform.up * _JumpForce); } } // Direction of the camera float lDirection = 0f; // We do the inverse tilt so we calculate the rotation in "natural up" space vs. "actor up" space. Quaternion lInvTilt = QuaternionExt.FromToRotation(mActorController._Transform.up, Vector3.up); // Forward direction of the actor in "natural up" Vector3 lControllerForward = lInvTilt * mActorController._Transform.forward; // Get the angular difference between the camera-based input and the spider's "natural-up" forward lDirection = NumberHelper.GetHorizontalAngle(lControllerForward, rInput); mAnimator.SetFloat("Direction", lDirection); mAnimator.SetFloat("Speed", rInput.magnitude); mAnimator.SetBool("Jump", lIsInJump); }
/// <summary> /// Causes us to ignore user input and force the camera to the specified localangles /// </summary> /// <param name="rYaw">Target local yaw</param> /// <param name="rPitch">Target local pitch</param> /// <param name="rSpeed">Degrees per second we'll rotate. A value of -1 uses the current yaw speed.</param> /// <param name="rAutoClearTarget">Determines if we'll clear the target once we reach it.</param> public override void SetTargetYawPitch(float rYaw, float rPitch, float rSpeed = -1F, bool rAutoClearTarget = true) { Vector3 lNewAnchorPosition = _Anchor.position + (_Anchor.rotation * _AnchorOffset); // Grab the rotation amount. We do the inverse tilt so we calculate the rotation in // "natural up" space. Later we'll use the tilt to put it back into "anchor up" space. Quaternion lInvTilt = QuaternionExt.FromToRotation(_Anchor.up, Vector3.up); // Yaw is simple as we can go 360 Quaternion lYaw = Quaternion.AngleAxis((rYaw - LocalYaw), lInvTilt * _Transform.up); // Pitch is more complicated since we can't go beyond the north/south pole float lPitchAngle = Vector3.Angle(mToCameraDirection, lInvTilt * _Anchor.up); float lPitchDelta = rPitch - LocalPitch; if (lPitchAngle < MIN_PITCH && lPitchDelta > 0f) { lPitchDelta = 0f; } else if (lPitchAngle > MAX_PITCH && lPitchDelta < 0f) { lPitchDelta = 0f; } Quaternion lPitch = Quaternion.AngleAxis(lPitchDelta, lInvTilt * _Transform.right); // Calculate the new "natural up" direction mToCameraDirection = lPitch * lYaw * mToCameraDirection; // Update our tilt to match the anchor's tilt mTilt = QuaternionExt.FromToRotation(mTilt.Up(), _Anchor.up) * mTilt; // Put the new direction relative to the anchor's tilt Vector3 lToCameraDirection = mTilt * mToCameraDirection; if (lToCameraDirection.sqrMagnitude == 0f) { lToCameraDirection = -_Anchor.forward; } // Calculate the new orbit center (anchor) and camera position Vector3 lNewCameraPosition = lNewAnchorPosition + (lToCameraDirection.normalized * _Radius); Quaternion lNewCameraRotation = Quaternion.LookRotation(lNewAnchorPosition - lNewCameraPosition, _Anchor.up); _Transform.position = lNewCameraPosition; _Transform.rotation = lNewCameraRotation; }
/// <summary> /// When we want to rotate based on the camera direction (which input does), we need to tweak the actor /// rotation AFTER we process the camera. Otherwise, we can get small stutters during camera rotation. /// /// This is the only way to keep them totally in sync. It also means we can't run any of our AC processing /// as the AC already ran. So, we do minimal work here /// </summary> /// <param name="rDeltaTime"></param> /// <param name="rUpdateCount"></param> /// <param name="rCamera"></param> private void OnCameraUpdated(float rDeltaTime, int rUpdateIndex, BaseCameraRig rCamera) { if (mMotionController._CameraTransform == null) { return; } // Get out early if we we aren't modifying the view. if (mMotionController._InputSource != null && mMotionController._InputSource.ViewX == 0f) { return; } // We do the inverse tilt so we calculate the rotation in "natural up" space vs. "actor up" space. Quaternion lInvTilt = QuaternionExt.FromToRotation(mMotionController._Transform.up, Vector3.up); // Forward direction of the actor in "natural up" Vector3 lControllerForward = lInvTilt * mMotionController._Transform.forward; // Camera forward in "natural up" Vector3 lCameraForward = lInvTilt * mMotionController._CameraTransform.forward; // Create a quaternion that gets us from our world-forward to our camera direction. Quaternion lToCamera = Quaternion.LookRotation(lCameraForward, Vector3.up); // Transform joystick from world space to camera space. Now the input is relative // to how the camera is facing. Vector3 lMoveDirection = lToCamera * mMotionController.State.InputForward; float lInputFromAvatarAngle = NumberHelper.GetHorizontalAngle(lControllerForward, lMoveDirection); // Clear the link if we're out of rotation range if (Mathf.Abs(lInputFromAvatarAngle) > _RotationSpeed * rDeltaTime * 5f) { mIsRotationLocked = false; } // We only want to do this is we're very very close to the desired angle. This will remove any stuttering if (_RotationSpeed == 0f || mIsRotationLocked || Mathf.Abs(lInputFromAvatarAngle) < _RotationSpeed * rDeltaTime * 1f) { mIsRotationLocked = true; // Since we're after the camera update, we have to force the rotation outside the normal flow Quaternion lRotation = Quaternion.AngleAxis(lInputFromAvatarAngle, Vector3.up); mActorController.Yaw = mActorController.Yaw * lRotation; mActorController._Transform.rotation = mActorController.Tilt * mActorController.Yaw; } }
/// <summary> /// ajout / enleve avec l'input du joueur up / down /// </summary> private void ModifyRopeUpDown() { if (!CanModifyUpDown()) { return; } Vector3 dirRope = Vector3.zero; if (!ropeHandler.IsTenseForAirMove) { //ici on reprend avec l'angle d'avant de la rope dirRope = holdDirRope; } else { dirRope = ropeHandler.GetVectorFromPlayer(playerController.IdPlayer); //dirRope = playerPenduleMove.GetDirRopeFromPivot(); holdDirRope = dirRope; timeWhenWeCanModifyRope.StartCoolDown(); } Vector3 dirRopeInverse = -dirRope; Vector3 dirInput = playerInput.GetDirInput(); float angleRope = QuaternionExt.GetAngleFromVector(dirRope); float angleRopeInverse = QuaternionExt.GetAngleFromVector(dirRopeInverse); float angleInput = QuaternionExt.GetAngleFromVector(dirInput); Debug.DrawRay(transform.position, dirRope, Color.green, 1f); Debug.DrawRay(transform.position, dirInput, Color.red, 1f); float diffAngleRopeNormal; if (QuaternionExt.IsAngleCloseToOtherByAmount(angleInput, angleRope, diffAngleForUpAndDown, out diffAngleRopeNormal)) { //Debug.Log("delete"); RemoveRopeParticle(); } else if (QuaternionExt.IsAngleCloseToOtherByAmount(angleInput, angleRopeInverse, diffAngleForUpAndDown, out diffAngleRopeNormal)) { //Debug.Log("add"); AddRopeParticle(); } }
/// <summary> /// When we want to rotate based on the camera direction (which input does), we need to tweak the actor /// rotation AFTER we process the camera. Otherwise, we can get small stutters during camera rotation. /// /// This is the only way to keep them totally in sync. It also means we can't run any of our AC processing /// as the AC already ran. So, we do minimal work here /// </summary> /// <param name="rDeltaTime"></param> /// <param name="rUpdateCount"></param> /// <param name="rCamera"></param> protected virtual void OnCameraUpdated(float rDeltaTime, int rUpdateIndex, BaseCameraRig rCamera) { if (!_RotateWithCamera) { return; } if (_RequireTarget && mCombatant != null && mCombatant.IsTargetLocked) { return; } // Get out early if we we aren't modifying the view. if (mMotionController._InputSource != null && mMotionController._InputSource.ViewX == 0f) { return; } // We do the inverse tilt so we calculate the rotation in "natural up" space vs. "actor up" space. Quaternion lInvTilt = QuaternionExt.FromToRotation(mMotionController._Transform.up, Vector3.up); // Forward direction of the actor in "natural up" Vector3 lActorForward = lInvTilt * mMotionController._Transform.forward; // Camera forward in "natural up" Vector3 lCameraForward = lInvTilt * mMotionController._CameraTransform.forward; // Get the rotation angle to the camera float lActorToCameraAngle = NumberHelper.GetHorizontalAngle(lActorForward, lCameraForward); // Clear the link if we're out of rotation range if (Mathf.Abs(lActorToCameraAngle) > _RotationSpeed * rDeltaTime * 5f) { mIsRotationLocked = false; } // We only want to do this is we're very very close to the desired angle. This will remove any stuttering if (_RotationSpeed == 0f || mIsRotationLocked || Mathf.Abs(lActorToCameraAngle) < _RotationSpeed * rDeltaTime * 1f) { mIsRotationLocked = true; // Since we're after the camera update, we have to force the rotation outside the normal flow Quaternion lRotation = Quaternion.AngleAxis(lActorToCameraAngle, Vector3.up); mActorController.Yaw = mActorController.Yaw * lRotation; mActorController._Transform.rotation = mActorController.Tilt * mActorController.Yaw; } }
/* * /// <summary> * /// est-ce qu'on essai d'aller à l'inverse ? * /// </summary> * /// <returns></returns> * private bool ForceInverse() * { * if (!isAirTense) * return (true); * * Vector3 dirPlayer = dirPlayerAirMove; * Vector3 dirVelocity = rb.velocity; * float velocityRigidbody = rb.velocity.sqrMagnitude; * * if (velocityRigidbody < speedWhenCantDoInverse) * return (true); * * Vector3 dirInverse = -dirPlayer; * * float anglePlayer = QuaternionExt.GetAngleFromVector(dirPlayer); * float angleInverse = QuaternionExt.GetAngleFromVector(dirInverse); * float angleVelocity = QuaternionExt.GetAngleFromVector(dirVelocity); * * float diffAnglePlayerVelocity; * QuaternionExt.IsAngleCloseToOtherByAmount(anglePlayer, angleVelocity, diffAngleInverseVelocity, out diffAnglePlayerVelocity); * float diffAngleInversePlayerVelocity; * QuaternionExt.IsAngleCloseToOtherByAmount(angleInverse, angleVelocity, diffAngleInverseVelocity, out diffAngleInversePlayerVelocity); * * //si on veut aller vers la velocity, alors ok * if (diffAnglePlayerVelocity < diffAngleInversePlayerVelocity) * { * //Debug.Log("dans le sens !"); * return (true); * } * else * { * //Debug.Log("inverse !"); * //sinon, on va trop vite pour pouvoir aller contre ! * return (false); * } * } */ /// <summary> /// ici test si on a juste inversé le pendule ! /// </summary> private bool WeJustInversePendule() { //si on vient de commencer, osef, on fait normalement if (dirPlayerAirMove == Vector3.zero || lastDirTensity == Vector3.zero) { return(false); } float diffVector = QuaternionExt.GetDiffAngleBetween2Vectors(lastDirTensity, dirPlayerAirMove); if (diffVector < 90) { //on a pas inversé return(false); } //on a inversé ! return(true); }
public override void ProcessFrame(Playable playable, FrameData info, object playerData) { Transform binding = playerData as Transform; if (binding == null) { return; } int inputCount = playable.GetInputCount(); if (inputCount == 0) { return; } float totalWeight = 0; Quaternion outputRotation = new Quaternion(); for (int i = 0; i < inputCount; i++) { var inputPlayable = (ScriptPlayable <EZTransformConstraintBehaviour>)playable.GetInput(i); var inputBehaviour = inputPlayable.GetBehaviour(); if (inputBehaviour.target == null) { continue; } float inputWeight = playable.GetInputWeight(i); if (inputWeight == 0) { continue; } totalWeight += inputWeight; outputRotation = QuaternionExt.Cumulate(outputRotation, inputBehaviour.target.rotation.Scale(inputWeight)); } if (totalWeight < 1e-5) { return; } binding.rotation = outputRotation; }
/// <summary> /// retourne la direction quand on saute... /// </summary> /// <returns></returns> private Vector3 GetDirWhenJumpAndMoving() { Vector3 finalVelocityDir = Vector3.zero; //get la direction du joystick Vector3 dirInputPlayer = playerInput.GetDirInput(); //get le dot product normal -> dir Arrow float dotDirPlayer = QuaternionExt.DotProduct(worldCollision.GetSumNormalSafe(), dirInputPlayer); //si positif, alors on n'a pas à faire de mirroir if (dotDirPlayer > margeHoriz) { //direction visé par le joueur Debug.Log("Direction de l'arrow !" + dotDirPlayer); finalVelocityDir = dirInputPlayer.normalized; } else if (dotDirPlayer < -margeHoriz) { //ici on vise dans le négatif, faire le mirroir du vector par rapport à... Debug.Log("ici mirroir de l'arrow !" + dotDirPlayer); //récupéré le vecteur de DROITE de la normal Vector3 rightVector = QuaternionExt.CrossProduct(worldCollision.GetSumNormalSafe(), Vector3.forward) * -1; //Debug.DrawRay(transform.position, rightVector.normalized, Color.blue, 1f); //faire le mirroir entre la normal et le vecteur de droite Vector3 mirror = QuaternionExt.ReflectionOverPlane(dirInputPlayer, rightVector * -1) * -1; //Debug.DrawRay(transform.position, mirror.normalized, Color.yellow, 1f); //direction inverse visé par le joueur finalVelocityDir = mirror.normalized; } else { Debug.Log("ici on est proche du 90°, faire la bisection !"); //ici l'angle normal - direction est proche de 90°, ducoup on fait le milieu des 2 axe //ici faire la moyenne des 2 vecteur normal, et direction arrow finalVelocityDir = QuaternionExt.GetMiddleOf2Vector(worldCollision.GetSumNormalSafe(), dirInputPlayer); } return(finalVelocityDir); }