Unity 之 Lua使用Vector3遇到的问题
【摘要】
Unity 之 Lua使用Vector3遇到的问题
1.正常使用2.遇到问题3.原来如此4.ToLua中的V3实现表
1.正常使用
在Lua使用的形式和C#中大致相同,只是Lua使用表的形式来模拟V3类型,原来C#中各种常用的属性和方法也都相应的被实现了。(详情可查看文末源码)
使用示例:
local V3;
V3 = Vector3(0,0,0...
1.正常使用
在Lua使用的形式和C#中大致相同,只是Lua使用表的形式来模拟V3类型,原来C#中各种常用的属性和方法也都相应的被实现了。(详情可查看文末源码)
使用示例:
local V3;
V3 = Vector3(0,0,0);
V3 = Vector3.zero;
V3 = Vector3.left * 10;
V3 = Vector3.left * 10 + Vector3.down * 10;
- 1
- 2
- 3
- 4
- 5
2.遇到问题
当将一个number类型放到乘号左边时,则程序执行到这一行就不会向下执行了;【思考一下】
V3 = 10 * Vector3.left;
- 1
原来在C#中是没有这种限制的,想下面这种代码随便怎么放位置都可以,只要满足你的需求,写法随便;
V3 = (hang - 1) / 2 * Vector3.down * hangGao;
V3 = Vector3.down * hangGao* (hang - 1) / 2;
- 1
- 2
- 3
但是在Lua中就只能将模拟 V3类型的变量放到前面来写;
3.原来如此
后知后觉:在Lua中V3是个表,而这个表的加,减,乘,除 这写运算操作试Lua使用原方法帮我们实现的,打开源码:
V3表乘法操作部分:
Vector3.__mul = function(va, d)
if type(d) == "number" then
return _new(va.x * d, va.y * d, va.z * d)
else
local vec = va:Clone()
vec:MulQuat(d)
return vec
end
end
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
这下明白了吧,这个原方法定义的时候,第一个参数是模拟V3类型,第二个是参数是Number类型;所有就会有上面的问题,当我们将V3类型的变量放到后面写的时候,当然执行不下去了。
结论:使用V3变量时,放到表达式的最左侧书写
4.ToLua中的V3实现表
local math = math
local acos = math.acos
local sqrt = math.sqrt
local max = math.max
local min = math.min
local clamp = Mathf.Clamp
local cos = math.cos
local sin = math.sin
local abs = math.abs
local sign = Mathf.Sign
local setmetatable = setmetatable
local rawset = rawset
local rawget = rawget
local type = type
local rad2Deg = 57.295779513082
local deg2Rad = 0.017453292519943
local Vector3 = {}
local get = tolua.initget(Vector3)
Vector3.__index = function(t,k)
local var = rawget(Vector3, k) if var == nil then var = rawget(get, k) if var ~= nil then return var(t) end end return var
end
function Vector3.New(x, y, z) local t = {x = x or 0, y = y or 0, z = z or 0}
setmetatable(t, Vector3) return t
end
local _new = Vector3.New
Vector3.__call = function(t,x,y,z)
local t = {x = x or 0, y = y or 0, z = z or 0}
setmetatable(t, Vector3) return t
end
function Vector3:Set(x,y,z)
self.x = x or 0
self.y = y or 0
self.z = z or 0
end
function Vector3.Get(v) return v.x, v.y, v.z
end
function Vector3:Clone()
return setmetatable({x = self.x, y = self.y, z = self.z}, Vector3)
end
function Vector3.Distance(va, vb)
return sqrt((va.x - vb.x)^2 + (va.y - vb.y)^2 + (va.z - vb.z)^2)
end
function Vector3.Dot(lhs, rhs)
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z
end
function Vector3.Lerp(from, to, t)
t = clamp(t, 0, 1)
return _new(from.x + (to.x - from.x) * t, from.y + (to.y - from.y) * t, from.z + (to.z - from.z) * t)
end
function Vector3:Magnitude()
return sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
end
function Vector3.Max(lhs, rhs)
return _new(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z))
end
function Vector3.Min(lhs, rhs)
return _new(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z))
end
function Vector3.Normalize(v)
local x,y,z = v.x, v.y, v.z local num = sqrt(x * x + y * y + z * z) if num > 1e-5 then return setmetatable({x = x / num, y = y / num, z = z / num}, Vector3) end return setmetatable({x = 0, y = 0, z = 0}, Vector3)
end
function Vector3:SetNormalize()
local num = sqrt(self.x * self.x + self.y * self.y + self.z * self.z) if num > 1e-5 then self.x = self.x / num
self.y = self.y / num
self.z = self.z /num else self.x = 0
self.y = 0
self.z = 0
end return self
end
function Vector3:SqrMagnitude()
return self.x * self.x + self.y * self.y + self.z * self.z
end
local dot = Vector3.Dot
function Vector3.Angle(from, to)
return acos(clamp(dot(from:Normalize(), to:Normalize()), -1, 1)) * rad2Deg
end
function Vector3:ClampMagnitude(maxLength)
if self:SqrMagnitude() > (maxLength * maxLength) then self:SetNormalize()
self:Mul(maxLength) end return self
end
function Vector3.OrthoNormalize(va, vb, vc)
va:SetNormalize()
vb:Sub(vb:Project(va))
vb:SetNormalize() if vc == nil then
return va, vb
end vc:Sub(vc:Project(va))
vc:Sub(vc:Project(vb))
vc:SetNormalize() return va, vb, vc
end
function Vector3.MoveTowards(current, target, maxDistanceDelta)
local delta = target - current local sqrDelta = delta:SqrMagnitude()
local sqrDistance = maxDistanceDelta * maxDistanceDelta if sqrDelta > sqrDistance then local magnitude = sqrt(sqrDelta) if magnitude > 1e-6 then delta:Mul(maxDistanceDelta / magnitude) delta:Add(current) return delta
else return current:Clone()
end end return target:Clone()
end
function ClampedMove(lhs, rhs, clampedDelta)
local delta = rhs - lhs if delta > 0 then
return lhs + min(delta, clampedDelta)
else
return lhs - min(-delta, clampedDelta)
end
end
local overSqrt2 = 0.7071067811865475244008443621048490
local function OrthoNormalVector(vec)
local res = _new() if abs(vec.z) > overSqrt2 then local a = vec.y * vec.y + vec.z * vec.z
local k = 1 / sqrt (a)
res.x = 0
res.y = -vec.z * k
res.z = vec.y * k
else local a = vec.x * vec.x + vec.y * vec.y
local k = 1 / sqrt (a)
res.x = -vec.y * k
res.y = vec.x * k
res.z = 0
end return res
end
function Vector3.RotateTowards(current, target, maxRadiansDelta, maxMagnitudeDelta)
local len1 = current:Magnitude()
local len2 = target:Magnitude() if len1 > 1e-6 and len2 > 1e-6 then local from = current / len1
local to = target / len2 local cosom = dot(from, to) if cosom > 1 - 1e-6 then return Vector3.MoveTowards (current, target, maxMagnitudeDelta) elseif cosom < -1 + 1e-6 then local axis = OrthoNormalVector(from) local q = Quaternion.AngleAxis(maxRadiansDelta * rad2Deg, axis) local rotated = q:MulVec3(from) local delta = ClampedMove(len1, len2, maxMagnitudeDelta) rotated:Mul(delta) return rotated
else local angle = acos(cosom) local axis = Vector3.Cross(from, to) axis:SetNormalize () local q = Quaternion.AngleAxis(min(maxRadiansDelta, angle) * rad2Deg, axis) local rotated = q:MulVec3(from) local delta = ClampedMove(len1, len2, maxMagnitudeDelta) rotated:Mul(delta) return rotated
end
end return Vector3.MoveTowards(current, target, maxMagnitudeDelta)
end
function Vector3.SmoothDamp(current, target, currentVelocity, smoothTime)
local maxSpeed = Mathf.Infinity
local deltaTime = Time.deltaTime smoothTime = max(0.0001, smoothTime) local num = 2 / smoothTime local num2 = num * deltaTime local num3 = 1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2) local vector2 = target:Clone() local maxLength = maxSpeed * smoothTime
local vector = current - target vector:ClampMagnitude(maxLength) target = current - vector local vec3 = (currentVelocity + (vector * num)) * deltaTime currentVelocity = (currentVelocity - (vec3 * num)) * num3 local vector4 = target + (vector + vec3) * num3 if Vector3.Dot(vector2 - current, vector4 - vector2) > 0 then vector4 = vector2 currentVelocity:Set(0,0,0) end return vector4, currentVelocity
end function Vector3.Scale(a, b)
local x = a.x * b.x
local y = a.y * b.y
local z = a.z * b.z
return _new(x, y, z)
end
function Vector3.Cross(lhs, rhs)
local x = lhs.y * rhs.z - lhs.z * rhs.y
local y = lhs.z * rhs.x - lhs.x * rhs.z
local z = lhs.x * rhs.y - lhs.y * rhs.x
return _new(x,y,z)
end
function Vector3:Equals(other)
return self.x == other.x and self.y == other.y and self.z == other.z
end function Vector3.Reflect(inDirection, inNormal)
local num = -2 * dot(inNormal, inDirection)
inNormal = inNormal * num
inNormal:Add(inDirection)
return inNormal
end function Vector3.Project(vector, onNormal)
local num = onNormal:SqrMagnitude() if num < 1.175494e-38 then return _new(0,0,0)
end local num2 = dot(vector, onNormal)
local v3 = onNormal:Clone()
v3:Mul(num2/num)
return v3
end
function Vector3.ProjectOnPlane(vector, planeNormal)
local v3 = Vector3.Project(vector, planeNormal)
v3:Mul(-1)
v3:Add(vector)
return v3
end function Vector3.Slerp(from, to, t)
local omega, sinom, scale0, scale1
if t <= 0 then return from:Clone()
elseif t >= 1 then return to:Clone()
end local v2 = to:Clone()
local v1 = from:Clone()
local len2 = to:Magnitude()
local len1 = from:Magnitude()
v2:Div(len2)
v1:Div(len1)
local len = (len2 - len1) * t + len1
local cosom = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z if cosom > 1 - 1e-6 then
scale0 = 1 - t
scale1 = t
elseif cosom < -1 + 1e-6 then local axis = OrthoNormalVector(from) local q = Quaternion.AngleAxis(180.0 * t, axis) local v = q:MulVec3(from)
v:Mul(len) return v
else
omega = acos(cosom)
sinom = sin(omega)
scale0 = sin((1 - t) * omega) / sinom
scale1 = sin(t * omega) / sinom
end
v1:Mul(scale0)
v2:Mul(scale1)
v2:Add(v1)
v2:Mul(len)
return v2
end
function Vector3:Mul(q)
if type(q) == "number" then
self.x = self.x * q
self.y = self.y * q
self.z = self.z * q
else
self:MulQuat(q)
end return self
end
function Vector3:Div(d)
self.x = self.x / d
self.y = self.y / d
self.z = self.z / d return self
end
function Vector3:Add(vb)
self.x = self.x + vb.x
self.y = self.y + vb.y
self.z = self.z + vb.z return self
end
function Vector3:Sub(vb)
self.x = self.x - vb.x
self.y = self.y - vb.y
self.z = self.z - vb.z return self
end
function Vector3:MulQuat(quat) local num = quat.x * 2
local num2 = quat.y * 2
local num3 = quat.z * 2
local num4 = quat.x * num
local num5 = quat.y * num2
local num6 = quat.z * num3
local num7 = quat.x * num2
local num8 = quat.x * num3
local num9 = quat.y * num3
local num10 = quat.w * num
local num11 = quat.w * num2
local num12 = quat.w * num3 local x = (((1 - (num5 + num6)) * self.x) + ((num7 - num12) * self.y)) + ((num8 + num11) * self.z)
local y = (((num7 + num12) * self.x) + ((1 - (num4 + num6)) * self.y)) + ((num9 - num10) * self.z)
local z = (((num8 - num11) * self.x) + ((num9 + num10) * self.y)) + ((1 - (num4 + num5)) * self.z) self:Set(x, y, z)
return self
end
function Vector3.AngleAroundAxis (from, to, axis) from = from - Vector3.Project(from, axis)
to = to - Vector3.Project(to, axis) local angle = Vector3.Angle (from, to) return angle * (Vector3.Dot (axis, Vector3.Cross (from, to)) < 0 and -1 or 1)
end
Vector3.__tostring = function(self)
return "["..self.x..","..self.y..","..self.z.."]"
end
Vector3.__div = function(va, d)
return _new(va.x / d, va.y / d, va.z / d)
end
Vector3.__mul = function(va, d)
if type(d) == "number" then
return _new(va.x * d, va.y * d, va.z * d)
else
local vec = va:Clone()
vec:MulQuat(d)
return vec
end
end
Vector3.__add = function(va, vb)
return _new(va.x + vb.x, va.y + vb.y, va.z + vb.z)
end
Vector3.__sub = function(va, vb)
return _new(va.x - vb.x, va.y - vb.y, va.z - vb.z)
end
Vector3.__unm = function(va)
return _new(-va.x, -va.y, -va.z)
end
Vector3.__eq = function(a,b)
local v = a - b
local delta = v:SqrMagnitude()
return delta < 1e-10
end
get.up = function() return _new(0,1,0) end
get.down = function() return _new(0,-1,0) end
get.right = function() return _new(1,0,0) end
get.left = function() return _new(-1,0,0) end
get.forward = function() return _new(0,0,1) end
get.back = function() return _new(0,0,-1) end
get.zero = function() return _new(0,0,0) end
get.one = function() return _new(1,1,1) end
get.magnitude = Vector3.Magnitude
get.normalized = Vector3.Normalize
get.sqrMagnitude= Vector3.SqrMagnitude
UnityEngine.Vector3 = Vector3
setmetatable(Vector3, Vector3)
return Vector3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
文章来源: czhenya.blog.csdn.net,作者:陈言必行,版权归原作者所有,如需转载,请联系作者。
原文链接:czhenya.blog.csdn.net/article/details/107716442
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)