骑砍战团MOD开发(49)-使用ScoEditor编辑sco文件制作游戏场景

一.ScoEditor下载霸王•吕布 / ScoEditor · GitCodeicon-default.png?t=N7T8https://gitcode.net/qq_35829452/scoeditor二.ScoEditor导出文件种类

     mission_objects.json:场景物/出生点/通道等物体

     layer_ground_elevation.pfm:场景terrain/ground地形增量,采用PFM深度图存储

     ai_mesh.obj:AI网格静态模型,由点/线面构成

三.mission_objects.json

     object_type = ['prop', 'entry', 'item', 'unused', 'plant', 'passage']
 
     object = {
         'type': object_type[type], 类型,场景物/出生点/通道
         'id': id, ID.scene_props.py定义ID
         'garbage': '%0#x' % garbage,
         'rotation_matrix': [mtx_a, mtx_b, mtx_c], 旋转矩阵(右手坐标系,ZXY顺序旋转),转化后获得沿XYZ旋转角度
         'pos': pos, 世界坐标系坐标
         'str': str, spr_torch等标识
         'entry_no': entry_no, (若为prop则prop_instance_get_variation_id获取)
         'menu_entry_no': menu_item_no,(若为prop则prop_instance_get_variation_id_2获取)
         'scale': scale, 伸缩变换比例
     }

     <1.旋转角度转化:euler_angle_to_rotation.bat/rotation_to_euler_angle.bat

     将Blender旋转角度调整为ZXY模式,输入rotx,roty,rotz至 euler_angle_to_rotation.py中得到旋转矩阵,拷贝至mission_objects.json.

     <2.blender python脚本实现导出mission_object.json

import bpy
import math
import json
import mathutils
# mission_obj data_format
# object_type = ['prop', 'entry', 'item', 'unused', 'plant', 'passage']
# object = {
#   'type': object_type[type], 类型,场景物/出生点/通道
#   'id': id, ID.scene_props.py定义ID
#   'garbage': '%0#x' % garbage,
#   'rotation_matrix': [mtx_a, mtx_b, mtx_c], 旋转矩阵(右手坐标系,ZXY顺序旋转),转化后获得沿XYZ旋转角度
#   'pos': pos, 世界坐标系坐标
#   'str': str, spr_torch等标识
#   'entry_no': entry_no, (若为prop则prop_instance_get_variation_id获取)
#   'menu_entry_no': menu_item_no,(若为prop则prop_instance_get_variation_id_2获取)
#   'scale': scale, 伸缩变换比例
#}

# 获取当前场景中所有的对象
objects = bpy.context.scene.objects

mission_objects = []
for object in objects:
    mission_obj = {}
    mission_obj['type'] =  object.get('type')
    mission_obj['id'] = object.get('id')
    mission_obj['garbage'] = object.get('garbage')
    rotation_euler_XYZ = object.rotation_euler.copy()
    rotation_euler_XYZ[0] = rotation_euler_XYZ[0] * -1
    rotation_euler_XYZ[1] = rotation_euler_XYZ[1] * -1
    rotation_euler_XYZ[2] = rotation_euler_XYZ[2] * -1
    rot_matrix = rotation_euler_XYZ.to_matrix()
    mission_obj['rotation_matrix'] = [
     [rot_matrix[0][0], rot_matrix[0][1], rot_matrix[0][2]],
     [rot_matrix[1][0], rot_matrix[1][1], rot_matrix[1][2]],
     [rot_matrix[2][0], rot_matrix[2][1], rot_matrix[2][2]],
    ]
    mission_obj['pos'] = [object.location.x, object.location.y, object.location.z]
    mission_obj['str'] = object.get('str')
    mission_obj['entry_no'] = object.get('entry_no')
    mission_obj['menu_entry_no'] = object.get('menu_entry_no')
    mission_obj['scale'] = [object.scale.x, object.scale.y, object.scale.z]
    mission_objects.append(mission_obj)
    
mission_objects_json = json.dumps(mission_objects, indent=4)
 
# 打开文件进行写入,如果文件不存在则创建
with open('F:\mission_objects.json', 'w', encoding='utf-8') as file:
    file.write(mission_objects_json)  # 将字符串写入文件

     <3.blender python脚本实现导入mission_object.json

import bpy
import math
import json
import mathutils
# mission_obj data_format
# object_type = ['prop', 'entry', 'item', 'unused', 'plant', 'passage']
# object = {
#   'type': object_type[type], 类型,场景物/出生点/通道
#   'id': id, ID.scene_props.py定义ID
#   'garbage': '%0#x' % garbage,
#   'rotation_matrix': [mtx_a, mtx_b, mtx_c], 旋转矩阵(右手坐标系,ZXY顺序旋转),转化后获得沿XYZ旋转角度
#   'pos': pos, 世界坐标系坐标
#   'str': str, spr_torch等标识
#   'entry_no': entry_no, (若为prop则prop_instance_get_variation_id获取)
#   'menu_entry_no': menu_item_no,(若为prop则prop_instance_get_variation_id_2获取)
#   'scale': scale, 伸缩变换比例
#}

# 获取当前场景中所有的对象
objects = bpy.context.scene.objects

def get_object_by_mission_object(mission_object):
    spr_name = mission_object["str"]
    type = mission_object["type"]
    if type == 'entry':
        return objects["lol_entry_point"]
    elif type == 'prop':
        for object in objects:
            if ('spr_' + object.name) == spr_name:
                return object
    
def handle_mission_object(mission_object_index, mission_object):
    object = get_object_by_mission_object(mission_object)
    new_obj = object.copy()
    new_obj.data = object.data.copy()
    new_obj.data.materials[0] = object.data.materials[0].copy()
    new_obj.rotation_euler = object.rotation_euler.copy()
    new_obj.location = object.location.copy()
    new_obj.scale = object.scale.copy()
    
    new_obj.name = object.name + '_' + str(mission_object_index)
    
    #set mission_object pos rotation and scale
    new_obj.location.x = mission_object["pos"][0]
    new_obj.location.y = mission_object["pos"][1]
    new_obj.location.z = mission_object["pos"][2]
    
    
    new_obj.scale.x = mission_object["scale"][0]
    new_obj.scale.y = mission_object["scale"][1]
    new_obj.scale.z = mission_object["scale"][2]
    
    
    rotation_matrix = mathutils.Matrix(mission_object["rotation_matrix"])
    new_obj.rotation_euler = rotation_matrix.to_euler()
    new_obj.rotation_euler[0] = new_obj.rotation_euler[0] * (-1)
    new_obj.rotation_euler[1] = new_obj.rotation_euler[1] * (-1)
    new_obj.rotation_euler[2] = new_obj.rotation_euler[2] * (-1)
    
    #set mission_object prop
    new_obj["id"] = mission_object["id"]
    new_obj["type"] = mission_object["type"]
    new_obj["garbage"] = mission_object["garbage"]
    new_obj["str"] = mission_object["str"]
    new_obj["entry_no"] = mission_object["entry_no"]
    new_obj["menu_entry_no"] = mission_object["menu_entry_no"]
    bpy.context.collection.objects.link(new_obj)

with open('F:/mission_objects.json', "r") as file:
    mission_objects_json_str = file.read()
    print(mission_objects_json_str)

mission_objects = json.loads(mission_objects_json_str)

for mission_object_index, mission_object in enumerate(mission_objects):
    handle_mission_object(mission_object_index, mission_object)
        

四.ai_mesh.obj

五.layer_ground_elevation.pfm

六.解包sco文件

    将拷贝sco文件至工具目录,运行unpack.bat进行解包.

七.封包sco文件

    修改解包文件夹下的文件,运行repack.bat重新打包生成sco文件.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/479422.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

购买阿里云服务器,有啥优惠吗?

购买阿里云服务器&#xff0c;有啥优惠吗&#xff1f;有的。2024年腾讯云服务器优惠价格表&#xff0c;一张表整理阿里云服务器最新报价&#xff0c;阿里云服务器网整理云服务器ECS和轻量应用服务器详细CPU内存、公网带宽和系统盘详细配置报价单&#xff0c;大家也可以直接移步…

[Linux]互斥锁(什么是锁,为什么需要锁,怎么使用锁(接口),演示代码)

目录 一、锁的概念 一些需要了解的概念 什么是锁&#xff1f;为什么需要锁&#xff1f;什么时候使用锁&#xff1f;怎么定义锁&#xff1f; 二、锁的接口 1.初始化锁 2.加锁 3.申请锁 4.解锁 5.销毁锁 三、实践&#xff08;写代码&#xff09;&#xff1a;黄牛抢票 一…

Matlab有限差分法求解狄利克雷(Dirichlet)边界的泊松(Poisson)问题,边界值为任意值

参考l链接&#xff1a; 有限差分法-二维泊松方程及其Matlab程序实现弹性力学方程 有限差分法matlab,泊松方程的有限差分法的MATLAB实现 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Matrix method for Poisson Equation %%%% %%% …

用redis lua脚本实现时间窗分布式限流

需求背景&#xff1a; 限制某sql在30秒内最多只能执行3次 需求分析 微服务分布式部署&#xff0c;既然是分布式限流&#xff0c;首先自然就想到了结合redis的zset数据结构来实现。 分析对zset的操作&#xff0c;有几个步骤&#xff0c;首先&#xff0c;判断zset中符合rangeS…

express+mysql+vue,从零搭建一个商城管理系统15--快递查询(对接快递100)

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、安装md5&#xff0c;axios二、新建config/logistics.js三、修改routes/order.js四、查询物流信息五、试错与误区总结 前言 需求&#xff1a;主要学习express&#xff0c;所以先写service部分 快递100API…

纹波和噪声有啥区别(一)

首先要知道的是他们都是在电源输出中出现的信号波动&#xff0c;但两者存在明显的区别。 一&#xff0c;纹波的产生 电源纹波是指电源输出时&#xff0c;叠加在稳定的直流电源上的交流成分。 这种波动主要是由于电源自身的开关、PWM 调节等因素引起的&#xff0c;其频率一般…

python的stone音乐播放器的设计与实现flask-django-php-nodejs

该系统利用python语言、MySQL数据库&#xff0c;flask框架&#xff0c;结合目前流行的 B/S架构&#xff0c;将stone音乐播放器的各个方面都集中到数据库中&#xff0c;以便于用户的需要。该系统在确保系统稳定的前提下&#xff0c;能够实现多功能模块的设计和应用。该系统由管理…

Word文档密码设置:Python设置、更改及移除Word文档密码

给Word文档设置打开密码是常见的Word文档加密方式。为Word文档设置打开密码后&#xff0c;在打开该文档时&#xff0c;需要输入密码才能预览及编辑&#xff0c;为Word文档中的信息提供了有力的安全保障。如果我们需要对大量的Word文档进行加密、解密处理&#xff0c;Python是一…

3.C#对接微信Native支付(注册微信支付)

在完成了所有的准备工作之后&#xff0c;我们开始进行实际的对接工作&#xff0c;由于官方没有提供C#版本的SDK我们需要自己手动实现所有的功能&#xff0c;介于再去研究文档太麻烦我们借助第三方的sdk 盛派微信 SDK 它是由苏震巍先生发起的国内知名的 .NET 开源项目。https://…

ZYNQ 自定义AXI接口 IP(PWM)

系统框图 1 FPGA PWM源码 / // Description: pwm model // pwm out period frequency(pwm_out) * (2 ** N) / frequency(clk); // // // Revision History: // Date By Revision Change Description //--------------------------------------…

Vue2(七):超详细vue开发环境搭建(win7),nodejs下载与安装,安装淘宝镜像(报错已解决),配置脚手架

一、安装node.js 本来想粗略写一下的&#xff0c;但是搭建脚手架的时候&#xff0c;遇到了很多问题&#xff0c;浪费快两天时间&#xff0c;记录一下自己的解决办法希望对你们有帮助&#xff01; 1.下载nodejs 安装包下载链接【CNPM Binaries Mirror】 下载我划线的这个&am…

vue学习日记14:工程化开发脚手架Vue CLI

一、概念 二、安装 1.全局安装&查看版本 注意启动cmd输入命令 要以管理员运行哦 安装了一次就行以后不用再创建了 yarn global addvue/cli vue --version 显示了版本号即可 2.创建项目架子 创建项目的路径在哪 项目就在哪 项目名字不能用中文 vue create project-n…

命令提示符——CMD基础操作介绍

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

初识C++(一)

目录 一、什么是C 二、关键字&#xff1a; 三、命名空间 &#xff1a; 1. C语言存在的问题&#xff1a; 2. namespace关键字&#xff1a; 3. 注意点&#xff1a; 4.使用命名空间分为三种&#xff1a; 四、输入输出&#xff1a; 五、缺省函数&#xff1a; 1. 什么是缺省…

PTA L2-026 小字辈

本题给定一个庞大家族的家谱&#xff0c;要请你给出最小一辈的名单。 输入格式&#xff1a; 输入在第一行给出家族人口总数 N&#xff08;不超过 100 000 的正整数&#xff09; —— 简单起见&#xff0c;我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号&#xff0c;…

java网络原理(三)----三次握手四次挥手

三次握手 三次握手是建立连接的过程&#xff0c;四次挥手是断开连接的过程&#xff0c;三次握手发生在socket.accept()之前。 客户端和服务器尝试建立连接的时候服务器就会和客户端进行一系列的数据交换称为握手&#xff0c;这个过程建立完了后&#xff0c;连接就好了。 A和B…

2024不起眼的“致富”野路子,不想打工了,做做这些暴利创业项目。2024个人创业做什么项目好;最适合白手起家的创业项目

经济大环境差&#xff0c;并不代表就没有机会。相反&#xff0c;主流经济不好正是另一些人所看重的千载难逢的机会。就像股票市场一样&#xff0c;有人靠做多赚钱&#xff0c;有人靠做空赚钱。下面我们就来分析一下哪些行业会在这个时候崛起。 首先二手行业会迅速崛起&#xff…

东芝复印机3115 日志清除

以管理员登录&#xff0c;默认的用户名是admin&#xff0c;密码123456. 点日志中的导出日志&#xff0c;逐个清除日志。

陪诊APP开发价格的价格是多少

随着社会的发展&#xff0c;人们的生活节奏越来越快&#xff0c;对于医疗服务的需求也在不断增加。特别是在老年人口逐渐增多的今天&#xff0c;陪诊服务成为越来越多人关注的焦点。那么&#xff0c;陪诊APP的开发价格需要多少钱呢&#xff1f;本文将从以下几个方面进行详细分析…

Android 地图SDK 去除缩放

问题 Android 地图SDK 去除缩放 详细问题 笔者进行Android 项目开发&#xff0c;接入高德地图SDK。但是默认在地图右下角有高德地图缩放按钮&#xff0c;现需要去除该按钮 预期效果 解决方案 mMapView.getMap().getUiSettings().setZoomControlsEnabled(false);代码含义解…