Custom script: Reading a string and changing arrangement of objects

Hi,

Apologies for the code dump. I’m trying to align letter-shaped chain links into a circle. This script works great for alignment (it counts the letters in ‘BraceletString’) but it doesn’t respond to configuration changes made by the website. Do I have to do some sort of async function? I followed the example in the docs as a template but I think there might be something I’m missing.

//Get api data
const config = api.configurator.getConfiguration();

const pi = 3.14159265359;
//get string info
const stringInput = config['BraceletString']
const num = stringInput.length

if(num > 20){
	num = 20;
}

//per-link rotational offset in degrees
const rot = 360/num;
//radius of the arranged circle
const spc = ((num * 1) / pi) * .5

function circleAlign(){

	//for each link (named letter1, letter2, ... letterN)
	for (let i = 1; i < 21; i++) {
		//move out to radius distance
		api.scene.set({
				from: api.instanceId,
				name: 'letter' + i.toString(),
				plug: 'Transform',
				property: 'translation',
			}, { 
				x: 0, 
				y : 0,
				z: 1 * spc
			}
		);

		//set pivot point to (0,0,0)
		api.scene.set({
				from: api.instanceId,
				name: 'letter' + i.toString(),
				plug: 'Transform',
				property: 'localRotatePivot',
			}, { 
				x: 0, 
				y : 0,
				z: -1 * spc
			}
		);

		//rotate by specified offset
		api.scene.set({
				from: api.instanceId,
				name: 'letter' + i.toString(),
				plug: 'Transform',
				property: 'rotation',
			}, { 
				x: 0,
				y : rot * i, 
				z: 0
			}
		);
	}
}

function straightAlign(){

	//for each link (named letter1, letter2, ... letterN)
	for (let i = 1; i < num + 1; i++) {

	//set pivot point to (0,0,0)
		api.scene.set({
			from: api.instanceId,
			name: 'letter' + i.toString(),
			plug: 'Transform',
			property: 'localRotatePivot',
		}, { 
			x: 0, 
			y: 0,
			z: 0
			}
		);
		//rotate by specified offset
		api.scene.set({
			from: api.instanceId,
			name: 'letter' + i.toString(),
			plug: 'Transform',
			property: 'rotation',
		}, { 
			x: 0,
			y: 0, 
			z: 0
		}
		);
	
		//move out to radius distance
		api.scene.set({
				from: api.instanceId,
				name: 'letter' + i.toString(),
				plug: 'Transform',
				property: 'translation',
			}, { 
				x: i - (num * 0.5),
				y: 0,
				z: 0
			}
		);
	}
}

//TODO: make these inivisible instead of moving them out of frame
function hideUnused(){

	if(num >= 20){
		return;
	}

	for (let i = num + 1; i < 21; i++) {
		api.scene.set({
			from: api.instanceId,
			name: 'letter' + i.toString(),
			plug: 'Transform',
			property: 'translation',
		}, { 
			x: 100,
			y: 100,
			z: 100
		}
	);
	}
}

function setCamera(camName){
	// id = api.scene.findNode({
	// 	from:api.instanceId,
	// 	name: camName,
	// });

	// api.setActiveCamera(id)
	config['CurrentCam'] = camName
	api.configurator.setConfiguration(config)
}

if(num > 8){
	circleAlign()
	setCamera('OrbitCam')
}else{
	straightAlign()
	setCamera('FixedCam')
}

hideUnused()

For reference, this is the website test:

The string asset should change to ‘isNotShowingUpInTheConfig’ but instead the string stays blank

Hi Andrew,

I haven’t looked through your script extensively but I believe the issue your having is that in your embed ‘Attribute Name’ should be replaced with the name of the part reference attribute you’re using.

hope this helps, Ian

1 Like

Well this is embarrassing! I expected it to be a structural problem and it was something pretty basic. It works now. Thanks for the help.

initialConfiguration: {
         'BraceletString': 'andrewq'
          },
1 Like