【Unity】虚拟现实 VRTK插件使用教程(四)武器事件处理


武器脚本

通常在游戏中可以使用多种武器,那么每类武器就应该有自己独立的脚本,每个实际的武器又应该有其单独的脚本实例。比如,我有一部分武器是单发的枪,那我就应该有一个单发枪的脚本 SingleGunControl ,这个脚本可以指定一些枪支的基本参数(单发伤害,子弹初速度,子弹类型,射速,换弹速度等),在生成不同的单发枪支时给这些参数赋值。

开火事件注册

在定义好 SingleGunControl 脚本后,我们需要给手柄控制器提供开火事件响应器。代码如下:

/// <summary>
/// 单发枪的控制脚本
/// </summary>
public class SingleGunControl : MonoBehaviour
{
    private VRTK_ControllerEvents controller;

	// 当物体被激活,提供开火事件响应器
    private void OnEnable()
    {
        controller = GetComponentInParent<VRTK_ControllerEvents>();
        if (controller == null)
        {
            this.enabled = false;
            return;
        }
        controller.TriggerPressed += OnTriggerPressed;
    }
    
	// 当物体被禁用,注销开火事件响应器
    private void OnDisable()
    {
        if (controller == null)
        {
            return;
        }
        controller.TriggerPressed -= OnTriggerPressed;
    }

    private void OnTriggerPressed(object sender, ControllerInteractionEventArgs e)
    {
    	// 开火事件响应内容
		// ...
        
        Debug.LogFormat("{0} -- {1}", sender, e.touchpadAngle);
    }
}

此脚本应该挂在枪支对象上,当枪支刚生成时,处于还没有被抓取的状态,我们先将此脚本禁用。既然有禁用,那就应该有启用,这时候就需要另外一个脚本 GrabWeapon,专门用来处理武器抓取事件,在此处可以使用此脚本来改变武器控制脚本的状态。当前枪支的控制脚本为 SingleGunControl ,针对不同的枪支类型,会有不同的控制脚本,但用于转换武器控制脚本状态的 GrabWeapon 则可以重复使用。

/// <summary>
/// 抓取武器的脚本
/// </summary>
public class GrabWeapon : MonoBehaviour
{
    private void Start()
    {
        // 注册抓取事件
        GetComponent<VRTK_InteractableObject>().InteractableObjectGrabbed += OnWeaponGrabbed;
    }

    /// <summary>
    /// 抓取事件处理器 
    /// </summary>
    /// <param name="sender">事件触发对象</param>
    /// <param name="e">事件变量对象</param>
    private void OnWeaponGrabbed(object sender, InteractableObjectEventArgs e)
    {
        // 由于当前帧无法获取SingleGunControl脚本,所以使用协程在后续时间启用武器控制脚本
        StartCoroutine(SetWeaponControlState(sender));
    }

    /// <summary>
    /// 改变武器控制器的状态 
    /// </summary>
    /// <param name="sender">事件触发对象</param>
    /// <returns>协程迭代器</returns>
    private IEnumerator SetWeaponControlState(object sender)
    {
        yield return null; // 等待一帧,或者也可以yield return WaitForEndOfFrame();等待当前帧结束
        GetComponent<SingleGunControl>().enabled = true;
        Debug.LogFormat("{0} 已启用", sender);
    }
}

当物体被抓取时,VRTK 会先调用 InteractableObjectGrabbed 事件响应器然后再将武器挂载到手柄控制器节点下面,这就导致了当 InteractableObjectGrabbed 事件触发时, SingleGunControl 脚本的 OnEnable 方法仍然无法在其父节点上找到手柄控制器,所以 SingleGunControl 中控制器的 TriggerPressed 事件依然无法完成注册,所以这时候使用协程来延迟一帧,等到物体被挂到手柄控制器节点下以后再进行事件注册。

另外,如果要GrabWeapon能够自适应武器类型,可以将 GetComponent().enabled = true; 中的SingleGunControl改为泛型,并限制该泛型必须继承自WeaponControl类。


更多内容请查看总目录【Unity】Unity学习笔记目录整理

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值