胡闹厨房Unity小白学习篇|第三期
上一期大概对小黄鸡进行了移动输入的编写,能让小鸡在一个二维平面里面呢进行左右上下的移动。这期主要研究小黄鸡的对外交互,以及交互后的桌台特效。
第一期| unity小白胡闹厨房学习篇-第一期
第二期| unity小白胡闹厨房学习篇-第二期
本文内容包含:
交互特效
素小黄鸡能跑起来,然后碰到前方有障碍物的时候可以停止,或者向两侧方向移动只是第一步。但需要角色能够检测到需要交互的桌台,并能够发生交互事件。前期桌台的交互是通过改变桌台的视觉效果来呈现的。
视频中的交互特效是将桌台叠加一个相对较暗较灰的同类型的桌台,然后定义一个bool类型的变量控制选中桌台是否显示来实现的。处理步骤如下:
- 第一步
:在预制体Prefabs中(这步特别重要,这样生成的所有桌台都具备实现的功能),将原来的ClearCounter复制一遍,重命名为Selected,表示是选中的视觉效果。
- 第二步
:选中selectd的Visual,并添加CounterSelected的材质,如下图所示,也就是展现一种灰色的选中状态。同时为了防止切换的时候带来的视觉闪烁,选中的状态大小设定为了1.01.
- 第三步
:定义一个私有的变量visualGameObject,同时编辑Show和Hide函数,用来控制SelectdVisual的展示和关闭。这样只要交互发生后就可以通过判断触发状态来控制虚拟视觉的展示和关闭。
[SerializeField] private GameObject visualGameObject;
private void ShowVisual()
{
visualGameObject.SetActive(true);
}
private void HideVisual()
{
visualGameObject.SetActive(false);
}
角色交互
能够产生选中特效后,后面需要做的就是触发选中特效。总体思路还是采用射线检测的方式,检测到前方有障碍物并为桌台后,触发交互,并将自身桌台以事件的方式发射出去,所有订阅此消息的物体都可以触发特效。所有的实现代码如下:
// 发送选中桌台更改事件
[SerializeField] private LayerMask clearCounterLayerMask;
public event EventHandler<OnSelectedClearCounterChangedEventArgs> OnSelectedClearCounterChanged;
public class OnSelectedClearCounterChangedEventArgs : EventArgs
{
public ClearCounter selectedClearCounter;
}
private void Update()
{
HandleInteractions(); // 处理玩家交互
}
private void HandleInteractions()
{
float interactionDistance = 2f;
Vector2 inputVictor = gameInput.GetGameInputVectorNormalized();
Vector3 moveDir = new Vector3(inputVictor.x, 0f, inputVictor.y);
if (moveDir != Vector3.zero)
{
lastInteractorDir = moveDir;
}
if (Physics.Raycast(transform.position, lastInteractorDir, out RaycastHit raycastHit, interactionDistance, clearCounterLayerMask))
{
//Debug.Log(raycastHit.transform);
if (raycastHit.transform.TryGetComponent(out ClearCounter clearCounter))
{
if (selectedClearCounter != clearCounter)
{
selectedClearCounter = clearCounter;
SetSeletedClearCouter(selectedClearCounter);
}
}
else
{
selectedClearCounter = null;
SetSeletedClearCouter(selectedClearCounter);
}
}
else
{
selectedClearCounter = null;
SetSeletedClearCouter(selectedClearCounter);
}
}
private void SetSeletedClearCouter(ClearCounter clearCounter)
{
selectedClearCounter = clearCounter;
OnSelectedClearCounterChanged?.Invoke(this, new OnSelectedClearCounterChangedEventArgs() { selectedClearCounter = selectedClearCounter });
}
其中Physics.Raycast是检测的核心函数,其输入参数包括:origin原始位置,direction移动方向,RaycastHit输出句柄,interactionDistance交互距离,LayerMask图层,各个参数的具体含义如下:
参数含义
Property Name | Type | Description |
---|---|---|
origin | Vector3 | 物体的原始位置, |
direction | Vector3 | 物体的移动位置 |
RaycastHit | RaycastHit | 射线检测返回的句柄类,可以从中提取射线检测到的物体信息 |
interactionDistance | float | 射线检测范围,因为小黄鸡有自己的体积,所以这里定义2,作为检测范围 |
LayerMask | LayerMask | 通过层级定义可以快速筛选桌台类 |
射线检测后通过检测RaycastHit句柄中的组件类型是否为ClearCounter类,来进行后续的处理。如果为桌台类,则将其赋值给全局的selectedClearCounter,并触发OnSelectedClearCounterChanged事件,事件中携带OnSelectedClearCounterChangedEventArgs类。在前一部分定义的SelectedCounterVisual脚本中订阅该事件,然后根据类型判断,是否启用选中特效,即可完成。
private void Start()
{
Player.Instance.OnSelectedClearCounterChanged += Player_OnSelectedClearCounterChanged;
}
private void Player_OnSelectedClearCounterChanged(object sender, Player.OnSelectedClearCounterChangedEventArgs e)
{
if (e.selectedClearCounter == clearCounter)
{
ShowVisual();
}
else
{
HideVisual();
}
}
clearCounter)
{
ShowVisual();
}
else
{
HideVisual();
}
}