目录
(三)创建pick_up_object_on_table脚本
在 3A 游戏中,物品拾取到手上的交互功能是增强游戏真实感与沉浸感的关键环节。本期教程,我们将详细讲解如何运用 Unity 引擎,结合 Timeline 和代码,实现这一功能。即便你没有观看过上期视频,也能轻松跟上节奏,独立学习。
一、前期准备
- 场景搭建:准备一个全新的 Pro Ground 场景。制作一张桌子,在 Hierarchy 面板中新建一个空节点作为桌子的父物体,方便整体控制。从其他地方拷贝一个盒子,调整其位置,并将其 Tag 修改为 “box”。若没有 “box” 标签,点击 “ADD tag” 添加后再修改。
- 碰撞体设置:为盒子添加 Box Collider 组件,勾选 “is trigger” 选项,点击 “编辑” 动态调整可触发的位置区域,确保玩家进入该区域时才能拾取物体。
- 人物手部节点添加:将人物放置到桌子附近,在人物层级中找到手部部分,右键添加一个球体。这个球体代表手上物体所在的点,调整其大小和位置,后续拾取的物体将作为它的子物体。在实际项目中,可能会有多个这样的点,用于适配不同的拾取物体。
二、Timeline 动画设置
- 打开 Timeline 窗口:若在界面中未找到 Timeline 窗口,可在 “Windows” 菜单下的 “Second thing” 中点击 “Timeline” 打开。
- 创建 Timeline 并添加轨道:选择桌子物体,在 Timeline 窗口中点击 “Create”,并保存 Playable 资产。接着添加一个 Animation 轨道,暂时将主角人物添加进来。
- 添加动画:把之前下载好的拾取装备动作添加到工程中。选择该动作文件,在 “RG” 标签下切换成 “human”,在 “Animation” 标签下更改动画名称。切换回 Timeline 窗口,找到拾取动画文件,拖动到轨道上,再找到站立动作添加到后面,让动画有一个合适的过渡。
- 调整动画设置:拖动滑杆查看效果时,会发现角色目前会回归到零点的站立位置。点击轨道,选择 “按照场景的偏移变换”,并将轨道改名为 “玩家的轨道”。调整桌子位置时,若出现回跳现象,可点击 Timeline 窗口的锁头标志锁定窗口,避免失去焦点。
三、代码实现
(一)修改角色控制器脚本
- 添加布尔变量:选择主角的角色,找到 “第三人称控制器” 脚本,双击打开代码。添加一个布尔型的类成员变量,用于标记是否开关移动操作。
private bool isMovingDisabled = false;
- 在 Update 中增加判断:在
Update
方法中增加一段判断代码,用于控制角色移动。
void Update()
{
if (isMovingDisabled)
{
// 这里可以根据需求添加暂停角色移动相关的逻辑,例如设置角色速度为0
return;
}
// 原有的角色移动控制代码
}
(二)创建player_pick_up_ability
脚本
- 定义接口:这个脚本用于赋予玩家拾取物体的能力。首先定义一个接口
i_can_pick_up
。
public interface i_can_pick_up
{
void pick_up();
bool pick_up_complete { get; set; }
}
- 碰撞触发函数:编写碰撞触发函数,当玩家碰撞到标签为 “box” 的物体时,判断其是否具有可拾取的接口组件,若有则加入到可拾取列表中。
private List<i_can_pick_up> pickableObjects = new List<i_can_pick_up>();
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("box"))
{
i_can_pick_up pickable = other.GetComponent<i_can_pick_up>();
if (pickable!= null)
{
pickableObjects.Add(pickable);
}
}
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("box"))
{
i_can_pick_up pickable = other.GetComponent<i_can_pick_up>();
if (pickable!= null)
{
pickableObjects.Remove(pickable);
}
}
}
- 添加拾取操作代码:增加公共属性获取手部的
transform
,并保存当前拥有拾取接口的目标。当操作函数被执行时,判断是否有当前正在拾取的目标,若有则从列表中取得第一个进行拾取动作。
public Transform hand;
private i_can_pick_up currentPickable;
public void PickUp()
{
if (pickableObjects.Count > 0)
{
currentPickable = pickableObjects[0];
currentPickable.pick_up();
}
}
private void Update()
{
if (currentPickable!= null && currentPickable.pick_up_complete)
{
currentPickable = null;
}
}
(三)创建pick_up_object_on_table
脚本
- 实现接口:在类上面添加可拾取的接口
i_can_pick_up
,并实现接口中的代码。
public class pick_up_object_on_table : MonoBehaviour, i_can_pick_up
{
public float pickUpTime;
public GameObject pickedObject;
public Transform playerStandPoint;
private bool isPickUpComplete = false;
public bool pick_up_complete
{
get { return isPickUpComplete; }
set { isPickUpComplete = value; }
}
public void pick_up()
{
// 开启协程控制动画播放
StartCoroutine(PickUpCoroutine());
}
}
- 协程控制动画播放:用一个协程来实现对动画播放的控制,在动画播放前后控制角色的移动状态,并标记拾取完成状态。
private IEnumerator PickUpCoroutine()
{
// 获取角色控制器脚本
var characterController = GetComponent<第三人称控制器>();
// 停止角色移动
characterController.isMovingDisabled = true;
// 找到名为player_track的轨道
var timeline = GameObject.FindObjectOfType<Timeline.TimelineAsset>();
var director = gameObject.AddComponent<Timeline.TimelinePlayer>();
director.Play(timeline);
yield return new WaitForSeconds(pickUpTime);
// 将物体设置到手上
pickedObject.transform.SetParent(hand);
pickedObject.transform.localPosition = Vector3.zero;
pickedObject.transform.localRotation = Quaternion.identity;
// 人物移动到站立目标点
transform.position = playerStandPoint.position;
transform.rotation = playerStandPoint.rotation;
// 恢复角色移动
characterController.isMovingDisabled = false;
// 标记拾取完成
isPickUpComplete = true;
}
四、在 Unity 中配置脚本
- 为玩家添加拾取能力:回到 Unity Editor,为玩家添加
player_pick_up_ability
脚本,将手部球体拖到 “hand” 属性上。 - 配置操作按键:若之前未添加过操作代码,找到 “Input” 组件,双击打开配置资产。删除原有的设置,重新点击添加 “Action”,更改名称为 “operate”。选择下面的绑定选项,在右侧绑定属性的 “patch” 中点击下拉菜单,输入 “F” 键确定绑定,勾选 “keyboard board” 选项,确保应用到键鼠方案,点击 “save asse” 保存资产。此时在 “behavior” 中会出现 “on operator” 的显示,表示按下 “F” 键时会触发脚本中同名函数。
- 为桌子添加拾取脚本:选择桌子物体,添加
pick_up_object_on_table
脚本,将需要拾取的物体拖动到 “object” 属性中,将站立点添加到对应的属性引用。根据动画文件适配拾取发生的时间。最后,将 “director” 中的唤醒(播放)勾选项去掉。
至此,我们就完成了在 Unity 中实现拾取物体到手上的交互功能。通过上述步骤,你可以用同样的方法实现拾取各种各样物体的交互功能。如果在实现过程中遇到问题,欢迎在评论区留言交流。希望大家多多点赞支持,后续我会带来更多有趣的游戏开发教程。