第1章:VEX语法核心(上)——变量声明、数据类型与常量
各位同学,欢迎来到VEX脚本的第一课。说实话,每次带新人学Houdini,我都是从这一章开始的。VEX的语法看着简单,但坑不少。今天咱们就把变量声明、数据类型、常量这些基础打牢。
1.1 变量声明:先声明,后使用
VEX是强类型语言。什么意思?就是每个变量在用之前,必须告诉它「你是什么类型」。我见过不少新手直接写 a = 10;,结果编译报错——嗯,VEX不认识这种写法。
正确的姿势是这样的:
int a = 10; // 整数
float b = 3.14; // 浮点数
vector c = {1,2,3}; // 向量
string d = "hello"; // 字符串
我个人习惯把变量声明放在代码块的最前面。这样一眼扫过去,就知道这个节点里用了哪些数据。你在写复杂特效时,这个习惯能帮你省不少调试时间。
int i, j, k;。但我不建议这么干——可读性太差。一行一个,清清楚楚。
1.2 数据类型详解
VEX的数据类型不多,但每个都很关键。咱们一个一个过。
1.2.1 int(整数)
整数就是不带小数点的数。范围大概在 -20亿 到 20亿 之间。够用吗?大部分场景够了。但我在做粒子数量计算时遇到过溢出——几百万粒子一乘,直接变负数。所以大数运算时,心里要有根弦。
int count = 100;
int negative = -42;
int hex = 0xFF; // 十六进制,等于255
1.2.2 float(浮点数)
浮点数就是带小数点的数。VEX里的浮点数是32位精度,不是64位的double。这意味着什么?说白了,就是小数点后第7位开始可能不准。做科学计算时要注意。
float pi = 3.14159;
float speed = 0.5;
float scientific = 1.5e3; // 等于1500.0
1/2 的结果是0,不是0.5!因为两个整数相除,结果还是整数。要写成 1.0/2.0 或 float(1)/2。我曾经因为这个bug排查了半小时,最后发现是整数除法惹的祸。
1.2.3 vector(向量)
向量是VEX里最常用的类型之一。它包含三个浮点数,分别代表X、Y、Z分量。你可以用它表示位置、方向、颜色,甚至旋转。
vector pos = {0, 1.5, -3};
vector dir = normalize({1,1,0});
vector color = {1, 0.5, 0}; // 橙色
访问向量的分量有三种方式:
pos.x、pos.y、pos.z—— 最直观pos[0]、pos[1]、pos[2]—— 数组风格pos.r、pos.g、pos.b—— 颜色风格
你想想看,同一个变量,既可以用xyz表示空间位置,又可以用rgb表示颜色,是不是很巧妙?
1.2.4 matrix(矩阵)
矩阵是4x4的浮点数阵列。它主要用于变换——平移、旋转、缩放。说实话,刚开始学VEX时,我很少直接操作矩阵。但后来做角色绑定和程序化建模时,发现矩阵是绕不开的。
matrix m = ident(); // 单位矩阵
matrix m2 = translate(m, {1,0,0}); // 平移矩阵
matrix m3 = rotate(m2, 3.14, {0,1,0}); // 绕Y轴旋转
访问矩阵元素用 m[row][col],比如 m[0][3] 就是平移的X分量。
1.2.5 string(字符串)
字符串用双引号括起来。VEX里字符串操作不多,但很实用。我经常用字符串来传递文件路径、属性名、或者做调试输出。
string name = "point_01";
string path = chs("file_path"); // 从参数面板读取字符串
string msg = sprintf("count is %d", count); // 格式化字符串
1.3 常量与字面量
常量就是值不会变的量。VEX里用 const 关键字声明。字面量则是直接写在代码里的值。
const float PI = 3.1415926;
const int MAX_POINTS = 10000;
const string TOOL_NAME = "my_sop";
为什么用常量?两个原因:一是防止意外修改,二是方便维护。比如你写了一个特效,里面用了10次 3.14159,突然发现精度不够要改成 3.1415926535——用常量的话,改一处就行。
VEX里还有一些内置常量,可以直接用:
| 常量名 | 值 | 说明 |
|---|---|---|
PI |
3.141592653589793 | 圆周率 |
E |
2.718281828459045 | 自然常数 |
TRUE |
1 | 布尔真 |
FALSE |
0 | 布尔假 |
字面量方面,记住几个规则:
- 整数:
42、-1、0xFF - 浮点数:
3.14、.5(等于0.5)、1e3 - 向量:
{1,2,3}、0(零向量) - 字符串:
"hello"、"path/to/file"
const int MAX = 100; 写在了循环内部。每次循环都重新声明常量,虽然编译没问题,但性能差了很多。常量尽量声明在代码块顶部,或者用全局变量。
1.4 知识体系总览
下面这张图帮你理清本章的知识结构。我画图时习惯把核心概念放在中间,分支展开细节。你看一眼就能知道VEX数据类型的全貌。
这张图把本章的核心内容串起来了。你看,数据类型是基础,常量是保护机制,变量声明是使用方式。三者缺一不可。
1.5 实战小练习
光看不练假把式。给你留个小任务:
- 声明一个
float变量,赋值为圆周率 - 声明一个
vector变量,表示一个点 (1.5, -2.0, 3.8) - 用
printf输出这个向量的Y分量 - 声明一个
const int表示最大迭代次数为500
代码框架我给你:
// 你的代码写在这里
float pi = 3.14159;
vector pt = {1.5, -2.0, 3.8};
printf("Y分量是: %f\n", pt.y);
const int MAX_ITER = 500;
试试看,在Houdini的Attribute Wrangle节点里跑一下。如果报错,仔细检查类型是否匹配。
printf 打印出来看看。虽然麻烦,但能帮你快速建立「代码-结果」的对应关系。等你熟练了,自然就知道每一步会产生什么结果。
好了,这一章的内容就到这里。变量声明、数据类型、常量——这三个概念是VEX的基石。下一章咱们继续聊运算符和控制流,到时候你会发现,今天学的这些会反复用到。