• 【Unity】如何限制相机、物体的移动角度、位置等


    此文弊端:使用Clamp来限制数值范围,数值本身不会变化,如果需要数值本身变化,请选择以下方法:

    if(x>0){x=0};

    if(x<1){x=1};

    应用场景:限制相机视角、限制相机位置;

    话不多说,直接上干货,同时也会介绍该类中一些常见方法的使用;

    限制相机范围无非是改变参数,使用Mathf.Clamp方法可以对参数进行限制,无论是角度还是位置。示例如下:

    1. public void UpdateTransform(Transform t)
    2. {
    3. 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) );
    4. }

    上述代码段中,使用了三次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 之间

    附带一篇略加变动官方的相机控制脚本;

    1. #if ENABLE_INPUT_SYSTEM
    2. using UnityEngine.InputSystem;
    3. #endif
    4. using UnityEngine;
    5. namespace UnityTemplateProjects
    6. {
    7. public class MainCameraMove : MonoBehaviour
    8. {
    9. public static bool home, yamaha, zhijiao, chuang, abb, store, pack, sort, trans, agv;
    10. public static bool duoji, jjhome;
    11. class CameraState
    12. {
    13. public float yaw;
    14. public float pitch;
    15. public float roll;
    16. public float x;
    17. public float y;
    18. public float z;
    19. public void SetFromTransform(Transform t)
    20. {
    21. pitch = t.eulerAngles.x;
    22. yaw = t.eulerAngles.y;
    23. roll = t.eulerAngles.z;
    24. x = t.position.x;
    25. y = t.position.y;
    26. z = t.position.z;
    27. }
    28. public void Translate(Vector3 translation)
    29. {
    30. Vector3 rotatedTranslation = Quaternion.Euler(pitch, yaw, roll) * translation;
    31. x += rotatedTranslation.x;
    32. y += rotatedTranslation.y;
    33. z += rotatedTranslation.z;
    34. }
    35. public void LerpTowards(CameraState target, float positionLerpPct, float rotationLerpPct)
    36. {
    37. yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct);
    38. pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct);
    39. roll = Mathf.Lerp(roll, target.roll, rotationLerpPct);
    40. x = Mathf.Lerp(x, target.x, positionLerpPct);
    41. y = Mathf.Lerp(y, target.y, positionLerpPct);
    42. z = Mathf.Lerp(z, target.z, positionLerpPct);
    43. }
    44. public void UpdateTransform(Transform t)
    45. {
    46. t.eulerAngles = new Vector3(pitch, yaw, roll);
    47. //t.position = new Vector3(x , y, z);
    48. 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) );
    49. }
    50. }
    51. CameraState m_TargetCameraState = new CameraState();
    52. CameraState m_InterpolatingCameraState = new CameraState();
    53. [Header("Movement Settings")]
    54. [Tooltip("Exponential boost factor on translation, controllable by mouse wheel.")]
    55. public float boost = 3.5f;
    56. [Tooltip("Time it takes to interpolate camera position 99% of the way to the target."), Range(0.001f, 1f)]
    57. public float positionLerpTime = 0.2f;
    58. [Header("Rotation Settings")]
    59. [Tooltip("X = Change in mouse position.\nY = Multiplicative factor for camera rotation.")]
    60. public AnimationCurve mouseSensitivityCurve = new AnimationCurve(new Keyframe(0f, 0.5f, 0f, 5f), new Keyframe(1f, 2.5f, 0f, 0f));
    61. [Tooltip("Time it takes to interpolate camera rotation 99% of the way to the target."), Range(0.001f, 1f)]
    62. public float rotationLerpTime = 0.01f;
    63. [Tooltip("Whether or not to invert our Y axis for mouse input to rotation.")]
    64. public bool invertY = false;
    65. #if ENABLE_INPUT_SYSTEM
    66. InputAction movementAction;
    67. InputAction verticalMovementAction;
    68. InputAction lookAction;
    69. InputAction boostFactorAction;
    70. bool mouseRightButtonPressed;
    71. void Start()
    72. {
    73. var map = new InputActionMap("Simple Camera Controller");
    74. lookAction = map.AddAction("look", binding: "/delta");
    75. movementAction = map.AddAction("move", binding: "/leftStick");
    76. verticalMovementAction = map.AddAction("Vertical Movement");
    77. boostFactorAction = map.AddAction("Boost Factor", binding: "/scroll");
    78. lookAction.AddBinding("/rightStick").WithProcessor("scaleVector2(x=15, y=15)");
    79. movementAction.AddCompositeBinding("Dpad")
    80. .With("Up", "/w")
    81. .With("Up", "/upArrow")
    82. .With("Down", "/s")
    83. .With("Down", "/downArrow")
    84. .With("Left", "/a")
    85. .With("Left", "/leftArrow")
    86. .With("Right", "/d")
    87. .With("Right", "/rightArrow");
    88. verticalMovementAction.AddCompositeBinding("Dpad")
    89. .With("Up", "/pageUp")
    90. .With("Down", "/pageDown")
    91. .With("Up", "/e")
    92. .With("Down", "/q")
    93. .With("Up", "/rightshoulder")
    94. .With("Down", "/leftshoulder");
    95. boostFactorAction.AddBinding("/Dpad").WithProcessor("scaleVector2(x=1, y=4)");
    96. movementAction.Enable();
    97. lookAction.Enable();
    98. verticalMovementAction.Enable();
    99. boostFactorAction.Enable();
    100. }
    101. #endif
    102. void OnEnable()
    103. {
    104. m_TargetCameraState.SetFromTransform(transform);
    105. m_InterpolatingCameraState.SetFromTransform(transform);
    106. }
    107. Vector3 GetInputTranslationDirection()
    108. {
    109. Vector3 direction = Vector3.zero;
    110. #if ENABLE_INPUT_SYSTEM
    111. var moveDelta = movementAction.ReadValue();
    112. direction.x = moveDelta.x;
    113. direction.z = moveDelta.y;
    114. direction.y = verticalMovementAction.ReadValue().y;
    115. #else
    116. if (Input.GetKey(KeyCode.W))
    117. {
    118. direction += Vector3.forward;
    119. }
    120. if (Input.GetKey(KeyCode.S))
    121. {
    122. direction += Vector3.back;
    123. }
    124. if (Input.GetKey(KeyCode.A))
    125. {
    126. direction += Vector3.left;
    127. }
    128. if (Input.GetKey(KeyCode.D))
    129. {
    130. direction += Vector3.right;
    131. }
    132. if (Input.GetKey(KeyCode.E))
    133. {
    134. direction += Vector3.down;
    135. }
    136. if (Input.GetKey(KeyCode.Q))
    137. {
    138. direction += Vector3.up;
    139. }
    140. #endif
    141. return direction;
    142. }
    143. void Update()
    144. {
    145. // Exit Sample
    146. if (IsEscapePressed())
    147. {
    148. Application.Quit();
    149. #if UNITY_EDITOR
    150. UnityEditor.EditorApplication.isPlaying = false;
    151. #endif
    152. }
    153. // Hide and lock cursor when right mouse button pressed
    154. if (IsRightMouseButtonDown())
    155. {
    156. Cursor.lockState = CursorLockMode.Locked;
    157. }
    158. // Unlock and show cursor when right mouse button released
    159. if (IsRightMouseButtonUp())
    160. {
    161. Cursor.visible = true;
    162. Cursor.lockState = CursorLockMode.None;
    163. }
    164. // Rotation
    165. if (IsCameraRotationAllowed())
    166. {
    167. var mouseMovement = GetInputLookRotation() * Time.deltaTime * 5;
    168. if (invertY)
    169. mouseMovement.y = -mouseMovement.y;
    170. var mouseSensitivityFactor = mouseSensitivityCurve.Evaluate(mouseMovement.magnitude);
    171. m_TargetCameraState.yaw += mouseMovement.x * mouseSensitivityFactor;
    172. m_TargetCameraState.pitch += mouseMovement.y * mouseSensitivityFactor;
    173. }
    174. // Translation
    175. var translation = GetInputTranslationDirection() * Time.deltaTime;
    176. // Speed up movement when shift key held
    177. if (IsBoostPressed())
    178. {
    179. translation *= 10.0f;
    180. }
    181. // Modify movement by a boost factor (defined in Inspector and modified in play mode through the mouse scroll wheel)
    182. boost += GetBoostFactor();
    183. translation *= Mathf.Pow(2.0f, boost);
    184. m_TargetCameraState.Translate(translation);
    185. // Framerate-independent interpolation
    186. // Calculate the lerp amount, such that we get 99% of the way to our target in the specified time
    187. var positionLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / positionLerpTime) * Time.deltaTime);
    188. var rotationLerpPct = 1f - Mathf.Exp((Mathf.Log(1f - 0.99f) / rotationLerpTime) * Time.deltaTime);
    189. m_InterpolatingCameraState.LerpTowards(m_TargetCameraState, positionLerpPct, rotationLerpPct);
    190. //一键到仓库位置
    191. if (store)
    192. {
    193. m_TargetCameraState.yaw = 118.386f;
    194. m_TargetCameraState.pitch = 19.651f;
    195. m_TargetCameraState.x = -1.956715f;
    196. m_TargetCameraState.y = 1.364126f;
    197. m_TargetCameraState.z = -7.513207f;
    198. //m_InterpolatingCameraState.UpdateTransform(new Vector3(-4.152681f, 1.914845f, 0.7370217f));
    199. //transform.x = -4.152681f;
    200. //transform.y = 1.914845f;
    201. //transform.z = 0.7370217f;
    202. store = false;
    203. }
    204. m_InterpolatingCameraState.UpdateTransform(transform);
    205. }
    206. float GetBoostFactor()
    207. {
    208. #if ENABLE_INPUT_SYSTEM
    209. return boostFactorAction.ReadValue().y * 0.01f;
    210. #else
    211. return Input.mouseScrollDelta.y * 0.2f;
    212. #endif
    213. }
    214. Vector2 GetInputLookRotation()
    215. {
    216. #if ENABLE_INPUT_SYSTEM
    217. return lookAction.ReadValue();
    218. #else
    219. return new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * 10;
    220. #endif
    221. }
    222. bool IsBoostPressed()
    223. {
    224. #if ENABLE_INPUT_SYSTEM
    225. bool boost = Keyboard.current != null ? Keyboard.current.leftShiftKey.isPressed : false;
    226. boost |= Gamepad.current != null ? Gamepad.current.xButton.isPressed : false;
    227. return boost;
    228. #else
    229. return Input.GetKey(KeyCode.LeftShift);
    230. #endif
    231. }
    232. bool IsEscapePressed()
    233. {
    234. #if ENABLE_INPUT_SYSTEM
    235. return Keyboard.current != null ? Keyboard.current.escapeKey.isPressed : false;
    236. #else
    237. return Input.GetKey(KeyCode.Escape);
    238. #endif
    239. }
    240. bool IsCameraRotationAllowed()
    241. {
    242. #if ENABLE_INPUT_SYSTEM
    243. bool canRotate = Mouse.current != null ? Mouse.current.rightButton.isPressed : false;
    244. canRotate |= Gamepad.current != null ? Gamepad.current.rightStick.ReadValue().magnitude > 0 : false;
    245. return canRotate;
    246. #else
    247. return Input.GetMouseButton(1);
    248. #endif
    249. }
    250. bool IsRightMouseButtonDown()
    251. {
    252. #if ENABLE_INPUT_SYSTEM
    253. return Mouse.current != null ? Mouse.current.rightButton.isPressed : false;
    254. #else
    255. return Input.GetMouseButtonDown(1);
    256. #endif
    257. }
    258. bool IsRightMouseButtonUp()
    259. {
    260. #if ENABLE_INPUT_SYSTEM
    261. return Mouse.current != null ? !Mouse.current.rightButton.isPressed : false;
    262. #else
    263. return Input.GetMouseButtonUp(1);
    264. #endif
    265. }
    266. }
    267. }

  • 相关阅读:
    正则表达式常用语法解析
    leetcode 33. 搜索旋转排序数组-java
    MODBUS-RTU从站通信(SMART PLC作为MODBUS-RTU从站)
    关于 css 伪元素 content属性值 为中文字符时出现乱码问题的处理
    分布式定时任务xxljob
    Greenplum GPKafka【实践 01】使用GPKafka实现Kafka数据导入Greenplum数据库踩坑问题记录(不断更新ing)
    DockerFile笔记
    举例说明自然语言处理(NLP)技术
    8086读取键盘-磁盘输入
    七点工具箱(安卓)
  • 原文地址:https://blog.csdn.net/u011723630/article/details/127876190