【无标题】unity按键拾取物体和丢弃

这段代码是一个Unity游戏示例,展示了如何在用户界面(UI)中显示与动作绑定相关的提示信息。当玩家切换控制方案或自定义控制时,显示的文本可能会有所变化。具体来说,玩家能够在游戏中移动、观看物体(这里是简单的立方体),并在物体进入视线时通过按键拾取物体。拾取物体后,玩家可以选择投掷或丢弃物体。代码根据当前的游戏上下文,更新UI中的提示信息,反映当前激活的控制绑定。

下面是对代码的逐步分解和详细解释:

  1. 命名空间和类声明
  2. namespace UnityEngine.InputSystem.Samples.InGameHints
  3. {
  4.     public class InGameHintsExample : MonoBehaviour
  5.     ```
  6. 这段代码声明了一个名为`InGameHintsExample`的类,该类继承自`MonoBehaviour`,并且位于`UnityEngine.InputSystem.Samples.InGameHints`命名空间中。

CopyInsert

  1. 公共变量
  2. public Text helpText;
  3. public float moveSpeed;
  4. public float rotateSpeed;
  5. public float throwForce;
  6. public float pickupDistance;
  7. public float holdDistance;

CopyInsert

这些变量可以在Unity编辑器中设置。helpText用于显示提示信息;其他四个变量分别为移动速度、旋转速度、投掷力、拾取距离和持有距离。

  1. 私有变量
  2. private Vector2 m_Rotation;
  3. private enum State { Wandering, ObjectInSights, ObjectPickedUp }
  4. private PlayerInput m_PlayerInput;
  5. private State m_CurrentState;
  6. private Transform m_CurrentObject;
  7. private MaterialPropertyBlock m_PropertyBlock;
  8. private string m_LookAtObjectHelpText;
  9. private string m_ThrowObjectHelpText;

CopyInsert

这些变量用于存储游戏状态、旋转信息、当前拾取的对象以及用于改变物体颜色的材质属性块等。

  1. 常量字符串
  2. private const string kDefaultHelpTextFormat = "Move close to one of the cubes and look at it to pick up";
  3. private const string kLookAtObjectHelpTextFormat = "Press {pickup} to pick object up";
  4. private const string kThrowObjectHelpTextFormat = "Press {throw} to throw object; press {drop} to drop object";

CopyInsert

定义了一些格式化的字符串,用于生成UI提示信息。{pickup}、{throw}和{drop}是占位符,会被实际的按键名称替换。

  1. Awake方法
  2. public void Awake()
  3. {
  4.     m_PlayerInput = GetComponent<PlayerInput>();
  5. }

CopyInsert

在游戏对象被创建后立即执行,获取并保存PlayerInput组件的引用。

  1. OnEnable方法
  2. public void OnEnable()
  3. {
  4.     ChangeState(State.Wandering);
  5. }

CopyInsert

当游戏对象被启用时,将当前游戏状态设置为Wandering(漫游),即玩家可以自由移动和旋转,寻找可拾取的物体。

  1. OnControlsChanged方法
  2. public void OnControlsChanged()
  3. {
  4.     UpdateUIHints(regenerate: true);
  5. }

CopyInsert

当玩家的控制方案或键盘布局改变时,会被调用。调用UpdateUIHints方法,重新生成提示信息以适应新的控制绑定。

  1. Update方法
  2. public void Update()
  3. {
  4.     var move = m_PlayerInput.actions["move"].ReadValue<Vector2>();
  5.     var look = m_PlayerInput.actions["look"].ReadValue<Vector2>();
  6.     Move(move);
  7.     Look(look);
  8.     switch (m_CurrentState)
  9.     {
  10.         case State.Wandering:
  11.         case State.ObjectInSights:
  12.             if (Physics.Raycast(transform.position, transform.forward, out var hitInfo, pickupDistance) && !hitInfo.collider.gameObject.isStatic)
  13.             {
  14.                 if (m_CurrentState != State.ObjectInSights)
  15.                     ChangeState(State.ObjectInSights);
  16.                 m_CurrentObject = hitInfo.transform;
  17.                 // ... (设置材质属性块)
  18.             }
  19.             // ... (如果视野中没有物体)
  20.             if (m_PlayerInput.actions["pickup"].triggered && m_CurrentObject != null)
  21.             {
  22.                 PickUp();
  23.                 ChangeState(State.ObjectPickedUp);
  24.             }
  25.             break;
  26.         case State.ObjectPickedUp:
  27.             // ... (投掷或丢弃物体)
  28.             break;
  29.     }
  30. }

CopyInsert

每帧调用,根据玩家的移动和旋转输入执行移动和旋转操作。同时,根据当前的游戏状态(Wandering、ObjectInSights、ObjectPickedUp)进行相应的处理。当玩家视线中有可拾取的物体时,提示信息会改变。拾取物体后,玩家可以投掷或丢弃物体,游戏状态也会相应改变。

  1. ChangeState方法
  2. private void ChangeState(State newState)
  3. {
  4.     m_CurrentState = newState;
  5.     UpdateUIHints();
  6. }

CopyInsert

改变游戏状态并更新UI提示信息。

  1. UpdateUIHints方法
  2. private void UpdateUIHints(bool regenerate = false)
  3. {
  4.     if (regenerate)
  5.     {
  6.         m_ThrowObjectHelpText = default;
  7.         m_LookAtObjectHelpText = default;
  8.     }
  9.     switch (m_CurrentState)
  10.     {
  11.         case State.ObjectInSights:
  12.             if (m_LookAtObjectHelpText == null)
  13.                 m_LookAtObjectHelpText = kLookAtObjectHelpTextFormat.Replace("{pickup}", m_PlayerInput.actions["pickup"].GetBindingDisplayString());
  14.             helpText.text = m_LookAtObjectHelpText;
  15.             break;
  16.         case State.ObjectPickedUp:
  17.             if (m_ThrowObjectHelpText == null)
  18.                 m_ThrowObjectHelpText = kThrowObjectHelpTextFormat.Replace("{throw}", m_PlayerInput.actions["throw"].GetBindingDisplayString()).Replace("{drop}", m_PlayerInput.actions["drop"].GetBindingDisplayString());
  19.             helpText.text = m_ThrowObjectHelpText;
  20.             break;
  21.         default:
  22.             helpText.text = kDefaultHelpTextFormat;
  23.             break;
  24.     }
  25. }

CopyInsert

更新UI中的提示信息。如果需要重新生成提示信息,则先清空缓存的字符串,然后根据当前状态生成新的提示信息并更新helpText的文本内容。提示信息中包含当前激活的控制绑定名称。

  1. Throw方法
  2. private void Throw(bool drop = false)
  3. {
  4.     m_CurrentObject.parent = null;
  5.     var rigidBody = m_CurrentObject.GetComponent<Rigidbody>();
  6.     rigidBody.isKinematic = false;
  7.     if (!drop)
  8.         rigidBody.AddForce(transform.forward * throwForce, ForceMode.Impulse);
  9.     m_CurrentObject = null;
  10. }

CopyInsert

拾取的物体被投掷或丢弃时调用。首先将物体从玩家的transform中移除,然后启用物体的物理模拟(即非刚体状态),如果不是丢弃的话,给物体施加一个投掷力,使其向前飞行。最后,将拾取的物体设置为null。

  1. PickUp方法
  2. private void PickUp()
  3. {
  4.     m_CurrentObject.position = default;
  5.     m_CurrentObject.SetParent(transform, worldPositionStays: false);
  6.     m_CurrentObject.localPosition += new Vector3(0, 0, holdDistance);
  7.     m_CurrentObject.GetComponent<Renderer>().SetPropertyBlock(null);
  8.     var rigidBody = m_CurrentObject.GetComponent<Rigidbody>();
  9.     rigidBody.isKinematic = true;
  10. }

CopyInsert

当玩家拾取物体时,将物体的位置设置为默认值,然后将物体挂载到玩家的transform下,调整其局部位置以便玩家持有物体。同时移除物体的颜色覆盖,将其设置为刚体(Kinematic)状态,即物体不会受到物理模拟影响。

  1. Move方法
  2. private void Move(Vector2 direction)
  3. {
  4.     if (direction.sqrMagnitude < 0.01)
  5.         return;
  6.     var scaledMoveSpeed = moveSpeed * Time.deltaTime;
  7.     var move = Quaternion.Euler(0, transform.eulerAngles.y, 0) * new Vector3(direction.x, 0, direction.y);
  8.     transform.position += move * scaledMoveSpeed;
  9. }

CopyInsert

根据玩家的移动输入改变玩家的位置。移动方向会被根据玩家当前的Y轴旋转调整,使得玩家能够朝向正确的方向移动。

  1. Look方法
  2. private void Look(Vector2 rotate)
  3. {
  4.     if (rotate.sqrMagnitude < 0.01)
  5.         return;
  6.     var scaledRotateSpeed = rotateSpeed * Time.deltaTime;
  7.     m_Rotation.y += rotate.x * scaledRotateSpeed;
  8.     m_Rotation.x = Mathf.Clamp(m_Rotation.x - rotate.y * scaledRotateSpeed, -89, 89);
  9.     transform.localEulerAngles = m_Rotation;
  10. }

CopyInsert

根据玩家的旋转输入改变玩家的旋转。通过限制x轴的旋转角度来防止玩家抬头到不自然的角度(如180度)。

总结: 这

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值