此文弊端:使用Clamp来限制数值范围,数值本身不会变化,如果需要数值本身变化,请选择以下方法:
if(x>0){x=0};
if(x<1){x=1};
应用场景:限制相机视角、限制相机位置;
话不多说,直接上干货,同时也会介绍该类中一些常见方法的使用;
限制相机范围无非是改变参数,使用Mathf.Clamp方法可以对参数进行限制,无论是角度还是位置。示例如下:
- public void UpdateTransform(Transform t)
- {
- t.position = new Vector3(Mathf.Clamp(x, -26.03408f, 11.81941f), Mathf.Clamp(y, 8.892664f, 29.212f), Mathf.Clamp(z, 3.319095f, 166.4727f) );
- }
上述代码段中,使用了三次Mathf.Clamp对相机的XYZ三轴进行了参数限制,方法的具体说明如下:
Mathf.Clamp(X, XMin, XMax)
上述代码段中:
X代表要限制的参数(例如相机要去的目标位置);
XMin代表要限制的最小值(当X小于XMin时,X=XMin);
XMax代表要限制的最大值(当X大于XMax时,X=XMax);
Mathf.Abs()取绝对值
Mathf.Ceil()向上取整,返回值为 Float 类型
Mathf.CeilToInt()向上取整,返回值为 Int 类型
Mathf.Floor()向下取整,返回值为 Float 类型
Mathf.FloorToInt()向下取整,返回值为 Int 类型
Mathf.Round()四舍五入,返回值为 Float 类型
Mathf.RoundToInt()四舍五入,返回值为 Int 类型
Mathf.Pow(float x,float y)返回 x 的 y 次方
Mathf.Sqrt(float x)返回 x 的平方根
Mathf.DeltaAngle(float current,float target)返回两个角夹角的最小值
Mathf.ClosestPowerOfTwo(float x)返回 2 的 x 次方
Mathf.Clamp(float x,float min,float max),这就是我们刚才说过的;
Mathf.Lerp(float a, float b, float t)线性赋予差值,匀速增加或减少,t=0 的时候返回 a,t=1 的时候返回 b,t=0.5 时返回(a+b)/2。
Mathf.MoveTowards(float current, float target, float maxDelta)与 Mathf.Lerp 差不多;
Mathf.PingPong(float t,float length)返回值在 0 和 length 之间
附带一篇略加变动官方的相机控制脚本;
- #if ENABLE_INPUT_SYSTEM
- using UnityEngine.InputSystem;
- #endif
-
- using UnityEngine;
-
- namespace UnityTemplateProjects
- {
-
- public class MainCameraMove : MonoBehaviour
- {
-
- public static bool home, yamaha, zhijiao, chuang, abb, store, pack, sort, trans, agv;
- public static bool duoji, jjhome;
- class CameraState
- {
-
- public float yaw;
- public float pitch;
- public float roll;
- public float x;
- public float y;
- public float z;
-
-
- public void SetFromTransform(Transform t)
- {
- pitch = t.eulerAngles.x;
- yaw = t.eulerAngles.y;
- roll = t.eulerAngles.z;
- x = t.position.x;
- y = t.position.y;
- z = t.position.z;
- }
-
- public void Translate(Vector3 translation)
- {
- Vector3 rotatedTranslation = Quaternion.Euler(pitch, yaw, roll) * translation;
-
- x += rotatedTranslation.x;
- y += rotatedTranslation.y;
- z += rotatedTranslation.z;
- }
-
- public void LerpTowards(CameraState target, float positionLerpPct, float rotationLerpPct)
- {
- yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct);
- pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct);
- roll = Mathf.Lerp(roll, target.roll, rotationLerpPct);
-
- x = Mathf.Lerp(x, target.x, positionLerpPct);
- y = Mathf.Lerp(y, target.y, positionLerpPct);
- z = Mathf.Lerp(z, target.z, positionLerpPct);
- }
-
- public void UpdateTransform(Transform t)
- {
- t.eulerAngles = new Vector3(pitch, yaw, roll);
- //t.position = new Vector3(x , y, z);
- t.position = new Vector3(Mathf.Clamp(x, -26.03408f, 11.81941f), Mathf.Clamp(y, 8.892664f, 29.212f), Mathf.Clamp(z, 3.319095f, 166.4727f) );
- }
- }
-
-
- CameraState m_TargetCameraState = new CameraState();
- CameraState m_InterpolatingCameraState = new CameraState();
-
- [Header("Movement Settings")]
- [Tooltip("Exponential boost factor on translation, controllable by mouse wheel.")]
- public float boost = 3.5f;
-
- [Tooltip("Time it takes to interpolate camera position 99% of the way to the target."), Range(0.001f, 1f)]
- public float positionLerpTime = 0.2f;
-
- [Header("Rotation Settings")]
- [Tooltip("X = Change in mouse position.\nY = Multiplicative factor for camera rotation.")]
- public AnimationCurve mouseSensitivityCurve = new AnimationCurve(new Keyframe(0f, 0.5f, 0f, 5f), new Keyframe(1f, 2.5f, 0f, 0f));
-
- [Tooltip("Time it takes to interpolate camera rotation 99% of the way to the target."), Range(0.001f, 1f)]
- public float rotationLerpTime = 0.01f;
-
- [Tooltip("Whether or not to invert our Y axis for mouse input to rotation.")]
- public bool invertY = false;
-
- #if ENABLE_INPUT_SYSTEM
- InputAction movementAction;
- InputAction verticalMovementAction;
- InputAction lookAction;
- InputAction boostFactorAction;
- bool mouseRightButtonPressed;
-
- void Start()
- {
- var map = new InputActionMap("Simple Camera Controller");
-
- lookAction = map.AddAction("look", binding: "
/delta" ); - movementAction = map.AddAction("move", binding: "
/leftStick" ); - verticalMovementAction = map.AddAction("Vertical Movement");
- boostFactorAction = map.AddAction("Boost Factor", binding: "
/scroll" ); -
- lookAction.AddBinding("
/rightStick" ).WithProcessor("scaleVector2(x=15, y=15)"); - movementAction.AddCompositeBinding("Dpad")
- .With("Up", "
/w" ) - .With("Up", "
/upArrow" ) - .With("Down", "
/s" ) - .With("Down", "
/downArrow" ) - .With("Left", "
/a" ) - .With("Left", "
/leftArrow" ) - .With("Right", "
/d" ) - .With("Right", "
/rightArrow" ); - verticalMovementAction.AddCompositeBinding("Dpad")
- .With("Up", "
/pageUp" ) - .With("Down", "
/pageDown" ) - .With("Up", "
/e" ) - .With("Down", "
/q" ) - .With("Up", "
/rightshoulder" ) - .With("Down", "
/leftshoulder" ); - boostFactorAction.AddBinding("
/Dpad" ).WithProcessor("scaleVector2(x=1, y=4)"); -
- movementAction.Enable();
- lookAction.Enable();
- verticalMovementAction.Enable();
- boostFactorAction.Enable();
- }
- #endif
-
- void OnEnable()
- {
- m_TargetCameraState.SetFromTransform(transform);
- m_InterpolatingCameraState.SetFromTransform(transform);
- }
-
- Vector3 GetInputTranslationDirection()
- {
- Vector3 direction = Vector3.zero;
- #if ENABLE_INPUT_SYSTEM
- var moveDelta = movementAction.ReadValue
(); - direction.x = moveDelta.x;
- direction.z = moveDelta.y;
- direction.y = verticalMovementAction.ReadValue
().y; - #else
-
-
-
- if (Input.GetKey(KeyCode.W))
- {
- direction += Vector3.forward;
- }
- if (Input.GetKey(KeyCode.S))
- {
- direction += Vector3.back;
- }
- if (Input.GetKey(KeyCode.A))
- {
- direction += Vector3.left;
- }
- if (Input.GetKey(KeyCode.D))
- {
- direction += Vector3.right;
- }
- if (Input.GetKey(KeyCode.E))
- {
- direction += Vector3.down;
- }
- if (Input.GetKey(KeyCode.Q))
- {
- direction += Vector3.up;
- }
-
-
- #endif
- return direction;
- }
-
- void Update()
- {
-
- // Exit Sample
-
- if (IsEscapePressed())
- {
- Application.Quit();
- #if UNITY_EDITOR
- UnityEditor.EditorApplication.isPlaying = false;
- #endif
- }
-
- // Hide and lock cursor when right mouse button pressed
- if (IsRightMouseButtonDown())
- {
- Cursor.lockState = CursorLockMode.Locked;
- }
-
- // Unlock and show cursor when right mouse button released
- if (IsRightMouseButtonUp())
- {
- Cursor.visible = true;
- Cursor.lockState = CursorLockMode.None;
- }
-
- // Rotation
- if (IsCameraRotationAllowed())
- {
- var mouseMovement = GetInputLookRotation() * Time.deltaTime * 5;
- if (invertY)
- mouseMovement.y = -mouseMovement.y;
-
- var mouseSensitivityFactor = mouseSensitivityCurve.Evaluate(mouseMovement.magnitude);
-
- m_TargetCameraState.yaw += mouseMovement.x * mouseSensitivityFactor;
- m_TargetCameraState.pitch += mouseMovement.y * mouseSensitivityFactor;
- }
-
- // Translation
- var translation = GetInputTranslationDirection() * Time.deltaTime;
-
- // Speed up movement when shift key held
- if (IsBoostPressed())
- {
- translation *= 10.0f;
- }
-
- // Modify movement by a boost factor (defined in Inspector and modified in play mode through the mouse scroll wheel)
- boost += GetBoostFactor();
- translation *= Mathf.Pow(2.0f, boost);
-
- m_TargetCameraState.Translate(translation);
- // Framerate-independent interpolation
- // Calculate the lerp amount, such that we get 99% of the way to our target in the specified time
- var positionLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / positionLerpTime) * Time.deltaTime);
- var rotationLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / rotationLerpTime) * Time.deltaTime);
- m_InterpolatingCameraState.LerpTowards(m_TargetCameraState, positionLerpPct, rotationLerpPct);
-
- //一键到仓库位置
- if (store)
- {
- m_TargetCameraState.yaw = 118.386f;
- m_TargetCameraState.pitch = 19.651f;
- m_TargetCameraState.x = -1.956715f;
- m_TargetCameraState.y = 1.364126f;
- m_TargetCameraState.z = -7.513207f;
- //m_InterpolatingCameraState.UpdateTransform(new Vector3(-4.152681f, 1.914845f, 0.7370217f));
-
- //transform.x = -4.152681f;
- //transform.y = 1.914845f;
- //transform.z = 0.7370217f;
- store = false;
- }
-
- m_InterpolatingCameraState.UpdateTransform(transform);
-
- }
-
- float GetBoostFactor()
- {
- #if ENABLE_INPUT_SYSTEM
- return boostFactorAction.ReadValue
().y * 0.01f; - #else
- return Input.mouseScrollDelta.y * 0.2f;
- #endif
- }
-
- Vector2 GetInputLookRotation()
- {
- #if ENABLE_INPUT_SYSTEM
- return lookAction.ReadValue
(); - #else
- return new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * 10;
- #endif
- }
-
- bool IsBoostPressed()
- {
- #if ENABLE_INPUT_SYSTEM
- bool boost = Keyboard.current != null ? Keyboard.current.leftShiftKey.isPressed : false;
- boost |= Gamepad.current != null ? Gamepad.current.xButton.isPressed : false;
- return boost;
- #else
- return Input.GetKey(KeyCode.LeftShift);
- #endif
-
- }
-
- bool IsEscapePressed()
- {
- #if ENABLE_INPUT_SYSTEM
- return Keyboard.current != null ? Keyboard.current.escapeKey.isPressed : false;
- #else
- return Input.GetKey(KeyCode.Escape);
- #endif
- }
-
- bool IsCameraRotationAllowed()
- {
- #if ENABLE_INPUT_SYSTEM
- bool canRotate = Mouse.current != null ? Mouse.current.rightButton.isPressed : false;
- canRotate |= Gamepad.current != null ? Gamepad.current.rightStick.ReadValue().magnitude > 0 : false;
- return canRotate;
- #else
- return Input.GetMouseButton(1);
- #endif
- }
-
- bool IsRightMouseButtonDown()
- {
- #if ENABLE_INPUT_SYSTEM
- return Mouse.current != null ? Mouse.current.rightButton.isPressed : false;
- #else
- return Input.GetMouseButtonDown(1);
- #endif
- }
-
- bool IsRightMouseButtonUp()
- {
- #if ENABLE_INPUT_SYSTEM
- return Mouse.current != null ? !Mouse.current.rightButton.isPressed : false;
- #else
- return Input.GetMouseButtonUp(1);
- #endif
- }
-
- }
-
- }