Unity3D学习笔记(三十):Lua

Lua:是一个轻量级的脚本语句。不需要编译,直接运行的语言。
 
环境配置:
 
执行Lua有两种方式:
1、交互式编程(输入后能立即看到效果)
2、脚本式编程:运行lua文件,.lua为文件后缀
 
Lua语句结尾不需要用分号结束,写了分号也没有问题。
删除一个中文字符,需要按两下删除
 
注释:
单行注释:--
多行注释:--[[...]]--或--[[...--]]或--[[...]]
print("Hello World")

--单行注释
--print("单行注释")

--多行注释
--[[
print("多行注释1")
]]

--[[
print("多行注释2")
--]]

--[[
print("多行注释3")
]]
变量定义:
Lua不需要写变量类型,变量名 = 值。
Lua的标识符(变量名),1个字母或下划线开头,后跟0个或多个字母、数字、下划线
Lua是区分大小写的。
变量存储什么类型的数据,就是什么类型的变量。
使用type()来获取变量的类型。
 
Lua的数据类型:
number:小数类型(lua没有整型和浮点的区分),对应C#的int,float,double(浮点类型不能加f)
boolean:布尔类型,true和false。Lua里把false和nil看作是假,其他的都是真。
nil:表示空数据,等同于null。对于未被定义的变量,想要使用的话得到的都是nil。
string:字符串类型,可以使用双引号,单引号,[[...]]表示。([[...]]与注释有歧义,不推荐使用)
1、在对两个字符串类型的变量,进行算数操作的时候,加减乘除求余,Lua会尝试把这两个字符串去转换成数字去做计算,如果字符串转换不成功则报错。
2、使用..来做两个字符串的连接。
3、使用#来计算字符串的长度,放在字符串的前面。
--变量定义
--C#
--int a = 1;
--Lua
a = 1
A = 2
_ = 3
print(a)
print(A)
print(_)

--变量赋值
b = true
print(b)
print(type(b))
b= 4
print(b)
print(type(b))

--number类型
c = 1
d = 1.2
print(c)
print(type(c))
print(d)
print(type(d))

--三种打印字符串的方式
e = "Hello World"
f = 'Hello World'
g = [[Hello World]]
print(e, f, g)

--..连接字符串
x = "1"
y = "2"
print(x + y)--加号表示算数运算
print(x .. y)

--#计算变量长度
print(#e)
print(#"Hello World")
print(#"你好")--汉字占两个字节
 
table类型:table表示一个数组的时候,默认索引是从1开始的
创建:b = {}
table并不是一个数组,实际是一个“关联数组”,关联数组的索引可以是数字,也可以是字符串
--C# int[] a = new int[]{1, 2, 3};

--Lua的table
a = {1, 6, 3}
print(a[1])
print(type(a))

--创建一个空表
b = {}

--创建一个表,并且对表进行初始化赋值
c = {"string", true, 1, nil}

--table的访问
print(c[1])

--table的修改
c[1] = 100
print(c[1])

print(#c)--能算table长度,但不一定是真实长度

--table的添加
c[5] = 200

--table的方法:数组的插入和删除(索引的连续性)
--第一个参剩:表的名字
--第二个参数:插入的内容
--依次向后找,只要找到一个nil的位置就把内容插入进去
table.insert(c, "你好")
print(c[4])--结果:你好

--第二个参数:要插入的位置,可以跳跃性的插入
table.insert(c, 10, "小明")
print(c[10])--结果:小明

--从第三个位置的元素开始,后面的元素依次后移
table.insert(c, 3, "小红")
print(c[3])--结果:小红
print(c[4])--结果:1

--删除
--删除指定索引的位置的元素,后面的元素依次前移
d = {1, 4, "你好", true}
table.remove(d, 1)
print(d[1])--结果:4

--删除连续索引的最后一个元素
d[6] = 10
table.remove(d)
print(d[3])--结果:nil
print(d[6])--结果:10
--table的索引
a = {}
a[1] = 0
print(a[1])

--把字符串作为一个索引
a["a"] = "nihao"
print(a["a"])

--table可以有0号索引
a[0] = 10
print(a[0])
--table可以有负号索引
a[-1] = 100
print(a[-1])

print("-----------------")
b = {[2] = 10, 1, 2, 3, 5, [-1] = 30, ["nihao"] = "你好", key = "不好", c = {1, 5}}
print(b[1])
print(b[2])--会被覆盖掉
print(b[3])
print(b[4])
print(b[5])
print(b[6])
print(b[7])
print(b[-1])
print(b["nihao"])

--第一种访问字符串为索引的元素
print("-----------------")
print(b["nihao"])
--第二种访问字符串为索引的元素
print(b.nihao)
print(b["key"])
print(b.key)
print(b.c[2])
--table.insert(c, 3, "小红")--报错:只能针对数组
--table.remove(c, 2)--报错:只能针对数组

--添加字符串为索引的元素
b["key1"] = "可以"
b.key2 = "不可以"
d = "可不可以"
print(b.key1)
print(b["key2"])
print(b[d])

print(#b)--结果:4,从1号位索引开始算,一旦索引断掉,就不往后面计算

f = {[2] = 2}
print(#f)
 
Lua中的运算符
数学运算符:+,-,*,/,%,^
Lua里没有自增自减运算符,也没有+= *=之类的
关系运算符:>,<,==,>=,<=,~=
Lua里的不等于~=
逻辑运算符:and,or,not
 
流程控制语句
--流程控制语句
--C# if(条件){}

--Lua
--if语句
--[[
if 条件 then
    print("if语句满足,执行")
end
]]--

if true then
    print("if语句满足,执行")
end

--if else语句
if a then
    print("if语句满足,执行")
else
    print("if语句不满足,执行")
end

--if elseif语句
if a then--一般条件后面才加then关键字
    print("if语句满足,执行")
elseif b then--注意elseif是连着的
    print("if语句不满足,执行")
end

--if elseif else语句
if a then
    print("if语句满足,执行")
elseif b then--注意elseif是连着的
    print("if语句不满足,执行")
else
    print("if语句都不满足,执行")
end

循环控制语句

--循环控制语句
--C# for,while,do while

--Lua
--while
a = 1
while a < 10 do
    print(a)
    a = a + 1
end

print("-------------")

--do while C#条件满足继续执行循?
--repeat 循环体 until 条件 条件满足跳出循环
a = 1
repeat
    print(a)
    a = a + 1
until a < 10

print("-------------")

--for 变量定义,条件,每次循环累加值 do 循环体 end
--条件就是一个数,变量 <= 条件,每次累加值可以不写,不写默认为1
--对于循环,有break关键字跳出,但是没有continue关键字
for a = 1, 10, 1 do
    print(a)
end
方法:调用方法时,一定是先定义,在调用!
--方法
function func3()
    func1()
end

--方法的定义1 function 方法名(参数) 方法体 end
function func1()
    print("func1")
end

--方法的定义2 方法名 = function(参数) 方法体 end
func2 = function()
    print("func2")
end

--方法的调用,先定义再调用
func1()
func2()
func3()

print("--------有参数的方法--------")

--有参数的方法
func4 = function(a, b)
    print(a, b)
end

func4()--可以不传参数,按照nil处理
func4(1)--可以少传
func4(1, 2)
func4(1, 2, 3)--可以多传,只取前2个

print("--------可变参数的方法--------")
--可变参数的方法,参数位置用...表示是可以传任意的参数
--通过arg来取传入的参数,arg实际就是一表表示的数组
--当调用的时候,把所有传递进来的参数存入到arg中
func5 = function(...)
    print(#arg)
    for i = 1, #arg do
        print(arg[i])
    end
end

func5(1,2,3,54,6,7,8)
func5(1,"nihao",true,54,6,7,false,nil)

print("--------带返回值的方法--------")
--带返回值的方法
func6 = function()
    return "func6"
end

a = func6()
print(func6(), a)

print("--------带多个返回值的方法--------")
--带多个返回值的方法
--多个返回值使用多个变量去接收,每个变量之间以逗号区别
--返回值与接收变量可以数量不一致,多退少补
func7 = function()
    return "a", true, 1, false
end

r1,r2,r3,r4 = func7()

print(func7())
print(r1,r2,r3,r4)


func8 = function()
    local z = "c"
end

func8()
print("z:", z)

--
a = {1,2,3,4,5,67,78}

--遍历
for i = 1, #a do
    print(a[i])
end

for key, value in ipairs(a) do
    print("key", key)
    print("value", value)
end

b = {1,2,4,5,[-1] = 5, ["key"] = "key", key1 = true}
--ipairs()这种方式只能比哪里出数值类型
for key, value in ipairs(b) do
    print("key", key)
    print("value", value)
end
--pairs()这种方式能全部遍历出键和值
for key, value in pairs(b) do
    print("key", key)
    print("value", value)
end
 
局部变量和全局变量
一般情况下,定义的变量都是全局的变量,包括方法内定义的
如果变量前多了local关键字,那么证明该变量局部的变量
--lua8
print("开始执行Lua8")

local lua8 = {}
lua8.const = 10

function lua8.func1()
    print("func1")
end

lua8.func2 = function()
    print("lua8.func2")
end

function lua8.func3()
    print("lua8.func3")
end

print("结束执行Lua8")

return lua8
--lua10
print("开始执行Lua10")

local lua8 = {func4 = function() print("func4") end, key = 10}
lua8.const = 20

function lua8.func1()
    print("Lua10.func1")
end

lua8.func2 = function()
    print("Lua10.func2")
end

function lua8.func3()
    print("Lua10.func3")
end

print("结束执行Lua10")

return lua8

Lua11.lua文件,在根目录下的Lua文件夹下

--Lua11
print("开始执行Lua11")
--require("Lua8")
--require('Lua8')
lua10 = require'Lua10'
lua8 = require'Lua8'

--func()
print(lua8.const)
print(lua10.const)

lua8.func3()
lua10.func3()

--package.path 里存储的都是require所能执行的lua的文件路径
--print(package.path)

--package.path = package.path .. ";D:\LuaProject\Lua\?.lua"
--..\上级目录,.\文件的当前目录
package.path = package.path .. ";.\Lua\?.lua"

print(package.path)

require'Lua11'
 
元表:改变规则的
Setmetatable(a, b)--把b设置成a的元表
Getmetatable(a)--返回a的元素
 
原方法的名字
算数类:__add(加)__sub(减)__mul(乘)__div(除)__unm(相反数)__mod(取余)__pow(求幂)
访问类:__index(查询)__newindex(修改table的字段)
关系类:__eg(等于)__lt(小于)等等
tab1 = {"tab1", "111", '222'}
tab2 = {"tab2", 11, true}
Set = {__add = function(t1, t2)--__add原方法
            for k1, v1 in pairs(t1) do
                print(k1, v1)
            end
            print("--------------")
            for k1, v1 in pairs(t2) do
                print(k1, v1)
            end
            return "Set"
        end}
setmetatable(tab2, Set)--设置元表,把Set这个表设置成tab1的元表
t = tab1 + tab2
--当两个表进行相加操作时,先判断两个表是否有元表?
--如果两个表都没有元表,两个表不能进行相加操作
--如果两个表任意一个表有元素
--再判断元表内是否有__add的元方法
--如果元表里没有__add的元方法,不会执行,报错
--如果有__add的元方法,那么两个表可以相加
--并且相加的结果,就是__add的返回值
--__add的参数1是加号左边的表,参数2是加号右边的表
print(t)

tab = getmetatable(tab2)
print(tab)
print("--------------")

tab3 = {key = "k1"}
Set1 = {__index = function(t1, key)
            print(type(t1))
            for k1, v1 in pairs(t1) do
                print(k1, v1)
            end
            print(type(key), key)
            return "Set1"
        end}

setmetatable(tab3, Set1)

--当你要访问一个键对应值时,先判断这个表中有没有这个键,如果有就返回这个键对应的值
--如果这个表没有这个键,先判断这个表有没有元表
--如果有元表,再判断这个元表有没有__index的元方法
--如果有,访问的值就是这个__index返回的值
--__index里的参数1:表,参数2:要访问的键名

print(tab3.key1)
 
补充内容
逻辑运算符:
 
 
VS编译:Ctrl + Shift + B
fixedDuration:固定过渡,不许打断
public float length { get; }//动画播放时长
public float normalizedTime { get; }//动画当前规范化时间,1是动画结尾,0.5是动画中间
public bool IsName(string name);
public bool IsTag(string tag);

public class SkillOverStateBehaviour : StateMachineBehaviour {
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        //PlayerController pc = animator.GetComponent<PlayerController>();//获取动画组件身上的脚本
        //pc.atkID = 0;//把脚本里的atkID归零
        //animator.SetInteger("skillID", 0);//把animator面板里的skillID归零
        animator.SetInteger("skillID", 0);
    }
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerControl : MonoBehaviour   
{
    Animator anim;
    private void Awake()
    {
        anim = GetComponent<Animator>();
    }
    private void Start()
    {
       
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            AnimatorStateInfo animSta = anim.GetCurrentAnimatorStateInfo(0);
            if (animSta.IsName("skill1") && animSta.normalizedTime > 0.3f)
            {
                anim.SetInteger("skillID", 2);
            }
            else if(animSta.IsName("skill2"))
            {
                anim.SetInteger("skillID", 3);
            }
            else if(animSta.IsName("skill3"))
            {
                anim.SetInteger("skillID", 4);
            }
            else if(animSta.IsName("skill4"))
            {
                anim.SetInteger("skillID", 5);
            }
            else if(animSta.IsName("skill5"))
            {
                anim.SetInteger("skillID", 6);
            }
            else if(animSta.IsName("skill6"))
            {
                anim.SetInteger("skillID", 0);
            }
            else
            {
                anim.SetInteger("skillID", 1);
            }
        }
    }
}
原文地址:https://www.cnblogs.com/vuciao/p/10363694.html