这段代码是一个Unity游戏示例,展示了如何在用户界面(UI)中显示与动作绑定相关的提示信息。当玩家切换控制方案或自定义控制时,显示的文本可能会有所变化。具体来说,玩家能够在游戏中移动、观看物体(这里是简单的立方体),并在物体进入视线时通过按键拾取物体。拾取物体后,玩家可以选择投掷或丢弃物体。代码根据当前的游戏上下文,更新UI中的提示信息,反映当前激活的控制绑定。
下面是对代码的逐步分解和详细解释:
- 命名空间和类声明:
- namespace UnityEngine.InputSystem.Samples.InGameHints
- {
- public class InGameHintsExample : MonoBehaviour
- ```
- 这段代码声明了一个名为`InGameHintsExample`的类,该类继承自`MonoBehaviour`,并且位于`UnityEngine.InputSystem.Samples.InGameHints`命名空间中。
CopyInsert
- 公共变量:
- public Text helpText;
- public float moveSpeed;
- public float rotateSpeed;
- public float throwForce;
- public float pickupDistance;
- public float holdDistance;
CopyInsert
这些变量可以在Unity编辑器中设置。helpText用于显示提示信息;其他四个变量分别为移动速度、旋转速度、投掷力、拾取距离和持有距离。
- 私有变量:
- private Vector2 m_Rotation;
- private enum State { Wandering, ObjectInSights, ObjectPickedUp }
- private PlayerInput m_PlayerInput;
- private State m_CurrentState;
- private Transform m_CurrentObject;
- private MaterialPropertyBlock m_PropertyBlock;
- private string m_LookAtObjectHelpText;
- private string m_ThrowObjectHelpText;
CopyInsert
这些变量用于存储游戏状态、旋转信息、当前拾取的对象以及用于改变物体颜色的材质属性块等。
- 常量字符串:
- private const string kDefaultHelpTextFormat = "Move close to one of the cubes and look at it to pick up";
- private const string kLookAtObjectHelpTextFormat = "Press {pickup} to pick object up";
- private const string kThrowObjectHelpTextFormat = "Press {throw} to throw object; press {drop} to drop object";
CopyInsert
定义了一些格式化的字符串,用于生成UI提示信息。{pickup}、{throw}和{drop}是占位符,会被实际的按键名称替换。
- Awake方法:
- public void Awake()
- {
- m_PlayerInput = GetComponent<PlayerInput>();
- }
CopyInsert
在游戏对象被创建后立即执行,获取并保存PlayerInput组件的引用。
- OnEnable方法:
- public void OnEnable()
- {
- ChangeState(State.Wandering);
- }
CopyInsert
当游戏对象被启用时,将当前游戏状态设置为Wandering(漫游),即玩家可以自由移动和旋转,寻找可拾取的物体。
- OnControlsChanged方法:
- public void OnControlsChanged()
- {
- UpdateUIHints(regenerate: true);
- }
CopyInsert
当玩家的控制方案或键盘布局改变时,会被调用。调用UpdateUIHints方法,重新生成提示信息以适应新的控制绑定。
- Update方法:
- public void Update()
- {
- var move = m_PlayerInput.actions["move"].ReadValue<Vector2>();
- var look = m_PlayerInput.actions["look"].ReadValue<Vector2>();
- Move(move);
- Look(look);
- switch (m_CurrentState)
- {
- case State.Wandering:
- case State.ObjectInSights:
- if (Physics.Raycast(transform.position, transform.forward, out var hitInfo, pickupDistance) && !hitInfo.collider.gameObject.isStatic)
- {
- if (m_CurrentState != State.ObjectInSights)
- ChangeState(State.ObjectInSights);
- m_CurrentObject = hitInfo.transform;
- // ... (设置材质属性块)
- }
- // ... (如果视野中没有物体)
- if (m_PlayerInput.actions["pickup"].triggered && m_CurrentObject != null)
- {
- PickUp();
- ChangeState(State.ObjectPickedUp);
- }
- break;
- case State.ObjectPickedUp:
- // ... (投掷或丢弃物体)
- break;
- }
- }
CopyInsert
每帧调用,根据玩家的移动和旋转输入执行移动和旋转操作。同时,根据当前的游戏状态(Wandering、ObjectInSights、ObjectPickedUp)进行相应的处理。当玩家视线中有可拾取的物体时,提示信息会改变。拾取物体后,玩家可以投掷或丢弃物体,游戏状态也会相应改变。
- ChangeState方法:
- private void ChangeState(State newState)
- {
- m_CurrentState = newState;
- UpdateUIHints();
- }
CopyInsert
改变游戏状态并更新UI提示信息。
- UpdateUIHints方法:
- private void UpdateUIHints(bool regenerate = false)
- {
- if (regenerate)
- {
- m_ThrowObjectHelpText = default;
- m_LookAtObjectHelpText = default;
- }
- switch (m_CurrentState)
- {
- case State.ObjectInSights:
- if (m_LookAtObjectHelpText == null)
- m_LookAtObjectHelpText = kLookAtObjectHelpTextFormat.Replace("{pickup}", m_PlayerInput.actions["pickup"].GetBindingDisplayString());
- helpText.text = m_LookAtObjectHelpText;
- break;
- case State.ObjectPickedUp:
- if (m_ThrowObjectHelpText == null)
- m_ThrowObjectHelpText = kThrowObjectHelpTextFormat.Replace("{throw}", m_PlayerInput.actions["throw"].GetBindingDisplayString()).Replace("{drop}", m_PlayerInput.actions["drop"].GetBindingDisplayString());
- helpText.text = m_ThrowObjectHelpText;
- break;
- default:
- helpText.text = kDefaultHelpTextFormat;
- break;
- }
- }
CopyInsert
更新UI中的提示信息。如果需要重新生成提示信息,则先清空缓存的字符串,然后根据当前状态生成新的提示信息并更新helpText的文本内容。提示信息中包含当前激活的控制绑定名称。
- Throw方法:
- private void Throw(bool drop = false)
- {
- m_CurrentObject.parent = null;
- var rigidBody = m_CurrentObject.GetComponent<Rigidbody>();
- rigidBody.isKinematic = false;
- if (!drop)
- rigidBody.AddForce(transform.forward * throwForce, ForceMode.Impulse);
- m_CurrentObject = null;
- }
CopyInsert
拾取的物体被投掷或丢弃时调用。首先将物体从玩家的transform中移除,然后启用物体的物理模拟(即非刚体状态),如果不是丢弃的话,给物体施加一个投掷力,使其向前飞行。最后,将拾取的物体设置为null。
- PickUp方法:
- private void PickUp()
- {
- m_CurrentObject.position = default;
- m_CurrentObject.SetParent(transform, worldPositionStays: false);
- m_CurrentObject.localPosition += new Vector3(0, 0, holdDistance);
- m_CurrentObject.GetComponent<Renderer>().SetPropertyBlock(null);
- var rigidBody = m_CurrentObject.GetComponent<Rigidbody>();
- rigidBody.isKinematic = true;
- }
CopyInsert
当玩家拾取物体时,将物体的位置设置为默认值,然后将物体挂载到玩家的transform下,调整其局部位置以便玩家持有物体。同时移除物体的颜色覆盖,将其设置为刚体(Kinematic)状态,即物体不会受到物理模拟影响。
- Move方法:
- private void Move(Vector2 direction)
- {
- if (direction.sqrMagnitude < 0.01)
- return;
- var scaledMoveSpeed = moveSpeed * Time.deltaTime;
- var move = Quaternion.Euler(0, transform.eulerAngles.y, 0) * new Vector3(direction.x, 0, direction.y);
- transform.position += move * scaledMoveSpeed;
- }
CopyInsert
根据玩家的移动输入改变玩家的位置。移动方向会被根据玩家当前的Y轴旋转调整,使得玩家能够朝向正确的方向移动。
- Look方法:
- private void Look(Vector2 rotate)
- {
- if (rotate.sqrMagnitude < 0.01)
- return;
- var scaledRotateSpeed = rotateSpeed * Time.deltaTime;
- m_Rotation.y += rotate.x * scaledRotateSpeed;
- m_Rotation.x = Mathf.Clamp(m_Rotation.x - rotate.y * scaledRotateSpeed, -89, 89);
- transform.localEulerAngles = m_Rotation;
- }
CopyInsert
根据玩家的旋转输入改变玩家的旋转。通过限制x轴的旋转角度来防止玩家抬头到不自然的角度(如180度)。
总结: 这

4053

被折叠的 条评论
为什么被折叠?



