記事ディレクトリ
この記事の最終的な効果
I.はじめに
みなさん、こんにちは。私は新しいです。
ファンからこの質問がありました。
プレーンテキストのデータを取得したと思いましたが、解析方法がわかりませんでした。データを解析したいだけなら、ツリーを使用する必要はまったくありませんでした。
フォーマットを見ると、yes 、プレーンテキストデータを取得し、フォーマットがyeslua
の場合、メソッドを使用してプレーンテキストを実行し、オブジェクトを取得できます。次に例を示します。table
lua
table
loadstring
table
local data_str = '{ a = 1, b = 2, { c=3, d = 4}, { e = { x = 5 }}}'
local func = loadstring('return ' .. data_str)
local tb = func()
-- TODO 解析tb这个table
ここで注意しなければならないのは、バージョン以降でloadstring
メソッドがlua 5.2
変更されているload
ため、バージョン以上の場合lua
は5.2
注意が必要ですlua
。ソースコードlbaselib.c
ファイルを表示できます。
実際、彼の意味を誤解して送ってくれました。別のデータ
そしてそれをこの形で示すと言われました、
このフォーマットはlua
正しくありませんtable
。この時点で、彼はWebページを作成していると思ったので、それを使用するかどうか尋ねましたjavascript
。
確認後、使用されlua
ます。彼はそれを変換しましtable
たが、ツリーを使用して再帰的トラバーサルを構築する方法がわかりません。
最後に、私は彼が遭遇した問題を理解しました、まあ、良い人々は最後まで助けてくれます、それでは特定の実装について話しましょう〜
注:上記
红点
は、私が以前に書いた別の記事を参照しています。[ゲーム開発の実践] luaを使用してUnityにレッドドットシステムを実装する方法を教えます(プレフィックスツリー|データ構造|デザインパターン|アルゴリズム|プロジェクトソースコードを含む)
第二に、Unitylua環境
使いたいのでlua
、Unity
デフォルトではフレームワークC#
を作成する必要があります。ちょうどいいタイミングで、フレームワークを統合しlua
たゲームフレームワークを自分で作成しました。詳しくは、以前書いたこのブログをご覧ください。 :[ゲーム開発フレームワーク]自家製Unity一般ゲームフレームワークUnityXFramework、詳細なチュートリアル(Unity3Dスキルツリー| tolua |フレームワーク|ホットアップデート)フレームワークオープンソースアドレス:https ://gitcode.net/linxinfa/UnityXFrameworkここでロジックを記述します環境のフレームワーク〜UnityXFramework
tolua
lua
3、ツリーノード
1.スクリプトを作成します:TreeNode.lua
まず、ディレクトリにLuaFramework/Lua/Logic
新しいTree
ディレクトリ
を作成し、Tree
ディレクトリに新しいTreeNode.lua
スクリプトを作成します。
2.パッケージノード
まず、ノードが必要とする情報について考え、絵を描きます
。次に、コードを書き留めます。TreeNode.lua
スクリプトコードは次のとおりです。
-- TreeNode.lua 树节点
TreeNode = TreeNode or {
}
TreeNode.__index = TreeNode
function TreeNode.New(name)
local self = {
}
-- 节点名
self.name = name
-- 值
self.value = nil
-- 父节点
self.parent = nil
-- 子节点
self.child = nil
-- 缩进
self.tab = 0
-- 是否展开
self.isopen = true
-- UI对象
self.uiObj = nil
setmetatable(self, TreeNode)
return self
end
第四に、ツリーロジック
1.スクリプトを作成します:TreeLogic.lua
次のように、Tree
ディレクトリに新しいTreeLogic.lua
スクリプトを作成し、最初にメソッドを
記述して、 1つ残しておきましょう。Init
TODO
-- TreeLogic.lua 树逻辑
TreeLogic = TreeLogic or {
}
local this = TreeLogic
-- 根节点
this.root = nil
-- 初始化
function TreeLogic.Init()
-- TODO
end
2.テストデータを作成します
ツリーを構築する場合は、最初にデータを用意する必要があります。要件に応じて、データは1つtable
であり、単に1つ書き込むだけです。
-- 测试数据
local data_table = {
name = "林新发",
university = "华南理工大学",
major = '信息工程',
job = 'Unity3D游戏开发工程师',
blog = 'https://blog.csdn.net/linxinfa',
hobby = {
'吉他', '钢琴', '画画', '撸猫'},
dream = {
developer = {
target = '成为一名优秀的独立游戏开发者',
style = {
'ARPG', 'FPS', 'SLG', 'MOBA'}
},
painter = {
target = '成为一个独立画家',
magnum_opus = {
'暴走柯南', '皮皮猫', '光'}
},
musician = {
target = '成为一个独立音乐人',
magnum_opus = {
'尘土', '树与风'}
}
}
}
3.ツリーの構築
次に、テストデータを使用してツリーを構築し、メソッドをカプセル化しますMakeTree
。実際には、構築プロセス中にノードの構築に焦点を当て、ノードの名前と値を設定し、親子ノードを設定するだけで済みます。ノードの関係、そして再帰的に実行します。
コードは以下のように表示されます
-- TreeLogic.lua
-- 构造树
-- tb: 数据table
-- parent: 父节点
function TreeLogic.MakeTree(tb, parent)
-- 遍历table
for k, v in pairs(tb) do
-- 新建一个节点
local node = TreeNode.New(k)
node.value = v
-- 设置父节点
node.parent = parent
-- 子节点缩进+1
node.tab = parent.tab + 1
-- 父节点的child塞入node
if nil == parent.child then
parent.child = {
}
end
parent.child[k] = node
-- 如果v是table,则递归遍历
if type(v) == 'table' then
-- 有子节点,默认不展开
node.isopen = false
this.MakeTree(v, node)
end
end
return parent
end
次に、メソッド内のメソッドをInit
呼び出します。MakeTree
-- 初始化
function TreeLogic.Init()
-- 测试数据 data_table = {}
-- ...
-- 根节点
this.root = TreeNode.New("Root")
-- 构造树
this.root = this.MakeTree(data_table, this.root)
end
この時点で30
、行の周りのコードを使用してノードのカプセル化とツリーの構築を完了しました。次のステップはUI
ツリーの表示です。
4.ツリーを印刷します
表示を行う前にUI
、ツリーを印刷する方法をカプセル化して、ツリー構造を確認することもできます。
-- 把树转为字符串
function TreeLogic.TreeToString(node, str)
if nil ~= node.value then
local tabspace = ''
for i = 1, node.tab do
tabspace = tabspace .. ' '
end
if 'table' == type(node.value) then
str = str .. string.format('%s▼ %s :\n', tabspace, node.name)
else
str = str .. string.format('%s● %s : %s\n', tabspace, node.name, tostring(node.value))
end
end
if nil ~= node.child then
for _, child_node in pairs(node.child) do
-- 递归
str = this.TreeToString(child_node, str)
end
end
return str
end
電話しましょう
-- 打印树
local str = ''
str = this.TreeToString(this.root, str)
log(str)
出力は以下の通りです
出力は正常です、どうぞよろしくお願いします〜
5番目に、UGUIを使用してツリーを表示します
1.インターフェースプリセットを作成します
次のようにTreePanel.prefab
インターフェイスプリセットを作成します。インターフェイス階層は次のとおりです。コンポーネントを垂直レイアウトに使用します。これにより、子ノードを追加すると、自動的に垂直に配置され、そのうちの1つはクリックの監視に接続され、1つは子ノードになります。子ノードが1つあります。座標を右に移動することで実現できます。
VerticalLayoutGroup
item
Button
Text
Text
2.インターフェイススクリプトを作成します:TreePanel.lua
ディレクトリにフォルダをLuaFramework/Lua/View
作成し、スクリプトを作成し、インターフェイスコードを記述します。インターフェイスコードのテンプレートを作成しました。以前に作成したフレームワークチュートリアルを参照できます。[ゲーム開発フレームワーク]自家製Unity一般ゲームフレームワークUnityXFramework 、詳細なチュートリアル(Unity3Dスキルツリー| tolua |フレームワーク|ホットアップデート)セクション:ツリーノードを再帰的に拡張してノードを閉じるロジックを書き留めることに焦点を当てます〜Tree
TreePanel.lua
8.2
3.ノードを展開します(再帰)
ノードを開くメソッドをカプセル化するために、ExpanNode
再帰を使用し、コードにコメントを書き込んだので、ここでは説明しません。
-- TreePanel.lua
-- 展开节点
function TreePanel.ExpanNode(node)
if nil == node.child then
return
end
local index = 1
for _, child_node in pairs(node.child) do
-- 创建节点的UI对象
local uiObj = LuaUtil.CloneObj(this.tiemForClone)
local text = uiObj.transform:GetChild(0):GetComponent("Text")
child_node.uiObj = uiObj
if not LuaUtil.IsNilOrNull(node.uiObj) then
-- 子节点塞在父节点下面
local siblingIndex = node.uiObj:GetComponent("RectTransform"):GetSiblingIndex()
child_node.uiObj:GetComponent("RectTransform"):SetSiblingIndex(siblingIndex + index)
index = index + 1
end
if type(child_node.value) == 'table' then
text.text = (child_node.isopen and '▼ ' or '► ') .. child_node.name
else
text.text = '● ' .. child_node.name .. ': ' .. child_node.value
end
-- 坐标缩进
text.transform.localPosition = text.transform.localPosition + Vector3.New((child_node.tab-1)*50, 0,0)
uiObj:GetComponent("Button").onClick:AddListener(function()
if not child_node.isopen then
child_node.isopen = true
-- 递归, 展开子节点
this.ExpanNode(child_node)
else
-- 关闭子节点
this.CloseNode(child_node)
end
if type(child_node.value) == 'table' then
text.text = ( child_node.isopen and '▼ ' or '► ') .. child_node.name
end
end)
end
end
ツリーのルートノードを渡す必要があります。メソッドをTreeLogic.lua
追加します。GetTree
-- TreeLogic.lua
function TreeLogic.GetTree()
return this.root
end
ExpanNode
次に、次のようにメソッドを呼び出します。
local tree = TreeLogic.GetTree()
this.ExpanNode(tree)
4.ノードを閉じます(再帰的)
CloseNode
ノードを閉じると、次のように、引き続き再帰を使用してメソッドもカプセル化されます。
-- 关闭子节点
function TreePanel.CloseNode(node)
if LuaUtil.IsNilOrNull(node.child) then
return
end
node.isopen = false
for _, child in pairs(node.child) do
child.isopen = false
LuaUtil.SafeDestroyObj(child.uiObj)
if nil ~= child.child then
-- 递归关闭子节点
this.CloseNode(child)
end
end
end
6.テスト
さて、効果をテストしましょう、
完璧です、それを1日と呼びましょう〜
私はフレームワークにコードを送信しました。レビューのためにプロジェクトをダウンロードできます、https://gitcode.net/linxinfa/UnityXFramework
私はLinXinfaです。https:
//blog.csdn.net/linxinfa、小さな会社で静かにUnity
働いている開発者Unity
です。学びたい人をもっと助け、お互いを励まし合うことができればと思います〜