利用NEO与Unity制作游戏(第2部分)"
往事随风760
发表于 2022-12-5 17:35:42
128
0
0
NEOLux提供了一些方便的方法,可以用于将你的游戏连接到官方的测试网或者是主网。% J. Y- j) |; M2 j9 ?( u
1 j; N: p7 P, s! f. b' N( _
但在本教程中,我们会搭建自己的私有网络。这个过车是非常简单的,一旦你克服了最初的障碍(我会引导你),你会发现这比使用测试网络更加简单。例如,尽管填写用于测试的GAS或者Tokens的申请表格可能不是世界上最困难的任务,但我发现就这样一点点小摩擦,往往会扼杀我继续的热情和动力。
6 j# {* m& E3 ^ a) q' R
你也可以在本地运行你自己的私有网络,不过在本教程中,我们将设置自己的服务器。这会使得团队工作或者构建工作这类事情更加简单直接。我将使用DigitalOcean。因为根据我的经验,他们具有良好的性价比。$ E* x4 v+ ~1 U5 v, z
免责声明:我不是一个后端/服务器开发者,我猜“中等”水平的人应该会喜欢使用命令行工具。对于那些知道自己在做什么的人来说,这些内容应该很容易。如果你了解Linux和Docker的话,可以直接从DockerHub安装NEOPrivateNet并使用DockerCompose运行NEOSCAN。对于其他那些或多或少是我这种水平的人来说,接下来的内容应该还是相当简单直接的。
如果你还没有DigitalOcean账户的话,就去创建一个。然后使用以下选项创建一个Droplet。8 D. f! m6 z' m: S( L! N- W
使用16.X或者18.X版本的Ubuntu
U1 R c; z( Z g' L7 S
使用中配应该就足够了–你可以在配置中自行尝试,并在评论中告诉我你的试验的结果
SSH登入到你新建的Droplet并安装docker。如果你按照DigitalOcean提供的指南进行操作的话,这个过程将非常简单:https://www.digitalocean.com/com ... ker-on-ubuntu-18-04
注意:在执行最开始的一步,向系统添加官方Docker库的GPG键这步操作时,我遇到了点小问题。我只是简单地跑了两次命令,然后一切都很顺利。: G0 M3 g/ T7 B0 J
然后安装docker组件。同样地,安装说明非常的简单。只需要确保你看的是针对Linux系统的说明就行。
安装私有网络和NEOSCAN
) D" a7 M1 \7 {( p
运行和安装我们自己的私有网络,这是最为困难的一步,好在CityofZion的人帮我们很好的做到了这一点。你可以点击这个链接查看他们的全部说明指导。同样地,SSH登录到你的Droplet,基本上我们只需要输入几个命令就行:
首先,从hub上下载docker镜像:
dockerpullcityofzion/neo-privatenet$ ~- e6 }& c3 v% k, E
! z7 ^' B1 v8 z4 h5 w0 t! E# T- t9 k
…下载NEOSCAN…9 S3 \/ J7 G( A6 r: @
4 |9 W7 q. }3 ?# o8 {
wgethttps://raw.githubusercontent.co ... /docker-compose.yml
…并运行privnet…
% o2 c+ O, f& ?* Q% D
docker-compose-fdocker-compose-neoscan.ymlup$ z8 o9 i/ M! x- N
( `5 G/ H h" ?/ s! `
让它运行起来,然后转到http:your-droplet-ip-address:4000查看NEOSCAN的运行情况:
3 {$ U9 d& w" k: W4 L1 M8 U
回到Unity7 Y8 O6 A# y7 _$ L$ F/ ?
# ?$ b* u$ v) q; q8 Y
我不想在本教程中深入探讨自己的开发风格,不过我要做的一件事就是将UniRx插件导入Unity中。UniRx是对.NETReactiveExtensions的重新实现,它针对Unity做了优化处理,而且能很好地兼容iOSIL2CPP。不必过于复杂的实现,它可以简化一些管理NEO和UI的代码。+ J3 k. L3 `; h$ [, |
/ b- u* [. m: R# w
在资产(Assets)–>脚本(Scripts)下创建另一个名为NEOManager的脚本,并复制+粘贴以下代码:0 L0 G/ g4 X4 K8 |6 K
usingSystem.Collections;) Z& X. G# i# ?4 C$ J
. Z; p0 Z% ?" Q
usingUnityEngine;
usingSystem;
+ c' n- Y! X' k8 i4 Q7 f
usingUniRx;- ?! `4 w0 [; }! G
4 K0 P; P2 L. v, f5 y8 Q Z c
usingNeo.Lux.Core;
usingNeo.Lux.Cryptography;; X6 J" a" d, H$ O0 {$ T, Z
. b/ u+ }0 x6 N1 {
usingUnityEngine.UI;
publicclassNEOManager:MonoBehaviour( i7 {% h! [( C
{
publicNeoAPIAPI;
+ r+ C6 Z) h- S
[SerializeField]privatestringRpcIP;
publicconststringAssetSymbol="GAS";6 Z) P2 d' X0 j* s4 K$ j7 o! L
[HideInInspector]' S: a; m3 F$ }) w, r2 g8 T
& k7 h3 \9 Y: P
publicKeyPairReactivePropertyPlayerKeyPair=newKeyPairReactiveProperty();8 s% D; D/ x( X9 |7 |0 D
[SerializeField]privateTextaddressText;4 Q$ @5 ^$ x' d: o
: h+ u! J1 f$ s# `
[SerializeField]privateTextbalanceText;
- T/ y* E: @) [& v
publicDecimalGASBalance;- _1 e( K5 M* u; l9 \ t4 Z
privatevoidOnEnable()7 x( ]9 ~3 s1 ~- \4 ^# Z# `" D
* R5 L( e# ]6 L& p( p, ^, `
{
+ X6 D- _3 e5 K( [3 G
PlayerKeyPair.Value=KeyPair.FromWIF("KxDgvEKzgSBPPfuVfw67oPQBSjidEiqTHURKSDL1R7yGaGYAeYnr");6 }2 s9 c: z: q, f0 }6 I# z- C. {& S
0 [: O4 Z. R N5 h$ \* A
#ifUNITY_EDITOR/ _0 t, H$ G" F6 g# V
( y' `7 Q! I$ h' A9 c! B
//this.API=newLocalRPCNode(30333,"http://localhost");7 m7 t5 \) ] `# s, S4 ~
6 i9 A. X, @ k; ?. @
this.API=newCustomRPC(30333,4000,"http://"+RpcIP);# i+ p9 j; D8 ?1 }- l
#else
//this.API=NeoRPC.ForTestNet();3 P1 Z6 ], H. s; o5 }+ O! q2 n5 L+ h
this.API=newCustomRPC(30333,4000,"http://"+RpcIP);
d T( p% a3 L/ [: B1 i* k$ W
#endif
. e/ K7 Y: r: H6 ~
this.PlayerKeyPair.DistinctUntilChanged().Where(kp=>kp!=null).Subscribe(keyPair=>3 L0 u% [0 a$ p8 p
{
4 c( R% R" A* r& T B" d( S4 y K
this.addressText.text="Address:"+keyPair.address;
' E6 P8 d U/ w
this.balanceText.text="Balance:Pleasewait,syncingbalance...";9 f" b# t, P6 m0 }9 d3 [) L
" B# w" k8 U9 b) j4 h
StartCoroutine(SyncBalance());
) I% d4 Z' c- X( K0 \9 z/ ^0 C1 Z
}).AddTo(this);
}
privateIEnumeratorSyncBalance()+ H* _0 A1 |# M5 }; l# w
$ P2 _! X8 o6 J( {# _
{! v8 {: b/ A" }" r- p r2 h
1 H$ J: f, d. \: H/ A+ Z; ^8 B, v
yieldreturnnull;
: u* e, L' x9 F" G
varbalances=this.API.GetAssetBalancesOf(this.PlayerKeyPair.Value);& }4 Z8 L& ~6 D
this.GASBalance=balances.ContainsKey(AssetSymbol)?balances[AssetSymbol]:0;
; n) `8 X. ?" M/ N# m! ^3 u
this.balanceText.text="Balance:"+GASBalance.Value.ToString()+""+AssetSymbol;
. k3 s6 \* R) R6 A. v9 _
}. C0 h! C) S* Y5 I) d
}
+ O' N j+ x6 q+ Y. f8 N
[Serializable], o. k% ^1 [, a1 r {* I: Z
* k; i7 c1 X2 r) M5 H. m! L
publicclassKeyPairReactiveProperty:ReactiveProperty
{
6 d5 \+ X5 ]3 |. m, x& T
publicKeyPairReactiveProperty(){}
publicKeyPairReactiveProperty(KeyPairinitialValue):base(initialValue){}
4 x2 v$ x& Z# T! X. H0 ^
}
" |# A' o5 n3 I( G- i, Y
保存脚本然后返回主场景。创建一个空的游戏对象(GameObject),将其命名为NEO,然后创建一个该NEO对象的空的游戏子对象(childGameObject),并将其命名为NEOManager,并将NEOManager脚本添加到这个NEO对象中。在检查器(inspector)中的RpcIP字段旁边输入你的Droplet的IP地址。$ R6 L/ D( M6 }# j
接下来,我们将创建一些UI元素并将它们连接到检查器中,这样在连接到主网的时候,我们就可以看到余额的更新。
/ B- T z2 R. `, X2 k1 n2 Q
创建UI画布并向其中添加两个子文本元素,然后单击并将它们的引用拖动到NEOManager的“(AddressText)”和“(BalanceText)”字段。
) @+ s1 ~% }6 V, d/ z) }2 s% }4 Z
单击播放(Play)按钮然后查看地址和余额的更新情况。
$ M* j& X4 _. c6 j- {
我们当前使用的是在安装私有网络时自动生成的测试账号。在下一部分中,我们会进行一些设置,以便我们的玩家可以输入他们自己的私钥然后开始与NEO区块链进行交互。
成为第一个吐槽的人