【unity实战】在Unity实现低耦合可复用的交互系统

文章目录

实践

1、交互接口定义

定义一个接口,方法接受一个GameObject引用通常是我们的玩家游戏对象

csharp 复制代码
using UnityEngine;

public interface IInteractable
{
    /// <summary>
    /// 交互方法
    /// </summary>
    /// <param name="interactor">发起交互的对象</param>
    /// <returns>交互是否成功</returns>
    bool Interact(GameObject interactor);
}

2、新增拾取交互脚本

csharp 复制代码
using UnityEngine;

//拾取交互
[RequireComponent(typeof(Collider))]
public class PickUpInteractable : MonoBehaviour, IInteractable
{
    public bool Interact(GameObject interactor)
    {
        //拾取逻辑
        
        // 可选:禁用或销毁场景中的对象
        gameObject.SetActive(false);
        
        return true;
    }
}

3、玩家检测交互

定义一个简单的脚本,实现玩家和物品之间的交互

csharp 复制代码
using UnityEngine;

public class Player : MonoBehaviour
{
    public float maxDistance = 3f; // 最大检测距离
    public LayerMask layerMask;//指定检测的层级
    public GameObject uiTips; // 提示 UI 文本组件
    void Update()
    {
        DetectInteractable();
    }

    //检测交互
    private void DetectInteractable()
    {
        // 从相机屏幕中心向前发射一条射线
        Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0f));
        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo, maxDistance, layerMask))
        {
            uiTips.SetActive(true);

            if (Input.GetKeyDown(KeyCode.E))
            {
                // 从碰撞体上获取所有实现了IInteractable接口的组件
                // 使用GetComponents而不是GetComponent,因为一个物体可能有多个可交互组件
                IInteractable[] interactables = hitInfo.transform.GetComponents<IInteractable>();

                // 遍历该物体上的所有可交互组件
                foreach (var interactableObj in interactables)
                {
                    // 执行交互逻辑,传入当前游戏对象作为交互发起者
                    interactableObj.Interact(gameObject);
                }
            }
        }
        else
        {
            uiTips.SetActive(false);
        }
    }
}

4、挂载脚本

物品挂载PickUpInteractable脚本,并修改层级,添加碰撞器

玩家挂载player脚本,并配置参数

5、运行游戏查看效果

6、扩展不同交互

现在我们可以轻易的扩展不同的交互,比如NPC对话,武器交互

csharp 复制代码
using UnityEngine;

// NPC交互
[RequireComponent(typeof(Collider))]
public class NPCInteractable : MonoBehaviour, IInteractable
{
    public bool Interact(GameObject interactor)
    {
        // 一些逻辑,比如对话
        
        return true;
    }
}
csharp 复制代码
using UnityEngine;

//武器交互
[RequireComponent(typeof(Collider))]
public class WeaponInteractable : MonoBehaviour, IInteractable
{
    public bool Interact(GameObject interactor)
    {
       // 一些逻辑,比如装备武器
        
        // 可选:禁用或销毁场景中的武器对象
        gameObject.SetActive(false);
        
        return true;
    }
}

我们还可以给同一个物品挂载多个交互脚本,比如拾取交互和武器交互,这样当我们触发交互时,会同时执行这两个交互。


专栏推荐

地址
【unity游戏开发入门到精通------C#篇】
【unity游戏开发入门到精通------unity通用篇】
【unity游戏开发入门到精通------unity3D篇】
【unity游戏开发入门到精通------unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发------模型篇】
【unity游戏开发------InputSystem】
【unity游戏开发------Animator动画】
【unity游戏开发------UGUI】
【unity游戏开发------联网篇】
【unity游戏开发------优化篇】
【unity游戏开发------shader篇】
【unity游戏开发------编辑器扩展】
【unity游戏开发------热更新】
【unity游戏开发------网络】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!