小工具整理
@@ -0,0 +1,950 @@
|
|||||||
|
#target photoshop
|
||||||
|
app.bringToFront();
|
||||||
|
|
||||||
|
// This script exports Adobe Photoshop layers as individual PNGs. It also
|
||||||
|
// writes a JSON file which can be imported into Spine where the images
|
||||||
|
// will be displayed in the same positions and draw order.
|
||||||
|
|
||||||
|
// Copyright (c) 2012-2017, Esoteric Software
|
||||||
|
// All rights reserved.
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
var scriptVersion = 2.9; // This is incremented every time the script is modified, so you know if you have the latest.
|
||||||
|
|
||||||
|
var cs2 = parseInt(app.version) < 10;
|
||||||
|
|
||||||
|
var originalDoc;
|
||||||
|
try {
|
||||||
|
originalDoc = app.activeDocument;
|
||||||
|
} catch (ignored) {}
|
||||||
|
|
||||||
|
var defaultSettings = {
|
||||||
|
ignoreHiddenLayers: false,
|
||||||
|
ignoreBackground: true,
|
||||||
|
writeTemplate: false,
|
||||||
|
writeJson: true,
|
||||||
|
trimWhitespace: true,
|
||||||
|
scale: 1,
|
||||||
|
padding: 1,
|
||||||
|
imagesDir: "./images/",
|
||||||
|
jsonPath: "./",
|
||||||
|
};
|
||||||
|
var settings = loadSettings();
|
||||||
|
showSettingsDialog();
|
||||||
|
|
||||||
|
var progress, cancel;
|
||||||
|
function run () {
|
||||||
|
showProgressDialog();
|
||||||
|
|
||||||
|
// Output dirs.
|
||||||
|
var jsonFile = new File(jsonPath(settings.jsonPath));
|
||||||
|
jsonFile.parent.create();
|
||||||
|
var imagesDir = absolutePath(settings.imagesDir);
|
||||||
|
var imagesFolder = new Folder(imagesDir);
|
||||||
|
imagesFolder.create();
|
||||||
|
|
||||||
|
// Get ruler origin.
|
||||||
|
var action = new ActionReference();
|
||||||
|
action.putEnumerated(cID("Dcmn"), cID("Ordn"), cID("Trgt"));
|
||||||
|
var result = executeActionGet(action);
|
||||||
|
var xOffSet = result.getInteger(sID("rulerOriginH")) >> 16;
|
||||||
|
var yOffSet = result.getInteger(sID("rulerOriginV")) >> 16;
|
||||||
|
|
||||||
|
activeDocument.duplicate();
|
||||||
|
deselectLayers();
|
||||||
|
|
||||||
|
try {
|
||||||
|
convertToRGB();
|
||||||
|
} catch (ignored) {}
|
||||||
|
if (app.activeDocument.mode != DocumentMode.RGB) {
|
||||||
|
alert("Please change the image mode to RGB color.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output template image.
|
||||||
|
if (settings.writeTemplate) {
|
||||||
|
if (settings.scale != 1) {
|
||||||
|
storeHistory();
|
||||||
|
scaleImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = new File(imagesDir + "template.png");
|
||||||
|
if (file.exists) file.remove();
|
||||||
|
|
||||||
|
savePNG(file);
|
||||||
|
|
||||||
|
if (settings.scale != 1) restoreHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settings.jsonPath && !settings.imagesDir) {
|
||||||
|
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rasterize all layers.
|
||||||
|
try {
|
||||||
|
executeAction(sID("rasterizeAll"), undefined, DialogModes.NO);
|
||||||
|
} catch (ignored) {}
|
||||||
|
|
||||||
|
// Add a history item to prevent layer visibility from changing by the active layer being reset to the top.
|
||||||
|
activeDocument.artLayers.add();
|
||||||
|
|
||||||
|
// Collect and hide layers.
|
||||||
|
var layers = [];
|
||||||
|
collectLayers(activeDocument, layers);
|
||||||
|
var layersCount = layers.length;
|
||||||
|
|
||||||
|
// Add a history item to prevent layer visibility from changing by restoreHistory.
|
||||||
|
activeDocument.artLayers.add();
|
||||||
|
|
||||||
|
// Store the bones, slot names, and layers for each skin.
|
||||||
|
var bones = { root: { name: "root", x: 0, y: 0, children: [] } };
|
||||||
|
var slots = {}, slotsCount = 0;
|
||||||
|
var skins = { "default": [] }, skinsCount = 0;
|
||||||
|
var totalLayerCount = 0;
|
||||||
|
outer:
|
||||||
|
for (var i = 0; i < layersCount; i++) {
|
||||||
|
var layer = layers[i];
|
||||||
|
if (layer.kind != LayerKind.NORMAL && !isGroup(layer)) continue;
|
||||||
|
layer.attachmentName = folders(layer, "") + stripTags(layer.name);
|
||||||
|
|
||||||
|
var bone = null;
|
||||||
|
var boneLayer = findTagLayer(layer, "bone", null);
|
||||||
|
if (boneLayer) {
|
||||||
|
function getParentBone (boneLayer, bones) {
|
||||||
|
var parentName = findTag(boneLayer.parent, "bone", "root");
|
||||||
|
var parent = bones[parentName];
|
||||||
|
if (!parent) { // Parent bone group with no attachment layers.
|
||||||
|
var parentParent = getParentBone(boneLayer.parent, bones);
|
||||||
|
bones[parentName] = parent = { name: parentName, parent: parentParent, children: [], x: 0, y: 0 };
|
||||||
|
parentParent.children.push(parent);
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
var parent = getParentBone(boneLayer, bones);
|
||||||
|
|
||||||
|
var boneName = stripTags(boneLayer.name);
|
||||||
|
bone = bones[boneName];
|
||||||
|
if (bone) {
|
||||||
|
if (parent != bone.parent) {
|
||||||
|
alert("Multiple layers for the \"" + boneName + "\" bone have different parent bones:\n\n"
|
||||||
|
+ bone.parent.name + "\n"
|
||||||
|
+ parent.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bones[boneName] = bone = { name: boneName, parent: parent, children: [] };
|
||||||
|
parent.children.push(bone);
|
||||||
|
}
|
||||||
|
if (layer.wasVisible) {
|
||||||
|
bone.x = (layer.bounds[0].as("px")) * settings.scale - settings.padding;
|
||||||
|
bone.x += (layer.bounds[2].as("px") - layer.bounds[0].as("px")) * settings.scale / 2 + settings.padding;
|
||||||
|
bone.y = (activeDocument.height.as("px") - layer.bounds[1].as("px")) * settings.scale + settings.padding;
|
||||||
|
bone.y -= (layer.bounds[3].as("px") - layer.bounds[1].as("px")) * settings.scale / 2 + settings.padding;
|
||||||
|
|
||||||
|
// Make relative to the Photoshop document ruler origin.
|
||||||
|
bone.x -= xOffSet * settings.scale;
|
||||||
|
bone.y -= (activeDocument.height.as("px") - yOffSet) * settings.scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.slotName = findTag(layer, "slot", layer.attachmentName);
|
||||||
|
if (!slots[layer.slotName]) slotsCount++;
|
||||||
|
slots[layer.slotName] = { bone: bone, attachment: layer.wasVisible ? layer.attachmentName : null };
|
||||||
|
|
||||||
|
if (layer.blendMode == BlendMode.LINEARDODGE)
|
||||||
|
slots[layer.slotName].blend = "additive";
|
||||||
|
else if (layer.blendMode == BlendMode.MULTIPLY)
|
||||||
|
slots[layer.slotName].blend = "multiply";
|
||||||
|
else if (layer.blendMode == BlendMode.SCREEN)
|
||||||
|
slots[layer.slotName].blend = "screen";
|
||||||
|
|
||||||
|
var skinName = findTag(layer, "skin", "default");
|
||||||
|
var skinSlots = skins[skinName];
|
||||||
|
if (!skinSlots) {
|
||||||
|
skins[skinName] = skinSlots = {};
|
||||||
|
skinsCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var skinLayers = skinSlots[layer.slotName];
|
||||||
|
if (!skinLayers) skinSlots[layer.slotName] = skinLayers = [];
|
||||||
|
for (var ii = 0, nn = skinLayers.length; ii < nn; ii++) {
|
||||||
|
if (skinLayers[ii].attachmentName == layer.attachmentName) {
|
||||||
|
alert("Multiple layers for the \"" + skinName + "\" skin have the same name:\n\n"
|
||||||
|
+ layer.attachmentName
|
||||||
|
+ "\n\nRename or use the [ignore] tag for the other layers.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
skinLayers[skinLayers.length] = layer;
|
||||||
|
totalLayerCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output skeleton.
|
||||||
|
var json = '{ "skeleton": { "images": "' + imagesDir + '" },\n"bones": [\n';
|
||||||
|
|
||||||
|
// Output bones.
|
||||||
|
function outputBone (bone) {
|
||||||
|
var json = bone.parent ? ",\n" : "";
|
||||||
|
json += '\t{ "name": ' + quote(bone.name);
|
||||||
|
var x = bone.x, y = bone.y;
|
||||||
|
if (bone.parent) {
|
||||||
|
x -= bone.parent.x;
|
||||||
|
y -= bone.parent.y;
|
||||||
|
json += ', "parent": ' + quote(bone.parent.name);
|
||||||
|
}
|
||||||
|
if (x) json += ', "x": ' + x;
|
||||||
|
if (y) json += ', "y": ' + y;
|
||||||
|
json += ' }';
|
||||||
|
for (var i = 0, n = bone.children.length; i < n; i++)
|
||||||
|
json += outputBone(bone.children[i]);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
for (var boneName in bones) {
|
||||||
|
if (!bones.hasOwnProperty(boneName)) continue;
|
||||||
|
var bone = bones[boneName];
|
||||||
|
if (!bone.parent) json += outputBone(bone);
|
||||||
|
}
|
||||||
|
json += '\n],\n"slots": [\n';
|
||||||
|
|
||||||
|
// Output slots.
|
||||||
|
var slotIndex = 0;
|
||||||
|
for (var slotName in slots) {
|
||||||
|
if (!slots.hasOwnProperty(slotName)) continue;
|
||||||
|
var slot = slots[slotName];
|
||||||
|
json += '\t{ "name": ' + quote(slotName) + ', "bone": ' + quote(slot.bone ? slot.bone.name : "root");
|
||||||
|
if (slot.attachment) json += ', "attachment": ' + quote(slot.attachment);
|
||||||
|
if (slot.blend) json += ', "blend": ' + quote(slot.blend);
|
||||||
|
json += ' }';
|
||||||
|
slotIndex++;
|
||||||
|
json += slotIndex < slotsCount ? ",\n" : "\n";
|
||||||
|
}
|
||||||
|
json += '],\n"skins": {\n';
|
||||||
|
|
||||||
|
// Output skins.
|
||||||
|
var skinIndex = 0, layerCount = 0;
|
||||||
|
for (var skinName in skins) {
|
||||||
|
if (!skins.hasOwnProperty(skinName)) continue;
|
||||||
|
json += '\t"' + skinName + '": {\n';
|
||||||
|
|
||||||
|
var skinSlots = skins[skinName];
|
||||||
|
var skinSlotIndex = 0, skinSlotsCount = countAssocArray(skinSlots);
|
||||||
|
for (var slotName in skinSlots) {
|
||||||
|
if (!skinSlots.hasOwnProperty(slotName)) continue;
|
||||||
|
var bone = slots[slotName].bone;
|
||||||
|
|
||||||
|
json += '\t\t' + quote(slotName) + ': {\n';
|
||||||
|
|
||||||
|
var skinLayers = skinSlots[slotName];
|
||||||
|
var skinLayerIndex = 0, skinLayersCount = skinLayers.length;
|
||||||
|
for (var i = skinLayersCount - 1; i >= 0; i--) {
|
||||||
|
var layer = skinLayers[i];
|
||||||
|
layer.visible = true;
|
||||||
|
|
||||||
|
if (cancel) {
|
||||||
|
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setProgress(++layerCount / totalLayerCount, trim(layer.name));
|
||||||
|
|
||||||
|
var placeholderName = layer.attachmentName;
|
||||||
|
var attachmentName = (skinName == "default" ? "" : skinName + "/") + placeholderName;
|
||||||
|
|
||||||
|
if (isGroup(layer)) {
|
||||||
|
activeDocument.activeLayer = layer;
|
||||||
|
layer = layer.merge();
|
||||||
|
}
|
||||||
|
|
||||||
|
storeHistory();
|
||||||
|
|
||||||
|
var x = activeDocument.width.as("px") * settings.scale;
|
||||||
|
var y = activeDocument.height.as("px") * settings.scale;
|
||||||
|
if (settings.trimWhitespace) {
|
||||||
|
if (!layer.isBackgroundLayer) activeDocument.trim(TrimType.TRANSPARENT, false, true, true, false);
|
||||||
|
x -= activeDocument.width.as("px") * settings.scale;
|
||||||
|
y -= activeDocument.height.as("px") * settings.scale;
|
||||||
|
if (!layer.isBackgroundLayer) activeDocument.trim(TrimType.TRANSPARENT, true, false, false, true);
|
||||||
|
}
|
||||||
|
var width = activeDocument.width.as("px") * settings.scale + settings.padding * 2;
|
||||||
|
var height = activeDocument.height.as("px") * settings.scale + settings.padding * 2;
|
||||||
|
|
||||||
|
// Save image.
|
||||||
|
if (settings.imagesDir) {
|
||||||
|
if (settings.scale != 1) scaleImage();
|
||||||
|
if (settings.padding > 0) activeDocument.resizeCanvas(width, height, AnchorPosition.MIDDLECENTER);
|
||||||
|
|
||||||
|
var file = new File(imagesDir + attachmentName);
|
||||||
|
file.parent.create();
|
||||||
|
savePNG(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreHistory();
|
||||||
|
if (layerCount < totalLayerCount) deleteLayer(layer);
|
||||||
|
|
||||||
|
x += Math.round(width) / 2 - settings.padding;
|
||||||
|
y += Math.round(height) / 2 - settings.padding;
|
||||||
|
|
||||||
|
// Make relative to the Photoshop document ruler origin.
|
||||||
|
x -= xOffSet * settings.scale;
|
||||||
|
y -= (activeDocument.height.as("px") - yOffSet) * settings.scale;
|
||||||
|
|
||||||
|
if (bone) { // Make relative to parent bone.
|
||||||
|
x -= bone.x;
|
||||||
|
y -= bone.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
json += "\t\t\t" + quote(placeholderName) + ': { ';
|
||||||
|
if (attachmentName != placeholderName) json += '"name": ' + quote(attachmentName) + ', ';
|
||||||
|
json += '"x": ' + x + ', "y": ' + y + ', "width": ' + Math.round(width) + ', "height": ' + Math.round(height);
|
||||||
|
|
||||||
|
json += " }" + (++skinLayerIndex < skinLayersCount ? ",\n" : "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
json += "\t\t}" + (++skinSlotIndex < skinSlotsCount ? ",\n" : "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
json += "\t\}" + (++skinIndex < skinsCount ? ",\n" : "\n");
|
||||||
|
}
|
||||||
|
json += '},\n"animations": { "animation": {} }\n}';
|
||||||
|
|
||||||
|
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
|
||||||
|
|
||||||
|
// Output JSON file.
|
||||||
|
if (settings.writeJson && settings.jsonPath) {
|
||||||
|
jsonFile.encoding = "UTF-8";
|
||||||
|
jsonFile.remove();
|
||||||
|
jsonFile.open("w", "TEXT");
|
||||||
|
jsonFile.lineFeed = "\n";
|
||||||
|
jsonFile.write(json);
|
||||||
|
jsonFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings dialog:
|
||||||
|
|
||||||
|
function showSettingsDialog () {
|
||||||
|
if (parseInt(app.version) < 9) {
|
||||||
|
alert("Photoshop CS2 or later is required.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!originalDoc) {
|
||||||
|
alert("Please open a document before running the PhotoshopToSpine script.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!hasFilePath()) {
|
||||||
|
alert("Please save the document before running the PhotoshopToSpine script.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout.
|
||||||
|
var dialog = new Window("dialog", "PhotoshopToSpine v" + scriptVersion), group;
|
||||||
|
dialog.alignChildren = "fill";
|
||||||
|
|
||||||
|
try {
|
||||||
|
dialog.add("image", undefined, new File(scriptDir() + "logo.png"));
|
||||||
|
} catch (ignored) {}
|
||||||
|
|
||||||
|
var settingsGroup = dialog.add("panel", undefined, "Settings");
|
||||||
|
settingsGroup.margins = [10,15,10,10];
|
||||||
|
settingsGroup.alignChildren = "fill";
|
||||||
|
var checkboxGroup = settingsGroup.add("group");
|
||||||
|
checkboxGroup.alignChildren = ["left", ""];
|
||||||
|
checkboxGroup.orientation = "row";
|
||||||
|
group = checkboxGroup.add("group");
|
||||||
|
group.orientation = "column";
|
||||||
|
group.alignChildren = ["left", ""];
|
||||||
|
var ignoreHiddenLayersCheckbox = group.add("checkbox", undefined, " Ignore hidden layers");
|
||||||
|
ignoreHiddenLayersCheckbox.value = settings.ignoreHiddenLayers;
|
||||||
|
var ignoreBackgroundCheckbox = group.add("checkbox", undefined, " Ignore background layer");
|
||||||
|
ignoreBackgroundCheckbox.value = settings.ignoreBackground;
|
||||||
|
var trimWhitespaceCheckbox = group.add("checkbox", undefined, " Trim whitespace");
|
||||||
|
trimWhitespaceCheckbox.value = settings.trimWhitespace;
|
||||||
|
group = checkboxGroup.add("group");
|
||||||
|
group.orientation = "column";
|
||||||
|
group.alignChildren = ["left", ""];
|
||||||
|
group.alignment = ["", "top"];
|
||||||
|
var writeJsonCheckbox = group.add("checkbox", undefined, " Write Spine JSON");
|
||||||
|
writeJsonCheckbox.value = settings.writeJson;
|
||||||
|
var writeTemplateCheckbox = group.add("checkbox", undefined, " Write template image");
|
||||||
|
writeTemplateCheckbox.value = settings.writeTemplate;
|
||||||
|
var scaleText, paddingText, scaleSlider, paddingSlider;
|
||||||
|
if (!cs2) {
|
||||||
|
var slidersGroup = settingsGroup.add("group");
|
||||||
|
group = slidersGroup.add("group");
|
||||||
|
group.orientation = "column";
|
||||||
|
group.alignChildren = ["right", ""];
|
||||||
|
group.add("statictext", undefined, "Scale:");
|
||||||
|
group.add("statictext", undefined, "Padding:");
|
||||||
|
group = slidersGroup.add("group");
|
||||||
|
group.orientation = "column";
|
||||||
|
scaleText = group.add("edittext", undefined, settings.scale * 100);
|
||||||
|
scaleText.characters = 4;
|
||||||
|
paddingText = group.add("edittext", undefined, settings.padding);
|
||||||
|
paddingText.characters = 4;
|
||||||
|
group = slidersGroup.add("group");
|
||||||
|
group.orientation = "column";
|
||||||
|
group.add("statictext", undefined, "%");
|
||||||
|
group.add("statictext", undefined, "px");
|
||||||
|
group = slidersGroup.add("group");
|
||||||
|
group.orientation = "column";
|
||||||
|
group.alignChildren = ["fill", ""];
|
||||||
|
group.alignment = ["fill", ""];
|
||||||
|
scaleSlider = group.add("slider", undefined, settings.scale * 100, 1, 100);
|
||||||
|
paddingSlider = group.add("slider", undefined, settings.padding, 0, 4);
|
||||||
|
} else {
|
||||||
|
group = settingsGroup.add("group");
|
||||||
|
group.add("statictext", undefined, "Scale:");
|
||||||
|
scaleText = group.add("edittext", undefined, settings.scale * 100);
|
||||||
|
scaleText.preferredSize.width = 50;
|
||||||
|
scaleSlider = settingsGroup.add("slider", undefined, settings.scale * 100, 1, 100);
|
||||||
|
group = settingsGroup.add("group");
|
||||||
|
group.add("statictext", undefined, "Padding:");
|
||||||
|
paddingText = group.add("edittext", undefined, settings.padding);
|
||||||
|
paddingText.preferredSize.width = 50;
|
||||||
|
paddingSlider = settingsGroup.add("slider", undefined, settings.padding, 0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
var outputPathGroup = dialog.add("panel", undefined, "Output Paths");
|
||||||
|
outputPathGroup.alignChildren = ["fill", ""];
|
||||||
|
outputPathGroup.margins = [10,15,10,10];
|
||||||
|
var imagesDirText, imagesDirPreview, jsonPathText, jsonPathPreview;
|
||||||
|
if (!cs2) {
|
||||||
|
var textGroup = outputPathGroup.add("group");
|
||||||
|
textGroup.orientation = "column";
|
||||||
|
textGroup.alignChildren = ["fill", ""];
|
||||||
|
group = textGroup.add("group");
|
||||||
|
group.add("statictext", undefined, "Images:");
|
||||||
|
imagesDirText = group.add("edittext", undefined, settings.imagesDir);
|
||||||
|
imagesDirText.alignment = ["fill", ""];
|
||||||
|
imagesDirPreview = textGroup.add("statictext", undefined, "");
|
||||||
|
imagesDirPreview.maximumSize.width = 260;
|
||||||
|
group = textGroup.add("group");
|
||||||
|
var jsonLabel = group.add("statictext", undefined, "JSON:");
|
||||||
|
jsonLabel.justify = "right";
|
||||||
|
jsonLabel.minimumSize.width = 41;
|
||||||
|
jsonPathText = group.add("edittext", undefined, settings.jsonPath);
|
||||||
|
jsonPathText.alignment = ["fill", ""];
|
||||||
|
jsonPathPreview = textGroup.add("statictext", undefined, "");
|
||||||
|
jsonPathPreview.maximumSize.width = 260;
|
||||||
|
} else {
|
||||||
|
outputPathGroup.add("statictext", undefined, "Images:");
|
||||||
|
imagesDirText = outputPathGroup.add("edittext", undefined, settings.imagesDir);
|
||||||
|
imagesDirText.alignment = "fill";
|
||||||
|
outputPathGroup.add("statictext", undefined, "JSON:");
|
||||||
|
jsonPathText = outputPathGroup.add("edittext", undefined, settings.jsonPath);
|
||||||
|
jsonPathText.alignment = "fill";
|
||||||
|
}
|
||||||
|
var buttonGroup = dialog.add("group");
|
||||||
|
var helpButton;
|
||||||
|
if (!cs2) helpButton = buttonGroup.add("button", undefined, "Help");
|
||||||
|
group = buttonGroup.add("group");
|
||||||
|
group.alignment = ["fill", ""];
|
||||||
|
group.alignChildren = ["right", ""];
|
||||||
|
var runButton = group.add("button", undefined, "OK");
|
||||||
|
var cancelButton = group.add("button", undefined, "Cancel");
|
||||||
|
|
||||||
|
// Tooltips.
|
||||||
|
writeTemplateCheckbox.helpTip = "When checked, a PNG is written for the currently visible layers.";
|
||||||
|
writeJsonCheckbox.helpTip = "When checked, a Spine JSON file is written.";
|
||||||
|
trimWhitespaceCheckbox.helpTip = "When checked, blank pixels aroind the edges of each image are removed.";
|
||||||
|
scaleSlider.helpTip = "Scales the PNG files. Useful when using higher resolution art in Photoshop than in Spine.";
|
||||||
|
paddingSlider.helpTip = "Blank pixels around the edge of each image. Can avoid aliasing artifacts for opaque pixels along the image edge.";
|
||||||
|
imagesDirText.helpTip = "The folder to write PNGs. Begin with \"./\" to be relative to the PSD file. Blank to disable writing PNGs.";
|
||||||
|
jsonPathText.helpTip = "Output JSON file if ending with \".json\", else the folder to write the JSON file. Begin with \"./\" to be relative to the PSD file. Blank to disable writing a JSON file.";
|
||||||
|
|
||||||
|
// Events.
|
||||||
|
scaleText.onChanging = function () { scaleSlider.value = scaleText.text; };
|
||||||
|
scaleSlider.onChanging = function () { scaleText.text = Math.round(scaleSlider.value); };
|
||||||
|
paddingText.onChanging = function () { paddingSlider.value = paddingText.text; };
|
||||||
|
paddingSlider.onChanging = function () { paddingText.text = Math.round(paddingSlider.value); };
|
||||||
|
cancelButton.onClick = function () {
|
||||||
|
cancel = true;
|
||||||
|
dialog.close();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if (!cs2) helpButton.onClick = showHelpDialog;
|
||||||
|
jsonPathText.onChanging = function () {
|
||||||
|
var text = jsonPathText.text ? jsonPath(jsonPathText.text) : "<no JSON output>";
|
||||||
|
if (!cs2) {
|
||||||
|
jsonPathPreview.text = text;
|
||||||
|
jsonPathPreview.helpTip = text;
|
||||||
|
} else
|
||||||
|
jsonPathText.helpTip = text;
|
||||||
|
};
|
||||||
|
imagesDirText.onChanging = function () {
|
||||||
|
var text = imagesDirText.text ? absolutePath(imagesDirText.text) : "<no image output>";
|
||||||
|
if (!cs2) {
|
||||||
|
imagesDirPreview.text = text;
|
||||||
|
imagesDirPreview.helpTip = text;
|
||||||
|
} else
|
||||||
|
imagesDirText.helpTip = text;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Run now.
|
||||||
|
jsonPathText.onChanging();
|
||||||
|
imagesDirText.onChanging();
|
||||||
|
|
||||||
|
function updateSettings () {
|
||||||
|
settings.ignoreHiddenLayers = ignoreHiddenLayersCheckbox.value;
|
||||||
|
settings.ignoreBackground = ignoreBackgroundCheckbox.value;
|
||||||
|
settings.writeTemplate = writeTemplateCheckbox.value;
|
||||||
|
settings.writeJson = writeJsonCheckbox.value;
|
||||||
|
settings.trimWhitespace = trimWhitespaceCheckbox.value;
|
||||||
|
|
||||||
|
var scaleValue = parseFloat(scaleText.text);
|
||||||
|
if (scaleValue > 0 && scaleValue <= 100) settings.scale = scaleValue / 100;
|
||||||
|
|
||||||
|
settings.imagesDir = imagesDirText.text;
|
||||||
|
settings.jsonPath = jsonPathText.text;
|
||||||
|
|
||||||
|
var paddingValue = parseInt(paddingText.text);
|
||||||
|
if (paddingValue >= 0) settings.padding = paddingValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
runButton.onClick = function () {
|
||||||
|
if (scaleText.text <= 0 || scaleText.text > 100) {
|
||||||
|
alert("Scale must be between > 0 and <= 100.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (paddingText.text < 0) {
|
||||||
|
alert("Padding must be >= 0.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSettings();
|
||||||
|
saveSettings();
|
||||||
|
|
||||||
|
ignoreHiddenLayersCheckbox.enabled = false;
|
||||||
|
ignoreBackgroundCheckbox.enabled = false;
|
||||||
|
writeTemplateCheckbox.enabled = false;
|
||||||
|
writeJsonCheckbox.enabled = false;
|
||||||
|
trimWhitespaceCheckbox.enabled = false;
|
||||||
|
scaleText.enabled = false;
|
||||||
|
scaleSlider.enabled = false;
|
||||||
|
paddingText.enabled = false;
|
||||||
|
paddingSlider.enabled = false;
|
||||||
|
imagesDirText.enabled = false;
|
||||||
|
jsonPathText.enabled = false;
|
||||||
|
if (!cs2) helpButton.enabled = false;
|
||||||
|
runButton.enabled = false;
|
||||||
|
cancelButton.enabled = false;
|
||||||
|
|
||||||
|
var rulerUnits = app.preferences.rulerUnits;
|
||||||
|
app.preferences.rulerUnits = Units.PIXELS;
|
||||||
|
try {
|
||||||
|
// var start = new Date().getTime();
|
||||||
|
run();
|
||||||
|
// alert(new Date().getTime() - start);
|
||||||
|
} catch (e) {
|
||||||
|
alert("An unexpected error has occurred.\n\nTo debug, run the PhotoshopToSpine script using Adobe ExtendScript "
|
||||||
|
+ "with \"Debug > Do not break on guarded exceptions\" unchecked.");
|
||||||
|
debugger;
|
||||||
|
} finally {
|
||||||
|
if (activeDocument != originalDoc) activeDocument.close(SaveOptions.DONOTSAVECHANGES);
|
||||||
|
app.preferences.rulerUnits = rulerUnits;
|
||||||
|
dialog.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.center();
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadSettings () {
|
||||||
|
var options = null;
|
||||||
|
try {
|
||||||
|
options = app.getCustomOptions(sID("settings"));
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = {};
|
||||||
|
for (var key in defaultSettings) {
|
||||||
|
if (!defaultSettings.hasOwnProperty(key)) continue;
|
||||||
|
var typeID = sID(key);
|
||||||
|
if (options && options.hasKey(typeID))
|
||||||
|
settings[key] = options["get" + getOptionType(defaultSettings[key])](typeID);
|
||||||
|
else
|
||||||
|
settings[key] = defaultSettings[key];
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSettings () {
|
||||||
|
if (cs2) return; // No putCustomOptions.
|
||||||
|
var action = new ActionDescriptor();
|
||||||
|
for (var key in defaultSettings) {
|
||||||
|
if (!defaultSettings.hasOwnProperty(key)) continue;
|
||||||
|
action["put" + getOptionType(defaultSettings[key])](sID(key), settings[key]);
|
||||||
|
}
|
||||||
|
app.putCustomOptions(sID("settings"), action, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOptionType (value) {
|
||||||
|
switch (typeof(value)) {
|
||||||
|
case "boolean": return "Boolean";
|
||||||
|
case "string": return "String";
|
||||||
|
case "number": return "Double";
|
||||||
|
};
|
||||||
|
throw new Error("Invalid default setting: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Help dialog.
|
||||||
|
|
||||||
|
function showHelpDialog () {
|
||||||
|
var dialog = new Window("dialog", "PhotoshopToSpine - Help");
|
||||||
|
dialog.alignChildren = ["fill", ""];
|
||||||
|
dialog.orientation = "column";
|
||||||
|
dialog.alignment = ["", "top"];
|
||||||
|
|
||||||
|
var helpText = dialog.add("statictext", undefined, ""
|
||||||
|
+ "This script writes layers as images and creates a JSON file to bring the images into Spine in the same positions and draw order as they had in Photoshop.\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "The ruler origin corresponds to 0,0 in Spine.\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Tags in square brackets can be used in layer and group names to customize the output.\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Group names:\n"
|
||||||
|
+ "• [bone] Slot and bone layers in the group are placed under a bone, named after the group. The bone is created at the center of a visible attachment.\n"
|
||||||
|
+ "• [slot] Layers in the group are placed in a slot, named after the group.\n"
|
||||||
|
+ "• [skin] Layers in the group are placed in a skin, named after the group. Skin images are output in a subfolder for the skin.\n"
|
||||||
|
+ "• [merge] Layers in the group are merged and a single image is output, named after the group.\n"
|
||||||
|
+ "• [folder] Layers in the group will be output in a subfolder. Folder groups can be nested.\n"
|
||||||
|
+ "• [ignore] Layers in the group and any child groups will not be output.\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Layer names:\n"
|
||||||
|
+ "• [ignore] The layer will not be output."
|
||||||
|
, {multiline: true});
|
||||||
|
helpText.preferredSize.width = 325;
|
||||||
|
|
||||||
|
var closeButton = dialog.add("button", undefined, "Close");
|
||||||
|
closeButton.alignment = ["center", ""];
|
||||||
|
|
||||||
|
closeButton.onClick = function () {
|
||||||
|
dialog.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.center();
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Progress dialog:
|
||||||
|
|
||||||
|
function showProgressDialog () {
|
||||||
|
var dialog = new Window("palette", "PhotoshopToSpine - Processing...");
|
||||||
|
dialog.alignChildren = "fill";
|
||||||
|
dialog.orientation = "column";
|
||||||
|
|
||||||
|
var message = dialog.add("statictext", undefined, "Initializing...");
|
||||||
|
|
||||||
|
var group = dialog.add("group");
|
||||||
|
var bar = group.add("progressbar");
|
||||||
|
bar.preferredSize = [300, 16];
|
||||||
|
bar.maxvalue = 10000;
|
||||||
|
var cancelButton = group.add("button", undefined, "Cancel");
|
||||||
|
|
||||||
|
cancelButton.onClick = function () {
|
||||||
|
cancel = true;
|
||||||
|
cancelButton.enabled = false;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.center();
|
||||||
|
dialog.show();
|
||||||
|
dialog.active = true;
|
||||||
|
|
||||||
|
progress = {
|
||||||
|
dialog: dialog,
|
||||||
|
bar: bar,
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setProgress (percent, layerName) {
|
||||||
|
progress.bar.value = 10000 * percent;
|
||||||
|
progress.message.text = "Layer: " + layerName;
|
||||||
|
if (!progress.dialog.active) progress.dialog.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PhotoshopToSpine utility:
|
||||||
|
|
||||||
|
function unlock (layer) {
|
||||||
|
if (layer.allLocked) layer.allLocked = false;
|
||||||
|
if (!layer.layers) return;
|
||||||
|
for (var i = layer.layers.length - 1; i >= 0; i--)
|
||||||
|
unlock(layer.layers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteLayer (layer) {
|
||||||
|
unlock(layer);
|
||||||
|
activeDocument.activeLayer = activeDocument.artLayers[0];
|
||||||
|
layer.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectLayers (parent, collect) {
|
||||||
|
for (var i = parent.layers.length - 1; i >= 0; i--) {
|
||||||
|
if (cancel) return;
|
||||||
|
var layer = parent.layers[i];
|
||||||
|
if (settings.ignoreHiddenLayers && !layer.visible) {
|
||||||
|
deleteLayer(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (settings.ignoreBackground && layer.isBackgroundLayer) {
|
||||||
|
deleteLayer(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (findTag(layer, "ignore")) {
|
||||||
|
deleteLayer(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var group = isGroup(layer);
|
||||||
|
if (!group && layer.bounds[2] == 0 && layer.bounds[3] == 0) {
|
||||||
|
deleteLayer(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure tags are valid.
|
||||||
|
var re = /\[([^\]]+)\]/g;
|
||||||
|
while (true) {
|
||||||
|
var matches = re.exec(layer.name);
|
||||||
|
if (!matches) break;
|
||||||
|
var tag = matches[1].toLowerCase();
|
||||||
|
if (group) {
|
||||||
|
if (!isValidGroupTag(tag)) {
|
||||||
|
var message = "Invalid group name:\n\n" + layer.name;
|
||||||
|
if (isValidLayerTag(tag))
|
||||||
|
message += "\n\nThe [" + tag + "] tag is only valid for layers, not for groups.";
|
||||||
|
else
|
||||||
|
message += "\n\nThe [" + tag + "] tag is not a valid tag.";
|
||||||
|
alert(message);
|
||||||
|
cancel = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (!isValidLayerTag(tag)) {
|
||||||
|
var message = "Invalid layer name:\n\n" + layer.name;
|
||||||
|
if (isValidGroupTag(tag))
|
||||||
|
message += "\n\nThe [" + tag + "] tag is only valid for groups, not for layers.";
|
||||||
|
else
|
||||||
|
message += "\n\nThe [" + tag + "] tag is not a valid tag.";
|
||||||
|
alert(message);
|
||||||
|
cancel = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure only one tag.
|
||||||
|
if (layer.name.replace(/\[[^\]]+\]/, "").search(/\[[^\]]+\]/) != -1) {
|
||||||
|
alert("A " + (group ? "group" : "layer") + " name must not have more than one tag:\n" + layer.name);
|
||||||
|
cancel = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var changeVisibility = layer.kind == LayerKind.NORMAL || group;
|
||||||
|
if (changeVisibility) {
|
||||||
|
layer.wasVisible = layer.visible;
|
||||||
|
layer.visible = true;
|
||||||
|
if (layer.allLocked) layer.allLocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (group && findTag(layer, "merge")) {
|
||||||
|
collectGroupMerge(layer);
|
||||||
|
if (!layer.layers || layer.layers.length == 0) continue;
|
||||||
|
} else if (layer.layers && layer.layers.length > 0) {
|
||||||
|
collectLayers(layer, collect);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changeVisibility) layer.visible = false;
|
||||||
|
collect.push(layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectGroupMerge (parent) {
|
||||||
|
if (!parent.layers) return;
|
||||||
|
for (var i = parent.layers.length - 1; i >= 0; i--) {
|
||||||
|
var layer = parent.layers[i];
|
||||||
|
if (settings.ignoreHiddenLayers && !layer.visible) {
|
||||||
|
deleteLayer(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (findTag(layer, "ignore")) {
|
||||||
|
deleteLayer(layer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
collectGroupMerge(layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidGroupTag (tag) {
|
||||||
|
switch (tag) {
|
||||||
|
case "bone":
|
||||||
|
case "slot":
|
||||||
|
case "skin":
|
||||||
|
case "merge":
|
||||||
|
case "folder":
|
||||||
|
case "ignore":
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isValidLayerTag (tag) {
|
||||||
|
switch (tag) {
|
||||||
|
case "ignore":
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isGroup (layer) {
|
||||||
|
return layer.typename == "LayerSet";
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripTags (name) {
|
||||||
|
return trim(name.replace(/\[[^\]]+\]/g, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
function findTagLayer (layer, tag) {
|
||||||
|
while (layer) {
|
||||||
|
if (tag == "ignore" || isGroup(layer)) { // Non-group layers can only have ignore tag.
|
||||||
|
if (layer.name.toLowerCase().indexOf("[" + tag + "]") != -1) return layer;
|
||||||
|
}
|
||||||
|
layer = layer.parent;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findTag (layer, tag, otherwise) {
|
||||||
|
var found = findTagLayer(layer, tag);
|
||||||
|
return found ? stripTags(found.name) : otherwise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonPath (jsonPath) {
|
||||||
|
if (endsWith(jsonPath, ".json")) {
|
||||||
|
var index = jsonPath.replace("\\", "/").lastIndexOf("/");
|
||||||
|
if (index != -1) return absolutePath(jsonPath.slice(0, index + 1)) + jsonPath.slice(index + 1);
|
||||||
|
return absolutePath("./") + jsonPath;
|
||||||
|
}
|
||||||
|
var name = decodeURI(originalDoc.name);
|
||||||
|
return absolutePath(jsonPath) + name.substring(0, name.indexOf(".")) + ".json";
|
||||||
|
}
|
||||||
|
|
||||||
|
function folders (layer, path) {
|
||||||
|
var folderLayer = findTagLayer(layer, "folder");
|
||||||
|
return folderLayer ? folders(folderLayer.parent, stripTags(folderLayer.name) + "/" + path) : path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Photoshop utility:
|
||||||
|
|
||||||
|
function scaleImage () {
|
||||||
|
var imageSize = activeDocument.width.as("px") * settings.scale;
|
||||||
|
activeDocument.resizeImage(UnitValue(imageSize, "px"), null, null, ResampleMethod.BICUBICSHARPER);
|
||||||
|
}
|
||||||
|
|
||||||
|
var history;
|
||||||
|
function storeHistory () {
|
||||||
|
history = activeDocument.activeHistoryState;
|
||||||
|
}
|
||||||
|
function restoreHistory () {
|
||||||
|
activeDocument.activeHistoryState = history;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scriptDir () {
|
||||||
|
var file;
|
||||||
|
if (!cs2)
|
||||||
|
file = $.fileName;
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
var error = THROW_ERROR; // Force error which provides the script file name.
|
||||||
|
} catch (ex) {
|
||||||
|
file = ex.fileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new File(file).parent + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasFilePath () {
|
||||||
|
var action = new ActionReference();
|
||||||
|
action.putEnumerated(cID("Dcmn"), cID("Ordn"), cID("Trgt"));
|
||||||
|
return executeActionGet(action).hasKey(sID("fileReference"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function absolutePath (path) {
|
||||||
|
path = trim(path);
|
||||||
|
if (!startsWith(path, "./")) {
|
||||||
|
var absolute = decodeURI(new File(path).absoluteURI);
|
||||||
|
if (!startsWith(absolute, decodeURI(new File("child").parent.absoluteURI))) return absolute + "/";
|
||||||
|
path = "./" + path;
|
||||||
|
}
|
||||||
|
if (path.length == 0)
|
||||||
|
path = decodeURI(activeDocument.path);
|
||||||
|
else if (startsWith(settings.imagesDir, "./"))
|
||||||
|
path = decodeURI(activeDocument.path) + path.substring(1);
|
||||||
|
path = (new File(path).fsName).toString();
|
||||||
|
path = path.replace(/\\/g, "/");
|
||||||
|
if (path.substring(path.length - 1) != "/") path += "/";
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cID (id) {
|
||||||
|
return charIDToTypeID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sID (id) {
|
||||||
|
return stringIDToTypeID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bgColor (control, r, g, b) {
|
||||||
|
control.graphics.backgroundColor = control.graphics.newBrush(control.graphics.BrushType.SOLID_COLOR, [r, g, b]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deselectLayers () {
|
||||||
|
var desc = new ActionDescriptor();
|
||||||
|
var ref = new ActionReference();
|
||||||
|
ref.putEnumerated(cID("Lyr "), cID("Ordn"), cID("Trgt"));
|
||||||
|
desc.putReference(cID("null"), ref);
|
||||||
|
executeAction(sID("selectNoLayers"), desc, DialogModes.NO);
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToRGB () {
|
||||||
|
var desc = new ActionDescriptor();
|
||||||
|
desc.putClass(cID("T "), cID("RGBM"));
|
||||||
|
desc.putBoolean(cID("Mrge"), false);
|
||||||
|
desc.putBoolean(cID("Rstr"), true);
|
||||||
|
executeAction(cID("CnvM"), desc, DialogModes.NO);
|
||||||
|
}
|
||||||
|
|
||||||
|
function savePNG (file) {
|
||||||
|
var options = new PNGSaveOptions();
|
||||||
|
options.compression = 9;
|
||||||
|
activeDocument.saveAs(file, options, true, Extension.LOWERCASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// JavaScript utility:
|
||||||
|
|
||||||
|
function countAssocArray (obj) {
|
||||||
|
var count = 0;
|
||||||
|
for (var key in obj)
|
||||||
|
if (obj.hasOwnProperty(key)) count++;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trim (value) {
|
||||||
|
return value.replace(/^\s+|\s+$/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function startsWith (str, prefix) {
|
||||||
|
return str.indexOf(prefix) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function endsWith (str, suffix) {
|
||||||
|
return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function quote (value) {
|
||||||
|
return '"' + value.replace('"', '\\"') + '"';
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
1、把插件放到PS的这个目录下:\Adobe Photoshop CS6 (64 Bit)\Presets\Scripts\LayersToPNG.jsx
|
||||||
|
(如果PS是开着的,需要重启一下)
|
||||||
|
|
||||||
|
2、PS内启动脚本的方法:“文件”—“脚本”——“LayersTOPNG”
|
||||||
|
|
||||||
|
|
||||||
|
更多spine源文件,max源文件,bip文件和 好用的工具,请关注我
|
||||||
|
B站:做动画的大熊
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#target photoshopapp.bringToFront();
|
||||||
|
if (documents.length == 0) {
|
||||||
|
alert("没有可处理的文档");
|
||||||
|
} else {
|
||||||
|
var visibility = false;
|
||||||
|
var docRef = activeDocument;
|
||||||
|
var layers = docRef.layers;
|
||||||
|
if (layers.length == 1 && docRef.activeLayer.isBackgroundLayer == 1) {
|
||||||
|
alert("The Background layer can not be hidden when it is the only layer in a document.");
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < layers.length; i++) {
|
||||||
|
layers[i].name = "" + [i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,790 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public class DependencyOrganizerWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private List<UnityEngine.Object> draggedAssets = new List<UnityEngine.Object>();
|
||||||
|
private Vector2 prefabScroll;
|
||||||
|
private Vector2 depScroll;
|
||||||
|
|
||||||
|
private Dictionary<string, Dictionary<string, bool>> dependenciesByType = new Dictionary<string, Dictionary<string, bool>>();
|
||||||
|
private Dictionary<string, bool> typeToggle = new Dictionary<string, bool>();
|
||||||
|
private Dictionary<string, bool> typeFoldout = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
private Dictionary<string, bool> filterTypeToggle = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
// 贴图路径 -> HashSet<材质路径>
|
||||||
|
private Dictionary<string, HashSet<string>> textureUsedByMaterials = new Dictionary<string, HashSet<string>>();
|
||||||
|
|
||||||
|
private string targetRootFolder = string.Empty;
|
||||||
|
private string lastOrganizeAbsPath = string.Empty;
|
||||||
|
|
||||||
|
private SortedDictionary<long, string> undoManifests = new SortedDictionary<long, string>();
|
||||||
|
|
||||||
|
private const string UndoManifestDir = "Assets/Editor/DependencyOrganizerUndo";
|
||||||
|
private const string UndoManifestPrefix = "DependencyOrganizerWindow_undo_";
|
||||||
|
|
||||||
|
private Dictionary<string, bool> matsFoldout = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
[MenuItem("Tools/特效依赖整理工具")]
|
||||||
|
public static void ShowWindow()
|
||||||
|
{
|
||||||
|
var w = GetWindow<DependencyOrganizerWindow>("特效依赖整理工具-by很喜欢乱来");
|
||||||
|
w.minSize = new Vector2(700, 700);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
LoadUndoManifests();
|
||||||
|
InitFilterTypeToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitFilterTypeToggle()
|
||||||
|
{
|
||||||
|
string[] filterTypes = new string[] {
|
||||||
|
"Textures", "Materials", "Models", "Shaders", "Scripts",
|
||||||
|
"Prefabs", "Animations", "Animators", "Audio", "Physics", "Others"
|
||||||
|
};
|
||||||
|
foreach (var t in filterTypes)
|
||||||
|
{
|
||||||
|
if (!filterTypeToggle.ContainsKey(t))
|
||||||
|
filterTypeToggle[t] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
GUILayout.Label("依赖整理工具-by很喜欢乱来", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.HelpBox(
|
||||||
|
"1. 拖入Prefab/Scene/ScriptableObject等资源。\n" +
|
||||||
|
"2. 点击“收集依赖资源”,按类型和文件复选。\n" +
|
||||||
|
"3. 支持折叠、全选/反选。\n" +
|
||||||
|
"4. 选择目标根目录(支持拖入文件夹)。\n" +
|
||||||
|
"5. 点击“整理”移动资源,自动避免冲突重命名。\n" +
|
||||||
|
"6. 支持多版本撤销。\n" +
|
||||||
|
"7. 支持导出UnityPackage。\n" +
|
||||||
|
"8. 移动时显示进度条。\n" +
|
||||||
|
"9. 显示资源大小预估。\n" +
|
||||||
|
"10. 资源名点击定位,右键复制资源名。\n" +
|
||||||
|
"11. 贴图资源显示被哪些材质引用,材质路径列表可点击定位。\n",
|
||||||
|
MessageType.Info);
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawFilterTypeToggle();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawDragArea();
|
||||||
|
DrawPrefabList();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (GUILayout.Button("收集依赖资源", GUILayout.Height(30)))
|
||||||
|
CollectDependencies();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawDependenciesList();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawSizeEstimate();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawTargetFolderSelector();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawActionButtons();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
DrawUndoHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawFilterTypeToggle()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
foreach (var key in new List<string>(filterTypeToggle.Keys))
|
||||||
|
{
|
||||||
|
bool val = filterTypeToggle[key];
|
||||||
|
bool newVal = GUILayout.Toggle(val, key, "Button", GUILayout.Height(22));
|
||||||
|
if (newVal != val)
|
||||||
|
{
|
||||||
|
filterTypeToggle[key] = newVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawDragArea()
|
||||||
|
{
|
||||||
|
Rect dropArea = GUILayoutUtility.GetRect(0, 60, GUILayout.ExpandWidth(true));
|
||||||
|
GUI.Box(dropArea, "拖入Prefab/Scene/ScriptableObject/Hierarchy中的GameObject");
|
||||||
|
|
||||||
|
var evt = Event.current;
|
||||||
|
if ((evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform) && dropArea.Contains(evt.mousePosition))
|
||||||
|
{
|
||||||
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||||
|
if (evt.type == EventType.DragPerform)
|
||||||
|
{
|
||||||
|
DragAndDrop.AcceptDrag();
|
||||||
|
foreach (var obj in DragAndDrop.objectReferences)
|
||||||
|
{
|
||||||
|
string path = AssetDatabase.GetAssetPath(obj);
|
||||||
|
|
||||||
|
if (obj is GameObject go)
|
||||||
|
{
|
||||||
|
bool isPrefab = !string.IsNullOrEmpty(path) && path.StartsWith("Assets");
|
||||||
|
if (isPrefab)
|
||||||
|
{
|
||||||
|
if (!draggedAssets.Contains(obj))
|
||||||
|
draggedAssets.Add(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameObject prefabRoot = PrefabUtility.GetCorrespondingObjectFromSource(go);
|
||||||
|
if (prefabRoot != null && !draggedAssets.Contains(prefabRoot))
|
||||||
|
draggedAssets.Add(prefabRoot);
|
||||||
|
else if (!draggedAssets.Contains(obj))
|
||||||
|
draggedAssets.Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IsSupportedAsset(obj, path))
|
||||||
|
{
|
||||||
|
if (!draggedAssets.Contains(obj))
|
||||||
|
draggedAssets.Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evt.Use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsSupportedAsset(UnityEngine.Object obj, string path)
|
||||||
|
{
|
||||||
|
if (obj == null || string.IsNullOrEmpty(path)) return false;
|
||||||
|
return (obj is GameObject && path.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
|
||||||
|
|| path.EndsWith(".unity", StringComparison.OrdinalIgnoreCase)
|
||||||
|
|| obj is ScriptableObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawPrefabList()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("已拖入资源:");
|
||||||
|
if (draggedAssets.Count > 0)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("清空列表", GUILayout.Width(80)))
|
||||||
|
{
|
||||||
|
draggedAssets.Clear();
|
||||||
|
dependenciesByType.Clear();
|
||||||
|
typeToggle.Clear();
|
||||||
|
typeFoldout.Clear();
|
||||||
|
textureUsedByMaterials.Clear();
|
||||||
|
matsFoldout.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prefabScroll = EditorGUILayout.BeginScrollView(prefabScroll, GUILayout.Height(100));
|
||||||
|
for (int i = draggedAssets.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
draggedAssets[i] = EditorGUILayout.ObjectField(draggedAssets[i], typeof(UnityEngine.Object), false);
|
||||||
|
if (GUILayout.Button("移除", GUILayout.Width(60)))
|
||||||
|
draggedAssets.RemoveAt(i);
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CollectDependencies()
|
||||||
|
{
|
||||||
|
dependenciesByType.Clear();
|
||||||
|
typeToggle.Clear();
|
||||||
|
typeFoldout.Clear();
|
||||||
|
textureUsedByMaterials.Clear();
|
||||||
|
matsFoldout.Clear();
|
||||||
|
|
||||||
|
if (draggedAssets.Count == 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "请先拖入至少一个资源。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<string> allDeps = new HashSet<string>();
|
||||||
|
|
||||||
|
foreach (var obj in draggedAssets)
|
||||||
|
{
|
||||||
|
string origPath = AssetDatabase.GetAssetPath(obj);
|
||||||
|
var deps = AssetDatabase.GetDependencies(origPath, true);
|
||||||
|
foreach (var dep in deps)
|
||||||
|
{
|
||||||
|
if (!dep.StartsWith("Assets/") || dep.StartsWith("Assets/Editor/") || dep.Contains("Packages/"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
allDeps.Add(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建贴图->材质引用映射
|
||||||
|
foreach (var dep in allDeps)
|
||||||
|
{
|
||||||
|
Type type = AssetDatabase.GetMainAssetTypeAtPath(dep);
|
||||||
|
if (type == typeof(Material))
|
||||||
|
{
|
||||||
|
Material mat = AssetDatabase.LoadAssetAtPath<Material>(dep);
|
||||||
|
if (mat == null) continue;
|
||||||
|
|
||||||
|
Shader shader = mat.shader;
|
||||||
|
int propertyCount = ShaderUtil.GetPropertyCount(shader);
|
||||||
|
for (int i = 0; i < propertyCount; i++)
|
||||||
|
{
|
||||||
|
if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
|
||||||
|
{
|
||||||
|
string propName = ShaderUtil.GetPropertyName(shader, i);
|
||||||
|
Texture tex = mat.GetTexture(propName);
|
||||||
|
if (tex != null)
|
||||||
|
{
|
||||||
|
string texPath = AssetDatabase.GetAssetPath(tex);
|
||||||
|
if (!string.IsNullOrEmpty(texPath))
|
||||||
|
{
|
||||||
|
if (!textureUsedByMaterials.TryGetValue(texPath, out var mats))
|
||||||
|
{
|
||||||
|
mats = new HashSet<string>();
|
||||||
|
textureUsedByMaterials[texPath] = mats;
|
||||||
|
}
|
||||||
|
mats.Add(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var dep in allDeps)
|
||||||
|
{
|
||||||
|
Type type = AssetDatabase.GetMainAssetTypeAtPath(dep);
|
||||||
|
string folder = GetTargetFolder(type, dep);
|
||||||
|
|
||||||
|
if (!dependenciesByType.ContainsKey(folder))
|
||||||
|
dependenciesByType[folder] = new Dictionary<string, bool>();
|
||||||
|
|
||||||
|
if (!dependenciesByType[folder].ContainsKey(dep))
|
||||||
|
dependenciesByType[folder][dep] = true;
|
||||||
|
|
||||||
|
if (!typeToggle.ContainsKey(folder))
|
||||||
|
typeToggle[folder] = true;
|
||||||
|
|
||||||
|
if (!typeFoldout.ContainsKey(folder))
|
||||||
|
typeFoldout[folder] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawDependenciesList()
|
||||||
|
{
|
||||||
|
if (dependenciesByType.Count == 0) return;
|
||||||
|
|
||||||
|
float availableHeight = position.height - 550f;
|
||||||
|
if (availableHeight < 150f) availableHeight = 150f;
|
||||||
|
|
||||||
|
depScroll = EditorGUILayout.BeginScrollView(depScroll, GUILayout.Height(availableHeight));
|
||||||
|
foreach (var kvp in dependenciesByType)
|
||||||
|
{
|
||||||
|
string type = kvp.Key;
|
||||||
|
var filesDict = kvp.Value;
|
||||||
|
|
||||||
|
if (!filterTypeToggle.TryGetValue(type, out bool showType) || !showType)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!typeFoldout.ContainsKey(type)) typeFoldout[type] = false;
|
||||||
|
if (!typeToggle.ContainsKey(type)) typeToggle[type] = true;
|
||||||
|
|
||||||
|
EditorGUILayout.BeginVertical("box");
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
typeFoldout[type] = EditorGUILayout.Foldout(typeFoldout[type], $"{type} ({filesDict.Count})", true);
|
||||||
|
|
||||||
|
if (GUILayout.Button("全选", GUILayout.Width(40)))
|
||||||
|
{
|
||||||
|
typeToggle[type] = true;
|
||||||
|
foreach (var k in filesDict.Keys.ToList())
|
||||||
|
filesDict[k] = true;
|
||||||
|
}
|
||||||
|
if (GUILayout.Button("反选", GUILayout.Width(40)))
|
||||||
|
{
|
||||||
|
bool allSelected = filesDict.Values.All(v => v);
|
||||||
|
foreach (var k in filesDict.Keys.ToList())
|
||||||
|
filesDict[k] = !allSelected;
|
||||||
|
typeToggle[type] = filesDict.Values.Any(v => v);
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
bool newTypeToggle = EditorGUILayout.ToggleLeft("选择该类型全部文件", typeToggle[type]);
|
||||||
|
if (newTypeToggle != typeToggle[type])
|
||||||
|
{
|
||||||
|
typeToggle[type] = newTypeToggle;
|
||||||
|
foreach (var k in filesDict.Keys.ToList())
|
||||||
|
filesDict[k] = newTypeToggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeFoldout[type])
|
||||||
|
{
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
foreach (var fileKey in filesDict.Keys.ToList())
|
||||||
|
{
|
||||||
|
bool selected = filesDict[fileKey];
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal(GUILayout.Height(22));
|
||||||
|
|
||||||
|
GUILayout.Space(6 * (EditorGUI.indentLevel - 1));
|
||||||
|
|
||||||
|
Rect toggleRect = GUILayoutUtility.GetRect(24, 22, GUILayout.Width(24));
|
||||||
|
bool newSelected = EditorGUI.Toggle(toggleRect, selected);
|
||||||
|
if (newSelected != selected)
|
||||||
|
filesDict[fileKey] = newSelected;
|
||||||
|
|
||||||
|
if (!newSelected)
|
||||||
|
GUI.enabled = false;
|
||||||
|
|
||||||
|
string fileName = Path.GetFileName(fileKey);
|
||||||
|
GUIContent fileNameContent = new GUIContent(fileName);
|
||||||
|
Vector2 fileNameSize = EditorStyles.boldLabel.CalcSize(fileNameContent);
|
||||||
|
float fileNameWidth = Mathf.Min(fileNameSize.x, 200);
|
||||||
|
|
||||||
|
GUILayout.Space(6);
|
||||||
|
|
||||||
|
Rect fileNameRect = GUILayoutUtility.GetRect(fileNameWidth, 22, GUILayout.Width(fileNameWidth));
|
||||||
|
GUI.Label(fileNameRect, fileName, EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && fileNameRect.Contains(Event.current.mousePosition))
|
||||||
|
{
|
||||||
|
var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fileKey);
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
EditorGUIUtility.PingObject(obj);
|
||||||
|
Event.current.Use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Event.current.type == EventType.ContextClick && fileNameRect.Contains(Event.current.mousePosition))
|
||||||
|
{
|
||||||
|
Event.current.Use();
|
||||||
|
GenericMenu menu = new GenericMenu();
|
||||||
|
menu.AddItem(new GUIContent("复制资源名称"), false, () =>
|
||||||
|
{
|
||||||
|
GUIUtility.systemCopyBuffer = fileName;
|
||||||
|
});
|
||||||
|
menu.ShowAsContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
GUILayout.Label(fileKey, EditorStyles.miniLabel, GUILayout.ExpandWidth(true));
|
||||||
|
|
||||||
|
if (GUILayout.Button("定位", GUILayout.Width(60)))
|
||||||
|
{
|
||||||
|
var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(fileKey);
|
||||||
|
if (obj != null)
|
||||||
|
EditorGUIUtility.PingObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newSelected)
|
||||||
|
GUI.enabled = true;
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
if (textureUsedByMaterials.TryGetValue(fileKey, out var mats) && mats.Count > 0)
|
||||||
|
{
|
||||||
|
if (!matsFoldout.ContainsKey(fileKey)) matsFoldout[fileKey] = false;
|
||||||
|
|
||||||
|
Rect foldoutRect = GUILayoutUtility.GetRect(130, EditorGUIUtility.singleLineHeight);
|
||||||
|
matsFoldout[fileKey] = EditorGUI.Foldout(foldoutRect, matsFoldout[fileKey], $"引用于 {mats.Count} 个材质", true);
|
||||||
|
|
||||||
|
if (matsFoldout[fileKey])
|
||||||
|
{
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
foreach (var matPath in mats)
|
||||||
|
{
|
||||||
|
Rect matRect = GUILayoutUtility.GetRect(20, 18);
|
||||||
|
GUILayout.Space(6 * (EditorGUI.indentLevel - 1));
|
||||||
|
if (GUI.Button(matRect, matPath, EditorStyles.linkLabel))
|
||||||
|
{
|
||||||
|
var matObj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(matPath);
|
||||||
|
if (matObj != null)
|
||||||
|
EditorGUIUtility.PingObject(matObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSizeEstimate()
|
||||||
|
{
|
||||||
|
long totalBytes = 0;
|
||||||
|
foreach (var kvp in dependenciesByType)
|
||||||
|
{
|
||||||
|
foreach (var path in kvp.Value.Keys)
|
||||||
|
{
|
||||||
|
string absPath = Path.Combine(Application.dataPath, path.Substring("Assets/".Length));
|
||||||
|
if (File.Exists(absPath))
|
||||||
|
{
|
||||||
|
totalBytes += new FileInfo(absPath).Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorGUILayout.LabelField($"预估待移动资源大小: {totalBytes / 1024f / 1024f:F2} MB");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTargetFolderSelector()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUILayout.LabelField("目标根目录:", GUILayout.Width(80));
|
||||||
|
|
||||||
|
GUIStyle boxStyle = GUI.skin.box;
|
||||||
|
Rect dragRect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth - 100, EditorGUIUtility.singleLineHeight + 6);
|
||||||
|
GUI.Box(dragRect, "", boxStyle);
|
||||||
|
|
||||||
|
GUI.Label(dragRect, string.IsNullOrEmpty(targetRootFolder) ? "<拖入目标根目录文件夹>" : targetRootFolder, EditorStyles.label);
|
||||||
|
|
||||||
|
Event evt = Event.current;
|
||||||
|
if ((evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform) && dragRect.Contains(evt.mousePosition))
|
||||||
|
{
|
||||||
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
||||||
|
|
||||||
|
if (evt.type == EventType.DragPerform)
|
||||||
|
{
|
||||||
|
DragAndDrop.AcceptDrag();
|
||||||
|
|
||||||
|
if (DragAndDrop.objectReferences.Length > 0)
|
||||||
|
{
|
||||||
|
UnityEngine.Object obj = DragAndDrop.objectReferences[0];
|
||||||
|
string path = AssetDatabase.GetAssetPath(obj);
|
||||||
|
if (AssetDatabase.IsValidFolder(path))
|
||||||
|
{
|
||||||
|
targetRootFolder = path;
|
||||||
|
evt.Use();
|
||||||
|
EditorGUIUtility.ExitGUI();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
|
||||||
|
{
|
||||||
|
string firstPath = DragAndDrop.paths[0];
|
||||||
|
if (Directory.Exists(firstPath))
|
||||||
|
{
|
||||||
|
string absDataPath = Application.dataPath.Replace("/", "\\");
|
||||||
|
string absFirstPath = firstPath.Replace("/", "\\");
|
||||||
|
|
||||||
|
if (absFirstPath.StartsWith(absDataPath))
|
||||||
|
{
|
||||||
|
string relativePath = "Assets" + absFirstPath.Substring(absDataPath.Length);
|
||||||
|
targetRootFolder = relativePath.Replace("\\", "/");
|
||||||
|
evt.Use();
|
||||||
|
EditorGUIUtility.ExitGUI();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evt.Use();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
evt.Use();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawActionButtons()
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
if (GUILayout.Button("整理", GUILayout.Height(30))) MoveSelectedDependencies();
|
||||||
|
if (GUILayout.Button("导出 UnityPackage", GUILayout.Height(30))) ExportPackage();
|
||||||
|
if (GUILayout.Button("撤销", GUILayout.Height(30))) ShowUndoMenu();
|
||||||
|
if (!string.IsNullOrEmpty(lastOrganizeAbsPath) && GUILayout.Button("打开生成路径", GUILayout.Height(30)))
|
||||||
|
EditorUtility.RevealInFinder(lastOrganizeAbsPath);
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawUndoHistory()
|
||||||
|
{
|
||||||
|
if (undoManifests.Count == 0)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("暂无撤销历史");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EditorGUILayout.LabelField("撤销历史记录:");
|
||||||
|
foreach (var kvp in undoManifests.Reverse())
|
||||||
|
{
|
||||||
|
string label = DateTimeOffset.FromUnixTimeMilliseconds(kvp.Key).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
EditorGUILayout.LabelField(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowUndoMenu()
|
||||||
|
{
|
||||||
|
if (undoManifests.Count == 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "没有可用的撤销记录。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GenericMenu menu = new GenericMenu();
|
||||||
|
foreach (var kvp in undoManifests.Reverse())
|
||||||
|
{
|
||||||
|
string label = DateTimeOffset.FromUnixTimeMilliseconds(kvp.Key).ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss");
|
||||||
|
string path = kvp.Value;
|
||||||
|
menu.AddItem(new GUIContent(label), false, () =>
|
||||||
|
{
|
||||||
|
UndoMoveAssets(path);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
menu.ShowAsContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UndoMoveAssets(string manifestPath)
|
||||||
|
{
|
||||||
|
if (!File.Exists(manifestPath))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("错误", "撤销文件不存在。", "确定");
|
||||||
|
RemoveManifestByPath(manifestPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string json = File.ReadAllText(manifestPath);
|
||||||
|
var manifest = JsonUtility.FromJson<MoveManifest>(json);
|
||||||
|
if (manifest == null || manifest.entries == null)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("错误", "撤销文件格式错误。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetDatabase.StartAssetEditing();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var e in manifest.entries.Reverse())
|
||||||
|
{
|
||||||
|
if (AssetDatabase.MoveAsset(e.destPath, e.originalPath).Length == 0)
|
||||||
|
Debug.Log($"已恢复 {e.destPath}");
|
||||||
|
else
|
||||||
|
Debug.LogWarning($"恢复失败或路径冲突: {e.destPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
AssetDatabase.StopAssetEditing();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
File.Delete(manifestPath);
|
||||||
|
RemoveManifestByPath(manifestPath);
|
||||||
|
EditorUtility.DisplayDialog("撤销完成", "资源已恢复。", "确定");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveManifestByPath(string manifestPath)
|
||||||
|
{
|
||||||
|
var keysToRemove = undoManifests.Where(kvp => kvp.Value == manifestPath).Select(kvp => kvp.Key).ToList();
|
||||||
|
foreach (var key in keysToRemove)
|
||||||
|
undoManifests.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadUndoManifests()
|
||||||
|
{
|
||||||
|
undoManifests.Clear();
|
||||||
|
if (!AssetDatabase.IsValidFolder(UndoManifestDir))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string fullDir = Path.Combine(Application.dataPath, "Editor/DependencyOrganizerUndo");
|
||||||
|
if (!Directory.Exists(fullDir))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var file in Directory.GetFiles(fullDir, UndoManifestPrefix + "*.json"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string fileName = Path.GetFileNameWithoutExtension(file);
|
||||||
|
string timestampStr = fileName.Substring(UndoManifestPrefix.Length);
|
||||||
|
if (long.TryParse(timestampStr, out long ts))
|
||||||
|
undoManifests[ts] = file;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveSelectedDependencies()
|
||||||
|
{
|
||||||
|
if (draggedAssets.Count == 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "请先拖入至少一个资源。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dependenciesByType.Count == 0)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("提示", "请先收集依赖资源。", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AssetDatabase.IsValidFolder(UndoManifestDir))
|
||||||
|
AssetDatabase.CreateFolder("Assets/Editor", "DependencyOrganizerUndo");
|
||||||
|
|
||||||
|
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
string manifestFile = $"{UndoManifestDir}/{UndoManifestPrefix}{timestamp}.json";
|
||||||
|
|
||||||
|
List<MoveEntry> moves = new List<MoveEntry>();
|
||||||
|
List<(string originalPath, string destPath)> movesToDo = new List<(string, string)>();
|
||||||
|
|
||||||
|
AssetDatabase.StartAssetEditing();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var obj in draggedAssets)
|
||||||
|
{
|
||||||
|
string origPath = AssetDatabase.GetAssetPath(obj);
|
||||||
|
string root;
|
||||||
|
if (!string.IsNullOrEmpty(targetRootFolder) && AssetDatabase.IsValidFolder(targetRootFolder))
|
||||||
|
{
|
||||||
|
root = targetRootFolder;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string exportBase = "Assets/export";
|
||||||
|
if (!AssetDatabase.IsValidFolder(exportBase))
|
||||||
|
AssetDatabase.CreateFolder("Assets", "export");
|
||||||
|
string name = Path.GetFileNameWithoutExtension(origPath);
|
||||||
|
root = $"{exportBase}/{name}";
|
||||||
|
if (!AssetDatabase.IsValidFolder(root))
|
||||||
|
AssetDatabase.CreateFolder(exportBase, name);
|
||||||
|
}
|
||||||
|
lastOrganizeAbsPath = Path.GetFullPath(root);
|
||||||
|
|
||||||
|
var deps = AssetDatabase.GetDependencies(origPath, true);
|
||||||
|
|
||||||
|
foreach (var dep in deps)
|
||||||
|
{
|
||||||
|
if (!dep.StartsWith("Assets/") || dep.StartsWith("Assets/Editor/") || dep.Contains("Packages/"))
|
||||||
|
continue;
|
||||||
|
if (movesToDo.Any(m => m.destPath == dep) || dep.StartsWith(root + "/"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Type type = AssetDatabase.GetMainAssetTypeAtPath(dep);
|
||||||
|
string folder = GetTargetFolder(type, dep);
|
||||||
|
|
||||||
|
if (!dependenciesByType.TryGetValue(folder, out var filesDict))
|
||||||
|
continue;
|
||||||
|
if (!filesDict.TryGetValue(dep, out bool moveThis) || !moveThis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string dstDir = $"{root}/{folder}";
|
||||||
|
if (!AssetDatabase.IsValidFolder(dstDir))
|
||||||
|
AssetDatabase.CreateFolder(root, folder);
|
||||||
|
|
||||||
|
string dst = GetUniqueAssetPath($"{dstDir}/{Path.GetFileName(dep)}");
|
||||||
|
movesToDo.Add((dep, dst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int total = movesToDo.Count;
|
||||||
|
for (int i = 0; i < total; i++)
|
||||||
|
{
|
||||||
|
var (src, dst) = movesToDo[i];
|
||||||
|
EditorUtility.DisplayProgressBar("移动资源", $"正在移动 {Path.GetFileName(src)} ({i + 1}/{total})", (float)i / total);
|
||||||
|
string err = AssetDatabase.MoveAsset(src, dst);
|
||||||
|
if (string.IsNullOrEmpty(err))
|
||||||
|
moves.Add(new MoveEntry(src, dst));
|
||||||
|
else
|
||||||
|
Debug.LogWarning($"移动失败: {src} -> {dst},错误:{err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
EditorUtility.ClearProgressBar();
|
||||||
|
AssetDatabase.StopAssetEditing();
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(manifestFile, JsonUtility.ToJson(new MoveManifest { entries = moves.ToArray() }, true));
|
||||||
|
AssetDatabase.ImportAsset(manifestFile);
|
||||||
|
LoadUndoManifests();
|
||||||
|
|
||||||
|
EditorUtility.DisplayDialog("整理完成", $"共移动 {moves.Count} 个资源,存放于 {(!string.IsNullOrEmpty(targetRootFolder) ? targetRootFolder : "Assets/export")}", "确定");
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetTargetFolder(Type type, string path)
|
||||||
|
{
|
||||||
|
string ext = Path.GetExtension(path).ToLowerInvariant();
|
||||||
|
if (new[] { ".cs" }.Contains(ext)) return "Scripts";
|
||||||
|
if (new[] { ".fbx", ".obj", ".blend" }.Contains(ext)) return "Models";
|
||||||
|
if (new[] { ".anim" }.Contains(ext) || type == typeof(AnimationClip)) return "Animations";
|
||||||
|
if (new[] { ".controller" }.Contains(ext) || type == typeof(UnityEditor.Animations.AnimatorController)) return "Animators";
|
||||||
|
if (new[] { ".shader", ".shadergraph" }.Contains(ext) || type == typeof(Shader)) return "Shaders";
|
||||||
|
if (new[] { ".png", ".jpg", ".jpeg", ".tga", ".psd", ".exr" }.Contains(ext) || type == typeof(Texture2D)) return "Textures";
|
||||||
|
if (new[] { ".wav", ".mp3", ".ogg" }.Contains(ext) || type == typeof(AudioClip)) return "Audio";
|
||||||
|
if (ext == ".mat" || type == typeof(Material)) return "Materials";
|
||||||
|
if (ext == ".physicmaterial" || type == typeof(PhysicMaterial)) return "Physics";
|
||||||
|
if (ext == ".prefab" || type == typeof(GameObject)) return "Prefabs";
|
||||||
|
return "Others";
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetUniqueAssetPath(string desiredPath)
|
||||||
|
{
|
||||||
|
string path = desiredPath;
|
||||||
|
string dir = Path.GetDirectoryName(desiredPath);
|
||||||
|
string filename = Path.GetFileNameWithoutExtension(desiredPath);
|
||||||
|
string ext = Path.GetExtension(desiredPath);
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
while (AssetPathExists(path))
|
||||||
|
{
|
||||||
|
path = $"{dir}/{filename}_{count}{ext}";
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool AssetPathExists(string path)
|
||||||
|
{
|
||||||
|
return AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExportPackage()
|
||||||
|
{
|
||||||
|
string exportRel = !string.IsNullOrEmpty(targetRootFolder) && AssetDatabase.IsValidFolder(targetRootFolder)
|
||||||
|
? targetRootFolder : "Assets/export";
|
||||||
|
if (!AssetDatabase.IsValidFolder(exportRel))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("错误", $"导出目录无效:{exportRel}", "确定");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var guids = AssetDatabase.FindAssets("", new[] { exportRel });
|
||||||
|
var paths = guids.Select(AssetDatabase.GUIDToAssetPath).ToArray();
|
||||||
|
string save = EditorUtility.SaveFilePanel("保存 UnityPackage", Application.dataPath, "Package.unitypackage", "unitypackage");
|
||||||
|
if (string.IsNullOrEmpty(save)) return;
|
||||||
|
AssetDatabase.ExportPackage(paths, save, ExportPackageOptions.Default);
|
||||||
|
EditorUtility.DisplayDialog("导出成功", $"已导出 {paths.Length} 个资源到 {save}", "确定");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
private class MoveEntry
|
||||||
|
{
|
||||||
|
public string originalPath;
|
||||||
|
public string destPath;
|
||||||
|
public MoveEntry(string o, string d) { originalPath = o; destPath = d; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
private class MoveManifest
|
||||||
|
{
|
||||||
|
public MoveEntry[] entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
1.DependencyOrganizer.cs
|
||||||
|
脚本需要放在unity工程的Asset/Editor下面,然后菜单工具栏(Tool)下面会出现相关工具按钮
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
bip=$.controller
|
||||||
|
|
||||||
|
--a=$'Bip002 R Thigh'.Controller
|
||||||
|
|
||||||
|
--biped.saveBipFile bip "C:\Users\ab\Desktop\savetest.bip"
|
||||||
|
--biped.loadBipFile bip "C:\Users\ab\Desktop\savetest.bip"
|
||||||
|
|
||||||
|
--biped.clearAllAnimation bip
|
||||||
|
--biped.mirror bip
|
||||||
|
|
||||||
|
biped.copyPosture bip (#pose) 1 1 1
|
||||||
|
--biped.pastePosture bip #posture 0 "0001"
|
||||||
|
|
||||||
|
--biped.loadCopyPasteFile bip "C:\Users\ab\Desktop\savetest.cpy"
|
||||||
|
--biped.saveCopyPasteFile bip "C:\Users\ab\Desktop\savetest1.cpy"
|
||||||
|
|
||||||
|
--biped.numCopies bip #pose
|
||||||
|
|
||||||
|
--biped.deleteCopy bip #posture "abc"
|
||||||
|
--biped.setCopyName bip #posture 2 "def"
|
||||||
|
|
||||||
|
--biped.getCopyName bip #posture 1
|
||||||
|
|
||||||
|
--biped.createCopyCollection bip "ghi"
|
||||||
|
|
||||||
|
--biped.numCopyCollections bip
|
||||||
|
|
||||||
|
--collection001=biped.getCopyCollection bip 1
|
||||||
|
|
||||||
|
--biped.deleteCopyCollection bip 1
|
||||||
|
--arr=#()
|
||||||
|
--biped.copyBipPosture bip collection001 arr #snapview
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--coll=biped.createCopyCollection bip abc
|
||||||
|
--biped.copyBipPose bip 1 1
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
nums=3
|
||||||
|
b=$Point001
|
||||||
|
c=$Point002
|
||||||
|
a=#()
|
||||||
|
a[1]=b
|
||||||
|
|
||||||
|
for i=1 to (nums-1) do
|
||||||
|
(
|
||||||
|
a[i+1]=point()
|
||||||
|
|
||||||
|
a[i+1].pos=(i*c.pos+(nums-i)*b.pos)/nums
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
a[nums+1]=c
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
OpzeyetgcunSGXfRDPnbhvl4Y4U0n8oNolqvWh4xtwWHUoar5xpJGlx8WQ07J02/Xt9CH2qpPNBcO8Rep8GOxez8SUPzEw8xSQxpkHoIHvsdNiBDZCxQTZU5MaB/8SfuTESosGV3p5AQ2aqFaKrpGABBSGebgfL75uDHmSFq8ME=
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<RSAKeyValue><Modulus>zyQ7zokCM/wHwJrb89hKyzC4LTPDCvR7qw8sIuJLGsbPJqJReTgAxxDyZNrIobDjO2M5OaCljSP2VDv6lxwMG8wNlyKoy5opBtWjUtZgc+/H54hppLGmgaWR3pYmojEomHw5gmFdAWZpz42yf3QO4ehYIVHuOpeXJpBpdEgrY2k=</Modulus><Exponent>AQAB</Exponent><P>4lUl/1Skw5S3xuXSh3gYzVQFyqAsrnJeENQxJ8Abx1PR2Gck+wkcadaqdRD+9sLeff9rsVwAObGAGzfQ2mBzow==</P><Q>6ksbSrCw14U2XOWrLyQynyodtHYBoMQRfS0uUTwJutCgb+Rfe56Lfv4nUXnC/GpiZkuXnZsKcLNvyB1PQtpdgw==</Q><DP>T3/xNNqadUiLtQWNCaCZtaXJ0v6oMy5g9DBUg83q8/zxPL4eMz9kB5krjqtFo4+Xb1KElWvneFxszyKv7cTrWQ==</DP><DQ>4oSO9F1z/Er8zj/2i3NRxfSwF4Nn+4jU59NAzqVfOtDt7IA9mIUmlTcfyHQSgnxQelpnUadOJrw1PKKpuRbqBQ==</DQ><InverseQ>IXxMkGm2cn7esrIdZBTXv8gOmV8DBP3ERleT3VBUfyR4Qa1uhJ8agGZdDm/TcLlte45uUHhgPJuSYvjLo7ZLBA==</InverseQ><D>yY2vKAtGeoC8plvIs998/3M7crhQC2PSxaKwxoy8maRjQmtkrXehwhEqWppL6JDuugWVVA6Np+UbNeFatxhSaiWRJJv0iccR0GyT38vWGbmN2FNew+2KsP/+2MDva3z8o5OZ+p0bsqUwiTL05z71zK/dd5tZHGhHmM4W3sMdbKU=</D></RSAKeyValue>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
-- 使用私钥进行解密的函数
|
||||||
|
fn decryptWithPrivateKey encryptedData privateKey =
|
||||||
|
(
|
||||||
|
rsaProvider = dotnetobject "System.Security.Cryptography.RSACryptoServiceProvider"
|
||||||
|
rsaProvider.FromXmlString(privateKey)
|
||||||
|
methodprivatekey = (dotnetclass "System.Security.Cryptography.RSAEncryptionPadding").Pkcs1
|
||||||
|
|
||||||
|
try(
|
||||||
|
-- 使用私钥解密字节数组
|
||||||
|
decryptedBytes = rsaProvider.Decrypt encryptedData methodprivatekey
|
||||||
|
|
||||||
|
-- 将字节数组转换为文本
|
||||||
|
decryptedText = (dotnetclass "System.Text.Encoding").UTF8.GetString(decryptedBytes)
|
||||||
|
|
||||||
|
return decryptedText)catch(return "解密错误!!!")
|
||||||
|
)
|
||||||
|
|
||||||
|
-- 从文件中读取加密后的数据
|
||||||
|
encryptedDataFilePath = getFilenamePath(getThisScriptFilename()) + "data.txt"
|
||||||
|
streamReader = dotnetobject "System.IO.StreamReader" encryptedDataFilePath
|
||||||
|
|
||||||
|
encryptedData = (dotnetclass "System.Convert").FromBase64String(streamReader.ReadLine())
|
||||||
|
streamReader.Close()
|
||||||
|
|
||||||
|
-- 从文件中读取私钥
|
||||||
|
privateKeyFilePath = getFilenamePath(getThisScriptFilename()) + "privateKey.xml"
|
||||||
|
streamReader = dotnetobject "System.IO.StreamReader" privateKeyFilePath
|
||||||
|
privateKey = streamReader.ReadToEnd()
|
||||||
|
streamReader.Close()
|
||||||
|
|
||||||
|
-- 示例:使用私钥解密之前加密的数据
|
||||||
|
decryptedText = decryptWithPrivateKey encryptedData privateKey
|
||||||
|
|
||||||
|
-- 输出解密后的数据
|
||||||
|
print decryptedText
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
-- 使用非对称加密进行加密的函数
|
||||||
|
fn encryptWithPublicKey plaintext publicKey =
|
||||||
|
(
|
||||||
|
rsaProvider = dotnetobject "System.Security.Cryptography.RSACryptoServiceProvider"
|
||||||
|
rsaProvider.FromXmlString(publicKey)
|
||||||
|
methodpublickey = (dotnetclass "System.Security.Cryptography.RSAEncryptionPadding").Pkcs1
|
||||||
|
|
||||||
|
-- 将文本转换为字节数组
|
||||||
|
plaintextBytes = (dotnetclass "System.Text.Encoding").UTF8.GetBytes(plaintext)
|
||||||
|
|
||||||
|
-- 使用公钥加密字节数组
|
||||||
|
encryptedData = rsaProvider.Encrypt plaintextBytes methodpublickey
|
||||||
|
|
||||||
|
|
||||||
|
return encryptedData
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
-- 要加密的文字内容
|
||||||
|
plaintext = "我是机密,不能告诉其他人。"
|
||||||
|
|
||||||
|
-- 生成公钥和私钥
|
||||||
|
rsaProvider = dotnetobject "System.Security.Cryptography.RSACryptoServiceProvider"
|
||||||
|
publicKey = rsaProvider.ToXmlString(false)
|
||||||
|
privateKey = rsaProvider.ToXmlString(true)
|
||||||
|
|
||||||
|
-- 将私钥保存到文件
|
||||||
|
privateKeyFilePath = getFilenamePath(getThisScriptFilename()) +"privateKey.xml"
|
||||||
|
streamWriter = dotnetobject "System.IO.StreamWriter" privateKeyFilePath
|
||||||
|
streamWriter.WriteLine(privateKey)
|
||||||
|
streamWriter.Close()
|
||||||
|
|
||||||
|
|
||||||
|
-- 使用公钥加密
|
||||||
|
encryptedData = encryptWithPublicKey plaintext publicKey
|
||||||
|
|
||||||
|
-- 将加密后的字节数组转换为Base64字符串
|
||||||
|
encryptedDataString = (dotnetclass "System.Convert").ToBase64String(encryptedData)
|
||||||
|
|
||||||
|
-- 将加密后的数据保存到文件
|
||||||
|
encryptedDataFilePath = getFilenamePath(getThisScriptFilename()) +"data.txt"
|
||||||
|
streamWriter = dotnetobject "System.IO.StreamWriter" encryptedDataFilePath
|
||||||
|
streamWriter.WriteLine(encryptedDataString)
|
||||||
|
streamWriter.Close()
|
||||||
@@ -0,0 +1,408 @@
|
|||||||
|
/*
|
||||||
|
编写代码注意事项:
|
||||||
|
1.控件移除后,不可访问任何属性以及数值
|
||||||
|
2.子栏目的高度固定为600,添加到子栏目后,原卷展栏的高度会失效
|
||||||
|
*/
|
||||||
|
|
||||||
|
if RigToolUI != undefined do (try(destroydialog RigToolUI)catch())
|
||||||
|
|
||||||
|
|
||||||
|
global L_rollout=#() --左侧子栏目
|
||||||
|
global R_rollout=#() --右侧子栏目
|
||||||
|
|
||||||
|
fn remove_L_rollout= --移除左侧子栏目
|
||||||
|
(
|
||||||
|
local ui_height=RigToolUI.height
|
||||||
|
|
||||||
|
for i=1 to L_rollout.count do removesubrollout RigToolUI.RTleft L_rollout[i]
|
||||||
|
free L_rollout
|
||||||
|
if (ui_height>=600) and (L_rollout.count==0) and (R_rollout.count==0) then RigToolUI.height -=600
|
||||||
|
)
|
||||||
|
|
||||||
|
fn remove_R_rollout= --移除右侧子栏目
|
||||||
|
(
|
||||||
|
local ui_height=RigToolUI.height
|
||||||
|
|
||||||
|
for i=1 to R_rollout.count do removesubrollout RigToolUI.RTright R_rollout[i]
|
||||||
|
free R_rollout
|
||||||
|
if (ui_height>=600) and (L_rollout.count==0) and (R_rollout.count==0) then RigToolUI.height -=600
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout NewRig "新建绑定" width:300 height:600
|
||||||
|
(
|
||||||
|
|
||||||
|
--bitmap bmp1 "Bitmap" pos:[10,10] width:285 height:140 align:#center fileName:("C:\Users\ab\Desktop\RigTool\ctrlcolor\mainabout.png") --bitmap:(bitmap 285 140 color:[255,255,255])
|
||||||
|
|
||||||
|
label lab01 "请输入新绑定名称:"
|
||||||
|
edittext cus_rig_name "" width:250 align:#center
|
||||||
|
button apply_name "确定" width:50 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout setupmodules "模块创建" width:318 height:300
|
||||||
|
(
|
||||||
|
GroupBox RTspline "条带样条线模块(脖子,脊椎)" width:290 height:120 pos:[10,10]
|
||||||
|
edittext pre_spline_name "名称" pos:[30,30] width:250
|
||||||
|
spinner spline_joints "关节数量" pos:[30,50] width:250 range:[0,100,3] type:#integer
|
||||||
|
radiobuttons spline_twisk "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,70] columns:2
|
||||||
|
checkbox spline_mirror "镜像模块" pos:[210,70] checked:false
|
||||||
|
button creatspline "创建条带" pos:[80,90] width:150 height:30
|
||||||
|
button spline_help "说明" pos:[250,90] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTarms "手臂模块" width:290 height:180 pos:[10,140]
|
||||||
|
edittext pre_arm_name "名称" pos:[30,160] width:250
|
||||||
|
spinner upperarm_twistjoints "上臂扭曲骨骼" pos:[30,180] width:250 range:[0,100,2] type:#integer
|
||||||
|
spinner lowerarm_twistjoints "下臂扭曲骨骼" pos:[30,200] width:250 range:[0,100,2] type:#integer
|
||||||
|
radiobuttons arm_elbow_joints "" labels:#("单肘部关节","双肘部关节") pos:[30,220] columns:2
|
||||||
|
spinner midarm_twistjoints "中部扭曲骨骼" pos:[30,240] width:250 range:[0,100,2] type:#integer enabled:false
|
||||||
|
radiobuttons arm_mirror "" labels:#("仅左臂","双臂","仅右臂") pos:[30,260] default:2 columns:3
|
||||||
|
button creatarm "创建手臂" pos:[80,280] width:150 height:30
|
||||||
|
button arm_help "说明" pos:[250,280] width:35 height:30
|
||||||
|
|
||||||
|
on arm_elbow_joints changed sel do
|
||||||
|
if sel==2 then midarm_twistjoints.enabled=true else midarm_twistjoints.enabled=false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTlegs "腿部模块" width:290 height:180 pos:[10,330]
|
||||||
|
edittext pre_leg_name "名称" pos:[30,350] width:250
|
||||||
|
spinner upperleg_twistjoints "大腿扭曲骨骼" pos:[30,370] width:250 range:[0,100,2] type:#integer
|
||||||
|
spinner lowerleg_twistjoints "小腿扭曲骨骼" pos:[30,390] width:250 range:[0,100,2] type:#integer
|
||||||
|
radiobuttons leg_elbow_joints "" labels:#("单膝盖关节","双膝盖关节") pos:[30,410] columns:2
|
||||||
|
spinner midleg_twistjoints "中部扭曲骨骼" pos:[30,430] width:250 range:[0,100,2] type:#integer enabled:false
|
||||||
|
radiobuttons leg_mirror "" labels:#("仅左腿","双腿","仅右腿") pos:[30,450] default:2 columns:3
|
||||||
|
button creatleg "创建腿部" pos:[80,470] width:150 height:30
|
||||||
|
button leg_help "说明" pos:[250,470] width:35 height:30
|
||||||
|
|
||||||
|
on leg_elbow_joints changed sel do
|
||||||
|
if sel==2 then midleg_twistjoints.enabled=true else midleg_twistjoints.enabled=false
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTFKchains "FK链模块(手指,舌头,尾巴,触须等)" width:290 height:170 pos:[10,520]
|
||||||
|
edittext pre_fkchains_name "名称" pos:[30,540] width:250
|
||||||
|
spinner fkchains_num "链条数量" pos:[30,560] width:250 range:[0,100,1] type:#integer
|
||||||
|
spinner fkchains_joints "每条链关节数" pos:[30,580] width:250 range:[0,100,1] type:#integer
|
||||||
|
radiobuttons fkchains_outer "" labels:#("X朝前","Y朝前","Z朝前","X朝后","Y朝后","Z朝后") pos:[30,600] default:2 columns:3
|
||||||
|
checkbox fkchains_mirror "镜像模块" pos:[30,630] checked:true
|
||||||
|
button creatfkchains "创建FK链" pos:[80,650] width:150 height:30
|
||||||
|
button fkchains_help "说明" pos:[250,650] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RThead "头部模块" width:290 height:140 pos:[10,700]
|
||||||
|
edittext pre_head_name "名称" pos:[30,720] width:250
|
||||||
|
checkbox jaw "下巴" pos:[30,740] checked:true
|
||||||
|
radiobuttons head_twist "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,760] default:1 columns:2
|
||||||
|
checkbox head_mirror "镜像模块" pos:[30,780] checked:true
|
||||||
|
button creathead "创建头部" pos:[80,800] width:150 height:30
|
||||||
|
button head_help "说明" pos:[250,800] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTlookat "注视模块" width:290 height:150 pos:[10,850]
|
||||||
|
edittext pre_lookat_name "名称" pos:[30,870] width:250
|
||||||
|
spinner lookat_joints "关节数量" pos:[30,890] width:250 range:[0,100,1] type:#integer
|
||||||
|
radiobuttons lookat_outer "" labels:#("X朝前","Y朝前","Z朝前","X朝后","Y朝后","Z朝后") pos:[30,910] default:2 columns:3
|
||||||
|
checkbox lookat_mirror "镜像模块" pos:[30,940] checked:true
|
||||||
|
button creatlookat "创建注视" pos:[80,960] width:150 height:30
|
||||||
|
button lookat_help "说明" pos:[250,960] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTauxiliary "辅助关节模块" width:290 height:100 pos:[10,1010]
|
||||||
|
edittext pre_auxiliary_name "名称" pos:[30,1030] width:250
|
||||||
|
checkbox auxiliary_mirror "镜像关节" pos:[30,1050] checked:true
|
||||||
|
button creatauxiliary "创建辅助关节" pos:[80,1070] width:150 height:30
|
||||||
|
button auxiliary_help "说明" pos:[250,1070] width:35 height:30
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout editmodules "模块编辑" width:318 height:300
|
||||||
|
(
|
||||||
|
GroupBox RTspline "条带样条线模块(脖子,脊椎)" width:290 height:120 pos:[10,10]
|
||||||
|
edittext pre_spline_name "名称" pos:[30,30] width:250
|
||||||
|
spinner spline_joints "关节数量" pos:[30,50] width:250 range:[0,100,3] type:#integer
|
||||||
|
radiobuttons spline_twisk "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,70] columns:2
|
||||||
|
button creatspline "应用条带" pos:[80,90] width:150 height:30
|
||||||
|
button spline_load "载入" pos:[20,90] width:35 height:30
|
||||||
|
button spline_help "说明" pos:[250,90] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTarms "手臂模块" width:290 height:180 pos:[10,140]
|
||||||
|
edittext pre_arm_name "名称" pos:[30,160] width:250
|
||||||
|
spinner upperarm_twistjoints "上臂扭曲骨骼" pos:[30,180] width:250 range:[0,100,2] type:#integer
|
||||||
|
spinner lowerarm_twistjoints "下臂扭曲骨骼" pos:[30,200] width:250 range:[0,100,2] type:#integer
|
||||||
|
radiobuttons arm_elbow_joints "" labels:#("单肘部关节","双肘部关节") pos:[30,220] columns:2
|
||||||
|
spinner midarm_twistjoints "中部扭曲骨骼" pos:[30,240] width:250 range:[0,100,2] type:#integer enabled:false
|
||||||
|
label arm_label01 "" pos:[30,260]
|
||||||
|
button creatarm "应用手臂" pos:[80,280] width:150 height:30
|
||||||
|
button arm_load "载入" pos:[20,280] width:35 height:30
|
||||||
|
button arm_help "说明" pos:[250,280] width:35 height:30
|
||||||
|
|
||||||
|
on arm_elbow_joints changed sel do
|
||||||
|
if sel==2 then midarm_twistjoints.enabled=true else midarm_twistjoints.enabled=false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTlegs "腿部模块" width:290 height:180 pos:[10,330]
|
||||||
|
edittext pre_leg_name "名称" pos:[30,350] width:250
|
||||||
|
spinner upperleg_twistjoints "大腿扭曲骨骼" pos:[30,370] width:250 range:[0,100,2] type:#integer
|
||||||
|
spinner lowerleg_twistjoints "小腿扭曲骨骼" pos:[30,390] width:250 range:[0,100,2] type:#integer
|
||||||
|
radiobuttons leg_elbow_joints "" labels:#("单膝盖关节","双膝盖关节") pos:[30,410] columns:2
|
||||||
|
spinner midleg_twistjoints "中部扭曲骨骼" pos:[30,430] width:250 range:[0,100,2] type:#integer enabled:false
|
||||||
|
label leg_label01 "" pos:[30,450]
|
||||||
|
button creatleg "应用腿部" pos:[80,470] width:150 height:30
|
||||||
|
button leg_load "载入" pos:[20,470] width:35 height:30
|
||||||
|
button leg_help "说明" pos:[250,470] width:35 height:30
|
||||||
|
|
||||||
|
on leg_elbow_joints changed sel do
|
||||||
|
if sel==2 then midleg_twistjoints.enabled=true else midleg_twistjoints.enabled=false
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTFKchains "FK链模块(手指,舌头,尾巴,触须等)" width:290 height:170 pos:[10,520]
|
||||||
|
edittext pre_fkchains_name "名称" pos:[30,540] width:250
|
||||||
|
spinner fkchains_num "链条数量" pos:[30,560] width:250 range:[0,100,1] type:#integer
|
||||||
|
spinner fkchains_joints "每条链关节数" pos:[30,580] width:250 range:[0,100,1] type:#integer
|
||||||
|
label fkchains_label01 "" pos:[30,600]
|
||||||
|
label fkchains_label02 "" pos:[30,620]
|
||||||
|
button creatfkchains "应用FK链" pos:[80,650] width:150 height:30
|
||||||
|
button fkchains_load "载入" pos:[20,650] width:35 height:30
|
||||||
|
button fkchains_help "说明" pos:[250,650] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RThead "头部模块" width:290 height:140 pos:[10,700]
|
||||||
|
edittext pre_head_name "名称" pos:[30,720] width:250
|
||||||
|
checkbox jaw "下巴" pos:[30,740] checked:true
|
||||||
|
radiobuttons head_twist "" labels:#("X轴扭曲","Y轴扭曲") pos:[30,760] default:1 columns:2
|
||||||
|
label head_label01 "" pos:[30,780]
|
||||||
|
button creathead "应用头部" pos:[80,800] width:150 height:30
|
||||||
|
button head_load "载入" pos:[20,800] width:35 height:30
|
||||||
|
button head_help "说明" pos:[250,800] width:35 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GroupBox RTlookat "注视模块" width:290 height:150 pos:[10,850]
|
||||||
|
edittext pre_lookat_name "名称" pos:[30,870] width:250
|
||||||
|
spinner lookat_joints "关节数量" pos:[30,890] width:250 range:[0,100,1] type:#integer
|
||||||
|
label lookat_label01 "" pos:[30,910]
|
||||||
|
label lookat_label02 "" pos:[30,940]
|
||||||
|
button creatlookat "应用注视" pos:[80,960] width:150 height:30
|
||||||
|
button lookat_load "载入" pos:[20,960] width:35 height:30
|
||||||
|
button lookat_help "说明" pos:[250,960] width:35 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout Advancedmodules "模块高级设置" width:300 height:600
|
||||||
|
(
|
||||||
|
local imagespath=#("","","","","","","","","","")
|
||||||
|
|
||||||
|
|
||||||
|
label label01 "----------------覆盖模块颜色------------------"
|
||||||
|
button ctrlcolor01 "1" width:50 height:20 across:5
|
||||||
|
button ctrlcolor02 "2" width:50 height:20
|
||||||
|
button ctrlcolor03 "3" width:50 height:20
|
||||||
|
button ctrlcolor04 "4" width:50 height:20
|
||||||
|
button ctrlcolor05 "5" width:50 height:20
|
||||||
|
button ctrlcolor06 "6" width:50 height:20 across:5
|
||||||
|
button ctrlcolor07 "7" width:50 height:20
|
||||||
|
button ctrlcolor08 "8" width:50 height:20
|
||||||
|
button ctrlcolor09 "9" width:50 height:20
|
||||||
|
button ctrlcolor10 "10" width:50 height:20
|
||||||
|
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
|
||||||
|
|
||||||
|
|
||||||
|
label label002 ""
|
||||||
|
label label003 ""
|
||||||
|
label label004 "----------------镜像模块------------------"
|
||||||
|
edittext mirror_modules_name "模块名称" width:240 align:#left across:2
|
||||||
|
button mirror_modules_load "载入" width:30 align:#right
|
||||||
|
radiobuttons mirror_LR "" labels:#("对齐左边","对齐右边") default:1 columns:2 align:#center
|
||||||
|
button mirror_modules_apply "应用模块镜像" width:150 align:#center height:30
|
||||||
|
|
||||||
|
label label02 ""
|
||||||
|
label label03 ""
|
||||||
|
label label04 "----------------重命名模块------------------"
|
||||||
|
edittext modules_name "模块新名称" width:240 align:#left across:2
|
||||||
|
button modules_name_load "载入" width:30 align:#right
|
||||||
|
button modules_name_apply "应用模块名称" width:150 align:#center height:30
|
||||||
|
|
||||||
|
|
||||||
|
label label05 ""
|
||||||
|
label label06 ""
|
||||||
|
label label07 "----------------模块父节点------------------"
|
||||||
|
edittext modules_parent "新链接模块" width:240 align:#left across:2
|
||||||
|
button modules_parent_load "载入" width:30 align:#right
|
||||||
|
button modules_parent_apply "将选定模块链接到新模块" width:150 align:#center height:30
|
||||||
|
|
||||||
|
label label08 ""
|
||||||
|
label label09 ""
|
||||||
|
label label10 "----------------删除模块------------------"
|
||||||
|
button modules_delete "删除选定模块" width:150 align:#center height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on Advancedmodules open do
|
||||||
|
(
|
||||||
|
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
|
||||||
|
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
|
||||||
|
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout RTctrlrig "生成/删除绑定" width:300 height:600
|
||||||
|
(
|
||||||
|
GroupBox creat_ctrlrig "生成绑定" width:290 height:100 pos:[10,10]
|
||||||
|
checkbox custom_prefix "添加自定义前缀名称" pos:[30,30] checked:false
|
||||||
|
edittext custom_prefix_name "名称" pos:[30,50] width:250 enabled:false
|
||||||
|
button create_rig "生成绑定" pos:[80,70] width:150 height:30
|
||||||
|
|
||||||
|
GroupBox delete_ctrlrig "删除绑定" width:290 height:100 pos:[10,120]
|
||||||
|
checkbox delete_bones "是否删除骨骼" pos:[30,150] checked:false
|
||||||
|
button delete_rig "删除绑定" pos:[80,170] width:150 height:30
|
||||||
|
|
||||||
|
on custom_prefix changed thestate do
|
||||||
|
if custom_prefix.state==true then custom_prefix_name.enabled=true else custom_prefix_name.enabled=false
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout RTctrlsetup "控制器设置" width:300 height:600
|
||||||
|
(
|
||||||
|
local imagespath=#("","","","","","","","","","")
|
||||||
|
|
||||||
|
label label01 "----------------控制器颜色------------------"
|
||||||
|
button ctrlcolor01 "1" width:50 height:20 across:5
|
||||||
|
button ctrlcolor02 "2" width:50 height:20
|
||||||
|
button ctrlcolor03 "3" width:50 height:20
|
||||||
|
button ctrlcolor04 "4" width:50 height:20
|
||||||
|
button ctrlcolor05 "5" width:50 height:20
|
||||||
|
button ctrlcolor06 "6" width:50 height:20 across:5
|
||||||
|
button ctrlcolor07 "7" width:50 height:20
|
||||||
|
button ctrlcolor08 "8" width:50 height:20
|
||||||
|
button ctrlcolor09 "9" width:50 height:20
|
||||||
|
button ctrlcolor10 "10" width:50 height:20
|
||||||
|
|
||||||
|
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
|
||||||
|
|
||||||
|
label label02 ""
|
||||||
|
label label03 ""
|
||||||
|
label label04 "----------------控制器缩放------------------"
|
||||||
|
checkbox x_scale "X轴局部" across:4 align:#left
|
||||||
|
checkbox y_scale "Y轴局部" align:#center
|
||||||
|
checkbox z_scale "Z轴局部" align:#center
|
||||||
|
checkbox mirror_scale "镜像" align:#right
|
||||||
|
slider scale_parmeter "" ticks:5 range:[0,100,50] type:#integer width:280 align:#center
|
||||||
|
label label05 "缩放比例:50%" align:#center
|
||||||
|
button apply_scale "应用缩放" width:150 height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on RTctrlsetup open do
|
||||||
|
(
|
||||||
|
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
|
||||||
|
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
|
||||||
|
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
|
||||||
|
)
|
||||||
|
|
||||||
|
on scale_parmeter changed val do
|
||||||
|
(
|
||||||
|
label05.text=("缩放比例:"+ val as string+"%")
|
||||||
|
)
|
||||||
|
on thecolor changed newcolor do selection.wirecolor = newcolor
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout RTctrlselect "选择器" width:300 height:600
|
||||||
|
(
|
||||||
|
button btn1 "功能1"
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout RigToolUI "绑定工具" width:700 height:60
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
checkbutton btnsub1 "创建Rig" width:50 height:20 across:5
|
||||||
|
button btnsub2 "移除左侧" width:70 height:20
|
||||||
|
button btnsub3 "移除右侧" width:70 height:20
|
||||||
|
button btnsub4 "打印" width:50 height:20
|
||||||
|
button btnsub5 "button" width:50 height:20
|
||||||
|
button btnsub6 "button" width:50 height:20 across:5
|
||||||
|
button btnsub7 "button" width:50 height:20
|
||||||
|
button btnsub8 "button" width:50 height:20
|
||||||
|
button btnsub9 "button" width:50 height:20
|
||||||
|
button btnsub10 "button" width:50 height:20
|
||||||
|
|
||||||
|
subrollout RTleft "" height:600 across:2
|
||||||
|
subrollout RTright "" height:600 across:2
|
||||||
|
|
||||||
|
on btnsub2 pressed do remove_L_rollout()
|
||||||
|
on btnsub3 pressed do remove_R_rollout()
|
||||||
|
on btnsub4 pressed do try (print RigToolUI.RTright.Advancedmodules.modules_name.text) catch()
|
||||||
|
|
||||||
|
on btnsub1 changed thestate do
|
||||||
|
if thestate then
|
||||||
|
(
|
||||||
|
remove_L_rollout()
|
||||||
|
remove_R_rollout()
|
||||||
|
RigToolUI.height +=600
|
||||||
|
|
||||||
|
addsubrollout RigToolUI.RTleft NewRig rolledup:false ; append L_rollout NewRig
|
||||||
|
addsubrollout RigToolUI.RTleft setupmodules rolledup:true ; append L_rollout setupmodules
|
||||||
|
addsubrollout RigToolUI.RTleft editmodules rolledup:true ; append L_rollout editmodules
|
||||||
|
addsubrollout RigToolUI.RTleft RTctrlrig rolledup:true ; append L_rollout RTctrlrig
|
||||||
|
addsubrollout RigToolUI.RTright Advancedmodules rolledup:false ; append R_rollout Advancedmodules
|
||||||
|
addsubrollout RigToolUI.RTright RTctrlsetup rolledup:true ; append R_rollout RTctrlsetup
|
||||||
|
)
|
||||||
|
else (remove_L_rollout() ;remove_R_rollout())
|
||||||
|
/*
|
||||||
|
(
|
||||||
|
|
||||||
|
removesubrollout RigToolUI.RTleft NewRig
|
||||||
|
removesubrollout RigToolUI.RTleft setupmodules
|
||||||
|
removesubrollout RigToolUI.RTleft editmodules
|
||||||
|
removesubrollout RigToolUI.RTleft RTctrlrig
|
||||||
|
removesubrollout RigToolUI.RTright Advancedmodules
|
||||||
|
removesubrollout RigToolUI.RTright RTctrlsetup
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
createDialog RigToolUI
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
dotnetSunnyUI=dotNet.loadAssembly "D:\Desktop\dll\SunnyUI.dll"
|
||||||
|
dotnetSunnyCommonUI=dotNet.loadAssembly "D:\Desktop\dll\SunnyUI.Common.dll"
|
||||||
|
|
||||||
|
--Create a DotNet Button
|
||||||
|
mButton = dotNetObject "Sunny.UI.UIbutton"
|
||||||
|
mButton.text = "Button"
|
||||||
|
|
||||||
|
--Create a DotNet Form
|
||||||
|
hForm = dotNetObject "Sunny.UI.UImainFrame"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
hForm.topmost = true
|
||||||
|
hForm.Style=hForm.Style.green
|
||||||
|
hForm.show()
|
||||||
|
showmethods hForm.controls
|
||||||
|
hForm.controls.Contains mButton
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
try(hForm.close())catch()
|
||||||
|
(
|
||||||
|
fn whenButtonIsPressed a b =
|
||||||
|
(
|
||||||
|
format "Pressed from a DotNet Button\n"
|
||||||
|
format "Argument a (Form): <%> \n" (classof a)
|
||||||
|
format "Properties:\n"
|
||||||
|
showproperties a
|
||||||
|
format "Methods:\n"
|
||||||
|
showmethods a
|
||||||
|
format "Events:\n"
|
||||||
|
showevents a
|
||||||
|
format "\nArgument b (Button): <%> \n" (classof b)
|
||||||
|
format "Properties:\n"
|
||||||
|
showproperties b
|
||||||
|
format "Methods:\n"
|
||||||
|
showmethods a
|
||||||
|
format "Events:\n"
|
||||||
|
showevents a
|
||||||
|
)
|
||||||
|
--Create a DotNet Form
|
||||||
|
hForm = dotNetObject "Sunny.UI.UImainFrame"
|
||||||
|
hForm.topmost = true
|
||||||
|
|
||||||
|
--Create a DotNet Button
|
||||||
|
mButton = dotNetObject "Sunny.UI.UIButton"
|
||||||
|
mButton.text = "BIG DotNet Button"
|
||||||
|
mButton.name = "BIG DotNet Button"
|
||||||
|
mButton.width=230
|
||||||
|
mButton.height=230
|
||||||
|
mButton.size = dotNetObject "System.Drawing.Size" 160 160
|
||||||
|
mButton.location = dotNetObject "System.Drawing.Point" 60 60
|
||||||
|
--mButton.BringToFront()
|
||||||
|
|
||||||
|
|
||||||
|
nButton = dotNetObject "System.Windows.Forms.Button"
|
||||||
|
nButton.text = "BIG DotNet Button"
|
||||||
|
nButton.size = dotNetObject "System.Drawing.Size" 160 160
|
||||||
|
nButton.location = dotNetObject "System.Drawing.Point" 100 260
|
||||||
|
--nButton.BringToFront()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--Add an Event Handler for the click event:
|
||||||
|
--hForm.controls.add mButton --add the Button to the Form
|
||||||
|
--hForm.controls.add nButton
|
||||||
|
dotNet.addEventHandler mButton "click" whenButtonIsPressed
|
||||||
|
--hForm.show() --show the Form with the Button
|
||||||
|
)
|
||||||
|
|
||||||
|
showmethods mButton
|
||||||
|
hForm.controls.add mButton;mButton.BringToFront()
|
||||||
|
mButton.SendToBack()
|
||||||
@@ -0,0 +1,280 @@
|
|||||||
|
if TestRollout != undefined do (try(destroydialog TestRollout)catch())
|
||||||
|
rollout abc "简介" width:300 height:600
|
||||||
|
(
|
||||||
|
|
||||||
|
bitmap bmp1 "Bitmap" pos:[10,10] width:285 height:140 align:#center fileName:("C:\Users\ab\Desktop\RigTool\ctrlcolor\mainabout.png") --bitmap:(bitmap 285 140 color:[255,255,255])
|
||||||
|
|
||||||
|
|
||||||
|
button btn01 "功能1" width:50 height:30 pos:[20,20]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout def "UI" width:300 height:600
|
||||||
|
(
|
||||||
|
|
||||||
|
edittext edittextbox "编辑框" width:280
|
||||||
|
--colorPicker thecolor "" color:[0,255,0] modal:false width:350 height:300
|
||||||
|
on thecolor changed newcolor do selection.wirecolor = newcolor
|
||||||
|
|
||||||
|
|
||||||
|
slider sliderui "滑块" ticks:5 range:[0,100,1] type:#integer
|
||||||
|
listbox fjfjf "列表盒" item:["1","2"] selection:1 height:2 orient:#horizontal --vertical
|
||||||
|
pickbutton pickname "拾取按钮"
|
||||||
|
|
||||||
|
radiobuttons djfsgkjk "单选" labels:#("1","2")
|
||||||
|
checkbox mycheckbox "是否选择"
|
||||||
|
button btn001 "按钮001" width:50 height:20 tooltip:"白色" images:#("C:\Users\ab\Desktop\3.png",undefined,1,1,1,1,1 )
|
||||||
|
checkbutton mycheckbutton "检查按钮"
|
||||||
|
dropdownList mydropdownlist "下拉菜单" items:#("1","2","3","4","5","6") height:4
|
||||||
|
progressBar my_progressbar value:70 color:red across:3
|
||||||
|
button mybutton "进度条+1"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on btn001 pressed do
|
||||||
|
(
|
||||||
|
--format ("name:%s\ncaption:%s\ntext:%s\n" edittext.name edittext.caption edittext.text)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
on mycheckbox changed thestate do
|
||||||
|
messageBox ("changed!!!current state is "+mycheckbox.state as string)
|
||||||
|
on mycheckbox rightclick do
|
||||||
|
messageBox "the checkbox RightClick!!"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on mycheckbutton changed state do
|
||||||
|
if state ==on then -- if mycheckbutton.state ==on then
|
||||||
|
messageBox "checkbutton is on"
|
||||||
|
else
|
||||||
|
messageBox "checkbutton is off"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on mydropdownlist selected i do
|
||||||
|
(
|
||||||
|
print mydropdownlist.selection
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on my_progressbar clicked i do
|
||||||
|
(
|
||||||
|
print i
|
||||||
|
my_progressbar.value=i
|
||||||
|
)
|
||||||
|
label progressbar_percent_1 ""
|
||||||
|
label progressbar_percent "%"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on mybutton pressed do
|
||||||
|
(
|
||||||
|
print my_progressbar.value
|
||||||
|
if my_progressbar.value >=100 then
|
||||||
|
my_progressbar.value=0
|
||||||
|
else
|
||||||
|
my_progressbar.value=my_progressbar.value+1
|
||||||
|
|
||||||
|
progressbar_percent_1.text=my_progressbar.value as string
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
timer clock "计时器" Interval:1000
|
||||||
|
local timertick=0
|
||||||
|
on clock tick do
|
||||||
|
(
|
||||||
|
timertick=timertick+1
|
||||||
|
print timertick
|
||||||
|
if my_progressbar.value >=100 then
|
||||||
|
my_progressbar.value=0
|
||||||
|
else
|
||||||
|
my_progressbar.value=my_progressbar.value+1
|
||||||
|
progressbar_percent_1.text=my_progressbar.value as string
|
||||||
|
|
||||||
|
if clock.active == true then print "Tick!!"
|
||||||
|
|
||||||
|
--clock.active=false --close the timer
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
spinner my_spinner "微调器" range:[0,100,1]
|
||||||
|
on my_spinner changed i do print i --my_spinner.value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
edittext my_edittext "编辑文本" multiline:true height:100 fieldwidth:200
|
||||||
|
|
||||||
|
|
||||||
|
combobox my_combobox "组合框" items:#("1","2","3","4","5") width:60
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout Advancedmodules "模块高级设置工具" width:300 height:600
|
||||||
|
(
|
||||||
|
local imagespath=#("","","","","","","","","","")
|
||||||
|
|
||||||
|
|
||||||
|
label label01 "----------------覆盖模块颜色------------------"
|
||||||
|
button ctrlcolor01 "1" width:50 height:20 across:5
|
||||||
|
button ctrlcolor02 "2" width:50 height:20
|
||||||
|
button ctrlcolor03 "3" width:50 height:20
|
||||||
|
button ctrlcolor04 "4" width:50 height:20
|
||||||
|
button ctrlcolor05 "5" width:50 height:20
|
||||||
|
button ctrlcolor06 "6" width:50 height:20 across:5
|
||||||
|
button ctrlcolor07 "7" width:50 height:20
|
||||||
|
button ctrlcolor08 "8" width:50 height:20
|
||||||
|
button ctrlcolor09 "9" width:50 height:20
|
||||||
|
button ctrlcolor10 "10" width:50 height:20
|
||||||
|
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
|
||||||
|
|
||||||
|
|
||||||
|
label label02 ""
|
||||||
|
label label03 ""
|
||||||
|
label label04 "----------------重命名模块------------------"
|
||||||
|
edittext modules_name "模块新名称" width:250 align:#center
|
||||||
|
button modules_name_apply "应用模块名称" width:150 align:#center height:30
|
||||||
|
|
||||||
|
|
||||||
|
label label05 ""
|
||||||
|
label label06 ""
|
||||||
|
label label07 "----------------模块父节点------------------"
|
||||||
|
edittext modules_parent "新链接模块" width:240 align:#left across:2
|
||||||
|
button modules_parent_load "载入" width:30 align:#right
|
||||||
|
button modules_parent_apply "将选定模块链接到新模块" width:150 align:#center height:30
|
||||||
|
|
||||||
|
label label08 ""
|
||||||
|
label label09 ""
|
||||||
|
label label10 "----------------删除模块------------------"
|
||||||
|
button modules_delete "删除选定模块" width:150 align:#center height:30
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on Advancedmodules open do
|
||||||
|
(
|
||||||
|
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
|
||||||
|
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
|
||||||
|
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout RTctrlsetup "控制器设置" width:300 height:600
|
||||||
|
(
|
||||||
|
local imagespath=#("","","","","","","","","","")
|
||||||
|
|
||||||
|
label label01 "----------------控制器颜色------------------"
|
||||||
|
button ctrlcolor01 "1" width:50 height:20 across:5
|
||||||
|
button ctrlcolor02 "2" width:50 height:20
|
||||||
|
button ctrlcolor03 "3" width:50 height:20
|
||||||
|
button ctrlcolor04 "4" width:50 height:20
|
||||||
|
button ctrlcolor05 "5" width:50 height:20
|
||||||
|
button ctrlcolor06 "6" width:50 height:20 across:5
|
||||||
|
button ctrlcolor07 "7" width:50 height:20
|
||||||
|
button ctrlcolor08 "8" width:50 height:20
|
||||||
|
button ctrlcolor09 "9" width:50 height:20
|
||||||
|
button ctrlcolor10 "10" width:50 height:20
|
||||||
|
|
||||||
|
colorPicker thecolor "" color:[255,0,0] modal:false width:280 height:20
|
||||||
|
|
||||||
|
label label02 ""
|
||||||
|
label label03 ""
|
||||||
|
label label04 "----------------控制器缩放------------------"
|
||||||
|
checkbox x_scale "X轴局部" across:4 align:#left
|
||||||
|
checkbox y_scale "Y轴局部" align:#center
|
||||||
|
checkbox z_scale "Z轴局部" align:#center
|
||||||
|
checkbox mirror_scale "镜像" align:#right
|
||||||
|
slider scale_parmeter "" ticks:5 range:[0,100,50] type:#integer width:280 align:#center
|
||||||
|
label label05 "缩放比例:50%" align:#center
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on RTctrlsetup open do
|
||||||
|
(
|
||||||
|
for i =1 to 10 do imagespath[i]=("C:\Users\ab\Desktop\RigTool\ctrlcolor\\"+ i as string +".png")
|
||||||
|
ctrlcolor01.images=#(imagespath[1],(bitmap 50 20 color:[0,0,0]),1,1,1,1,1)
|
||||||
|
ctrlcolor02.images=#(imagespath[2],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor03.images=#(imagespath[3],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor04.images=#(imagespath[4],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor05.images=#(imagespath[5],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor06.images=#(imagespath[6],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor07.images=#(imagespath[7],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor08.images=#(imagespath[8],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor09.images=#(imagespath[9],undefined,1,1,1,1,1)
|
||||||
|
ctrlcolor10.images=#(imagespath[10],undefined,1,1,1,1,1)
|
||||||
|
)
|
||||||
|
|
||||||
|
on scale_parmeter changed val do
|
||||||
|
(
|
||||||
|
label05.text=("缩放比例:"+ val as string+"%")
|
||||||
|
)
|
||||||
|
on thecolor changed newcolor do selection.wirecolor = newcolor
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout TestRollout "Test" width:700 height:60
|
||||||
|
(
|
||||||
|
|
||||||
|
|
||||||
|
checkbutton btnsub1 "button" width:50 height:20 across:5
|
||||||
|
button btnsub2 "button" width:50 height:20
|
||||||
|
button btnsub3 "button" width:50 height:20
|
||||||
|
button btnsub4 "button" width:50 height:20
|
||||||
|
button btnsub5 "button" width:50 height:20
|
||||||
|
button btnsub6 "button" width:50 height:20 across:5
|
||||||
|
button btnsub7 "button" width:50 height:20
|
||||||
|
button btnsub8 "button" width:50 height:20
|
||||||
|
button btnsub9 "button" width:50 height:20
|
||||||
|
button btnsub10 "button" width:50 height:20
|
||||||
|
subrollout RTleft "" height:600 across:2
|
||||||
|
subrollout RTright "" height:600 across:2
|
||||||
|
|
||||||
|
on btnsub1 changed thestate do
|
||||||
|
if thestate then
|
||||||
|
(
|
||||||
|
TestRollout.height +=600
|
||||||
|
addsubrollout TestRollout.RTleft abc
|
||||||
|
addsubrollout TestRollout.RTleft def
|
||||||
|
addsubrollout TestRollout.RTright Advancedmodules
|
||||||
|
addsubrollout TestRollout.RTright RTctrlsetup
|
||||||
|
)
|
||||||
|
else
|
||||||
|
(
|
||||||
|
TestRollout.height -=600
|
||||||
|
removesubrollout TestRollout.RTleft abc
|
||||||
|
removesubrollout TestRollout.RTleft def
|
||||||
|
removesubrollout TestRollout.RTright Advancedmodules
|
||||||
|
removesubrollout TestRollout.RTright RTctrlsetup
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
createDialog TestRollout
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
bipObj = biped.createNew 100 0 [0,0,0] arms:true neckLinks:5\
|
||||||
|
spineLinks:5 legLinks:4 tailLinks:5 ponyTail1Links:5 \
|
||||||
|
ponyTail2Links:5 fingers:5 fingerLinks:3 toes:5\
|
||||||
|
toeLinks:3 ankleAttach:0.3 trianglePelvis:True \
|
||||||
|
prop1Exists:True prop2Exists:True prop3Exists:True \
|
||||||
|
forearmTwistLinks:4
|
||||||
|
|
||||||
|
nn = biped.maxNumNodes bipObj
|
||||||
|
nl = biped.maxNumLinks bipObj
|
||||||
|
for i = 1 to nn do
|
||||||
|
(
|
||||||
|
anode = biped.getNode bipObj i
|
||||||
|
if anode != undefined do
|
||||||
|
(
|
||||||
|
format "% :\t%\n" i anode.name
|
||||||
|
for j = 1 to nl do
|
||||||
|
(
|
||||||
|
alink = biped.getNode bipObj i link:j
|
||||||
|
if alink != undefined do
|
||||||
|
format "% : % \t%\n" i j alink.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
if abc !=undefined then DestroyDialog abc
|
||||||
|
|
||||||
|
rollout abc "DotNet控件 UI" height:1000 width:830
|
||||||
|
(
|
||||||
|
button a "showProperties()显示属性" width:230 height:30 across:3
|
||||||
|
button b "showMethods()显示方法(调用函数)" width:230 height:30
|
||||||
|
button c "showevents()显示事件" width:230 height:30
|
||||||
|
button d "getProperty()获取属性值" width:230 height:30 across:3
|
||||||
|
button e "setProperty()设置属性值" width:230 height:30
|
||||||
|
button f "getpropnames()控件每个属性(数组)" width:230 height:30
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
dotNetControl dotnetdatagrid "datagridview" width:800 height:300
|
||||||
|
dotNetControl dotnetdatagridview "datagridview" width:800 height:300 --不是经典的datagrid
|
||||||
|
|
||||||
|
dotNetControl dotnettreeview "treeview" width:800 height:300
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
on a pressed do
|
||||||
|
(
|
||||||
|
showProperties dotnetdatagridview --显示属性
|
||||||
|
)
|
||||||
|
on b pressed do
|
||||||
|
(
|
||||||
|
showMethods dotnetdatagridview --显示方法(即可调用的函数)
|
||||||
|
)
|
||||||
|
on c pressed do
|
||||||
|
(
|
||||||
|
showevents dotnetdatagridview -- 显示控件可调用的事件
|
||||||
|
)
|
||||||
|
on d pressed do
|
||||||
|
(
|
||||||
|
format "获取到的属性值:%\n" (getProperty dotnetdatagridview "text" asdotnetobject:false) --获取名为text属性的值
|
||||||
|
)
|
||||||
|
on e pressed do
|
||||||
|
(
|
||||||
|
format "设置成的属性值:%\n" (setProperty dotnetdatagridview "text" "dotnet形式表格") --设置名为text属性的值为"dotnet按钮"
|
||||||
|
)
|
||||||
|
on f pressed do
|
||||||
|
(
|
||||||
|
print (getpropnames dotnetdatagridview) --控件的所有属性,输出为一个数组
|
||||||
|
)
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
-- on dotnetbtn click do print "点击了一次dotnet按钮"
|
||||||
|
-- on dotnetbtn mousedown do print "鼠标进入dotnet按钮范围"
|
||||||
|
|
||||||
|
on abc open do
|
||||||
|
(
|
||||||
|
for i =1 to 5 do dotnetdatagrid.columns.add ("column"+i as string) ("列 "+i as string)
|
||||||
|
dotnetdatagrid.RowCount=4
|
||||||
|
dotnetdatagrid.rows.item[3].cells.item[3].value = "举例dotnetdatagrid"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for i =1 to 5 do dotnetdatagridview.columns.add ("column"+i as string) ("列 "+i as string)
|
||||||
|
dotnetdatagridview.rows.add 4
|
||||||
|
dotnetdatagridview.rows.item[3].cells.item[3].value = "举例"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
dotnettreeview.CheckBoxes=true
|
||||||
|
treenode01=dotnettreeview.Nodes.add "树干1"
|
||||||
|
treenode02=dotnettreeview.Nodes.add "树干2"
|
||||||
|
treenode03=dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干48543"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干35485"
|
||||||
|
dotnettreeview.Nodes.add "树干16543"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干3"
|
||||||
|
dotnettreeview.Nodes.add "树干1788fgsd3"
|
||||||
|
for i=1 to 100 do
|
||||||
|
(
|
||||||
|
ndstext=("node"+i as string)
|
||||||
|
nds=treenode01.nodes.add ndstext
|
||||||
|
treenode01=nds
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
treenode04=treenode01.Nodes.add "树叶1"
|
||||||
|
treenode05=dotnettreeview.nodes.item[1].nodes.add "12"
|
||||||
|
treenode06=dotnettreeview.nodes.item[1].nodes.item[0].nodes.add "34"
|
||||||
|
|
||||||
|
format "全路径是:%\n" treenode06.FullPath
|
||||||
|
format "父级叶名称是:%\n" treenode06.parent.text
|
||||||
|
|
||||||
|
|
||||||
|
dotnettreeview.SelectedNode
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
on dotnettreeview AfterSelect do print dotnettreeview.SelectedNode.FullPath
|
||||||
|
|
||||||
|
)
|
||||||
|
CreateDialog abc
|
||||||
|
|
||||||
|
if abc.dotnettreeview.SelectedNode !=undefined then format "当前选择:%\n" abc.dotnettreeview.SelectedNode.FullPath
|
||||||
|
showevents abc.dotnettreeview
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
clearListener ()
|
||||||
|
try( hForm.close() )catch()
|
||||||
|
|
||||||
|
dotnet.loadAssembly "D:\\Desktop\\dll\\SunnyUI.Common.dll"
|
||||||
|
dotnet.loadAssembly "D:\\Desktop\\dll\\SunnyUI.dll"
|
||||||
|
|
||||||
|
fn whenButtonIsPressed =
|
||||||
|
(
|
||||||
|
print "button01"
|
||||||
|
)
|
||||||
|
|
||||||
|
fn whenNavIsPressed a b=
|
||||||
|
(
|
||||||
|
print(classof b)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
uiNavbar1=dotNetObject "Sunny.UI.UINavbar"
|
||||||
|
uiNavbar1.nodes.add("¿Ø¼þ")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--Create a DotNet Button
|
||||||
|
mButton = dotNetObject "Sunny.UI.UIbutton"
|
||||||
|
mButton.text = "mButton"
|
||||||
|
mButton.size = dotNetObject "System.Drawing.Size" 160 80
|
||||||
|
mButton.location = dotNetObject "System.Drawing.Point" 160 0
|
||||||
|
|
||||||
|
page1001Button = dotNetObject "Sunny.UI.UIbutton"
|
||||||
|
page1001Button.text = "page1001 Button"
|
||||||
|
page1001Button.size = dotNetObject "System.Drawing.Size" 160 80
|
||||||
|
page1001Button.location = dotNetObject "System.Drawing.Point" 0 0
|
||||||
|
|
||||||
|
page1002Button = dotNetObject "Sunny.UI.UIbutton"
|
||||||
|
page1002Button.text = "page1002 Button"
|
||||||
|
page1002Button.size = dotNetObject "System.Drawing.Size" 160 80
|
||||||
|
page1002Button.location = dotNetObject "System.Drawing.Point" 0 0
|
||||||
|
--Create a DotNet Form
|
||||||
|
hForm = dotNetObject "Sunny.UI.UIform"
|
||||||
|
|
||||||
|
|
||||||
|
--Create a DotNet page
|
||||||
|
hpage1001 = dotNetObject "Sunny.UI.UIpage"
|
||||||
|
hpage1001.AutoScaleMode=hpage1001.AutoScaleMode.none
|
||||||
|
hpage1001.PageIndex=1001
|
||||||
|
UIlabel1001=dotNetObject "Sunny.UI.UIlabel"
|
||||||
|
UIlabel1001.text="Page 1001"
|
||||||
|
UIlabel1001.location = dotNetObject "System.Drawing.Point" 0 200
|
||||||
|
UIlabel1001.ForeColor=(dotnetclass "System.Drawing.Color").FromArgb 255 0 255 255
|
||||||
|
hpage1001.text="page 1"
|
||||||
|
hpage1001.BackColor=(dotnetclass "System.Drawing.Color").FromArgb 255 0 0 0
|
||||||
|
|
||||||
|
|
||||||
|
hpage1002 = dotNetObject "Sunny.UI.UIpage"
|
||||||
|
hpage1002.AutoScaleMode=hpage1002.AutoScaleMode.none
|
||||||
|
hpage1002.text="page 2"
|
||||||
|
hpage1002.PageIndex=1002
|
||||||
|
|
||||||
|
--Create a DotNet uitablecontrol
|
||||||
|
htab = dotNetObject "Sunny.UI.UITabControl"
|
||||||
|
htab.size = dotNetObject "System.Drawing.Size" 30 30
|
||||||
|
htab.location = dotNetObject "System.Drawing.Point" 160 150
|
||||||
|
|
||||||
|
hForm.topmost = true
|
||||||
|
hForm.text="UIform"
|
||||||
|
hForm.AutoScaleMode=hForm.AutoScaleMode.none
|
||||||
|
hForm.ShowDragStretch =true
|
||||||
|
hForm.BackColor=(dotnetclass "System.Drawing.Color").FromArgb 255 255 255 255
|
||||||
|
|
||||||
|
--add controls
|
||||||
|
hForm.controls.add mButton
|
||||||
|
hForm.controls.add UIlabel1001
|
||||||
|
hForm.controls.add page1001Button
|
||||||
|
hForm.controls.add page1002Button
|
||||||
|
|
||||||
|
hForm.controls.add uiNavbar1
|
||||||
|
hForm.controls.add htab
|
||||||
|
hForm.AddPage hpage1001
|
||||||
|
hForm.SelectPage 1001
|
||||||
|
hForm.AddPage hpage1002
|
||||||
|
hForm.SelectPage 1002
|
||||||
|
hForm.MainTabControl=htab
|
||||||
|
|
||||||
|
|
||||||
|
--change the style
|
||||||
|
|
||||||
|
|
||||||
|
--Add an Event Handler for the click event
|
||||||
|
dotNet.addEventHandler mButton "click" whenButtonIsPressed
|
||||||
|
|
||||||
|
|
||||||
|
page1001Button.parent=hpage1001
|
||||||
|
page1002Button.parent=hpage1002
|
||||||
|
UIlabel1001.parent=hpage1001
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
hForm.show() --show the Form with the Button
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
showproperties hForm
|
||||||
|
show aside
|
||||||
|
showevents mButton
|
||||||
|
dotnet.showConstructors mButton
|
||||||
|
hForm.Region
|
||||||
|
hForm.controls.count
|
||||||
|
hForm.controls.item[0]
|
||||||
|
createDialog (dotNetObject "Sunny.UI.UIMessageDialog")
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
AsideHeaderMain = dotNetObject "Sunny.UI.UIAsideHeaderMainFrame"
|
||||||
|
--AsideHeaderMain.controls.clear()
|
||||||
|
AsideHeaderMain.show()
|
||||||
|
|
||||||
|
AsideHeaderMain.controls.count
|
||||||
|
--AsideHeaderMain.controls.item[0].backcolor=(dotnetclass "System.Drawing.Color").FromArgb 255 255 0 255
|
||||||
|
--AsideHeaderMain.controls.item[1].backcolor=(dotnetclass "System.Drawing.Color").FromArgb 255 0 255 255
|
||||||
|
--AsideHeaderMain.controls.item[2].backcolor=(dotnetclass "System.Drawing.Color").FromArgb 255 255 255 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for i=0 to AsideHeaderMain.controls.count-1 do AsideHeaderMain.controls.item[i].BringToFront()
|
||||||
|
AsideHeaderMain.AddPage (dotNetObject "Sunny.UI.UIPage")
|
||||||
|
AsideHeaderMain.AddPage (dotNetObject "Sunny.UI.UIPage")
|
||||||
|
showmethods AsideHeaderMain
|
||||||
|
*/
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
if abc !=undefined then DestroyDialog abc
|
||||||
|
|
||||||
|
rollout abc "DotNet控件 UI" height:800 width:830
|
||||||
|
(
|
||||||
|
button a "showProperties()显示属性" width:230 height:30 pos:[0,0]
|
||||||
|
button b "showMethods()显示方法(调用函数)" width:230 height:30 pos:[0,40]
|
||||||
|
button c "showevents()显示事件" width:230 height:30 pos:[0,80]
|
||||||
|
button d "getProperty()获取属性值" width:230 height:30 pos:[0,120]
|
||||||
|
button e "setProperty()设置属性值" width:230 height:30 pos:[0,160]
|
||||||
|
button f "getpropnames()控件每个属性(数组)" width:230 height:30 pos:[0,200]
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
dotNetControl dotnetbtn "button" height:50 width:230 pos:[0,240]
|
||||||
|
dotNetControl dotnetcalender "monthcalendar" height:180 width:280 pos:[0,300]
|
||||||
|
dotNetControl dotnettext "label" width:230 pos:[0,500]
|
||||||
|
dotNetControl dotnetlist "listbox" width:230 height:80 pos:[0,530]
|
||||||
|
dotNetControl dotnetdatagrid "datagrid" width:230 height:160 pos:[0,620]
|
||||||
|
|
||||||
|
|
||||||
|
dotNetControl dotnetpicturebox "picturebox" width:230 height:150 pos:[300,0]
|
||||||
|
dotNetControl dotnetprogressbar "progressbar" width:230 height:20 pos:[300,180]
|
||||||
|
dotNetControl dotnetcombobox "combobox" width:230 height:100 pos:[300,220]
|
||||||
|
dotNetControl dotnetcheckedlistbox "checkedlistbox" width:230 height:100 pos:[300,340]
|
||||||
|
dotNetControl dotnettrackbar "trackbar" width:230 height:50 pos:[300,460]
|
||||||
|
dotNetControl dotnetcheckbox "checkbox" width:230 height:30 pos:[300,510]
|
||||||
|
dotNetControl dotnettextbox "textbox" width:230 height:20 pos:[300,550]
|
||||||
|
dotNetControl dotnetrichtextbox "richtextbox" width:230 height:210 pos:[300,580]
|
||||||
|
|
||||||
|
|
||||||
|
dotNetControl dotnetNumericUpDown "NumericUpDown" width:230 height:20 pos:[600,0]
|
||||||
|
dotNetControl dotnetgroupbox "groupbox" width:230 height:100 pos:[600,40]
|
||||||
|
dotNetControl dotnetradiobutton "radiobutton" width:230 height:20 pos:[600,160]
|
||||||
|
dotNetControl dotnetvscrollbar "vscrollbar" width:20 height:200 pos:[600,200]
|
||||||
|
dotNetControl dotnethscrollbar "hscrollbar" width:230 height:20 pos:[600,410]
|
||||||
|
dotNetControl dotnettreeview "treeview" width:230 height:340 pos:[600,450]
|
||||||
|
----------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
on a pressed do
|
||||||
|
(
|
||||||
|
showProperties dotnethscrollbar --显示属性
|
||||||
|
)
|
||||||
|
on b pressed do
|
||||||
|
(
|
||||||
|
showMethods dotnetbtn --显示方法(即可调用的函数)
|
||||||
|
)
|
||||||
|
on c pressed do
|
||||||
|
(
|
||||||
|
showevents dotnetbtn -- 显示控件可调用的事件
|
||||||
|
)
|
||||||
|
on d pressed do
|
||||||
|
(
|
||||||
|
format "获取到的属性值:%\n" (getProperty dotnetbtn "text" asdotnetobject:false) --获取名为text属性的值
|
||||||
|
)
|
||||||
|
on e pressed do
|
||||||
|
(
|
||||||
|
format "设置成的属性值:%\n" (setProperty dotnetbtn "text" "dotnet形式的按钮") --设置名为text属性的值为"dotnet按钮"
|
||||||
|
)
|
||||||
|
on f pressed do
|
||||||
|
(
|
||||||
|
print (getpropnames dotnetbtn) --控件的所有属性,输出为一个数组
|
||||||
|
)
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
on dotnetbtn click do print "点击了一次dotnet按钮"
|
||||||
|
on dotnetbtn mousedown do print "鼠标进入dotnet按钮范围"
|
||||||
|
|
||||||
|
on abc open do
|
||||||
|
(
|
||||||
|
dotnetbtn.text="dotnet按钮"
|
||||||
|
dotnettext.text="dotnet标签"
|
||||||
|
dotnetprogressbar.value=50
|
||||||
|
dotnetcheckbox.text="check按钮"
|
||||||
|
dotnettextbox.text="textbox(单行)"
|
||||||
|
dotnetrichtextbox.text="richtextbox(多行)"
|
||||||
|
dotnetvscrollbar.value=20
|
||||||
|
dotnethscrollbar.value=80
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
CreateDialog abc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
--files = #("C:\Users\ab\Desktop\00000.jpg","C:\Users\ab\Desktop\00001.jpg")
|
||||||
|
|
||||||
|
files=#()
|
||||||
|
for i=0 to 127 do append files ("D:\Bip动作库\3dsmax\九尾狐\jiuwei_renxing_show\\"+i as string +".jpg")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GifFullPath = "C:\Users\ab\Desktop\mygif.gif"
|
||||||
|
gifwidth=400
|
||||||
|
gifheight=224
|
||||||
|
fps=30
|
||||||
|
ColorTolerance=1 --色差,数值约低质量越好
|
||||||
|
|
||||||
|
|
||||||
|
GifCreator = dotnetclass "RefPlayer.GifCreator"
|
||||||
|
GifCreator.Init fps ColorTolerance
|
||||||
|
dotNet.removeAllEventHandlers GifCreator
|
||||||
|
|
||||||
|
GifCreator.Start files GifFullPath gifwidth gifheight --不要宽高参数,则图片默认大小
|
||||||
|
|
||||||
|
showMethods GifCreator
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
--IKSys.ikChain $Bone035 $Bone037 IKLimb
|
||||||
|
IKSys.solverCount() --返回系统安装的可用ik求解器数
|
||||||
|
IKSys.solverName 1 --返回索引求解器字符串名称 hi结算器
|
||||||
|
IKSys.solverName 2 -- iklimb肢体结算器
|
||||||
|
IKSys.solverName 3 -- spline ik结算器
|
||||||
|
IKSys.solverUIName 2 --返回索引求解器ui名称
|
||||||
|
*/
|
||||||
|
--a=IKSys.ikChain $Bone035 $Bone037 (IKSys.solverName 2) --使用肢体求解器
|
||||||
|
--classOf a
|
||||||
|
--showClass "IK_Chain_Object"
|
||||||
|
--showProperties $
|
||||||
|
--showProperties $.pos.controller
|
||||||
|
--classOf $
|
||||||
|
--superClassOf $
|
||||||
|
--getPropNames $
|
||||||
|
|
||||||
|
--show $
|
||||||
|
|
||||||
|
--show $.transform.controller
|
||||||
|
$.transform.controller.VHTarget
|
||||||
|
$.pos
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
--SetINISetting <文件路径> <节> <键> <键值>
|
||||||
|
--例如:
|
||||||
|
--[CopyPaste1]
|
||||||
|
--nombredobjetselectionnay1=1
|
||||||
|
--nombredobjetselectionnay1
|
||||||
|
|
||||||
|
|
||||||
|
a="100"
|
||||||
|
SetINISetting "C:\Users\ab\Desktop\YWB_config.ini" "CopyPaste1" "nombredobjetselectionnay1" (selection.count as string)
|
||||||
|
SetINISetting "C:\Users\ab\Desktop\YWB_config.ini" "hello" "world" a --写入键值
|
||||||
|
--delINISetting "C:\Users\ab\Desktop\YWB_config.ini" "hello" "world" --删除键
|
||||||
|
--delINISetting "C:\Users\ab\Desktop\YWB_config.ini" "hello" --删除节和键值
|
||||||
|
world=getINISetting "C:\Users\ab\Desktop\YWB_config.ini" "CopyPaste1" "nombredobjetselectionnay1" --读取键值
|
||||||
|
hasINISetting "C:\Users\ab\Desktop\YWB_config.ini" "CopyPaste1" "nombredobjetselectionnay1" --如果存在,则返回true
|
||||||
|
format "world=%\n" world
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
--saveMaxFile "D:\ttt.max" --usenewfile:true
|
||||||
|
|
||||||
|
archiveMaxFile "C:\Users\ab\Desktop\1\wuxia" quiet:false --2019以及更高版本可用
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
if testtest != undefined do (try(destroydialog testtest)catch())
|
||||||
|
|
||||||
|
|
||||||
|
rcMenu myrcMenu
|
||||||
|
(
|
||||||
|
|
||||||
|
menuItem item1 "item1"
|
||||||
|
menuItem item2 "item2" checked:true
|
||||||
|
|
||||||
|
separator line1
|
||||||
|
|
||||||
|
submenu "submenu"
|
||||||
|
(
|
||||||
|
menuItem subitem1 "subitem1"
|
||||||
|
menuItem subitem2 "subitem2"
|
||||||
|
menuItem subitem3 "subitem3"
|
||||||
|
)
|
||||||
|
|
||||||
|
menuItem item3 "item3"
|
||||||
|
menuItem item4 "item4"
|
||||||
|
|
||||||
|
menuItem item5 "item5"
|
||||||
|
|
||||||
|
on item1 picked do item1.checked=true
|
||||||
|
on item2 picked do item2.checked=true
|
||||||
|
on item3 picked do item3.checked=true
|
||||||
|
|
||||||
|
|
||||||
|
on subitem1 picked do subitem1.checked=true
|
||||||
|
|
||||||
|
on myrcMenu open do print "open myremenu"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout testtest "test" width:400 height:300
|
||||||
|
(
|
||||||
|
button btn1 "rcmenu" width:80 height:80
|
||||||
|
|
||||||
|
on btn1 rightclick do popUpMenu myrcMenu align:#align_topleft
|
||||||
|
|
||||||
|
)
|
||||||
|
CreateDialog testtest
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
--$Sphere001.position=random [0,0,0][100,100,100]
|
||||||
|
--$Sphere001.position.x=random 0 100
|
||||||
|
|
||||||
|
--$Sphere001.transform=random [0,0,0][100,100,100]
|
||||||
|
--$Sphere001.rotation=random [0,0,0][100,100,100]
|
||||||
|
/*
|
||||||
|
format "$Sphere001.transform=%\n" $Sphere001.transform --世界位置,旋转,缩放
|
||||||
|
format "$Sphere001.rotation=%\n" $Sphere001.rotation --世界旋转(四元数)
|
||||||
|
format "$Sphere001.position=%\n" $Sphere001.position --世界位置
|
||||||
|
format "$Sphere001.scale=%\n" $Sphere001.scale --世界缩放
|
||||||
|
format "$Sphere001.pivot=%\n" $Sphere001.pivot --轴点
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--默认控制器下世界坐标
|
||||||
|
$Sphere003.position.controller.'X 位置' --英文版为 $Sphere003.position.controller.'X Position'
|
||||||
|
$Sphere003.rotation.controller.'X 轴旋转'=0 --英文版为 $Sphere003.rotation.controller.'X Rotation'
|
||||||
|
$Sphere003.scale.x --中英文一致
|
||||||
|
|
||||||
|
|
||||||
|
--旋转四元数 x y z w X、Y、Z构成矢量,W是围绕矢量的旋转角度
|
||||||
|
$Sphere003.rotation = $Sphere001.rotation
|
||||||
|
$Sphere003.rotation.x
|
||||||
|
$Sphere003.rotation.y
|
||||||
|
$Sphere003.rotation.z
|
||||||
|
$Sphere003.rotation.w
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*a=point()
|
||||||
|
a.transform=$.transform
|
||||||
|
b=point()
|
||||||
|
b.transform=$.children[1].transform
|
||||||
|
|
||||||
|
a.size=10
|
||||||
|
a.box=true
|
||||||
|
a.cross=false
|
||||||
|
b.size=10
|
||||||
|
b.box=true
|
||||||
|
b.cross=false
|
||||||
|
|
||||||
|
|
||||||
|
$.pos.controller = position_constraint()
|
||||||
|
$.pos.controller.appendtarget a 100
|
||||||
|
|
||||||
|
$.rotation.controller = lookat_constraint()
|
||||||
|
$.rotation.controller.appendtarget b 100
|
||||||
|
$.rotation.controller.lookat_vector_length = 0
|
||||||
|
$.rotation.controller.viewline_length_abs = off
|
||||||
|
|
||||||
|
$.rotation.controller.upnode_world = off --上方向节点设置
|
||||||
|
$.rotation.controller.pickupnode = b
|
||||||
|
|
||||||
|
$.rotation.controller.relative = on --保持初始偏移
|
||||||
|
|
||||||
|
$.children[1].pos.controller = position_constraint()
|
||||||
|
$.children[1].pos.controller.appendtarget b 100
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$.boneScaleType=#none
|
||||||
|
$.scale.controller = ScaleXYZ()
|
||||||
|
$.scale.controller.X_Scale.controller = float_script()
|
||||||
|
|
||||||
|
|
||||||
|
--骨骼链条生成
|
||||||
|
rollout boneRig "请先选中根骨"
|
||||||
|
(
|
||||||
|
button btn "骨链绑定"
|
||||||
|
|
||||||
|
on btn pressed do (
|
||||||
|
bo = $ --选中的骨骼节点
|
||||||
|
a = point() --已经在骨骼节点处创建的虚拟节点
|
||||||
|
a.size=10
|
||||||
|
a.cross=false
|
||||||
|
a.box=true
|
||||||
|
a.transform = bo.transform
|
||||||
|
|
||||||
|
while bo.children[1]!=null do (
|
||||||
|
bo.pos.controller = position_constraint() --先位置约束到已创建的a
|
||||||
|
bo.pos.controller.appendtarget a 100
|
||||||
|
|
||||||
|
bo.boneScaleType=#none --更正缩放控制
|
||||||
|
bo.scale.controller = ScaleXYZ()
|
||||||
|
bo.scale.controller.X_Scale.controller = float_script()
|
||||||
|
|
||||||
|
a = point() --为子端创建一个新节点
|
||||||
|
a.size=10
|
||||||
|
a.cross=false
|
||||||
|
a.box=true
|
||||||
|
|
||||||
|
a.transform = bo.children[1].transform --对齐到子端
|
||||||
|
|
||||||
|
bo.rotation.controller = lookat_constraint() --骨骼注视约束到子端的a
|
||||||
|
bo.rotation.controller.appendtarget a 100
|
||||||
|
bo.rotation.controller.lookat_vector_length = 0
|
||||||
|
bo.rotation.controller.viewline_length_abs = off
|
||||||
|
|
||||||
|
bo.rotation.controller.upnode_world = off --上方向节点设置
|
||||||
|
bo.rotation.controller.pickupnode = a
|
||||||
|
|
||||||
|
bo.rotation.controller.relative = on --保持初始偏移
|
||||||
|
|
||||||
|
bo = bo.children[1] --递进bo赋值为子骨骼
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
bo.pos.controller = position_constraint() --末端子骨骼位置约束
|
||||||
|
bo.pos.controller.appendtarget a 100
|
||||||
|
|
||||||
|
)
|
||||||
|
)
|
||||||
|
createdialog boneRig
|
||||||
|
*/
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
if rollouttest != undefined then
|
||||||
|
try(
|
||||||
|
cui.unRegisterDialogBar rollouttest
|
||||||
|
DestroyDialog rollouttest
|
||||||
|
)catch()
|
||||||
|
|
||||||
|
rollout subrollouttest "rollouttest"
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:2
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "左侧" width:80 height:30 across:2
|
||||||
|
button btn04 "右侧" width:80 height:30
|
||||||
|
button btn05 "左侧" width:80 height:30 across:2
|
||||||
|
button btn06 "右侧" width:80 height:30
|
||||||
|
button btn07 "左侧" width:80 height:30 across:2
|
||||||
|
button btn08 "右侧" width:80 height:30
|
||||||
|
button btn09 "左侧" width:80 height:30 across:2
|
||||||
|
button btn10 "右侧" width:80 height:30
|
||||||
|
button btn11 "左侧" width:80 height:30 across:2
|
||||||
|
button btn12 "右侧" width:80 height:30
|
||||||
|
button btn13 "左侧" width:80 height:30 across:2
|
||||||
|
button btn14 "右侧" width:80 height:30
|
||||||
|
button btn15 "左侧" width:80 height:30 across:2
|
||||||
|
button btn16 "右侧" width:80 height:30
|
||||||
|
button btn17 "左侧" width:80 height:30 across:2
|
||||||
|
button btn18 "右侧" width:80 height:30
|
||||||
|
button btn19 "左侧" width:80 height:30 across:2
|
||||||
|
button btn20 "右侧" width:80 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout subrollouttest02 "rollouttest02" width:200
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:2
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "左侧" width:80 height:30 across:2
|
||||||
|
button btn04 "右侧" width:80 height:30
|
||||||
|
button btn05 "左侧" width:80 height:30 across:2
|
||||||
|
button btn06 "右侧" width:80 height:30
|
||||||
|
button btn07 "左侧" width:80 height:30 across:2
|
||||||
|
button btn08 "右侧" width:80 height:30
|
||||||
|
button btn09 "左侧" width:80 height:30 across:2
|
||||||
|
button btn10 "右侧" width:80 height:30
|
||||||
|
button btn11 "左侧" width:80 height:30 across:2
|
||||||
|
button btn12 "右侧" width:80 height:30
|
||||||
|
button btn13 "左侧" width:80 height:30 across:2
|
||||||
|
button btn14 "右侧" width:80 height:30
|
||||||
|
button btn15 "左侧" width:80 height:30 across:2
|
||||||
|
button btn16 "右侧" width:80 height:30
|
||||||
|
button btn17 "左侧" width:80 height:30 across:2
|
||||||
|
button btn18 "右侧" width:80 height:30
|
||||||
|
button btn19 "左侧" width:80 height:30 across:2
|
||||||
|
button btn20 "右侧" width:80 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout subrollouttest03 "rollouttest03" width:200
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:2
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "左侧" width:80 height:30 across:2
|
||||||
|
button btn04 "右侧" width:80 height:30
|
||||||
|
button btn05 "左侧" width:80 height:30 across:2
|
||||||
|
button btn06 "右侧" width:80 height:30
|
||||||
|
button btn07 "左侧" width:80 height:30 across:2
|
||||||
|
button btn08 "右侧" width:80 height:30
|
||||||
|
button btn09 "左侧" width:80 height:30 across:2
|
||||||
|
button btn10 "右侧" width:80 height:30
|
||||||
|
button btn11 "左侧" width:80 height:30 across:2
|
||||||
|
button btn12 "右侧" width:80 height:30
|
||||||
|
button btn13 "左侧" width:80 height:30 across:2
|
||||||
|
button btn14 "右侧" width:80 height:30
|
||||||
|
button btn15 "左侧" width:80 height:30 across:2
|
||||||
|
button btn16 "右侧" width:80 height:30
|
||||||
|
button btn17 "左侧" width:80 height:30 across:2
|
||||||
|
button btn18 "右侧" width:80 height:30
|
||||||
|
button btn19 "左侧" width:80 height:30 across:2
|
||||||
|
button btn20 "右侧" width:80 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout rollouttest "rollouttest" width:300
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:3
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn05 "浮动" width:80 height:30
|
||||||
|
button btn06 "功能" width:80 height:30
|
||||||
|
subrollout RTleft "" width:280 height:650
|
||||||
|
|
||||||
|
on btn01 pressed do cui.dockDialogBar rollouttest #cui_dock_left
|
||||||
|
on btn02 pressed do cui.dockDialogBar rollouttest #cui_dock_right
|
||||||
|
on btn05 pressed do cui.floatDialogBar rollouttest
|
||||||
|
on btn06 pressed do print (cui.getDockState rollouttest)
|
||||||
|
)
|
||||||
|
CreateDialog rollouttest
|
||||||
|
|
||||||
|
cui.registerDialogBar rollouttest style:#(#cui_dock_vert,#cui_floatable)
|
||||||
|
cui.dockDialogBar rollouttest #cui_dock_left
|
||||||
|
|
||||||
|
|
||||||
|
addsubrollout rollouttest.RTleft subrollouttest
|
||||||
|
addsubrollout rollouttest.RTleft subrollouttest02 rolledup:true
|
||||||
|
addsubrollout rollouttest.RTleft subrollouttest03 rolledup:true
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
globel FBX_convert_str.ConverterFloater
|
||||||
|
|
||||||
|
rollout UImenu "1" width:300 height:150
|
||||||
|
(
|
||||||
|
|
||||||
|
GroupBox thegroupbox "工具组1:" height:40 offset:[0,0] width:280
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout UImenu2 "2" width:300 height:300
|
||||||
|
(
|
||||||
|
GroupBox thegroupbox1 "工具组2:" height:40 offset:[0,0] width:280
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout UImenu3 "3" width:300 height:300
|
||||||
|
(
|
||||||
|
GroupBox thegroupbox1 "工具组2:" height:40 offset:[0,0] width:280
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function MakerolloutFloat =
|
||||||
|
(
|
||||||
|
|
||||||
|
FBX_convert_str.ConverterFloater = newRolloutFloater "工具名称" 325 500
|
||||||
|
|
||||||
|
addRollout UImenu FBX_convert_str.ConverterFloater rolledup:false
|
||||||
|
addRollout UImenu2 FBX_convert_str.ConverterFloater rolledup:false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
closeRolloutFloater FBX_convert_str.ConverterFloater
|
||||||
|
removeRollout UImenu2
|
||||||
|
)
|
||||||
|
MakerolloutFloat()
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
ImageFileName = "C:\Users\ab\Desktop\2.jpg"
|
||||||
|
SaveFormat = (DotNetClass "System.Drawing.Imaging.ImageFormat").jpeg --ÓÐpng bmp gif icon tiff jpeg µÈµÈ³£Óøñʽ
|
||||||
|
start_posX=-1157
|
||||||
|
start_posY=288
|
||||||
|
picwidth=800
|
||||||
|
picheight=400
|
||||||
|
leftright_offset=0
|
||||||
|
updown_offset=0
|
||||||
|
|
||||||
|
ScreenBitmap = dotnetobject "System.Drawing.Bitmap" picwidth picheight (dotnetclass "System.Drawing.Imaging.PixelFormat").Format32bppPArgb
|
||||||
|
|
||||||
|
Graphics = (dotnetclass "System.Drawing.Graphics").FromImage ScreenBitmap
|
||||||
|
|
||||||
|
|
||||||
|
Graphics.CopyFromScreen start_posX start_posY leftright_offset updown_offset ScreenBitmap.Size (dotnetclass "System.Drawing.CopyPixelOperation").SourceCopy
|
||||||
|
|
||||||
|
|
||||||
|
ScreenBitmap.Save ImageFileName SaveFormat
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
--×ÀÃæ²¶×½
|
||||||
|
ssBitmap1 = windows.snapshot 0
|
||||||
|
--display ssBitmap1 caption:"Desktop Snapshot"
|
||||||
|
ssBitmap1.filename = "C:\Users\ab\Desktop\desktop.jpg"
|
||||||
|
save ssBitmap1
|
||||||
|
|
||||||
|
--maxÖ÷´°¿Ú
|
||||||
|
ssBitmap2 = windows.snapshot #max
|
||||||
|
--display ssBitmap2 caption:"3ds Max Main Window"
|
||||||
|
ssBitmap2.filename = "C:\Users\ab\Desktop\max.jpg"
|
||||||
|
save ssBitmap2
|
||||||
|
|
||||||
|
--µ±Ç°ÊÓ¿Ú
|
||||||
|
ssBitmap3 = windows.snapshot (viewport.getHWnd())
|
||||||
|
--display ssBitmap3 caption:"Active Viewport"
|
||||||
|
ssBitmap3.filename = "C:\Users\ab\Desktop\viewport.jpg"
|
||||||
|
save ssBitmap3
|
||||||
|
*/
|
||||||
|
|
||||||
|
ssBitmap4 = windows.snapshot 0 capturescreenpixels:true
|
||||||
|
display ssBitmap4 caption:"Active Viewport"
|
||||||
|
-- ssBitmap4.filename = "C:\Users\ab\Desktop\screenpiexls.jpg"
|
||||||
|
-- save ssBitmap4
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
--//对齐旋转
|
||||||
|
a=$box003
|
||||||
|
b=$box002
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
--//不建议使用这种写法
|
||||||
|
--a.rotation = b.rotation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--//建议使用这种写法
|
||||||
|
/*
|
||||||
|
a.rotation.x_rotation = b.rotation.x_rotation
|
||||||
|
a.rotation.y_rotation = b.rotation.y_rotation
|
||||||
|
a.rotation.z_rotation = b.rotation.z_rotation
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
--//镜像旋转 --仅适用于本身对称物体
|
||||||
|
|
||||||
|
Fn XPosMirror yuanlai mubiao SY_index =
|
||||||
|
(
|
||||||
|
local OriginalEuler,TargetController,TargetEuler
|
||||||
|
OriginalEuler = yuanlai.Rotation.Controller.Value as EulerAngles
|
||||||
|
TargetEuler = Copy OriginalEuler
|
||||||
|
TargetController = mubiao.Rotation.Controller
|
||||||
|
|
||||||
|
case SY_index of
|
||||||
|
(
|
||||||
|
1:
|
||||||
|
(
|
||||||
|
TargetEuler.X *= -1
|
||||||
|
TargetEuler.Z *= -1
|
||||||
|
|
||||||
|
TargetEuler.Z += 180.0
|
||||||
|
)
|
||||||
|
2:
|
||||||
|
(
|
||||||
|
TargetEuler.X *= -1
|
||||||
|
TargetEuler.Z *= -1
|
||||||
|
|
||||||
|
)
|
||||||
|
3:
|
||||||
|
(
|
||||||
|
TargetEuler.X *= -1
|
||||||
|
TargetEuler.Z *= -1
|
||||||
|
|
||||||
|
TargetEuler.Z *= -1
|
||||||
|
TargetEuler.Y += 180.0
|
||||||
|
TargetEuler.Z += 180.0
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
(
|
||||||
|
TargetEuler.X *= -1
|
||||||
|
TargetEuler.Z *= -1
|
||||||
|
|
||||||
|
TargetEuler.Z += 180.0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
TargetController.Value = TargetEuler as quat
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
a=$
|
||||||
|
a.pivot
|
||||||
|
b=copy a
|
||||||
|
b.pos.x *= -1 ; XPosMirror a b 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
a=b
|
||||||
|
b=copy a
|
||||||
|
b.pos.y *= -1 ; XPosMirror a b 2
|
||||||
|
|
||||||
|
|
||||||
|
a=b
|
||||||
|
b=copy a
|
||||||
|
b.pos.z *= -1 ; XPosMirror a b 3
|
||||||
|
*/
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
if rollouttest != undefined then
|
||||||
|
try(
|
||||||
|
cui.unRegisterDialogBar rollouttest
|
||||||
|
DestroyDialog rollouttest
|
||||||
|
)catch()
|
||||||
|
|
||||||
|
rollout subrollouttest "rollouttest"
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:2
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "左侧" width:80 height:30 across:2
|
||||||
|
button btn04 "右侧" width:80 height:30
|
||||||
|
button btn05 "左侧" width:80 height:30 across:2
|
||||||
|
button btn06 "右侧" width:80 height:30
|
||||||
|
button btn07 "左侧" width:80 height:30 across:2
|
||||||
|
button btn08 "右侧" width:80 height:30
|
||||||
|
button btn09 "左侧" width:80 height:30 across:2
|
||||||
|
button btn10 "右侧" width:80 height:30
|
||||||
|
button btn11 "左侧" width:80 height:30 across:2
|
||||||
|
button btn12 "右侧" width:80 height:30
|
||||||
|
button btn13 "左侧" width:80 height:30 across:2
|
||||||
|
button btn14 "右侧" width:80 height:30
|
||||||
|
button btn15 "左侧" width:80 height:30 across:2
|
||||||
|
button btn16 "右侧" width:80 height:30
|
||||||
|
button btn17 "左侧" width:80 height:30 across:2
|
||||||
|
button btn18 "右侧" width:80 height:30
|
||||||
|
button btn19 "左侧" width:80 height:30 across:2
|
||||||
|
button btn20 "右侧" width:80 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout subrollouttest02 "rollouttest02" width:200
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:2
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "左侧" width:80 height:30 across:2
|
||||||
|
button btn04 "右侧" width:80 height:30
|
||||||
|
button btn05 "左侧" width:80 height:30 across:2
|
||||||
|
button btn06 "右侧" width:80 height:30
|
||||||
|
button btn07 "左侧" width:80 height:30 across:2
|
||||||
|
button btn08 "右侧" width:80 height:30
|
||||||
|
button btn09 "左侧" width:80 height:30 across:2
|
||||||
|
button btn10 "右侧" width:80 height:30
|
||||||
|
button btn11 "左侧" width:80 height:30 across:2
|
||||||
|
button btn12 "右侧" width:80 height:30
|
||||||
|
button btn13 "左侧" width:80 height:30 across:2
|
||||||
|
button btn14 "右侧" width:80 height:30
|
||||||
|
button btn15 "左侧" width:80 height:30 across:2
|
||||||
|
button btn16 "右侧" width:80 height:30
|
||||||
|
button btn17 "左侧" width:80 height:30 across:2
|
||||||
|
button btn18 "右侧" width:80 height:30
|
||||||
|
button btn19 "左侧" width:80 height:30 across:2
|
||||||
|
button btn20 "右侧" width:80 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout subrollouttest03 "rollouttest03" width:200
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:2
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "左侧" width:80 height:30 across:2
|
||||||
|
button btn04 "右侧" width:80 height:30
|
||||||
|
button btn05 "左侧" width:80 height:30 across:2
|
||||||
|
button btn06 "右侧" width:80 height:30
|
||||||
|
button btn07 "左侧" width:80 height:30 across:2
|
||||||
|
button btn08 "右侧" width:80 height:30
|
||||||
|
button btn09 "左侧" width:80 height:30 across:2
|
||||||
|
button btn10 "右侧" width:80 height:30
|
||||||
|
button btn11 "左侧" width:80 height:30 across:2
|
||||||
|
button btn12 "右侧" width:80 height:30
|
||||||
|
button btn13 "左侧" width:80 height:30 across:2
|
||||||
|
button btn14 "右侧" width:80 height:30
|
||||||
|
button btn15 "左侧" width:80 height:30 across:2
|
||||||
|
button btn16 "右侧" width:80 height:30
|
||||||
|
button btn17 "左侧" width:80 height:30 across:2
|
||||||
|
button btn18 "右侧" width:80 height:30
|
||||||
|
button btn19 "左侧" width:80 height:30 across:2
|
||||||
|
button btn20 "右侧" width:80 height:30
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout rollouttest "rollout测试" width:300
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30 across:3
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn05 "浮动" width:80 height:30
|
||||||
|
button btn06 "功能" width:80 height:30
|
||||||
|
subrollout RTleft "" width:280 height:650
|
||||||
|
|
||||||
|
|
||||||
|
on btn01 pressed do cui.dockDialogBar rollouttest #cui_dock_left
|
||||||
|
on btn02 pressed do cui.dockDialogBar rollouttest #cui_dock_right
|
||||||
|
on btn05 pressed do cui.floatDialogBar rollouttest
|
||||||
|
on btn06 pressed do print (cui.getDockState rollouttest)
|
||||||
|
)
|
||||||
|
CreateDialog rollouttest
|
||||||
|
|
||||||
|
cui.registerDialogBar rollouttest style:#(#cui_dock_all,#cui_floatable)
|
||||||
|
cui.dockDialogBar rollouttest #cui_dock_left
|
||||||
|
|
||||||
|
|
||||||
|
addsubrollout rollouttest.RTleft subrollouttest
|
||||||
|
addsubrollout rollouttest.RTleft subrollouttest02 rolledup:true
|
||||||
|
addsubrollout rollouttest.RTleft subrollouttest03 rolledup:true
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
if rollouttest != undefined then
|
||||||
|
try(
|
||||||
|
cui.unRegisterDialogBar rollouttest
|
||||||
|
DestroyDialog rollouttest
|
||||||
|
)catch()
|
||||||
|
|
||||||
|
|
||||||
|
rollout rollouttest "rollouttest" width:200
|
||||||
|
(
|
||||||
|
button btn01 "左侧" width:80 height:30
|
||||||
|
button btn02 "右侧" width:80 height:30
|
||||||
|
button btn03 "上侧" width:80 height:30
|
||||||
|
button btn04 "下侧" width:80 height:30
|
||||||
|
button btn05 "浮动" width:80 height:30
|
||||||
|
button btn06 "功能" width:80 height:30
|
||||||
|
|
||||||
|
on btn01 pressed do cui.dockDialogBar rollouttest #cui_dock_left
|
||||||
|
on btn02 pressed do cui.dockDialogBar rollouttest #cui_dock_right
|
||||||
|
on btn03 pressed do cui.dockDialogBar rollouttest #cui_dock_top
|
||||||
|
on btn04 pressed do cui.dockDialogBar rollouttest #cui_dock_bottom
|
||||||
|
on btn05 pressed do cui.floatDialogBar rollouttest
|
||||||
|
on btn06 pressed do print (cui.getDockState rollouttest)
|
||||||
|
)
|
||||||
|
CreateDialog rollouttest
|
||||||
|
|
||||||
|
cui.registerDialogBar rollouttest style:#(#cui_dock_all,#cui_floatable)
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
localTime --"2022/9/27 9:35:42"
|
||||||
|
execute ("2022") --2022
|
||||||
|
filterString "2022/9/27 9:35:42" "/" --#("2022", "9", "27 9:35:42")
|
||||||
|
timeStamp() --返回当日0:00起所经历的毫秒数
|
||||||
|
getLocalTime() --#(2022, 9, 2, 27, 9, 40, 20, 612) 年月星期日小时分钟秒毫秒
|
||||||
|
getUniversalTime() --#(2022, 9, 2, 27, 1, 42, 22, 727) 返回协调世界时间UTC
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
--paramWire.start() --视口中选择了一个对象时才可以用,作用是启动参数连接
|
||||||
|
--paramWire.openEditor() --打开参数连接管理器
|
||||||
|
|
||||||
|
|
||||||
|
--paramWire.editParams $box001.baseobject[#width] $box002.baseobject[#height] --打开左右指定参数连接管理器
|
||||||
|
|
||||||
|
--paramWire.editParam $box001.baseobject[#width] --仅打开左侧指定参数参数管理器
|
||||||
|
|
||||||
|
--paramWire.editParam $box001.baseobject[#width] --访问对象本身属性width
|
||||||
|
--paramWire.editParam $box001.bend[#angle] --访问对象修改器属性angle
|
||||||
|
--paramWire.editParam $box001[#transform][#position][#x_position]--访问对象变换属性pos.x
|
||||||
|
|
||||||
|
--paramWire.Connect $box001.baseobject[#width] $box002.baseobject[#height] "宽度*2" --单项左连接右属性
|
||||||
|
--paramWire.Connect $box001[#transform][#position][#x_position] $box002[#transform][#position][#x_position] "x_位置+100" --单项左连接右属性
|
||||||
|
--paramWire.disconnect $box002.height.controller
|
||||||
|
--//注意:断开的是被控制的属性,不是主动控制属性
|
||||||
|
|
||||||
|
--paramWire.disconnect $box002.position.controller[1]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--paramWire.connect2Way $box001.baseobject[#length] $box002.baseobject[#length] "长度*2" "长度*2"
|
||||||
|
--双向连接左右属性,注意,右属性对左属性的影响会使左属性重新刷新,故尽量单项连接
|
||||||
|
--paramWire.connect2Way $box001[#transform][#position][#x_position] $box002[#transform][#position][#x_position] "x_位置+100" "x_位置-100" --单项左连接右属性
|
||||||
|
--paramWire.disconnect2Way $box001.position.controller[1] $box002.position.controller[1]
|
||||||
|
--断开双向连接左右属性
|
||||||
|
|
||||||
|
--//注意:单向连接和双向连接不同,不可互相混用
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
global bywn=#()
|
||||||
|
global cywn=1
|
||||||
|
global btnname="ÕâÊÇÒ»¸ö°´Å¥mac..."
|
||||||
|
callbacks.removeScripts #selectionSetChanged id:#Rollout
|
||||||
|
|
||||||
|
fn xianshi=
|
||||||
|
(
|
||||||
|
try(
|
||||||
|
for i=1 to selection.count do bywn[i]=selection[i].name
|
||||||
|
cywn=cywn-1
|
||||||
|
)catch cywn=cywn+1
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
fn hello = print "hello"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rollout test "test"
|
||||||
|
(
|
||||||
|
|
||||||
|
button Anims btnname
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on Anims pressed do
|
||||||
|
(
|
||||||
|
print cywn
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on test open do
|
||||||
|
(
|
||||||
|
callbacks.addScript #selectionSetChanged "hello() xianshi()" id:#Rollout
|
||||||
|
)
|
||||||
|
|
||||||
|
on test close do
|
||||||
|
(
|
||||||
|
callbacks.removeScripts #selectionSetChanged id:#Rollout
|
||||||
|
)
|
||||||
|
)
|
||||||
|
createdialog test
|
||||||
|
|
||||||
|
|
||||||
|
--registerRedrawViewsCallback xianshi
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
|
||||||
|
--//图层名称必须唯一
|
||||||
|
--a=$Sphere001
|
||||||
|
--b=$Sphere002
|
||||||
|
|
||||||
|
--layer0=LayerManager.getLayer 0--//获取图层
|
||||||
|
|
||||||
|
|
||||||
|
--LayerManager.newLayer() --//新建图层
|
||||||
|
--LayerManager.count --//总图层数量
|
||||||
|
|
||||||
|
--layer1=LayerManager.getLayer 1 --//获取图层
|
||||||
|
|
||||||
|
--layer1.addnodes #(a,b) --//添加节点到图层
|
||||||
|
|
||||||
|
--layer0.addnodes b --//添加节点到图层
|
||||||
|
|
||||||
|
|
||||||
|
--layer1.setname "我是图层1"
|
||||||
|
--//设置图层名称,返回值如果是false则说明重名
|
||||||
|
--//返回值是undefined则说明有重名图层
|
||||||
|
|
||||||
|
--layer1.addnodes $
|
||||||
|
--layer1.select on --//选择图层中所有节点,不会选择本图层或者子图层中的节点
|
||||||
|
--layer1.select off --//取消选择图层中所有
|
||||||
|
|
||||||
|
--layer2= layermanager.newLayerFromName "我是图层2" --//使用名称新建图层
|
||||||
|
|
||||||
|
--layer1.nodes &abc --//返回层上所有节点到abc数组中,&符号必须有
|
||||||
|
--print abc
|
||||||
|
|
||||||
|
|
||||||
|
--layerparent=layer3.getparent() --//获取layer3图层的父层,如果没有,返回undefined
|
||||||
|
--layerparent.name
|
||||||
|
--layer2.setparent layer0--//设置layer2的父层为layer0
|
||||||
|
|
||||||
|
|
||||||
|
--templayer=layer1.getChild 3 --//返回图层1下的第3个图层,如果没有则返回undefined
|
||||||
|
--templayer.name
|
||||||
|
|
||||||
|
--layer1.getNumChildren() --//返回子图层的数量
|
||||||
|
|
||||||
|
--layer3=LayerManager.getLayerFromName "层0121201" --//以名称选择图层,没有则返回undefined
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--layer3.candelete() --//该操作不会删除图层,但如果可以删除图层,则返回True,如果由于某些其他原因而无法删除图层,则返回 False。
|
||||||
|
--layer3=LayerManager.deleteLayerByName "层001" --//以名称删除图层
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--layer3=LayerManager.getLayerFromName "我是图层1"
|
||||||
|
--num=layer3.getNumNodes()--//返回图层中所有节点数量,不包括子图层中的节点数
|
||||||
|
|
||||||
|
--layer3.on=false --//获取/设置图层的隐藏显示
|
||||||
|
--layer3.on=true
|
||||||
|
|
||||||
|
|
||||||
|
--layer3.lock=true --//获取/设置图层的冻结解冻
|
||||||
|
--layer3.lock=false
|
||||||
|
|
||||||
|
--layer0=LayerManager.getLayer 0
|
||||||
|
--layer0.name
|
||||||
|
|
||||||
|
--layer3.current=true--//获取/设置图层是否为当前图层,但只能设置为true,如果设置为false,为非法操作
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
try (destroyDialog imagetest001) catch()
|
||||||
|
|
||||||
|
rollout imagetest001 "imagetest001"
|
||||||
|
(
|
||||||
|
dotNetControl f1 "Windows.Forms.PictureBox" align:#left height:224 width:400 pos:[0,0]
|
||||||
|
timer clock "testClock" interval:33
|
||||||
|
label text001 "123"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
on clock tick do
|
||||||
|
(
|
||||||
|
lab="D:\%´´ÊÀÏîÄ¿¶¯×÷¿â\3dsmax\¹ÖÎï002\creature_arieki_kalastride_fidget_v01"+"\\"+((clock.ticks) as string)+".jpg"
|
||||||
|
text001.text = lab
|
||||||
|
imagetest001.f1.ImageLocation=lab
|
||||||
|
)
|
||||||
|
|
||||||
|
on imagetest001 open do clock.active=false
|
||||||
|
on f1 MouseEnter do (clock.ticks=0;clock.active=true)
|
||||||
|
on f1 MouseLeave do (clock.ticks=0;clock.active=false)
|
||||||
|
)
|
||||||
|
createDialog imagetest001 400 244
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
使用说明:https://help.autodesk.com/view/MAXDEV/2022/ENU/?guid=GUID-A6A60FC7-6206-4FFC-80E2-0EF8544BE2C4
|
||||||
|
|
||||||
|
findString "Thanks for all the fish!" "all"
|
||||||
|
-- returns 12
|
||||||
|
|
||||||
|
filterString "MAX Script, is-dead-funky" ", -"
|
||||||
|
#("MAX","Script","is","dead","funky")
|
||||||
|
|
||||||
|
s="1234567890"
|
||||||
|
s1=replace s 5 3 "inserted string"
|
||||||
|
-- returns "1234inserted string890"
|
||||||
|
|
||||||
|
s ="Balerofon"
|
||||||
|
ss = substring s 5 3-- returns "rof"
|
||||||
|
ss = substring s 5 -1-- returns "rofon"
|
||||||
|
ss = substring s 5 100-- returns "rofon"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
--in coordsys local selection.pos=[10,0,0]
|
||||||
|
--in coordsys local rotate selection (eulerangles 90 0 0)
|
||||||
|
--rotate $ (eulerangles 90 0 0)
|
||||||
|
--in coordsys world selection.pos=[10,0,0]
|
||||||
|
--in coordsys world rotate selection (eulerangles 0 -90 0)
|
||||||
|
--in coordsys parent
|
||||||
|
--in coordsys grid
|
||||||
|
--in coordsys screen
|
||||||
|
in coordsys $Teapot001 rotate selection (eulerangles 0 -90 0)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
custAttributes.add $Sphere001 the_weaponData --给名为Sphere001的物体添加自定义属性,可包括按钮和各种UI(名称后加*号表示所有相同开头的物体加属性)
|
||||||
|
--custAttributes.add $Sphere001.modifiers the_weaponData --给名为Sphere001的物体属性承载器添加自定义属性
|
||||||
|
|
||||||
|
|
||||||
|
the_weaponData = attributes weaponData
|
||||||
|
(
|
||||||
|
parameters main rollout:params
|
||||||
|
(
|
||||||
|
hitPoints type: #float ui:hits default:10
|
||||||
|
cost type: #float ui:cost default:100
|
||||||
|
sound type: #string
|
||||||
|
)
|
||||||
|
|
||||||
|
parameters main2 rollout:params2
|
||||||
|
(
|
||||||
|
-- hitPointss type: #float ui:hits default:10
|
||||||
|
-- costs type: #float ui:cost default:100
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rollout params "叶文斌属性1"
|
||||||
|
(
|
||||||
|
spinner hits "Hit Points" type: #float
|
||||||
|
spinner cost "Cost" type: #float
|
||||||
|
dropdownlist sound_dd "Sound" items:# ("boom","sparkle","zap","fizzle")
|
||||||
|
button havepressed "哈哈哈" width:100 height:50
|
||||||
|
|
||||||
|
|
||||||
|
on havepressed pressed do
|
||||||
|
(
|
||||||
|
print "cost.name="
|
||||||
|
print cost.name
|
||||||
|
print "cost="
|
||||||
|
print cost.value
|
||||||
|
print "sound="
|
||||||
|
print sound
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
rollout params2 "叶文斌属性飞过"
|
||||||
|
(
|
||||||
|
|
||||||
|
group "选项" (
|
||||||
|
radiobuttons uiRBtnLoadingType "第一" labels:#("Name", "Handle") default:1
|
||||||
|
checkbox uiCBoxAutoHide "第二" across:2
|
||||||
|
checkbox uiCBoxNonBipedMode "第三"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*属性访问方法:
|
||||||
|
直接访问:
|
||||||
|
$box01.hitPoints
|
||||||
|
$box01.cost
|
||||||
|
$box01.sound
|
||||||
|
方法二:通过属性块访问
|
||||||
|
$box01.weaponData.hitPoints
|
||||||
|
$box01.weaponData.cost
|
||||||
|
$box01.weaponData.sound
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
--//常识性
|
||||||
|
--$foo --在整个场景中查找名为foo的对象,如果有多个同名对象,将只会返回找到的第一个对象
|
||||||
|
--$/foo --将仅查找名为foo的顶级对象
|
||||||
|
--$/foo/foo1 --将仅查找foo子级下名为foo1的对象
|
||||||
|
|
||||||
|
/*--//在foo下创建一个box
|
||||||
|
in $foo
|
||||||
|
(
|
||||||
|
box()
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
|
--select $foo* --//旋转所有以foo名称开头的物体
|
||||||
|
|
||||||
|
|
||||||
|
--DisableSceneRedraw() --禁用场景绘制
|
||||||
|
--EnableSceneRedraw() --启用场景绘制
|
||||||
|
|
||||||
|
|
||||||
|
/*--//撤销块内的操作可以被撤销
|
||||||
|
undo on
|
||||||
|
(
|
||||||
|
delete $box002
|
||||||
|
delete $foo1
|
||||||
|
)
|
||||||
|
|
||||||
|
max undo --对刚刚的操作进行撤销
|
||||||
|
clearUndoBuffer() --清理撤销后无法再撤销操作
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*--//撤销块拥有标签 可以指定撤销哪一部分
|
||||||
|
undo "chexiao" on
|
||||||
|
(
|
||||||
|
delete $foo1
|
||||||
|
)
|
||||||
|
max undo "chexiao" --撤销名为“chexiao”的撤销块
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*--//with的用法是默认进入某种状态,完成操作后回到操作之前状态
|
||||||
|
--//with后面常跟animate,undo,redraw等操作
|
||||||
|
a=$foo1
|
||||||
|
with redraw off --//括号内的内容会在重绘关闭的时候操作,操作完后重绘重新打开
|
||||||
|
(
|
||||||
|
at time 0 a.length=100
|
||||||
|
at time 10 a.length=200
|
||||||
|
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*--//可将多个上下文前缀放在一行里面使用
|
||||||
|
animate on, at time 0, with undo, in coordsys local
|
||||||
|
(
|
||||||
|
|
||||||
|
)
|
||||||
|
*/
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
-------//控制器只能用控制器赋值,控制器下的子动画可用索引进行访问,但不可赋值
|
||||||
|
$box001.position.controller==position_list ()--//Position_XYZ ()
|
||||||
|
$box001.position.controller[1]
|
||||||
|
$box001.position.controller[2]
|
||||||
|
$box001.position.controller[3]
|
||||||
|
$box001.position.controller.x_position=0 --//控制器的属性允许赋值
|
||||||
|
$box001.pos.x
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
--$box001.rotation.controller=Euler_XYZ ()
|
||||||
|
--$box001.rotation.controller[1] --//访问的是控制器指针,指向控制器下的第一个子动画
|
||||||
|
--$box001.rotation.controller.X_Rotation.controller = tcb_float () --//访问的是控制器,并修改控制器
|
||||||
|
--$box001.rotation.controller.X_Rotation --//访问的是数值
|
||||||
|
--$box001.rotation.controller.'X 轴旋转' --//中英文版本相同,但是参数连接器中不同
|
||||||
|
--$box001.rotation.controller[2]
|
||||||
|
--$box001.rotation.controller[3]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--//以下可用于控制器列表
|
||||||
|
--$box001.rotation.controller=rotation_list ()--//tcb_rotation ()--//Euler_XYZ ()
|
||||||
|
--//尽量仅执行一次,多次执行会多次添加列表控制器
|
||||||
|
--$box001.rotation.controller.list
|
||||||
|
--$box001.rotation.controller.available.controller=tcb_rotation () --在列表中新添加控制器
|
||||||
|
--$box001.rotation.controller.getcount() --获取控制器列表中的控制器数量
|
||||||
|
--$box001.rotation.controller.setactive 2 --设置激活控制器列表中第2个控制器
|
||||||
|
--$box001.rotation.controller.getactive()--获取控制器列表中第几个控制器是激活的
|
||||||
|
--$box001.rotation.controller.delete 2 --删除第2个控制器
|
||||||
|
--$box001.rotation.controller.getname 2 --获取第2个控制器名称
|
||||||
|
--$box001.rotation.controller.setname 2 "ywb" --设置第2个控制器名称,仅设置名称而已
|
||||||
|
--$box001.rotation.controller.ywb.lookat_vector_length=201 --设置控制器某个属性的值
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--$box001.rotation.controller.setname 5 "xuanzhuanliebiao"
|
||||||
|
|
||||||
|
--$box001.rotation.controller.x_rotation --//四元数/矩阵表示旋转
|
||||||
|
--$box001.rotation.x
|
||||||
|
|
||||||
|
/*
|
||||||
|
$box001.scale.controller=ScaleXYZ()--//bezier_scale ()
|
||||||
|
$box001.scale.controller[1]
|
||||||
|
$box001.scale.controller[2]
|
||||||
|
$box001.scale.controller[3]
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
--必须安装有excel才能进行操作,否则报错
|
||||||
|
|
||||||
|
-- 创建Excel应用程序对象
|
||||||
|
excelApp = createOLEObject "Excel.Application"
|
||||||
|
|
||||||
|
-- 显示Excel应用程序
|
||||||
|
excelApp.Visible = false
|
||||||
|
|
||||||
|
-- 创建一个新的工作簿
|
||||||
|
--workbook = excelApp.Workbooks.Add()
|
||||||
|
workbook=excelApp.Workbooks.open(excelFile)
|
||||||
|
|
||||||
|
-- 获取活动工作表
|
||||||
|
sheet = workbook.ActiveSheet
|
||||||
|
|
||||||
|
-- 写入数据到单元格A1
|
||||||
|
(sheet.Cells 1 1).Value = "Hello"
|
||||||
|
(sheet.Cells 1 2).Value = "World!"
|
||||||
|
|
||||||
|
-- 保存工作簿到指定路径
|
||||||
|
--workbook.SaveAs "D:\\Desktop\\123.xlsx"
|
||||||
|
workbook.Save()
|
||||||
|
|
||||||
|
-- 关闭工作簿
|
||||||
|
workbook.Close()
|
||||||
|
|
||||||
|
-- 退出Excel应用程序
|
||||||
|
excelApp.Quit()
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Startup Ops
|
||||||
|
-- Generate a filename
|
||||||
|
--这里是excel文件的绝对路径
|
||||||
|
excelFile = "D:\\Desktop\\123.xlsx"
|
||||||
|
|
||||||
|
-- Start an Excel OLE Object
|
||||||
|
x = CreateOLEObject "Excel.Application"
|
||||||
|
|
||||||
|
-- Create a new workbook in the new excel document
|
||||||
|
x.application.Workbooks.open(excelFile)
|
||||||
|
|
||||||
|
-- This makes Excel Visible
|
||||||
|
-- true的话脚本运行时看到打开excel
|
||||||
|
x.visible = false
|
||||||
|
|
||||||
|
--示例 获取表中1,1位置的数据
|
||||||
|
pictureNum = (x.ActiveSheet.Cells 1 1).Value
|
||||||
|
(x.ActiveSheet.Cells 1 1).Value="12345"
|
||||||
|
|
||||||
|
--之后是释放操作,如果未执行会导致excel文件一直被占用,只能以只读被打开
|
||||||
|
-- Cleanup Ops
|
||||||
|
-- Close the spreadsheet
|
||||||
|
x.application.ActiveWorkbook.Close
|
||||||
|
|
||||||
|
-- quit excel
|
||||||
|
x.quit()
|
||||||
|
|
||||||
|
-- Release the OLE Object
|
||||||
|
releaseOLEObject x
|
||||||
|
|
||||||
|
-- Release ALL OLE Objects, just in case
|
||||||
|
releaseAllOLEObjects()
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
a=#("a","b","c","d","e")
|
||||||
|
b=#("x","y","z")
|
||||||
|
c="s"
|
||||||
|
append a "f"
|
||||||
|
appendIfUnique a "f" --对比如果有 则附加
|
||||||
|
deleteitem a a.count --删除a索引位置的元素
|
||||||
|
join a b --只能是数组 不能join a c
|
||||||
|
insertItem c a 3 --把c插入a的第3个位置
|
||||||
|
findItem a "k" --寻找不成功返回0 成功返回索引
|
||||||
|
a
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
f=fopen "C:\Users\ab\Desktop\a.bin" "wb"
|
||||||
|
WriteString f "String"
|
||||||
|
WriteByte f 64
|
||||||
|
WriteShort f 128
|
||||||
|
WriteLong f 256
|
||||||
|
WriteFloat f 512.0
|
||||||
|
WriteString f "gnirtS"
|
||||||
|
WriteLong f (ftell f)
|
||||||
|
fclose f
|
||||||
|
f=fopen "C:\Users\ab\Desktop\a.bin" "rb"
|
||||||
|
ReadString f
|
||||||
|
ReadByte f
|
||||||
|
ReadShort f
|
||||||
|
ReadLong f
|
||||||
|
ReadFloat f
|
||||||
|
ReadString f
|
||||||
|
ftell f
|
||||||
|
ReadLong f
|
||||||
|
fclose f
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
--filename = getOpenFileName()
|
||||||
|
--filepath=getSavePath caption:"mt" initialdir:"D:\Users\ab\Desktop\1"
|
||||||
|
arr=getfiles "D:\Bip动作库\bip\走路\*"
|
||||||
|
dir=getDirectories "D:\Bip动作库\bip\*"
|
||||||
|
print dir
|
||||||
|
print arr
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
a=createfile "C:\Users\ab\Desktop\\test.txt"
|
||||||
|
b=10
|
||||||
|
print 5 to:a
|
||||||
|
format "%,%\n" 1 2 to:a
|
||||||
|
print b to:a
|
||||||
|
format "%,%\n" 3 4 to:a
|
||||||
|
|
||||||
|
close a
|
||||||
|
free a
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
openf=openfile "C:\Users\ab\Desktop\\test.txt"
|
||||||
|
if openf !=undefined then
|
||||||
|
(
|
||||||
|
i=readValue openf
|
||||||
|
j=readline openf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
k=readValue openf
|
||||||
|
|
||||||
|
format "filepos=%\n" (filepos openf)
|
||||||
|
|
||||||
|
seek openf 0
|
||||||
|
l=readValue openf
|
||||||
|
m=readValue openf
|
||||||
|
|
||||||
|
format "i=%\n" i
|
||||||
|
format "j=%\n" j
|
||||||
|
format "k=%\n" k
|
||||||
|
format "l=%\n" l
|
||||||
|
format "m=%\n" m
|
||||||
|
|
||||||
|
|
||||||
|
format "\n\n"
|
||||||
|
print j
|
||||||
|
|
||||||
|
eof openf
|
||||||
|
flush openf
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
free openf
|
||||||
|
close openf
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
--//坐标解释
|
||||||
|
--//在表达式、操作或块表达式前面加上上下文前缀会导致在指定的坐标系中解释3D坐标操作
|
||||||
|
--//注:用法类似于animate on 仅影响块、后续表达式或下一行表达式
|
||||||
|
/*
|
||||||
|
in coordsys world --//使用世界坐标系
|
||||||
|
in coordsys local --//使用局部坐标系
|
||||||
|
in coordsys parent --//使用父级坐标系
|
||||||
|
in coordsys grid --//使用活动网格坐标系
|
||||||
|
in coordsys screen --//使用屏幕坐标系
|
||||||
|
in coordsys <node> --//使用节点对象坐标系
|
||||||
|
in coordsys <Matrix3> --//使用3D矩阵坐标系
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--//欧拉旋转
|
||||||
|
--a=$Box002
|
||||||
|
--rot=EulerAngles 0 10 0 --//定义一个特殊的欧拉对象rot
|
||||||
|
--rotate a rot --//将欧拉对象应用于对象a
|
||||||
|
--rotate a (EulerAngles 0 10 0) --//与上式等效
|
||||||
|
--rotate a 10 y_axis --//与上式等效
|
||||||
|
|
||||||
|
|
||||||
|
--//例如:
|
||||||
|
--in coordsys local selection.pos=random[-20,0,0][20,0,0] --//局部x轴随机位移-20到20的距离
|
||||||
|
--in coordsys local rotate selection (EulerAngles 0 10 0) --//局部坐标轴下绕y轴旋转10度
|
||||||
|
--in coordsys world rotate selection (EulerAngles 10 0 0) --//世界坐标轴下绕y轴旋转10度
|
||||||
|
--in coordsys world rotate selection 10 y_axis --//世界坐标轴下绕y轴旋转10度
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
function local_sys_time= -----获取时间的函数,返回值是字符串
|
||||||
|
(
|
||||||
|
local local_time=timeStamp()
|
||||||
|
local shijian=(((local_time/1000.0)/60.0)/60.0)
|
||||||
|
local xiaoshi=shijian as integer
|
||||||
|
local fenzhong=((shijian-xiaoshi)*60) as integer
|
||||||
|
local kkk=(local_time/1000.0)-xiaoshi*60.0*60.0-fenzhong*60.0
|
||||||
|
local miao=((local_time/1000.0)-xiaoshi*60.0*60.0-fenzhong*60.0 )as integer
|
||||||
|
local haomiao=((kkk-miao)*100) as integer
|
||||||
|
local h=xiaoshi as string
|
||||||
|
local m=fenzhong as string
|
||||||
|
local s=miao as string
|
||||||
|
local f=haomiao as string
|
||||||
|
return ("当前时间为:"+h+"小时"+m+"分钟"+s+"秒"+f)
|
||||||
|
)
|
||||||
|
|
||||||
|
a=local_sys_time()
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*fn shape001=
|
||||||
|
(
|
||||||
|
ss=SplineShape()
|
||||||
|
addNewSpline ss
|
||||||
|
addKnot ss 1 #corner #curve [0,0,0]
|
||||||
|
addKnot ss 1 #corner #curve [100,0,0]
|
||||||
|
|
||||||
|
addNewSpline ss
|
||||||
|
addKnot ss 2 #corner #curve [0,10,0]
|
||||||
|
addKnot ss 2 #corner #curve [100,10,0]
|
||||||
|
|
||||||
|
|
||||||
|
addNewSpline ss
|
||||||
|
addKnot ss 3 #corner #curve [0,20,0]
|
||||||
|
addKnot ss 3 #corner #curve [100,20,0]
|
||||||
|
|
||||||
|
updateShape ss
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
addKnot ss 2 #corner #curve [200,10,0]
|
||||||
|
updateShape ss
|
||||||
|
ss.pos=[0,0,100]
|
||||||
|
|
||||||
|
|
||||||
|
a=Rectangle()
|
||||||
|
convertToSplineShape a
|
||||||
|
b=Circle()
|
||||||
|
convertToSplineShape b
|
||||||
|
|
||||||
|
|
||||||
|
addAndWeld a ss 0
|
||||||
|
|
||||||
|
addAndWeld a b 0
|
||||||
|
|
||||||
|
updateShape a
|
||||||
|
|
||||||
|
return a
|
||||||
|
)
|
||||||
|
|
||||||
|
b=shape001()
|
||||||
|
print "***************"
|
||||||
|
print b*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*for shapes in selection do
|
||||||
|
(
|
||||||
|
if not isShapeObject shapes do continue
|
||||||
|
print "123"
|
||||||
|
)*/
|
||||||
|
--isShapeObject shapes--判断曲线
|
||||||
|
--numSplines shapes --曲线对象包含几根
|
||||||
|
--numKnots shapes i --第i条曲线节点数量
|
||||||
|
--getKnotPoint shapes i j--第i条曲线第j个顶点位置
|
||||||
|
--$.transform
|
||||||
|
--inverse $.transform
|
||||||
|
|
||||||
|
/*getPointController $ 1 2*/
|
||||||
|
--if keyboard.escPressed then exit
|
||||||
|
--setKnotPoint shapes i j transvertTM.position
|
||||||
|
/*setKnotPoint $ 1 1 [100,0,0]
|
||||||
|
setKnotPoint $ 1 2 [200,0,0]
|
||||||
|
setKnotPoint $ 1 3 [300,0,0]
|
||||||
|
updateShape $*/
|
||||||
|
|
||||||
|
--DisableSceneRedraw()--关闭视口场景绘制
|
||||||
|
--completeRedraw()--视口刷新
|
||||||
|
--ForceCompleteRedraw()--所有视口强制刷新
|
||||||
|
--redrawViews()--仅刷新已经更改的部分
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--makedir "C:\\Users\\ab\\Desktop\\yewenbin\\" --建立文件夹
|
||||||
|
--setINISetting "$scripts\\DTools\jiaoben_weizhi.ini" "splineAnime" "splineAnime_weizhi" (splineAnime_weizhi as string )
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
(
|
||||||
|
-- 这是一个关于如何使用MySQL Connector查询MySQL数据库的小教程。
|
||||||
|
-- 本教程假设您已经设置了MySQL服务器,安装了MySQL Connector(可在MySQL官网找到),并且具有SQL的基本知识。
|
||||||
|
|
||||||
|
-- 我将在不久的将来创建一个更易于使用的封装。
|
||||||
|
-- 祝您愉快。
|
||||||
|
-- Ofer Zelichover(www.oferz.com)2008-03-08
|
||||||
|
--ySQL Connector下载链接:https://www.mysql.com/products/connector 下载时选择.net版本就行,一路默认安装即可
|
||||||
|
-- 首先加载dotNet程序集。确保字符串指向安装了MySQL Connector DLL文件的位置。
|
||||||
|
dotNet.loadAssembly "C:\\Program Files (x86)\\MySQL\\MySQL Connector NET 8.2.0\\MySql.Data.dll"
|
||||||
|
|
||||||
|
-- 现在定义连接参数。
|
||||||
|
local host = "localhost" -- MySQL服务器的名称
|
||||||
|
local database = "test" -- 要使用的数据库的名称
|
||||||
|
local user = "test" -- 要使用的用户名
|
||||||
|
local password = "test" -- 要使用的密码
|
||||||
|
|
||||||
|
-- 构建连接字符串
|
||||||
|
local connectionString = "Database=" + database + ";Data Source=" + host + ";User Id=" + user + ";Password=" + password
|
||||||
|
|
||||||
|
-- 创建连接对象
|
||||||
|
local DBConnection = dotNetObject "MySql.Data.MySqlClient.MySqlConnection"
|
||||||
|
-- 使用连接字符串设置连接参数。
|
||||||
|
DBConnection.ConnectionString = connectionString
|
||||||
|
-- 打开数据库连接
|
||||||
|
DBConnection.open()
|
||||||
|
|
||||||
|
-- 打印连接状态:1 - 已连接;0 - 未连接。
|
||||||
|
print DBConnection.state.value__
|
||||||
|
|
||||||
|
|
||||||
|
-- 添加两行新记录
|
||||||
|
local cmdObject = DBConnection.CreateCommand()
|
||||||
|
cmdObject.commandText = "INSERT INTO test_table (`name`, `phone`) VALUES ('另一个名字','1234567890'), ('又一个名字','2468101214')"
|
||||||
|
local readerObject = cmdObject.ExecuteReader()
|
||||||
|
-- 打印受影响的行数
|
||||||
|
format "添加了 % 行\n" readerObject.RecordsAffected
|
||||||
|
readerObject.close()
|
||||||
|
|
||||||
|
|
||||||
|
-- 更改表中第二行的值:
|
||||||
|
local cmdObject = DBConnection.CreateCommand()
|
||||||
|
cmdObject.commandText = "UPDATE test_table tt SET tt.name='修改后的名字', tt.phone=78978979 WHERE tt.id=2"
|
||||||
|
local readerObject = cmdObject.ExecuteReader()
|
||||||
|
-- 打印受影响的行数
|
||||||
|
format "修改了 % 行\n" readerObject.RecordsAffected
|
||||||
|
readerObject.close()
|
||||||
|
|
||||||
|
|
||||||
|
-- 查询数据库:
|
||||||
|
-- 首先创建一个命令对象。该对象用于将查询发送到数据库。
|
||||||
|
local cmdObject = DBConnection.CreateCommand()
|
||||||
|
-- 定义要执行的SQL查询:
|
||||||
|
cmdObject.commandText = "SELECT * FROM test_table tt"
|
||||||
|
-- 然后执行命令以创建读取器对象。
|
||||||
|
local readerObject = cmdObject.ExecuteReader()
|
||||||
|
|
||||||
|
-- 打印结果中的字段名:
|
||||||
|
for i = 0 to (readerObject.FieldCount - 1) do
|
||||||
|
print (readerObject.getName i)
|
||||||
|
|
||||||
|
-- 打印结果:
|
||||||
|
-- readerObject.read()方法将读取器对象中的记录移至下一条记录。
|
||||||
|
while readerObject.read() do (
|
||||||
|
local record = readerObject.item
|
||||||
|
-- 现在打印记录的值。这假设您知道字段名:
|
||||||
|
format "%\t%\t%\n" record["id"] record["name"] record["phone"]
|
||||||
|
|
||||||
|
-- 如果不想使用显式字段名,还有另一种选择:
|
||||||
|
for i = 0 to (readerObject.FieldCount - 1) do
|
||||||
|
format "%\t" record[i]
|
||||||
|
format "\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
-- 关闭读取器对象
|
||||||
|
readerObject.close()
|
||||||
|
|
||||||
|
-- 关闭连接
|
||||||
|
DBConnection.close()
|
||||||
|
)
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
dotNet.loadAssembly "C:\\Program Files (x86)\\MySQL\\MySQL Connector NET 8.2.0\\MySql.Data.dll"
|
||||||
|
|
||||||
|
host = "81.71.134.168" -- The name of the MySQL server
|
||||||
|
database = "admin" -- The name of the database to use
|
||||||
|
user = "admin123" -- The user name to use
|
||||||
|
password = "aiAtB23yajDj2Lpa" -- The password to use
|
||||||
|
connectionString = "Database=" + database + ";Data Source=" + host + ";User Id=" + user + ";Password=" + password
|
||||||
|
DBConnection = dotNetObject "MySql.Data.MySqlClient.MySqlConnection"
|
||||||
|
DBConnection.ConnectionString = connectionString
|
||||||
|
DBConnection.open()
|
||||||
|
-- Print the connection status: 1 - connected; 0 - not connected.
|
||||||
|
print DBConnection.state.value__
|
||||||
|
|
||||||
|
-- Add a new rows
|
||||||
|
cmdObject = DBConnection.CreateCommand()
|
||||||
|
cmdObject.commandText ="INSERT INTO `admin`.`students`(`id`, `name`, `age`, `score`, `birthday`, `insert_time`) VALUES (132, 'name03', 16, 35, '2023-11-23', '2023-12-13 10:50:56')"
|
||||||
|
|
||||||
|
readerObject = cmdObject.ExecuteReader()
|
||||||
|
-- 打印受影响的行数
|
||||||
|
format "添加了 % 行\n" readerObject.RecordsAffected
|
||||||
|
readerObject.close()
|
||||||
|
|
||||||
|
-- 查询数据库:
|
||||||
|
-- 首先创建一个命令对象。该对象用于将查询发送到数据库。
|
||||||
|
cmdObject = DBConnection.CreateCommand()
|
||||||
|
-- 定义要执行的SQL查询:
|
||||||
|
cmdObject.commandText = "SELECT * FROM `admin`.`students`"
|
||||||
|
-- 然后执行命令以创建读取器对象。
|
||||||
|
readerObject = cmdObject.ExecuteReader()
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
try(destroyDialog YeomaiDataBaseConnectionTest)catch()
|
||||||
|
try(dotNet.loadAssembly "C:\\Program Files (x86)\\MySQL\\MySQL Connector NET 8.2.0\\MySql.Data.dll")catch(messagebox("dll载入失败,插件无法使用"))
|
||||||
|
rollout YeomaiDataBaseConnectionTest "无标题" width:837 height:639
|
||||||
|
(
|
||||||
|
label 'lbl1' "服务器" pos:[100,100] width:53 height:13 align:#right
|
||||||
|
label 'lbl2' "数据库名" pos:[100,130] width:53 height:13 align:#right
|
||||||
|
label 'lbl3' "用户名" pos:[100,160] width:23 height:13 align:#right
|
||||||
|
label 'lbl4' "密码" pos:[100,190] width:23 height:13 align:#right
|
||||||
|
editText 'host' "" pos:[170,100] width:241 height:22 align:#left text:"81.71.134.168"
|
||||||
|
editText 'database' "" pos:[170,130] width:241 height:22 align:#left text:"admin"
|
||||||
|
editText 'user' "" pos:[170,160] width:241 height:22 align:#left text:"admin123"
|
||||||
|
editText 'password' "" pos:[170,190] width:241 height:22 align:#left text:"aiAtB23yajDj2Lpa"
|
||||||
|
button 'btn1' "连接数据库" pos:[170,240] width:84 height:23 align:#left
|
||||||
|
button 'btn2' "断开数据库" pos:[280,240] width:84 height:23 align:#left
|
||||||
|
|
||||||
|
on 'btn1' pressed do(
|
||||||
|
connectionString = "Database=" + database.text + ";Data Source=" + host.text + ";User Id=" + user.text + ";Password=" + password.text
|
||||||
|
DBConnection = dotNetObject "MySql.Data.MySqlClient.MySqlConnection"
|
||||||
|
DBConnection.ConnectionString = connectionString
|
||||||
|
DBConnection.open()
|
||||||
|
if DBConnection.state.value__ then messagebox("连接成功!") else messagebox("连接失败!")
|
||||||
|
)
|
||||||
|
|
||||||
|
on 'btn2' pressed do(
|
||||||
|
-- 关闭连接
|
||||||
|
if DBConnection.state.value__ then (DBConnection.close();messagebox("断开连接!"))
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
createDialog YeomaiDataBaseConnectionTest
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
addModifier $ (Spline_IK_Control())
|
||||||
|
$.Spline_IK_Control.box=false
|
||||||
|
$.Spline_IK_Control.helper_cross = false
|
||||||
|
$.Spline_IK_Control.linktypes=2
|
||||||
|
|
||||||
|
|
||||||
|
$.Spline_IK_Control.gethelpercount()
|
||||||
|
$.Spline_IK_Control.getknotcount()
|
||||||
|
$.Spline_IK_Control.createhelper 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
a=$.Spline_IK_Control.helper_list[1]
|
||||||
|
a.pos=[100,0,0]
|
||||||
|
b=$.Spline_IK_Control.helper_list[2]
|
||||||
|
b.pos=[200,0,0]
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
set animate off
|
||||||
|
a=$Box002
|
||||||
|
b=$Box003
|
||||||
|
c=$Box004
|
||||||
|
--//位置约束
|
||||||
|
--a.pos.controller=Position_Constraint()
|
||||||
|
--a.pos.controller.appendTarget b 100 --添加Sphere005为约束目标 权重值为100
|
||||||
|
--a.pos.controller.relative=on --保持初始偏移
|
||||||
|
--a.pos.controller.getweight 4 --获取第四个约束的权重值
|
||||||
|
--a.pos.controller.setweight 3 60 --设置第三个约束的权重为60
|
||||||
|
--nodename=(a.pos.controller.getnode 1) --获取第1个约束的节点
|
||||||
|
--print nodename.name
|
||||||
|
--show a.pos.controller
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--//旋转约束
|
||||||
|
a.rotation.controller=Orientation_Constraint()
|
||||||
|
a.rotation.controller.appendTarget b 100
|
||||||
|
a.rotation.controller.relative=on
|
||||||
|
a.rotation.controller.getweight 2
|
||||||
|
a.rotation.controller.setweight 1 60
|
||||||
|
nodename=(a.rotation.controller.getnode 1)
|
||||||
|
print nodename.name
|
||||||
|
show a.pos.controller
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
--macroScript MicroPaint category: "HowTo"
|
||||||
|
(
|
||||||
|
global MicroPaint_CanvasRollout
|
||||||
|
try (destroyDialog MicroPaint_CanvasRollout) catch()
|
||||||
|
local isDrawing = false
|
||||||
|
local bitmapX = bitmapY = 512
|
||||||
|
global theCanvasBitmap = bitmap bitmapX bitmapY color:white
|
||||||
|
local currentPos = lastPos = [0,0]
|
||||||
|
|
||||||
|
rollout MicroPaint_CanvasRollout "MicroPaint"
|
||||||
|
(
|
||||||
|
bitmap theCanvas pos:[0,0] width:bitmapX height:bitmapY bitmap:theCanvasBitmap
|
||||||
|
colorpicker inkColor height:16 modal:false color:black across:4
|
||||||
|
checkbutton airBrush "AirBrush"width:50
|
||||||
|
spinner AirBrushSpeed "Speed" range:[0.1,50,10] fieldwidth:30
|
||||||
|
spinner BrushSize "Size" range:[1,50,10] type:#integer fieldwidth:40
|
||||||
|
listbox BrushShape items:#("Circle","Box","Circle Smooth") pos:[bitmapX+5,0] width:90
|
||||||
|
dotNetControl f1 "Windows.Forms.PictureBox" align:#left height:bitmapY width:bitmapX pos:[bitmapX+100,0]
|
||||||
|
|
||||||
|
fn paintBrush pos =
|
||||||
|
(
|
||||||
|
case BrushShape.selection of
|
||||||
|
(
|
||||||
|
1: (
|
||||||
|
if distance pos currentPos <= BrushSize.value/2 do
|
||||||
|
setPixels theCanvasBitmap pos #(inkColor.color)
|
||||||
|
)
|
||||||
|
2: setPixels theCanvasBitmap pos #(inkColor.color)
|
||||||
|
3: (
|
||||||
|
theFactor = (distance pos currentPos) / (BrushSize.value/2.0)
|
||||||
|
if theFactor <= 1.0 do
|
||||||
|
(
|
||||||
|
theFactor = sin ( 90.0 * theFactor)
|
||||||
|
thePixels = getPixels theCanvasBitmap pos 1
|
||||||
|
if thePixels[1] != undefined do
|
||||||
|
(
|
||||||
|
thePixels[1] = (thePixels[1] * theFactor) + (inkColor.color * (1.0 - theFactor))
|
||||||
|
setPixels theCanvasBitmap pos thePixels
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)--end case 3
|
||||||
|
)--end case
|
||||||
|
)--end fn
|
||||||
|
|
||||||
|
fn drawStroke lastPos pos =
|
||||||
|
(
|
||||||
|
currentPos = lastPos
|
||||||
|
deltaX = pos.x - lastPos.x
|
||||||
|
deltaY = pos.y - lastPos.y
|
||||||
|
maxSteps = amax #(abs(deltaX),abs(deltaY))
|
||||||
|
deltaStepX = deltaX / maxSteps
|
||||||
|
deltaStepY = deltaY / maxSteps
|
||||||
|
for i = 0 to maxSteps do
|
||||||
|
(
|
||||||
|
if airBrush.checked then
|
||||||
|
(
|
||||||
|
for b = 1 to (BrushSize.value / AirBrushSpeed.value) do
|
||||||
|
paintBrush (currentPos + (random [-BrushSize.value/2,-BrushSize.value/2] [BrushSize.value/2,BrushSize.value/2] ))
|
||||||
|
)
|
||||||
|
else
|
||||||
|
for b = -BrushSize.value/2 to BrushSize.value/2 do
|
||||||
|
for c = -BrushSize.value/2 to BrushSize.value/2 do
|
||||||
|
paintBrush (currentPos + [c,b])
|
||||||
|
currentPos += [deltaStepX, deltaStepY]
|
||||||
|
)
|
||||||
|
theCanvas.bitmap = theCanvasBitmap
|
||||||
|
/*
|
||||||
|
local grab_bmp1
|
||||||
|
grab_bmp1 = bitmap 512 512 color:white
|
||||||
|
copy theCanvasBitmap grab_bmp1
|
||||||
|
grab_bmp1.filename ="D:\\Desktop\\123.png"
|
||||||
|
save grab_bmp1
|
||||||
|
f1.ImageLocation="D:\\Desktop\\123.png"
|
||||||
|
*/
|
||||||
|
)
|
||||||
|
|
||||||
|
on MicroPaint_CanvasRollout lbuttondown pos do
|
||||||
|
(
|
||||||
|
lastPos = pos
|
||||||
|
isDrawing = true
|
||||||
|
drawStroke lastPos pos
|
||||||
|
)
|
||||||
|
on MicroPaint_CanvasRollout lbuttonup pos do isDrawing = false
|
||||||
|
on MicroPaint_CanvasRollout mousemove pos do
|
||||||
|
(
|
||||||
|
if isDrawing do drawStroke lastPos pos
|
||||||
|
lastPos = pos
|
||||||
|
)
|
||||||
|
)
|
||||||
|
createDialog MicroPaint_CanvasRollout (bitmapx+620) (bitmapy+30)
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
clearlistener(); showProperties MicroPaint_CanvasRollout.f1
|
||||||
|
MicroPaint_CanvasRollout.f1.ImageLocation="D:\\Desktop\\123.png"
|
||||||
|
show MicroPaint_CanvasRollout.theCanvas.bitmap
|
||||||
|
|
||||||
|
-- MicroPaint_CanvasRollout.f1.image= (dotnetclass "System.Drawing.Graphics").FromImage
|
||||||
|
*/
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
--脚本加密方法:
|
||||||
|
--例如encryptScript "C:\Users\ab\Desktop\DTrajEdit.ms" version:1
|
||||||
|
--version为0 使用max2-max9的旧加密方法 为1 使用max9 sp1中引入的新方案
|
||||||
|
--新方案无法在旧版max中运行
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
currentFolder001 = getFilenamePath (getThisScriptFilename())
|
||||||
|
|
||||||
|
rulesScript = pathConfig.appendPath currentFolder001 "\SpineBones.ms"
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
--菜单文件路径-保存--读取
|
||||||
|
--menuMan.getMenuFile()
|
||||||
|
--menuMan.saveMenuFile (menuMan.getMenuFile())
|
||||||
|
|
||||||
|
--注销已存在的菜单
|
||||||
|
try(menuMan.unRegisterMenu (menuMan.findMenu "叶文斌"))catch()
|
||||||
|
try(menuMan.unRegisterMenu (menuMan.findMenu "叶文斌(二级菜单)"))catch()
|
||||||
|
|
||||||
|
--宏脚本定义,会在#usermacroscript目录下生成宏脚本文件
|
||||||
|
macroScript Free_Camera category:"Yewenbin" tooltip:"Free Camera"
|
||||||
|
(
|
||||||
|
StartObjectCreation FreeCamera
|
||||||
|
)
|
||||||
|
|
||||||
|
macroScript Target_Camera category:"Yewenbin"
|
||||||
|
(
|
||||||
|
StartObjectCreation TargetCamera
|
||||||
|
)
|
||||||
|
|
||||||
|
macroScript 文件 category:"Yewenbin"
|
||||||
|
(
|
||||||
|
print "文件宏脚本"
|
||||||
|
)
|
||||||
|
|
||||||
|
--生成目录和子目录
|
||||||
|
menusmtool = menuman.createmenu "叶文斌"
|
||||||
|
menusmtool02 = menuman.createmenu "叶文斌(二级菜单)"
|
||||||
|
submainmenuitem = menuman.createsubmenuitem "A01第一个" menusmtool
|
||||||
|
submainmenuitem01 = menuman.createsubmenuitem "A02第二个" menusmtool02
|
||||||
|
|
||||||
|
|
||||||
|
SeparatorItem001=menuMan.createSeparatorItem()
|
||||||
|
macroScript001=menuMan.createActionItem "文件" "Yewenbin"
|
||||||
|
macroScript002=menuMan.createActionItem "Free_Camera" "Yewenbin"
|
||||||
|
macroScript003=menuMan.createActionItem "Target_Camera" "Yewenbin"
|
||||||
|
SeparatorItem001=menuMan.createSeparatorItem()
|
||||||
|
|
||||||
|
|
||||||
|
menusmtool.addItem macroScript001 1
|
||||||
|
menusmtool.addItem macroScript002 2
|
||||||
|
menusmtool.addItem SeparatorItem001 3
|
||||||
|
menusmtool.addItem macroScript003 4
|
||||||
|
menusmtool.addItem SeparatorItem001 5
|
||||||
|
|
||||||
|
|
||||||
|
menusmtool.addItem submainmenuitem01 6
|
||||||
|
menusmtool02.addItem macroScript001 1
|
||||||
|
menusmtool02.addItem macroScript002 2
|
||||||
|
menusmtool02.addItem SeparatorItem001 3
|
||||||
|
menusmtool02.addItem macroScript003 4
|
||||||
|
menusmtool02.addItem SeparatorItem001 5
|
||||||
|
|
||||||
|
|
||||||
|
mainmenubar = menuman.getmainmenubar()
|
||||||
|
mainmenubar.addItem submainmenuitem (mainmenubar.numItems()+1)
|
||||||
|
|
||||||
|
|
||||||
|
menuman.updatemenubar()
|
||||||
|
|
||||||
|
/*
|
||||||
|
findme=menuMan.findMenu "AAAyewenbin"
|
||||||
|
menuMan.unRegisterMenu findme
|
||||||
|
*/
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
x_old=gw.getWinSizeX()
|
||||||
|
y_old=gw.getWinSizeY()
|
||||||
|
gw.setPos 0 0 200 112 --设置视口从[0,0]开始,到[400,200]结束的大小
|
||||||
|
x= gw.getWinSizeX() --获取视口横向大小
|
||||||
|
y= gw.getWinSizeY() --获取视口竖向大小
|
||||||
|
grab_tempbmp1 = gw.getViewportDib() --生成视口缩略图(系统存放在一个临时变量中,api的返回值是一个临时变量,需要把它赋值出来)
|
||||||
|
gw.setPos 0 0 x_old y_old
|
||||||
|
grab_bmp1 = bitmap x y color:[0,0,0]
|
||||||
|
copy grab_tempbmp1 grab_bmp1
|
||||||
|
grab_bmp1.filename = "C:\Users\ab\Desktop\CopyPaste222.bmp"
|
||||||
|
save grab_bmp1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
--连续命名选择的物体为objects 以第一个可用的名称+序号开始
|
||||||
|
for i in selection do (i.name = uniqueName "objects")
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
小脚本说明:获取顶点位置的方法
|
||||||
|
|
||||||
|
yeomai_test=$shixinvpu_new
|
||||||
|
yeomai_helper=$Point001
|
||||||
|
disableSceneRedraw()
|
||||||
|
set animate on
|
||||||
|
for i=1 to polyop.getNumVerts yeomai_test do
|
||||||
|
(
|
||||||
|
at time i
|
||||||
|
yeomai_helper.pos=polyop.getVert yeomai_test i
|
||||||
|
)
|
||||||
|
set animate off
|
||||||
|
enableSceneRedraw()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
小脚本说明:获取控制器关键帧的方法
|
||||||
|
|
||||||
|
getKeyTime $.rotation.controller 1
|
||||||
|
getKeyTime $.rotation.controller (numKeys $.rotation.controller)
|
||||||
|
*/
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
This software makes use of the following components:
|
||||||
|
|
||||||
|
|
||||||
|
AudioToolsLibrary
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
Copyright (c) 2000-2002 by Jurgen Faul
|
||||||
|
Copyright (c) 2003-2005 by The MAC Team
|
||||||
|
Web: http://mac.sourceforge.net/atl/
|
||||||
|
Email: macteam@users.sourceforge.net
|
||||||
|
|
||||||
|
dEXIF
|
||||||
|
~~~~~
|
||||||
|
Copyright © 2001 - 2006 Gerry McGuire
|
||||||
|
Web: http://mcguirez.homestead.com/
|
||||||
|
|
||||||
|
PascalScript
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
Copyright © RemObjects Software
|
||||||
|
Web: http://www.remobjects.com/ps
|
||||||
|
|
||||||
|
RegExpr
|
||||||
|
~~~~~~~
|
||||||
|
Copyright (c) 1999-2004 Andrey V. Sorokin, St.Petersburg, Russia
|
||||||
|
Email: anso@mail.ru
|
||||||
|
Web: http://RegExpStudio.com
|
||||||
|
Web: http://anso.da.ru/
|
||||||
|
|
||||||
|
SimpleIPC
|
||||||
|
~~~~~~~~~
|
||||||
|
Copyright (c) 2002-2003 Sunisoft
|
||||||
|
Web: http://www.sunisoft.com
|
||||||
|
Email: support@sunisoft.com
|
||||||
|
|
||||||
|
SMComponents
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
Copyright (c) 1998-2005, written by Mike Shkolnik, Scalabium Software
|
||||||
|
Email: mshkolnik@scalabium
|
||||||
|
Email: mshkolnik@yahoo.com
|
||||||
|
Web: http://www.scalabium.com
|
||||||
|
|
||||||
|
Virtual Treeview
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
The initial developer of the original code is digital
|
||||||
|
publishing AG (www.digitalpublishing.de).
|
||||||
|
Virtual Treeview is written, published and maintaned by
|
||||||
|
Mike Lischke (public@soft-gems.net, www.soft-gems.net).
|
||||||
|
(c) 1999-2005 Mike Lischke, Soft Gems software solutions.
|
||||||
|
|
||||||
|
DCPCrypt
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
DCPcrypt is copyrighted (c) 1999-2003 David Barton.
|
||||||
|
All trademarks are property of their respective owners.
|
||||||
|
|
||||||
|
Farm-Fresh Web Icons
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Some icons were taken from Farm-Fresh Web Icons collection.
|
||||||
|
http://www.fatcow.com/free-icons
|
||||||
|
|
||||||
|
famfamfam Flag Icons
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
These icons are public domain, and as such are free for any use
|
||||||
|
(attribution appreciated but not required).
|
||||||
|
Contact: mjames@gmail.com
|
||||||
|
http://www.famfamfam.com
|
||||||
|
After Width: | Height: | Size: 643 B |
|
After Width: | Height: | Size: 408 B |
|
After Width: | Height: | Size: 604 B |
|
After Width: | Height: | Size: 591 B |
|
After Width: | Height: | Size: 643 B |
|
After Width: | Height: | Size: 600 B |
|
After Width: | Height: | Size: 497 B |
|
After Width: | Height: | Size: 488 B |
|
After Width: | Height: | Size: 428 B |
|
After Width: | Height: | Size: 506 B |
|
After Width: | Height: | Size: 647 B |
|
After Width: | Height: | Size: 403 B |
|
After Width: | Height: | Size: 673 B |
|
After Width: | Height: | Size: 524 B |
|
After Width: | Height: | Size: 663 B |
|
After Width: | Height: | Size: 589 B |
|
After Width: | Height: | Size: 593 B |
|
After Width: | Height: | Size: 585 B |
|
After Width: | Height: | Size: 504 B |
|
After Width: | Height: | Size: 449 B |
|
After Width: | Height: | Size: 497 B |
|
After Width: | Height: | Size: 462 B |
|
After Width: | Height: | Size: 457 B |
|
After Width: | Height: | Size: 675 B |