我正在使用 NativeUI 脚本更改眼睛颜色(因为选择器选项超过 10)。但我不断收到错误:
Cannot set property 'material' of null
script.js:103:6
这是脚本:
// Selected Value - NativeUI Picker example v85
// by Luke Hurd :: @lukehurd
// WHAT HAS CHANGED FROM PREVIOUS VERSIONS//
// In order to load Textures, Materials, and Objects, we must
// now use something in Javascript called "Promises". The basic
// concept is Spark AR now wants to make sure these assets are
// available to the script to manipulate before executing any code.
// When loading assets, find() has been changed to findFirst() and findAll()
// Load the modules
const Scene = require('Scene');
const Materials = require('Materials');
const NativeUI = require('NativeUI');
const Textures = require('Textures');
// First, we create a Promise and load all the assets we need for our scene
// The following example shows how to load Textures, Materials, and an Object.
Promise.all([
// Loading Textures for the buttons
// I will be using 12 icons for 12 Materials
Textures.findFirst('icon01'),
Textures.findFirst('icon02'),
Textures.findFirst('icon03'),
// Loading the Materials we are switching on the plane
// I'm only currently using three Mats and Icons for testing
Materials.findFirst('Amethyst_Mat'),
Materials.findFirst('Blue_Mat'),
Materials.findFirst('BrilliantBlue_Mat'),
// Loading the plane
Scene.root.findFirst('plane0'),
// Now, we wait for a "go ahead" from the script to let us know when
// we can start using our assets and creating the NativeUI Picker
]).then(function(results){
// Assets are loaded, so let's set them all so we can use them later in the script.
// The assets are all returned in an object called "results" in the order that we
// loaded them. Remember, the index starts at 0 so the first asset is always results[0],
// the next is results[1], etc.
// First, we set the buttons for the NativeUI Picker
const icon01 = results[0];
const icon02 = results[1];
const icon03 = results[2];
// Next, we set the materials for the plane
const Amethyst = results[3];
const Blue = results[4];
const BrilliantBlue = results[5];
// Finally, we set the plane
const plane = results[6];
// Now, we can finally start building the NativeUI Picker
const configuration = {
// This index controls where the NativeUI Picker starts.
// In this example, we want to start on the second button,
// not the first. So we pass the initial value of "1" (which is the second button)
selectedIndex: 0,
// These are the image textures to use as the buttons in the NativeUI Picker
items: [
{image_texture: icon01},
{image_texture: icon02},
{image_texture: icon03}
],
// These are the materials we are switching between on the plane
mats: [
{material: Amethyst},
{material: Blue},
{material: BrilliantBlue}
]
};
// Create the NativeUI Picker
const picker = NativeUI.picker;
// Load our configuration
picker.configure(configuration);
// Show the NativeUI Picker
picker.visible = true;
picker.selectedIndex.monitor({fireOnInitialValue: true}).subscribe(function(val) {
plane.material = configuration.mats[val.newValue].material
});
});
我需要为 12 种材料加载/使用 12 个选择器选项。
我并不是真正的程序员,所以我只是复制粘贴我在谷歌上找到的脚本。该脚本加载我所有的选择器选项(12 个图标),没有任何问题。但他们不会加载相应的材质。在补丁编辑器中,我添加了脚本生成器补丁,然后使用“完全等于”补丁来加载垫子,但它们不起作用。
请帮忙?谢谢你。
问题似乎与飞机材料的安排有关。根据您提供的脚本,问题可能在于您如何配置
configuration
对象中的材质。特别是,mats
数组似乎缺少某些元素。
要解决此问题并加载 12 种材质的 12 个选择器选项,您需要对脚本进行一些调整。这是更新后的脚本:
// Load the modules
const Scene = require('Scene');
const Materials = require('Materials');
const NativeUI = require('NativeUI');
const Textures = require('Textures');
// First, we create a Promise and load all the assets we need for our scene
Promise.all([
// Loading Textures for the buttons
// I will be using 12 icons for 12 Materials
Textures.findFirst('icon01'),
Textures.findFirst('icon02'),
// ... (add the remaining of your 12 textures here)
// Loading the Materials we are switching on the plane
// Ensure you have 12 materials named 'Material_01', 'Material_02', ... 'Material_12'
// Ensure they are sequentially numbered like this so we can easily access them in the script
...Array.from({ length: 12 }, (_, index) => Materials.findFirst(`Material_${String(index + 1).padStart(2, '0')}`)),
// Loading the plane
Scene.root.findFirst('plane0'),
]).then(function(results) {
// Assets are loaded, so let's set them all so we can use them later in the script.
const icons = results.slice(0, 12);
const materials = results.slice(12, 24);
const plane = results[24];
// Now, we can finally start building the NativeUI Picker
const configuration = {
// This index controls where the NativeUI Picker starts.
// In this example, we want to start on the first button (index 0).
// If you want to start on a different button, change the selectedIndex value accordingly.
selectedIndex: 0,
// These are the image textures to use as the buttons in the NativeUI Picker
items: icons.map(icon => ({ image_texture: icon })),
// These are the materials we are switching between on the plane
mats: materials.map(material => ({ material: material })),
};
// Create the NativeUI Picker
const picker = NativeUI.picker;
// Load our configuration
picker.configure(configuration);
// Show the NativeUI Picker
picker.visible = true;
picker.selectedIndex.monitor({fireOnInitialValue: true}).subscribe(function(val) {
// Modify the material of the plane when a different option is picked
plane.material = configuration.mats[val.newValue].material;
});
});
以下是主要变更:
Array.from
方法创建一个从 1 到 12 的数字数组。然后使用 padStart
来保证数字用零填充为两位数('01'、'02'、...、 ‘12’).Materials.findFirst
查找名称为“Material_01”、“Material_02”、...、“Material_12”的所有 12 种材质,并将它们存储在 materials
数组中。items
对象的 mats
和 configuration
属性。selectedIndex
对象中的 configuration
属性以从第一个按钮(索引 0)开始。