You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Unity3D中实现玩家移动物体?适配《漫漫长夜》Melon Loader Mod

实现《漫漫长夜》可移动容器Mod方案(基于Melon Loader)

针对你需要实现的可移动带物品容器功能,以下是基于Melon Loader的无源码修改方案,适配新版游戏版本:

核心思路

通过Melon Loader内置的Harmony Hook机制,拦截游戏原有交互逻辑,替换为自定义的容器移动流程,同时维护容器与内部物品的层级关联,确保移动时物品同步跟随,且不修改游戏原生文件。

1. 识别可移动容器

首先需要确定游戏中哪些对象属于可移动容器,可以通过以下方式判断:

  • 查找对象上的Container组件(游戏原生容器标识)
  • 结合对象标签或预设名过滤(比如排除固定储物柜类容器)
  • Hook玩家交互检测逻辑,在交互触发时判断目标对象是否符合可移动容器条件

2. 拦截交互触发逻辑

使用Harmony Hook替换原生交互逻辑,当玩家点击可移动容器时,启动自定义移动流程:

using MelonLoader;
using HarmonyLib;
using UnityEngine;

[HarmonyPatch(typeof(PlayerInteract), "InteractWithObject")]
public static class ContainerInteractPatch
{
    static bool Prefix(GameObject targetObj)
    {
        Container targetContainer = targetObj.GetComponent<Container>();
        // 自定义判断逻辑:排除固定容器(如储物柜)
        if (targetContainer != null && IsMovable(targetContainer))
        {
            ContainerMovementHandler.StartMoving(targetContainer);
            return false; // 阻止原生交互逻辑执行
        }
        return true; // 非容器对象正常走原生逻辑
    }

    static bool IsMovable(Container container)
    {
        return container.m_ContainerType != ContainerType.Locker;
    }
}

3. 同步容器与内部物品位置

移动过程中,需要确保容器内物品跟随容器同步移动,核心是维护物品与容器的父级关系:

public static class ContainerMovementHandler
{
    private static Container _currentMovingContainer;
    public static bool IsMoving => _currentMovingContainer != null;

    public static void StartMoving(Container container)
    {
        _currentMovingContainer = container;
        // 将所有物品父级设为容器,保持局部位置不变
        foreach (Item item in container.GetAllItems())
        {
            if (item.gameObject != null)
            {
                item.gameObject.transform.SetParent(container.transform, false);
            }
        }
        // 禁用容器碰撞体避免移动时卡模型
        container.GetComponent<Collider>().enabled = false;
    }

    public static void UpdateMovement()
    {
        if (!IsMoving) return;

        // 通过鼠标射线获取地面放置位置
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hit, 6f, LayerMask.GetMask("Ground")))
        {
            // 微调位置避免穿模
            Vector3 targetPos = hit.point + Vector3.up * 0.1f;
            _currentMovingContainer.transform.position = targetPos;
        }

        // 松开鼠标左键完成放置
        if (Input.GetMouseButtonUp(0))
        {
            StopMoving();
        }
    }

    static void StopMoving()
    {
        if (_currentMovingContainer == null) return;

        // 恢复容器碰撞体
        _currentMovingContainer.GetComponent<Collider>().enabled = true;
        // 将物品父级还原为游戏原生层级(避免存档异常)
        foreach (Item item in _currentMovingContainer.GetAllItems())
        {
            if (item.gameObject != null)
            {
                item.gameObject.transform.SetParent(null);
                // 同步物品位置到游戏物品管理系统
                item.UpdatePosition(item.gameObject.transform.position);
            }
        }
        // 保存容器位置到存档(Hook游戏存档逻辑实现)
        SaveContainerPosition(_currentMovingContainer);
        _currentMovingContainer = null;
    }

    // 自定义存档逻辑:Hook游戏存档写入方法,添加容器位置数据
    static void SaveContainerPosition(Container container)
    {
        var saveManager = AccessTools.Field(typeof(SaveGameManager), "m_CurrentSaveData").GetValue(null);
        AccessTools.Field(saveManager.GetType(), $"ContainerPos_{container.GetInstanceID()}")
            .SetValue(saveManager, container.transform.position);
    }
}

4. 挂载移动更新逻辑

在Melon Loader的Update回调中触发移动更新:

public class ContainerMovementMod : MelonMod
{
    public override void OnUpdate()
    {
        base.OnUpdate();
        ContainerMovementHandler.UpdateMovement();
    }
}

版本适配要点

  1. 反编译游戏Assembly:用dnSpy查看最新版游戏的Container、PlayerInteract、Item类结构,替换代码中对应的字段/方法名(旧版失效多因类结构变更)
  2. 避免硬编码依赖:使用AccessTools.Field/AccessTools.Property访问私有成员,而非直接引用字段名
  3. 测试存档兼容性:移动后的容器位置需正确写入游戏存档,避免加载后位置重置

内容的提问来源于stack exchange,提问作者The Illusion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:06:32