예제 #1
0
    // The smaller of the two possible angles between the two vectors is returned, therefore the result will never be greater than 180 degrees or smaller than -180 degrees.
    // If you imagine the from and to vectors as lines on a piece of paper, both originating from the same point, then the /axis/ vector would point up out of the paper.
    // The measured angle between the two vectors would be positive in a clockwise direction and negative in an anti-clockwise direction.
    public static Fix64 SignedAngle(FixVector3 from, FixVector3 to, FixVector3 axis)
    {
        FixVector3 fromNorm = from.Normalized, toNorm = to.Normalized;
        Fix64      unsignedAngle = FixMath.Acos(FixMath.Clamp(Dot(fromNorm, toNorm), -Fix64.ONE, Fix64.ONE)) * FixMath.Rad2Deg;
        Fix64      sign          = FixMath.Sign(Dot(axis, Cross(fromNorm, toNorm)));

        return(unsignedAngle * sign);
    }
예제 #2
0
    public static FixVector2 Lerp(FixVector2 value1, FixVector2 value2, Fix64 amount)
    {
        amount = FixMath.Clamp(amount, 0, 1);

        return(new FixVector2(
                   FixMath.Lerp(value1.x, value2.x, amount),
                   FixMath.Lerp(value1.y, value2.y, amount)));
    }
예제 #3
0
    public static FixQuaternion Slerp(FixQuaternion from, FixQuaternion to, Fix64 t)
    {
        t = FixMath.Clamp(t, 0, 1);

        Fix64 dot = Dot(from, to);

        if (dot < 0.0f)
        {
            to  = Multiply(to, -1);
            dot = -dot;
        }

        Fix64 halfTheta = Fix64.Acos(dot);

        return(Multiply(Multiply(from, Fix64.Sin((1 - t) * halfTheta)) + Multiply(to, Fix64.Sin(t * halfTheta)), 1 / Fix64.Sin(halfTheta)));
    }
예제 #4
0
 private Fix64 ClampAngle(Fix64 angle, Fix64 min, Fix64 max)
 {
     while (angle < -360)
     {
         angle += 360;
     }
     while (angle > 360)
     {
         angle -= 360;
     }
     if (angle > max && angle - 360 >= min)
     {
         return(angle - 360);
     }
     if (angle < min && angle + 360 <= max)
     {
         return(angle + 360);
     }
     return(FixMath.Clamp(angle, -max, -min));
 }
예제 #5
0
 /// Clamp a vector to a bounding box.
 public FixVec2 ClampVect(FixVec2 v)
 {
     return(new FixVec2(FixMath.Clamp(v.X, L, R), FixMath.Clamp(v.Y, B, T)));
 }
예제 #6
0
    public static FixQuaternion Lerp(FixQuaternion a, FixQuaternion b, Fix64 t)
    {
        t = FixMath.Clamp(t, Fix64.Zero, Fix64.One);

        return(LerpUnclamped(a, b, t));
    }
예제 #7
0
 public static void Clamp(ref FixVector2 value1, ref FixVector2 min, ref FixVector2 max, out FixVector2 result)
 {
     result = new FixVector2(
         FixMath.Clamp(value1.x, min.x, max.x),
         FixMath.Clamp(value1.y, min.y, max.y));
 }
예제 #8
0
 public static FixVector2 Clamp(FixVector2 value1, FixVector2 min, FixVector2 max)
 {
     return(new FixVector2(
                FixMath.Clamp(value1.x, min.x, max.x),
                FixMath.Clamp(value1.y, min.y, max.y)));
 }
예제 #9
0
    public override void OnEnable()
    {
        base.OnEnable();

        PlayerControlComponents.OnAdd()
        .Where(entity => !entity.HasComponent <NetworkPlayerComponent>())
        .Subscribe(entity =>
        {
            var playerControlComponent = entity.GetComponent <PlayerControlComponent>();
            var characterController    = entity.GetComponent <CharacterController>();
            var viewComponent          = entity.GetComponent <ViewComponent>();

            Observable.EveryUpdate().Subscribe(_ =>
            {
                if (characterController.isGrounded)
                {
                    var angle = Vector3.Angle(viewComponent.Transforms[0].forward, mainCamera.transform.forward);
                    if (angle < InvertRange.Min || angle > InvertRange.Max)
                    {
                        playerControlComponent.motion = new FixVector3(Input.GetAxis(InputParameters.Horizontal), 0, Input.GetAxis(InputParameters.Vertical));
                    }
                    else
                    {
                        playerControlComponent.motion = new FixVector3(Input.GetAxis(InputParameters.Vertical), 0, Input.GetAxis(InputParameters.Horizontal));
                    }
                    playerControlComponent.motion  = (FixVector3)viewComponent.Transforms[0].TransformDirection((Vector3)playerControlComponent.motion);
                    playerControlComponent.motion *= playerControlComponent.Run;

                    if (Input.GetButton(InputParameters.Jump))
                    {
                        playerControlComponent.motion.y = playerControlComponent.Jump;
                    }
                }

                playerControlComponent.motion.y -= playerControlComponent.Gravity * Time.deltaTime;
                characterController.Move((Vector3)playerControlComponent.motion * Time.deltaTime);
            }).AddTo(this.Disposer).AddTo(playerControlComponent.Disposer);
        }).AddTo(this.Disposer);

        NetwrokTimeline.OnReverse((entity, result) =>
        {
            var playerControlComponent = entity.GetComponent <PlayerControlComponent>();
            var viewComponent          = entity.GetComponent <ViewComponent>();
            var playerControlResult    = (PlayerControlResult)result[0];

            viewComponent.Transforms[0].rotation   = playerControlResult.Rotation;
            playerControlComponent.Follow.rotation = playerControlResult.Follow;
            viewComponent.Transforms[0].position   = playerControlResult.Position;
        }).AddTo(this.Disposer);

        NetwrokTimeline.OnForward((entity, userInputData, deltaTime) =>
        {
            var playerControlComponent = entity.GetComponent <PlayerControlComponent>();
            var characterController    = entity.GetComponent <CharacterController>();
            var viewComponent          = entity.GetComponent <ViewComponent>();
            var animator            = entity.GetComponent <Animator>();
            var axisInput           = userInputData[0].GetInput <AxisInput>();
            var keyInput            = userInputData[1].GetInput <KeyInput>();
            var mouseInput          = userInputData[2].GetInput <MouseInput>();
            var playerControlResult = new PlayerControlResult();
            var smoothTime          = playerControlComponent.smoothTime;
            var yAngle = Fix64.Zero;

            playerControlResult.Rotation = viewComponent.Transforms[0].rotation;
            playerControlResult.Follow   = playerControlComponent.Follow.rotation;
            playerControlResult.Position = viewComponent.Transforms[0].position;

            if (mouseInput != null && keyInput != null && axisInput != null)
            {
                var rotLeftRight = mouseInput.Delta.x * playerControlComponent.MouseSensivity.x * deltaTime;
                var rotUpDown    = mouseInput.Delta.y * playerControlComponent.MouseSensivity.y * deltaTime;

                if (mouseInput.MouseButtons.Contains(1))
                {
                    playerControlComponent.aimTime += deltaTime;
                    if (playerControlComponent.Aim.Value == AimMode.Free && playerControlComponent.aimTime > ShoulderAimTime)
                    {
                        playerControlComponent.Aim.Value = AimMode.Shoulder;
                    }
                }
                else
                {
                    if (playerControlComponent.Aim.Value == AimMode.Free)
                    {
                        if (playerControlComponent.aimTime > 0)
                        {
                            playerControlComponent.Aim.Value = AimMode.AimDownSight;
                        }
                    }
                    else if (playerControlComponent.aimTime > 0)
                    {
                        playerControlComponent.Aim.Value = AimMode.Free;
                    }
                    playerControlComponent.aimTime = 0;
                }

                if (playerControlComponent.Aim.Value == AimMode.Free && keyInput.KeyCodes.Contains((int)KeyCode.LeftAlt))
                {
                    playerControlComponent.Follow.rotation = (Quaternion)((FixQuaternion)playerControlComponent.Follow.rotation * FixQuaternion.Euler(-rotUpDown, rotLeftRight, 0));
                    animator.SetFloat(Head_Vertical_f, 0);
                    animator.SetFloat(Body_Vertical_f, 0);
                    smoothTime = SmoothTime;
                }
                else
                {
                    if (smoothTime > 0)
                    {
                        playerControlComponent.Follow.localRotation = (Quaternion)FixQuaternion.Lerp(FixQuaternion.identity, (FixQuaternion)playerControlComponent.Follow.localRotation, FixMath.Clamp01(smoothTime / SmoothTime));
                        animator.SetFloat(Head_Vertical_f, 0);
                        animator.SetFloat(Body_Vertical_f, 0);
                        smoothTime -= deltaTime;
                    }
                    else
                    {
                        yAngle = ClampAngle(playerControlComponent.Follow.localEulerAngles.x, playerControlComponent.YAngleLimit.Min, playerControlComponent.YAngleLimit.Max);
                        yAngle = ClampAngle(yAngle - rotUpDown, playerControlComponent.YAngleLimit.Min, playerControlComponent.YAngleLimit.Max);

                        var vertical = 2 * (0.5f - FixMath.Abs(yAngle - playerControlComponent.YAngleLimit.Min) / FixMath.Abs(playerControlComponent.YAngleLimit.Max - playerControlComponent.YAngleLimit.Min));
                        animator.SetFloat(Head_Vertical_f, 0.5f * (float)vertical);
                        animator.SetFloat(Body_Vertical_f, (float)vertical);
                        viewComponent.Transforms[0].rotation           = (Quaternion)((FixQuaternion)viewComponent.Transforms[0].rotation * FixQuaternion.Euler(0, rotLeftRight, 0));
                        playerControlComponent.Follow.localEulerAngles = (Vector3) new FixVector3(yAngle, 0, 0);
                    }
                }

                if (characterController.isGrounded)
                {
                    playerControlComponent.motion = new FixVector3((float)axisInput.Horizontal, 0, (float)axisInput.Vertical);
                    playerControlComponent.motion = (FixVector3)viewComponent.Transforms[0].TransformDirection((Vector3)playerControlComponent.motion);

                    Fix64 t          = 0.75f;
                    Fix64 speed      = playerControlComponent.Walk;
                    Fix64 h          = FixMath.Abs(axisInput.Horizontal);
                    Fix64 sum        = h + FixMath.Abs(axisInput.Vertical);
                    Fix64 horizontal = sum == 0 ? 0 : axisInput.Horizontal * (h / sum);
                    if (playerControlComponent.Aim.Value == AimMode.Shoulder)
                    {
                        t = 0.5f;
                    }
                    else if (playerControlComponent.Aim.Value == AimMode.AimDownSight)
                    {
                        t = 0.25f;
                    }
                    else if (keyInput != null && keyInput.KeyCodes.Contains((int)KeyCode.LeftShift))
                    {
                        t     = 1f;
                        speed = playerControlComponent.Run;
                    }

                    playerControlComponent.Crouched = keyInput.KeyCodes.Contains((int)KeyCode.LeftControl);
                    animator.SetBool(Crouch_b, playerControlComponent.Crouched);
                    if (playerControlComponent.Crouched)
                    {
                        speed = 0;
                    }

                    playerControlComponent.motion *= t * speed;
                    animator.SetFloat(Speed_f, (axisInput.Horizontal != Fix64.Zero || axisInput.Vertical != Fix64.Zero) ? (float)FixMath.Clamp(t, 0.3f, 1f) : 0f);
                    animator.SetFloat(Head_Horizontal_f, 0.25f * (float)horizontal);
                    animator.SetFloat(Body_Horizontal_f, 0.35f * (float)horizontal);
                }

                if (keyInput.KeyCodes.Contains((int)KeyCode.Space) && !playerControlComponent.Crouched)
                {
                    playerControlComponent.motion.y = playerControlComponent.Jump;
                }
            }

            playerControlComponent.motion.y  -= playerControlComponent.Gravity * deltaTime;
            playerControlComponent.smoothTime = smoothTime;
            characterController.Move((Vector3)(playerControlComponent.motion * deltaTime));

            animator.SetBool(Jump_b, playerControlComponent.motion.y > 0);
            animator.SetBool(Grounded, characterController.isGrounded && playerControlComponent.motion.y <= 0);

            return(new IUserInputResult[] { playerControlResult });
        }).AddTo(this.Disposer);
    }
예제 #10
0
 // Returns the angle in degrees between /from/ and /to/. This is always the smallest
 public static Fix64 Angle(FixVector3 from, FixVector3 to)
 {
     return(FixMath.Acos(FixMath.Clamp(Dot(from.Normalized, to.Normalized), -Fix64.ONE, Fix64.ONE)) * FixMath.Rad2Deg);
 }