第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";  // 字符串

我个人习惯把变量声明放在代码块的最前面。这样一眼扫过去,就知道这个节点里用了哪些数据。你在写复杂特效时,这个习惯能帮你省不少调试时间。

小技巧:VEX允许在同一行声明多个同类型变量,比如 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
注意:VEX里 1/2 的结果是0,不是0.5!因为两个整数相除,结果还是整数。要写成 1.0/2.0float(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.xpos.ypos.z —— 最直观
  • pos[0]pos[1]pos[2] —— 数组风格
  • pos.rpos.gpos.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);  // 格式化字符串
核心要点:VEX的字符串是不可变的。任何修改操作都会生成新字符串,原字符串不变。这一点和Python类似。

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-10xFF
  • 浮点数:3.14.5(等于0.5)、1e3
  • 向量:{1,2,3}0(零向量)
  • 字符串:"hello""path/to/file"
避坑指南:我曾经在写一个循环时,把 const int MAX = 100; 写在了循环内部。每次循环都重新声明常量,虽然编译没问题,但性能差了很多。常量尽量声明在代码块顶部,或者用全局变量。

1.4 知识体系总览

下面这张图帮你理清本章的知识结构。我画图时习惯把核心概念放在中间,分支展开细节。你看一眼就能知道VEX数据类型的全貌。

VEX数据类型 int 整数:-2^31 ~ 2^31-1 float 浮点数:32位精度 vector 三维向量:{x,y,z} matrix 4x4矩阵:变换 string 字符串:不可变 十进制/十六进制 科学计数法 xyz / rgb 访问 平移/旋转/缩放 格式化/拼接 常量与字面量 const / PI / E / TRUE / FALSE 变量声明规则

这张图把本章的核心内容串起来了。你看,数据类型是基础,常量是保护机制,变量声明是使用方式。三者缺一不可。

1.5 实战小练习

光看不练假把式。给你留个小任务:

  1. 声明一个 float 变量,赋值为圆周率
  2. 声明一个 vector 变量,表示一个点 (1.5, -2.0, 3.8)
  3. printf 输出这个向量的Y分量
  4. 声明一个 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节点里跑一下。如果报错,仔细检查类型是否匹配。

我的经验:刚开始学VEX时,我每写一行代码都会用 printf 打印出来看看。虽然麻烦,但能帮你快速建立「代码-结果」的对应关系。等你熟练了,自然就知道每一步会产生什么结果。

好了,这一章的内容就到这里。变量声明、数据类型、常量——这三个概念是VEX的基石。下一章咱们继续聊运算符和控制流,到时候你会发现,今天学的这些会反复用到。


专注资料整理