コード例 #1
0
ファイル: FreeLook.cs プロジェクト: shrubba/planetexplorers
        public override Pose Calculate()
        {
            Col.Calculate();
            Sens.Calculate();
            Damp.Calculate();
            Lock.Calculate();
            PitchMax.Calculate();
            PitchMin.Calculate();
            DistLimit.Calculate();
            Prev.Calculate();

            if (controller != null && controller.executor != null)
            {
                float     yaw         = GetFloat("Yaw");
                float     pitch       = GetFloat("Pitch");
                float     yawWanted   = GetFloat("YawWanted");
                float     pitchWanted = GetFloat("PitchWanted");
                Vector3   defaultPos  = CameraController.GetGlobalVar("Default Anchor").value_v;
                Transform anchor      = CameraController.GetTransform("Anchor");
                Transform character   = CameraController.GetTransform("Character");
                float     sens        = Sens.value.value_f;
                bool      rotButton   = InputModule.Axis("Mouse Right Button").value_b;
                float     mouseX      = InputModule.Axis("Mouse X").value_f;
                float     mouseY      = InputModule.Axis("Mouse Y").value_f;
                float     JoystickX   = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickX * 25f * Time.deltaTime : 0f;
                float     JoystickY   = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickY * 12f * Time.deltaTime : 0f;
                float     mouseW      = InputModule.Axis("Mouse ScrollWheel").value_f;
                bool      inverseX    = GetBool("Inverse X");
                bool      inverseY    = GetBool("Inverse Y");
                float     pitchMax    = PitchMax.value.value_f;
                float     pitchMin    = PitchMin.value.value_f;
                float     damp        = Mathf.Clamp(Damp.value.value_f, 0.005f, 1f);
                float     distLimit   = DistLimit.value.value_f;
                float     dt          = Mathf.Clamp(Time.deltaTime, 0.001f, 0.1f);

                // Calc target
                Vector3 target = Vector3.zero;
                if (character != null)
                {
                    target = character.position;
                }
                else if (anchor != null)
                {
                    target = anchor.position;
                }
                else
                {
                    target = defaultPos;
                }

                // rotate / zoom
                float dx = 0, dy = 0;
                float dw = mouseW * 8;
                if (Prev.value.lockCursor || rotButton)
                {
                    dx = Mathf.Clamp(mouseX * sens * (inverseX ? -1f : 1f), -200, 200);
                    dy = Mathf.Clamp(mouseY * sens * (inverseY ? -1f : 1f), -200, 200);
                }

                //float mdx = 0, mdy = 0;
                float jdx = 0, jdy = 0;

                //mdx = dx;
                //mdy = dy;

                jdx = JoystickX * sens * (inverseX ? -1f : 1f);
                jdy = JoystickY * sens * (inverseY ? -1f : 1f);

                dx += jdx;
                dy += jdy;

                yawWanted   += dx;
                pitchWanted += dy;

                yawWanted   = Mathf.Repeat(yawWanted, 360f);
                pitchWanted = Mathf.Clamp(pitchWanted, pitchMin, pitchMax);

                yaw   = Mathf.LerpAngle(yaw, yawWanted, damp);
                pitch = Mathf.LerpAngle(pitch, pitchWanted, damp);

                Pose pose = Prev.value;
                pose.eulerAngles = new Vector3(-pitch, yaw, 0f);
                pose.lockCursor  = false;

                Vector3 forward = pose.rotation * Vector3.forward;
                Vector3 right   = pose.rotation * Vector3.right;
                //Vector3 up = pose.rotation * Vector3.up;
                if (PeInput.Get(PeInput.LogicFunction.MoveForward))
                {
                    pose.position = pose.position + forward * dt * 15f;
                }
                if (PeInput.Get(PeInput.LogicFunction.MoveBackward))
                {
                    pose.position = pose.position - forward * dt * 15f;
                }
                if (PeInput.Get(PeInput.LogicFunction.MoveLeft))
                {
                    pose.position = pose.position - right * dt * 15f;
                }
                if (PeInput.Get(PeInput.LogicFunction.MoveRight))
                {
                    pose.position = pose.position + right * dt * 15f;
                }

                if (dw != 0)
                {
                    pose.position = pose.position + forward * dw;
                }

                Vector3 ofs = pose.position - target;
                ofs           = Vector3.ClampMagnitude(ofs, distLimit);
                pose.position = target + ofs;

                controller.executor.SetFloat("Yaw", yaw);
                controller.executor.SetFloat("Pitch", pitch);
                controller.executor.SetFloat("YawWanted", yawWanted);
                controller.executor.SetFloat("PitchWanted", pitchWanted);

                return(pose);
            }

            return(Pose.Default);
        }
コード例 #2
0
        public override Pose Calculate()
        {
            Col.Calculate();
            Sens.Calculate();
            Damp.Calculate();
            LockCursor.Calculate();
            PitchMax.Calculate();
            PitchMin.Calculate();
            Offset.Calculate();
            OffsetUp.Calculate();
            OffsetDown.Calculate();
            Prev.Calculate();

            if (controller != null && controller.executor != null)
            {
                float     yaw         = GetFloat("Yaw");
                float     pitch       = GetFloat("Pitch");
                float     yawWanted   = GetFloat("YawWanted");
                float     pitchWanted = GetFloat("PitchWanted");
                Vector3   defaultPos  = CameraController.GetGlobalVar("Default Anchor").value_v;
                Transform anchor      = CameraController.GetTransform("Anchor");
                Transform character   = CameraController.GetTransform("Character");
                Transform neck_m      = CameraController.GetTransform("Bone Neck M");
                Transform neck_r      = CameraController.GetTransform("Bone Neck R");
                bool      isRagdoll   = GetBool("Is Ragdoll");
                float     sens        = Sens.value.value_f;
                bool      rotButton   = InputModule.Axis("Mouse Right Button").value_b;
                float     mouseX      = InputModule.Axis("Mouse X").value_f;
                float     mouseY      = InputModule.Axis("Mouse Y").value_f;
                float     JoystickX   = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickX * 25f * Time.deltaTime : 0f;
                float     JoystickY   = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickY * 12f * Time.deltaTime : 0f;
                bool      inverseX    = GetBool("Inverse X");
                bool      inverseY    = GetBool("Inverse Y");
                float     pitchMax    = PitchMax.value.value_f;
                float     pitchMin    = PitchMin.value.value_f;
                float     damp        = Mathf.Clamp(Damp.value.value_f, 0.005f, 1f);
                //float dt = Mathf.Clamp(Time.deltaTime, 0.001f, 0.1f);

                // Calc target
                Vector3 target = Vector3.zero;
                if (character != null)
                {
                    if (neck_m != null && neck_r != null)
                    {
                        target = Vector3.Lerp(character.position, (isRagdoll ? neck_r : neck_m).position, 0.4f);
                    }
                    else
                    {
                        target = character.position;
                    }
                }
                else if (anchor != null)
                {
                    target = anchor.position;
                }
                else
                {
                    target = defaultPos;
                }

                // rotate / zoom
                float dx = 0, dy = 0;
                if (Prev.value.lockCursor || rotButton)
                {
                    dx = Mathf.Clamp(mouseX * sens * (inverseX ? -1f : 1f), -200, 200) * Time.timeScale;
                    dy = Mathf.Clamp(mouseY * sens * (inverseY ? -1f : 1f), -200, 200) * Time.timeScale;
                }

                //float mdx = 0, mdy = 0;
                float jdx = 0, jdy = 0;

                //mdx = dx;
                //mdy = dy;

                jdx = JoystickX * sens * (inverseX ? -1f : 1f) * Time.timeScale;
                jdy = JoystickY * sens * (inverseY ? -1f : 1f) * Time.timeScale;

                dx += jdx;
                dy += jdy;

                dx = Mathf.Clamp(dx, -6 * sens, 6 * sens);
                dy = Mathf.Clamp(dy, -3 * sens, 3 * sens);

                yawWanted   += dx;
                pitchWanted += dy;

                yawWanted   = Mathf.Repeat(yawWanted, 360f);
                pitchWanted = Mathf.Clamp(pitchWanted, pitchMin, pitchMax);

                yaw   = Mathf.LerpAngle(yaw, yawWanted, damp);
                pitch = Mathf.LerpAngle(pitch, pitchWanted, damp);

                Pose pose = Prev.value;
                pose.eulerAngles = new Vector3(-pitch, yaw, 0);
                Vector3 forward = pose.rotation * Vector3.forward;
                Vector3 right   = pose.rotation * Vector3.right;
                Vector3 up      = pose.rotation * Vector3.up;
                Vector3 lofs    = Vector3.zero;
                if (pitch < 0)
                {
                    lofs = Vector3.Slerp(Offset.value.value_v, OffsetDown.value.value_v, pitch / pitchMin);
                }
                else
                {
                    lofs = Vector3.Slerp(Offset.value.value_v, OffsetUp.value.value_v, pitch / pitchMax);
                }
                Vector3 ofs = lofs.x * right + lofs.y * up + lofs.z * forward;

                float     aspect    = controller.executor.camera.aspect;
                float     ur        = Mathf.Sqrt(1f + aspect * aspect) * Mathf.Tan(pose.fov * 0.5f * Mathf.Deg2Rad);
                LayerMask layermask = controller.executor.GetVar("Obstacle LayerMask").value_i;
                float     NCR       = Utils.EvaluateNearclipPlaneRadius(target, 0.05f, pose.nearClip * ur, layermask);
                pose.nearClip = NCR / ur;
                RaycastHit rch;
                if (Physics.SphereCast(new Ray(target, ofs.normalized), NCR - 0.01f, out rch, ofs.magnitude, layermask, QueryTriggerInteraction.Ignore))
                {
                    ofs = ofs.normalized * rch.distance;
                }
                pose.position   = target + ofs;
                pose.lockCursor = LockCursor.value.value_b;

                controller.executor.SetFloat("Yaw", yaw);
                controller.executor.SetFloat("Pitch", pitch);
                controller.executor.SetFloat("YawWanted", yawWanted);
                controller.executor.SetFloat("PitchWanted", pitchWanted);

                return(pose);
            }

            return(Pose.Default);
        }
コード例 #3
0
        public override Pose Calculate()
        {
            Col.Calculate();
            Sens.Calculate();
            Damp.Calculate();
            FS.Calculate();
            AnimFactor.Calculate();
            Lock.Calculate();
            DistMax.Calculate();
            DistMin.Calculate();
            PitchMax.Calculate();
            PitchMin.Calculate();
            RollCoef.Calculate();
            Offset.Calculate();
            Prev.Calculate();

            if (controller != null && controller.executor != null)
            {
                float yaw         = GetFloat("Yaw");
                float pitch       = GetFloat("Pitch");
                float roll        = GetFloat("Roll");
                float dist        = GetFloat("Dist");
                float yawWanted   = GetFloat("YawWanted");
                float pitchWanted = GetFloat("PitchWanted");
                float distWanted  = GetFloat("DistWanted");
                float distLevel   = GetFloat("DistLevel");
                //float distVelocity = GetFloat("DistVelocity");
                Vector3   defaultPos  = CameraController.GetGlobalVar("Default Anchor").value_v;
                Transform anchor      = CameraController.GetTransform("Anchor");
                Transform character   = CameraController.GetTransform("Character");
                Transform neck_m      = CameraController.GetTransform("Bone Neck M");
                Transform neck_r      = CameraController.GetTransform("Bone Neck R");
                bool      isRagdoll   = GetBool("Is Ragdoll");
                Vector3   velocity    = controller.executor.GetVar("Character Velocity").value_v;
                float     followSpeed = FS.value.value_f;
                float     sens        = Sens.value.value_f;
                bool      lockCursor  = Lock.value.value_b;
                bool      rotButton   = InputModule.Axis("Mouse Right Button").value_b&& !GetBool("Mouse Op GUI");
                float     mouseX      = InputModule.Axis("Mouse X").value_f;
                float     mouseY      = InputModule.Axis("Mouse Y").value_f;
                float     JoystickX   = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickX * 25f * Time.deltaTime : 0f;
                float     JoystickY   = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickY * 12f * Time.deltaTime : 0f;
                float     mouseW      = GetBool("Mouse On Scroll") ? 0f : InputModule.Axis("Mouse ScrollWheel").value_f;
                bool      inverseX    = GetBool("Inverse X");
                bool      inverseY    = GetBool("Inverse Y");
                float     ACR         = GetFloat("Activity Space Size");
                bool      clampd      = GetBool("Geometry Clampd");
                float     distMax     = DistMax.value.value_f;
                float     distMin     = DistMin.value.value_f;
                float     pitchMax    = PitchMax.value.value_f;
                float     pitchMin    = PitchMin.value.value_f;
                float     rollCoef    = RollCoef.value.value_f;
                float     damp        = Mathf.Clamp(Damp.value.value_f, 0.005f, 1f);
                float     dt          = Mathf.Clamp(Time.deltaTime, 0.001f, 0.1f);

                // Calc target
                Vector3 target    = Vector3.zero;
                Vector3 target_up = Vector3.up;
                //if (character != null)
                //{
                //	if (neck_m != null && neck_r != null)
                //	{
                //		target = Vector3.Lerp(character.position, (isRagdoll ? neck_r : neck_m).position, AnimFactor.value.value_f);
                //	}
                //	else
                //	{
                //		target = character.position;
                //	}
                //	target_up = character.up;
                //}
                //else
                if (anchor != null)
                {
                    target = anchor.position;
                }
                else
                {
                    target = defaultPos;
                }
                //target -= velocity * 0.1f;

                // rotate / zoom
                float dx = 0, dy = 0;
                float dw = -mouseW * 8;
                if (Prev.value.lockCursor || rotButton)
                {
                    dx = Mathf.Clamp(mouseX * sens * (inverseX ? -1f : 1f), -200, 200) * Time.timeScale;
                    dy = Mathf.Clamp(mouseY * sens * (inverseY ? -1f : 1f), -200, 200) * Time.timeScale;
                }

                float mdx = 0, mdy = 0;
                float jdx = 0, jdy = 0;

                mdx = dx;
                mdy = dy;

                jdx = JoystickX * sens * (inverseX ? -1f : 1f) * Time.timeScale;
                jdy = JoystickY * sens * (inverseY ? -1f : 1f) * Time.timeScale;

                dx += jdx;
                dy += jdy;

                dx = Mathf.Clamp(dx, -6 * sens, 6 * sens);
                dy = Mathf.Clamp(dy, -3 * sens, 3 * sens);

                yawWanted   += dx;
                pitchWanted += dy;
                distLevel   += dw;
                distLevel    = Mathf.Clamp(distLevel, distMin, distMax);

                if (dw != 0)
                {
                    recalcDistTime         = 3f;
                    lockDistAfterClampTime = 0f;
                }
                if (recalcDistTime > 0)
                {
                    recalcDistTime -= Time.deltaTime;
                }
                if (lockDistAfterClampTime > 0)
                {
                    lockDistAfterClampTime -= dt;
                }
                if (clampd)
                {
                    lockDistAfterClampTime = 2f;
                    controller.executor.SetBool("Geometry Clampd", false);
                }

                float maxdist = Mathf.Clamp(ACR * 2f, distMin, distMax);

                float distcoef = 1;
                distcoef = Mathf.Clamp(ACR * 0.15f, 0.15f, 1f);

                distWanted = distLevel * distcoef;

                if (!Prev.value.lockCursor && rotButton)
                {
                    noControlTime = 0;
                }
                else if (Mathf.Abs(jdx) + Mathf.Abs(jdy) > 0.2f || Mathf.Abs(mdx) + Mathf.Abs(mdy) > 8f)
                {
                    noControlTime = 0;
                }
                else
                {
                    noControlTime += dt;
                }

                controller.executor.SetFloat("No Rotate Time", noControlTime);

                if (noControlTime > 1.3f)
                {
                    velUsed = Vector3.Lerp(velUsed, velocity, 0.2f);
                }
                else
                {
                    velUsed = Vector3.Lerp(velUsed, Vector3.zero, 0.2f);
                }
                if (float.IsNaN(velUsed.x) || float.IsNaN(velUsed.y) || float.IsNaN(velUsed.z))
                {
                    velUsed = Vector3.zero;
                }

                float vel_length = Mathf.Clamp01(velUsed.magnitude * 0.2f);
                float yaw_length = Mathf.Clamp01(new Vector2(velUsed.x, velUsed.z).magnitude * 0.2f);

                Debug.DrawLine(target, target + velUsed, Color.cyan);
                if (vel_length > 0.01f)
                {
                    Quaternion q      = Quaternion.LookRotation(velUsed);
                    Vector3    euler  = q.eulerAngles;
                    float      fyaw   = euler.y;
                    float      fpitch = -euler.x - 10;

                    if (Mathf.DeltaAngle(yawWanted, fyaw) > 120f || Mathf.DeltaAngle(yawWanted, fyaw) < -120f)
                    {
                        fyaw = yawWanted;
                    }
                    fyaw   = Mathf.LerpAngle(yawWanted, fyaw, yaw_length);
                    fpitch = Mathf.LerpAngle(pitchWanted, fpitch, vel_length);

                    Debug.DrawLine(target, target + Quaternion.Euler(new Vector3(-fpitch, fyaw, 0)) * Vector3.forward, Color.red);

                    if (distcoef < 0.2f)
                    {
                        followSpeed = followSpeed * 4f;
                    }
                    else if (distcoef < 0.3f)
                    {
                        followSpeed = followSpeed * 3f;
                    }
                    else if (distcoef < 0.4f)
                    {
                        followSpeed = followSpeed * 2.5f;
                    }
                    else if (distcoef < 0.5f)
                    {
                        followSpeed = followSpeed * 2f;
                    }
                    else if (distcoef < 0.6f)
                    {
                        followSpeed = followSpeed * 1.5f;
                    }

                    yawWanted   = Mathf.SmoothDampAngle(yawWanted, fyaw, ref vyaw, 20.0f / followSpeed);
                    pitchWanted = Mathf.SmoothDampAngle(pitchWanted, fpitch, ref vpitch, 40.0f / followSpeed);

//					float ayaw = Mathf.DeltaAngle(yawWanted, fyaw) * followSpeed * yaw_length;
//					float apitch = Mathf.DeltaAngle(pitchWanted, fpitch) * followSpeed * vel_length;
//
//					ayaw -= (vyaw*vyaw) * Mathf.Sign(vyaw) * 0.2f;
//					apitch -= (vpitch*vpitch) * Mathf.Sign(vpitch) * 0.2f;
//
//					ayaw = Mathf.Clamp(ayaw, -2000, 2000);
//					apitch = Mathf.Clamp(apitch, -2000, 2000);
//
//					Debug.DrawLine(target, target + Quaternion.Euler(new Vector3(-apitch, ayaw, 0)) * Vector3.forward, Color.green);
//
//					vyaw = vyaw + ayaw * dt;
//					vpitch = vpitch + apitch * dt;
//
//					vyaw = Mathf.Clamp(vyaw, -60, 60);
//					vpitch = Mathf.Clamp(vpitch, -60, 60);
//
//					Debug.DrawLine(target, target + Quaternion.Euler(new Vector3(-vpitch, vyaw, 0)) * Vector3.forward, Color.blue);
//
//					yawWanted += vyaw * dt;
//					pitchWanted += vpitch * dt;
                }


                yawWanted   = Mathf.Repeat(yawWanted, 360f);
                pitchWanted = Mathf.Clamp(pitchWanted, pitchMin, pitchMax);
                distWanted  = Mathf.Clamp(distWanted, distMin, maxdist);

                yaw   = Mathf.LerpAngle(yaw, yawWanted, damp);
                pitch = Mathf.LerpAngle(pitch, pitchWanted, damp);
                float vdist = controller.executor.GetVar("DistVelocity").value_f;
                if (lockDistAfterClampTime <= 0)
                {
                    dist = Mathf.SmoothDamp(dist, distWanted, ref vdist, 0.5f);
                }
                else if (dist < distMin)
                {
                    dist = Mathf.SmoothDamp(dist, distMin, ref vdist, 0.5f);
                }
                controller.executor.SetVar("DistVelocity", vdist);

                Pose pose = Prev.value;
                pose.eulerAngles = new Vector3(-pitch, yaw, 0);
                Vector3 forward = pose.rotation * Vector3.forward;
                Vector3 right   = pose.rotation * Vector3.right;
                Vector3 up      = pose.rotation * Vector3.up;
                Vector3 ofs     = Offset.value.value_v.x * right + Offset.value.value_v.y * up + Offset.value.value_v.z * forward;
                float   _dist   = dist;
                if (distMin == distMax)
                {
                    _dist = distMin;
                }
                //pose.position = target - _dist * forward + ofs;
                pose.position   = target - _dist * forward;
                pose.lockCursor = lockCursor;

                // Roll
                if (Mathf.Abs(rollCoef) > 0.001f)
                {
                    Vector3 horz_forward = forward;
                    Vector3 horz_right   = right;
                    horz_forward.y = 0;
                    horz_forward.Normalize();
                    horz_right.y = 0;

                    float   udotf   = Vector3.Dot(target_up, horz_forward);
                    Vector3 proj_up = target_up - udotf * horz_forward;
                    float   angle   = Vector3.Angle(proj_up, Vector3.up);
                    if (angle > 90)
                    {
                        angle = 90;
                    }
                    angle  = angle * Mathf.Pow(angle / 90f, 2) * rollCoef;
                    angle *= -Mathf.Sign(Vector3.Dot(proj_up, horz_right));
                    roll   = Mathf.Lerp(roll, angle, 0.15f);
                }
                else
                {
                    roll = Mathf.Lerp(roll, 0, 0.15f);
                }
                pose.eulerAngles = new Vector3(-pitch, yaw, roll);

                controller.executor.SetFloat("Yaw", yaw);
                controller.executor.SetFloat("Pitch", pitch);
                controller.executor.SetFloat("Roll", roll);
                controller.executor.SetFloat("Dist", dist);
                controller.executor.SetFloat("YawWanted", yawWanted);
                controller.executor.SetFloat("PitchWanted", pitchWanted);
                controller.executor.SetFloat("DistWanted", distWanted);
                controller.executor.SetFloat("DistLevel", distLevel);

                return(pose);
            }

            return(Pose.Default);
        }
コード例 #4
0
        public override Pose Calculate()
        {
            // Calculate Inputs
            Col.Calculate();
            Sens.Calculate();
            Damp.Calculate();
            FS.Calculate();
            Lock.Calculate();
            DistMax.Calculate();
            DistMin.Calculate();
            PitchMax.Calculate();
            PitchMin.Calculate();
            RollCoef.Calculate();
            FovCoef.Calculate();
            BlurCoef.Calculate();
            OffsetUp.Calculate();
            Offset.Calculate();
            OffsetDown.Calculate();
            Prev.Calculate();


            if (controller != null && controller.executor != null)
            {
                // Fetch vars
                float yaw   = GetFloat("Yaw");
                float pitch = GetFloat("Pitch");
                float roll  = GetFloat("Roll");
                float dist  = GetFloat("Dist");

                float yawWanted   = GetFloat("YawWanted");
                float pitchWanted = GetFloat("PitchWanted");
                float distWanted  = GetFloat("DistWanted");
                float distLevel   = GetFloat("DistLevel");
                //float distVelocity = GetFloat("DistVelocity");

                Vector3   defaultPos    = CameraController.GetGlobalVar("Default Anchor").value_v;
                Transform anchor        = CameraController.GetTransform("Anchor");
                Transform character     = CameraController.GetTransform("Character");
                Vector3   velocity      = controller.executor.GetVar("Driving Velocity").value_v;
                Vector3   rigidbody_vel = controller.executor.GetVar("Rigidbody Velocity").value_v;

                float followSpeed = FS.value.value_f;
                float sens        = Sens.value.value_f;
                bool  lockCursor  = Lock.value.value_b;
                float damp        = Mathf.Clamp(Damp.value.value_f, 0.005f, 1f);
                float dt          = Mathf.Clamp(Time.deltaTime, 0.001f, 0.1f);

                bool  rotButton = InputModule.Axis("Mouse Right Button").value_b&& !GetBool("Mouse Op GUI");
                float mouseX    = InputModule.Axis("Mouse X").value_f;
                float mouseY    = InputModule.Axis("Mouse Y").value_f;
                float JoystickX = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickX * 25f * Time.deltaTime : 0f;
                float JoystickY = SystemSettingData.Instance.UseController ? InControl.InputManager.ActiveDevice.RightStickY * 12f * Time.deltaTime : 0f;
                float mouseW    = GetBool("Mouse On Scroll") ? 0f : InputModule.Axis("Mouse ScrollWheel").value_f;
                bool  inverseX  = GetBool("Inverse X");
                bool  inverseY  = GetBool("Inverse Y");

                //float ACR = GetFloat("Activity Space Size");
                bool clampd = GetBool("Geometry Clampd");

                float distMax  = DistMax.value.value_f;
                float distMin  = DistMin.value.value_f;
                float pitchMax = PitchMax.value.value_f;
                float pitchMin = PitchMin.value.value_f;
                float rollCoef = RollCoef.value.value_f;
                float fovCoef  = FovCoef.value.value_f;
                float blurCoef = BlurCoef.value.value_f;


                // Calc target
                Vector3 target    = Vector3.zero;
                Vector3 target_up = Vector3.up;
                if (character != null)
                {
                    target    = character.position - character.up;
                    target_up = character.up;
                }
                else if (anchor != null)
                {
                    target = anchor.position;
                }
                else
                {
                    target = defaultPos;
                }

                // rotate / zoom
                float dx = 0, dy = 0;
                float dw = -mouseW * 8;
                if (Prev.value.lockCursor || rotButton)
                {
                    dx = Mathf.Clamp(mouseX * sens * (inverseX ? -1f : 1f), -200, 200) * Time.timeScale;
                    dy = Mathf.Clamp(mouseY * sens * (inverseY ? -1f : 1f), -200, 200) * Time.timeScale;
                }

                float mdx = 0, mdy = 0;
                float jdx = 0, jdy = 0;

                mdx = dx;
                mdy = dy;

                jdx = JoystickX * sens * (inverseX ? -1f : 1f) * Time.timeScale;
                jdy = JoystickY * sens * (inverseY ? -1f : 1f) * Time.timeScale;

                dx += jdx;
                dy += jdy;

                dx = Mathf.Clamp(dx, -6 * sens, 6 * sens);
                dy = Mathf.Clamp(dy, -3 * sens, 3 * sens);

                yawWanted   += dx;
                pitchWanted += dy;
                distLevel   += dw;
                distLevel    = Mathf.Clamp(distLevel, distMin, distMax);

                // lock dist
                if (dw != 0)
                {
                    recalcDistTime         = 3f;
                    lockDistAfterClampTime = 0f;
                }
                if (recalcDistTime > 0)
                {
                    recalcDistTime -= Time.deltaTime;
                }
                if (lockDistAfterClampTime > 0)
                {
                    lockDistAfterClampTime -= Time.deltaTime;
                }
                if (clampd)
                {
                    lockDistAfterClampTime = 2f;
                    controller.executor.SetBool("Geometry Clampd", false);
                }

                distWanted = distLevel;

                // record noControlTime
                if (!Prev.value.lockCursor && rotButton)
                {
                    noControlTime = 0;
                }
                else if (Mathf.Abs(jdx) + Mathf.Abs(jdy) > 0.2f || Mathf.Abs(mdx) + Mathf.Abs(mdy) > 8f)
                {
                    noControlTime = 0;
                }
                else
                {
                    noControlTime += dt;
                }

                controller.executor.SetFloat("No Rotate Time", noControlTime);

                // Follow
                if (noControlTime > 2.0f)
                {
                    velUsed = Vector3.Lerp(velUsed, velocity, 0.1f);
                }
                else
                {
                    velUsed = Vector3.Lerp(velUsed, Vector3.zero, 0.5f);
                }
                if (float.IsNaN(velUsed.x) || float.IsNaN(velUsed.y) || float.IsNaN(velUsed.z))
                {
                    velUsed = Vector3.zero;
                }

                float vel_length = Mathf.Clamp01((velUsed.magnitude - 2) * 0.1f);
                float yaw_length = Mathf.Clamp01((new Vector2(velUsed.x, velUsed.z).magnitude - 2) * 0.1f);

                Debug.DrawLine(target, target + velUsed, Color.cyan);
                if (vel_length > 0.01f)
                {
                    Quaternion q      = Quaternion.LookRotation(velUsed);
                    Vector3    euler  = q.eulerAngles;
                    float      fyaw   = euler.y;
                    float      fpitch = -euler.x - 10;

                    fyaw   = Mathf.LerpAngle(yawWanted, fyaw, yaw_length);
                    fpitch = Mathf.LerpAngle(pitchWanted, fpitch, vel_length * 0.02f);

                    yawWanted   = Mathf.SmoothDampAngle(yawWanted, fyaw, ref vyaw, 20.0f / followSpeed);
                    pitchWanted = Mathf.SmoothDampAngle(pitchWanted, fpitch, ref vpitch, 40.0f / followSpeed);

//					float ayaw = Mathf.DeltaAngle(yawWanted, fyaw) * followSpeed * yaw_length;
//					float apitch = Mathf.DeltaAngle(pitchWanted, fpitch) * followSpeed * vel_length;
//
//					ayaw -= (vyaw*vyaw) * Mathf.Sign(vyaw) * 1f;
//					apitch -= (vpitch*vpitch) * Mathf.Sign(vpitch) * 1f;
//
//					ayaw = Mathf.Clamp(ayaw, -2000, 2000);
//					apitch = Mathf.Clamp(apitch, -2000, 2000);
//
//					vyaw = vyaw + ayaw * dt;
//					vpitch = vpitch + apitch * dt;
//
//					vyaw = Mathf.Clamp(vyaw, -60, 60);
//					vpitch = Mathf.Clamp(vpitch, -60, 60);
//
//					yawWanted += vyaw * dt;
//					pitchWanted += vpitch * dt;
                }

                yawWanted   = Mathf.Repeat(yawWanted, 360f);
                pitchWanted = Mathf.Clamp(pitchWanted, pitchMin, pitchMax);
                distWanted  = Mathf.Clamp(distWanted, distMin, distMax);

                yaw   = Mathf.LerpAngle(yaw, yawWanted, damp);
                pitch = Mathf.LerpAngle(pitch, pitchWanted, damp);
                float vdist = controller.executor.GetVar("DistVelocity").value_f;
                if (lockDistAfterClampTime <= 0)
                {
                    dist = Mathf.SmoothDamp(dist, distWanted, ref vdist, 0.5f);
                }
                dist = Mathf.Clamp(dist, distMin, distMax);
                controller.executor.SetVar("DistVelocity", vdist);

                Pose pose = Prev.value;
                pose.eulerAngles = new Vector3(-pitch, yaw, 0);

                Vector3 forward = pose.rotation * Vector3.forward;
                Vector3 right   = pose.rotation * Vector3.right;
                //Vector3 up = pose.rotation * Vector3.up;
                Vector3 lofs = Vector3.zero;
                if (pitch < 0)
                {
                    lofs = Vector3.Slerp(Offset.value.value_v, OffsetDown.value.value_v, pitch / pitchMin);
                }
                else
                {
                    lofs = Vector3.Slerp(Offset.value.value_v, OffsetUp.value.value_v, pitch / pitchMax);
                }
                float _dist = dist;
                if (distMin == distMax)
                {
                    _dist = distMin;
                }
                pose.position   = target - _dist * forward + lofs * _dist;
                pose.lockCursor = lockCursor;

                // Roll
                if (Mathf.Abs(rollCoef) > 0.001f)
                {
                    Vector3 horz_forward = forward;
                    Vector3 horz_right   = right;
                    horz_forward.y = 0;
                    horz_forward.Normalize();
                    horz_right.y = 0;

                    float   udotf   = Vector3.Dot(target_up, horz_forward);
                    Vector3 proj_up = target_up - udotf * horz_forward;
                    float   angle   = Vector3.Angle(proj_up, Vector3.up);
                    float   falloff = 1f - Mathf.Pow((angle - 90f) / 90f, 2);
                    if (angle < 90)
                    {
                        angle = Mathf.Lerp(0, 90, falloff);
                    }
                    else
                    {
                        angle = Mathf.Lerp(180, 90, falloff);
                    }
                    angle *= rollCoef;
                    angle *= -Mathf.Sign(Vector3.Dot(proj_up, horz_right));
                    roll   = Mathf.Lerp(roll, angle, 0.15f);
                }
                else
                {
                    roll = Mathf.Lerp(roll, 0, 0.15f);
                }

                pose.eulerAngles = new Vector3(-pitch, yaw, roll);

                // Fov & blur
                float inc = Mathf.InverseLerp(10, 35, rigidbody_vel.magnitude);
                fovIncr         = Mathf.Lerp(fovIncr, inc * fovCoef, 0.2f);
                pose.fov        = Mathf.Clamp(pose.fov + fovIncr, 10f, 90f);
                blur            = Mathf.Lerp(blur, inc * blurCoef, 0.2f);
                pose.motionBlur = Mathf.Clamp(blur, 0, 0.8f);

                // Set vars
                controller.executor.SetFloat("Yaw", yaw);
                controller.executor.SetFloat("Pitch", pitch);
                controller.executor.SetFloat("Roll", roll);
                controller.executor.SetFloat("Dist", dist);
                controller.executor.SetFloat("YawWanted", yawWanted);
                controller.executor.SetFloat("PitchWanted", pitchWanted);
                controller.executor.SetFloat("DistWanted", distWanted);
                controller.executor.SetFloat("DistLevel", distLevel);

                return(pose);
            }

            return(Pose.Default);
        }