unity游戏开发之entitas框架
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgMAAAHyCAYAAAB2/c12AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAACTESURBVHhe7d1PbqPK2gfgbzE9yeTspCcZ9EYi9SD7iHSkLKQVqdfRitT7uLq6E74AxgGMgdgUrvL7DB6dE2PK9c9VP9OJ+b///Pd/FQAQlzAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDAAAMFtGgZ+/fyn+v7v38ljcC3zCyANYYBimF8AaQgDFMP8Akjj+jDw9lx9e/hn0tPb4Tnvr9X3wbHn6le/DMcdP3d8zfwC4CquDFAM8wsgDWGAYphfAGkIAxTD/AJIY9MwAACURxgAgOCEAQAIThgAgOCEAQAIThgAgOCEAQAIThgAgOCEAQAIbtMw8OffH74hjmTML4A0hAGKYX4BpCEMdEa3yt26Ham/Vz/C9/YLAwBpCAMf6np/e/hRvbz3H3se/HwtYeB6wgBAGsLAf39XTw//VE9vU8c6f6uXx8+rBt8enqtfo2NPb2057fHPYNEGjf65Bz9/H85v1Zv58djja/WnO/b+Wn3/eKzfr+1z2zqsLf8eCAMAaQgDzWbb39zH2s2+365mAz5u2F1QGAWAic3+XN80m3vv+eOf2zoeyu//f3f8cM69b5TCAEAawkDzuwIzYWAyLNRXAboNubsy0Dtel9n/dP/h/GbdL+tg4jXbAPJcPY2CSUcYAOBSwsBSGJjY2IcB4Mow0Gz8h0v7A+NP/4crECd1aQkDAFxKGFj6nYFbXBmY0FwZ+Pm7KWfq9wGEAQAuJQx8aDbY0Yb8+dcE7Wbfb1fz/ONmvy4MNJv5zKf6qQ3+aHD1Yjq8zJV/L4QBgDSEgYNmM+1dph+2o92Aj8cHm+66MHC8zN+VMdj8R8f6x5sgMFH++LHZ8u+DMACQhjBAMcwvgDSEAYphfgGkIQxQDPMLII1NwwAAUB5hAACCEwYAIDhhAACCEwYAILhNw4Df9iYl8wsgDWGAYphfAGkIAxTD/AJIQxigGOYXQBrCAMUwvwDSEAYohvkFkIYwQDHML4A09gkD76/V9+4++43n6pfjjq89fiAMAKThygDFML8A0hAGKIb5BZCGMEAxzC+ANIQBimF+AaQhDFAM8wsgDWGAYphfAGlsGgYAgPIIAwAQnDAAAMEJAwAQnDAAAMEJAwAQ3KZhwJ9+kZL5BZCGMEAxzC+ANIQBimF+AaQhDFAM8wsgjTBh4NfPf6pvDwePr9Wfiefcs3to/72HgXqMhJ3b0f9EFiIMNBvhz99nf75399J+YYCU9D+RBQgDv6unhx/Vy3vvsffX6vvDc/Vr8Lx7dT/tFwZISf8T2f2HgWbj+/gkfGK0Qd6rO2r/XYaBt+eJsWk9vR2eczKGoyDn+OXH1/Q/BBDzykAo99N+VwZISf8TWcjfGYjmXtovDJCS/ieyEGHgP//9W708Di8BxgoH99F+YYCU9D+RBQkD3APzCyANYYBimF8AaQgDFMP8Akhj0zAAAJRHGACA4IQBAAhOGACA4IQBAAhOGACA4DYNA/70i5TufX55/9yW/icyYYBiCAM5O3zl9eNr9WfyeP6sX0QmDFAMYeAydbmD+1J8+OrrLH9v/3wYKOF7/61fRCYMUIxs51d9T/wNPhEnDQNX3pjq2s1cGIC8CQM7qRfD4yezAi+l5lD/nOdX2z/P1a+JY2vdJgy0n+if3n5XT934PvyoXt7b4825x8d7euUNnjN6ncXz31+r773XO/vYDlL1P5RAGNhBs1H0Fsnxz7nLpf65z69247t8E0vVvqZeZ8eru731KACMnl+P+VLd5l7n/Pnt6/ePzdc3nVT9DyUQBpKrP3FNffK57lPkfvKpfxHzq/4ng49Pvk9vE8cWpGpfs7mOPpl/1q+7MtA7Z+KfPdKFgQ+D15uoz06sX0QmDKTWbJzDhbi1/2XQi6yp/8lzRkHh2uMHZ+dX6tdfWb/Bcy/4p5RU75+5TTqLMNAPnHX/+Wco2J0wkNzEJ+ui5FP/3OdXsxle0Vep2tfUK+sw8Hn8lmN8y9eGWxMGdlAvdOcX4/zlUv+c51fTR3NXDFZI1b663GvDQFPGwif2uddZPL+5ovLR/sfr+vAaqfofSiAM7KJdcD8vM+exua6XR/2znV8Tm+clUrWv2Yj7Y/fh83XWhYGTOXAc/4m5MTi+dP7o+A3fF9YvIhMGKMa9z6/Y75+JULIz6xeRCQMUQxi4X3Xbt7i6cg3rF5EJAxRDGLg/TQho/ungdr8r0LF+EdmmYQAAKI8wAADBCQMAEJwwAADBCQMAEJwwAADBbRoG/GkOKfnTQlLS/0QmDFAMYYCU9D+RCQMUQxggJf1PZMIAxRAGSEn/E1kxYaC9RezBjb/DPEcR+kcYICX9T2RFhIHx/fRzub9+LqL0jzBASvqfyAoIA7+rp4cf1ct777H31+p7Bjc2yUOc/hEGSEn/E1n+YaDZ2D4+6Z4YbYBRBeqfsGHgZIxHQc/x644fCANEVuaVAXri9E/YMMAu9D+RFfk7AwxF6R9hgJT0P5EVEQb+89+/1ctj/zKfcDAUo3+EAVLS/0RWSBgAYYC09D+RCQMUQxggJf1PZMIAxRAGSEn/E9mmYQAAKI8wAADBCQMAEJwwAADBCQMAENymYcBv45KSvyYgJf1PZMIAxRAGSEn/E5kwQDGEgRlvz4Ovo472Pqzvz3Ftm61fRCYMUAxhYFp93viW1X/+fQ51p09hAK4jDBw0d/7rPlk9vlZ/Jp5zjdTl526L9gsDU+pbWP9TPb1NHeuMb2TVu59/fUXh5+vx+NNbW95nuGjP/Xy8f6wzU/6q8+fmx/z5bRDqndu54EZdwgCRCQMfmoWot3iMf75W6vJzt1X7hYEJ76/V98HmO9Zupv1ymw2023AP/7xQh4lmXJqNttuAP8/vnnNy/lL5x/NHG/jMfBj+vHx+d861c6Mu957nF8wRBppPVqNPKosL7FekLj9327X/3hfri9rXbOYzfTnZ170xqc8/bNyfm2x/g2//f3jloXf+UvlT5/dec3l+LJ3fEgbgOsJAs/C0n3yGRgvUpVKXn7sN2y8MTFgKAxMb52CDvTYMLJW/tJkvzo+F8w+EAbiOMDD1yWRTqcvP3XbtFwam1P073qx7Bp+yO9Ob+eow0C9zqfzFzXxpfggDsAdh4MPw3yi3l7r83G3VfmFgWtO/ow31868J+ht77/ndZnpBGBiO50L5Kzbz+fmxfH6tqfvosa+69/kFc4SBRrvgDC5Tbrp5py4/d9u0/94X62va12yGvf4dltNePTge72+aK8NAv+zTsZsp/3D+/GY+9xprzq+NyjC/4EuEAYpx7/Mrz/ZNbMZ3yvpFZMIAxRAGbkEYgAiEAYohDNyCMAARbBoGAIDyCAMAEJwwAADBCQMAEJwwAADBCQMAENymYcCf5pCSPy0kJf1PZMIAxRAGSEn/E5kwQDGEAVLS/0QmDFAMYYCU9D+RZRMG2tuwHpzckYxby2F8hAFSuvf+r9/D5tft5N7/WYSB8f3Mxz9zW7mMjzBASsIAKeXe/xmEgfpe6D+ql/feY++v1feH5+rX4HncRj7jIwyQkjBASsLAkmZj+fikeWK0AXEbGY2PMEBKd9n/b88T793W8U6UJ+/xUdB3/PLja/o/E3leGSAj+YyPMEBK997/rgzclisDK9Sd5HcE8pXL+AgDpCQMkJIwsMrf6uVxeAlFOMhJHuMjDJCSMEBKwgBsRBggJf1PZMIAxRAGSEn/E5kwQDGEAVLS/0S2aRgAAMojDABAcMIAAAQnDABAcMIAAAQnDABAcJuGAX+aQ0r+tJCUzC9Syr3/hQGKYbEmJfOLlHLvf2GAYlisZ4xulRrtfbjF976bXzPMr7ufX8IAxbBYT6vP+za6zfSff59D3Rb8rhfreiN+fK3+TB37AvPrcsLAF+Xc2Howj8l2gzfW3kqv/xZyfzNd67L2/a6ePubE09vUsc74rpPP1a/uWL3R/Hw9Hn96a8v7XPzbcz8f7x/rzJS/6vy5+T1/frtR9c7tXHBXzfzXr36/fp35dWB+TQoRBpqJ0Bu88c+5K73+W8n9zXSti9r3/lp9n90k2sWuX26zwHUL4uHyb73YtwtmvRB2C+Tn+d1zTs5fKv94/miBnZnPw5+Xz+/OuXZu1OXmPL+adk9sdGtd1D7zqxFhfgUIA3XiG72BFid4Tkqv/3ZyfzNd66L2NYvtzFyYnCu9OVWff1hYPxfB/gLc/n+3UJ+cv1T+1Pm911ye30vntyIs1o3e5jp5fIb5dWB+Tbr/MNAMfJs8h0YTJFel139DRSzWV0iyWE8sbIMF8NrFeqn8pcV2cX4vnH8wu1ifvMZ0f53t/6XzUx/v65570ufLzK++DefXShf1/45iXhkoSun1307ub6ZrXda+en6MF9OeZjEcL+bTi+3qxbpf5lL5i4vt0vy2WHea8bliLTC/pphfnZC/M1Ca0uu/ldzfTNe6tH3N/BgteJ+/7d1feHvP7xa7Cxbr4XxcKH/FYjs/v5fPrzV1Hz32VTnPr3aMx5vi15hfveccLZ9fu/f5VQsRBroBH1wmOjs5clR6/beR+5vpWte0r1msevNjWE776e54vL+orVys+2Wfzr2Z8lcttnOvseb82qiMC94f2c6vyfZ+nfnVY36dCBIGuAf3Pr/ybN/EYnmnzK9bML9yIQxQDIv1LVis74X5dVu5zy9hgGJYrG/BYn0vzK/byn1+bRoGAIDyCAMAEJwwAADBCQMAEJwwAADBbRoG7v23cbktv+1NSuYXKeXe/8IAxbBYk5L5RUq5978wQDEs1qRkfpFS7v0vDFAMizUpmV+klHv/FxMG2jtnHZzcROL2cq/fkhLqb7EmJfOLlHLv/yLCwPgWlPO3pNxf7vVbUkr9LdakZH6RUu79X0AYqG9fObyX9n/eX6vvV97bezu5129JOfW3WJOS+UVKufd//mGg2Zg+PqmeGG1gt5J7/ZYUVH+LNSmFnV8na8Dog4Dj1x0/yH1+lXllICu5129JOfUPu1izC/OLlHLv/yJ/ZyA3pf2OwFgp9bdYk5L5RUq5938RYaC75/XnZZjcNq/c67ekjPpbrEnJ/CKl3Pu/kDAAFmvSMr9IKff+FwYohsWalMwvUsq9/4UBimGxJiXzi5Ry7/9NwwAAUB5hAACCEwYAIDhhAACCEwYAIDhhAACC2zQM+NMVUvKnX6RkfpFS7v0vDFAMizUpmV+klHv/CwMUw2I94+15cG+JaO/D+mZb17bZ/Erg5Pa+Hy6478kW43truc8vYYBiWKyn1ed9G92G+s+/zwXfVvvrhIFlN2lfEwb69/c/3BTt8bX603/eAmEgvTBhoLlNb5dMvzgRS5B7+7aon8V6yu/q6aNPn96mjnXGd6XsLc71FYWfr8fjT29teZ/hoj338/H+sc5M+avOn5sf8+fXfXY8r++CT5/mVwInYaB7bDgHBuPfe/7a8T13fk5yn18hwkAzUXqTZ/xz6XJv31b1s1hPmFpsB9rNtF9us8B2G+7hnxfqMNGMS7NIdxvw5/ndc07OXyr/eP5oA5+ZD8Ofl8/vzrl2btTlml8bm5yfwzlT16sfZpvxH31gmBvfNefnIPf5FSAM1J8ohil0eQEtSe7t265+ub+ZrnVR+5rNfKYvJ/u6Nyb1+YeFs379dpPtL9bt//cX28H5S+VPnd97zeX5sXR+SxhYdpP2Tc6PYRg4ce34Tpyfg9zn1/2HgWYy1p8sxkYLUKlyb9+G9bNYT6gXvrkwMLkw9jbY3vH69b8cBpbKnzq/f87i/Fg4/0AYWHaT9q0JA1Nz4Cvju+L8HOQ+v2JeGbgrubdvu/pZrKfU/TverHsmF+Ppzbx+/VVhoF/mUvmLm/nS/BAGtnKT9k3Nj+ax4fwY1OtL47vu/BzkPr9C/s7Avcm9fVvVz2I9renf0Yb6+dcEp4tl8/xusbwgDAzHc6H8ifPHi/X8/Fg+v9bUffTYV5lfCZyEgTa8fo73OMwejq8e33Xn5yD3+RUiDHQLyuAy0gabUz5yb9829bNYn9cslr3+HZZzWCA7/YVyZRjol306djPlH86f38znXmPN+bVRGebXiZu0rwkDvXH5MBjLWj2ex+Mfofbt45yvjO+q828v9/kVJAxwDyzWtzCxGd8p84uUcu9/YYBiWKxvQRi4F9bn28q9/4UBimGxvgVh4F5Yn28r9/7fNAwAAOURBgAgOGEAAIITBgAgOGEAAIITBgAgOGEAAIITBgAgOGEAAIITBgAguE3DQH0rUl93SSr3Pr+8f27L/CKl3PtfGKAYFmtSMr9IKff+FwYohsWalMwvUsq9/68PA2/P1beHfyYd73T2/lp9Hxx7rn71y3Dc8XPH18yvknn/3Pa4+ZX3+JR+vKD55coAxfDJjZTML1LKvf+FAYphsSYl84uUcu9/YYBiWKxJyfwipdz7f9MwAACURxgAgOCEAQAIThgAgOCEAQAIThgAgOCEAQAIThgAgOCEAQAILqsw8OffH74hCwB2JgwAQHDCAAAEJwwAQHDCAAAEJwwAQHDCAAAEJwwAQHDCAAAEJwwAQHDCAAAEJwwAQHDCAAAEJwwAQHBZhQEAYH/CAAAEJwwAQHDCAAAEJwwAQHBZhQF/TQAA+xMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACC4rMIAALA/YQAAghMGACA4YQAAghMGACA4YQAAgssqDPjTQgDYnzAAAMEJA7CHt+fq28M/R+Y5kBNhABKr5/W3hx/Vy/vnY79+Ple/es8BuCVhYEO/fvrEV7Ik4/f+Wn0fBYGxbt63oWHqysHf6uXx86rCt4d+kGiPPb11P3+or0I8vlZ/Bsd/V0/H88f1GZc/Kq//nGO5wD0RBjYkDJQtxfg1G/zCBnoMAd3zBgGi3YT79RqWuS4M9Df4cZ2an3/+/jx/kjAA90wY2JAwULb0YWD60/l4c26fdzjeBIPxPyn0jq8MA8NP+v3zD69/8hpAJMLAtUa/GNZ3XICbBb1/bLTwOn6742vG7wqnG31tYjM+98l8sLF3+hv89WGg1gaCQ9sXrxIA90YY2JArA2VLMn5NEBluvF8KA835o3Bz7ZWByTI77fMFAohFGNiQMFC2VONXlzu8WvGFMHDYnPv1asrrXS1ofu7O766CzISBwfMnTNfnEBJOrlIA90AY2FCqzYR9pBy/ZgPuLsM3PsPBfBio1eGhd+54Qx78M8hHufXPozDw+bofBq81cXxywxcG4J4JA3DXTq8MAIwJA3DXhAFgmTAAd00YAJZlFQYAgP0JAwAQnDAAAMEJAwAQnDAAAMEJAwAQXFZhoPQ/LfSnkWUzfkBUwsCGbCZly3P8An1PwOBrlXP7au9rv4752vOvdavX9z0XpRAGNiQMlC3d+B0W4os2un0W09vfV6O9/8KtNo3l9s9vpteen17a1z/f/n3mb2qp3x+3f/8JA5sSBsqWZvzaxfDycvdZTG++GM3eVjm9a9ufw2J+S+fbLwyskcP8EQY2dM9hoJ6sx0+2N/t0k1aa8Vv6xDuxWL499/q4O97+tx2Dz9sf98s4js/E650bv7rN/fOOFu5s+LXFfXz+xKZ/ZRg4Pz+7/uvf+XF0++jj4z299g+eM7q75LXnd+bfX9f1//zrz/fPkuX2d+X323Ba/tXrS/2e6c7/MHwfj/uvP8/m279mfGtn63/4p69+fdrntnVYW/4ehIENlV7/c5rJ25uc45/vRarx6xaK6QW8W4x6j02EgcH5zcL3uaA1C8rMeKwZv/qxc21fKn9eW/9+2U15h/Y1/99fBI/WB4P59nX9N1rgv9D+zlw/XHP+fP3nX/crpstZ1z9Lzrf/dP6Oy19q/6Lm/XAuwMzPvy3mx2L9m0BwKL///93xwzlL8yc1YWBDpdd/Wp2YR5P3xpd0U0k6fv1PLoOFpl2MlsLAMEgMx6RZvM6Ox7rxm1uM5stfMDlXtpxTS2Ut9W9rzWLc9MOZTery85f74qr+75l+/XX9s+R8+5fKv34uzPb94vy7dn6sq3/T94/P1dPHa02Vs2b+pCYMbKj0+k9qJvZhExsYvQHuwD7jVy8eH/03t9l/MQzUmsWmG5uTTyXdmPUNz19ajM6Wv2RyY5lo0xc3gKPF9l272H9q+mDrMLByfC7u/57p+q/rnyXn279Q/tXry9T7o2dx/l05P1bXv32dc/26Zv6kJgxsqPT6T5tIvndqt/FrFpC1m9XUYjc3JodF57jorxu/9YvRuPwFTVvnPpkdTD5vjaX2LfVv6+LN/ODy87/6/vpi//dMv/66/llyvv1L5X+1/WNt+Wf7fnH+XTs/1tW/6/u6nKmxWzN/UhMGNlR6/c85N4HvzV7j1ywMvcVm0L/dJ43j8dPFamk8uoWn+3nN+I3rNGdc/rzTxbqpz/i1Lg4DS+1bt9ivaf9cu685f8349H2t/z9Nn7euf5acb/9y+V9t/1jz2mfnztL8u35+LNa/Lu9Yvzo8jF7vw1z5exEGNlR6/c9r3zCDy2BXvHlzlWT8us29b/ymHzznY9Gofx4tVoPzB30/cfxkUVkzfqPnHI+vKX9JuwDOnn9FGJhvX3tsebP7QvsHx7c4f+I5c+d/qf+XXr89fm0YOHmdL5U/UcdB/yxrNtPe+cP38dz8W9v+c+2bONY/3gSBifLHj82Wvw9hYEP3GwZiMH5AVMLAhmwmZTN+QFTCwIZsJmUzfkBUWYUBAGB/wgAABCcMAEBwwgAABCcMAEBwWYUBf03ALRk/ICphYEM2k7IlH7/RtxHuM1cmvmFtpG53+m8+O3zD2pe/2W5DN+n/e5HB+JGUMLAhYaBsacdv+jvJ01sOA50mFNxtGEjb//X309/3e18YuHfCwIaEgbIlHb+rvnv/GrmEgRtL3P/3Hwa4d8LAhm5Z/+bOWd0l0ALTew71v10YOHzq6to/el5Xr2azPjxnfT27MNB/jelbrjblnwkDg/EZ1G9c91Y/fPTrfVp+V7/+zWTG9Vt+jUULYeB8+2qnr9+99qBtfV8MVcPX/3B8D3T903v+xI105t4/s/On6ZdRf48ey2L8SE4Y2NCt6t8sBL036fjn3OVS/xTjN1hIB7oNp10o+6/bnNNb0I9ldI9NLeBnfS7Ex8W3uWva6cbYvM5Ev9eP9xfuZnxGG85RXfaZsZsuv6vfaPM5Ox9O+2vOse9OfLZ/qX3T9R6qz7l07pzM98Fm37Z3LgyMzx//fOyDyflzZv5NtHf68bTjx36EgQ3dpv51Ih9tDAufgvKST/2Tjt+5Nk0+PuyTZnEdbL4TfXbWxGZy5vzxIn7WxCfTVl3u+XGbLn9pszs9vrqefV+ZU6P2Na+3cO7lYWBiLL4UBibOH7V1cf4svd7BTceP5ISBDd2k/s0bv07mY2s3ixvLqP5Jx+/cZjTaeFrDBfS6xXNqcf9iGJgao5M6txvi1CbSmS5/aTPZ6JPluf4/HptvX1P37thEH10cBqbqtbQ5949P1b3xOb7L86c3H+ryJsa2dtPxIzlhYEO3qf/0wl6OfOqfdPzObUaTjw/7ZHkxnzOxWH8pDEws3lMBpn5soY5z5S9uJv2N7pK+ONf/a9t31D5/XIctw0DTT8fXX+qf5ffPmvnT1b9+7rl23HT8SE4Y2NCt6j9M3uXJpf5Jx+8Lm1HTH73FdHoRXut0sT7X39OvU282/fPbnweb5dm2DU2Xv2azWy570dk6rmjfyFQ7msdmzjlvNP5120evPxivph0zxyesmj9NuR/z//F8X990/EhOGNjQ7erfviHLTd951D/p+M1umIcNqDPaVFYt5mct9e3E8fFzug2q8fEp9O2jLcc6Lp2/7vj5zeTQ/rPnrzTX/19t32h8WqPnfaV+3QbflT1q/+B43Yb650EdJurYe/118+dQxsnzJsoelN8eTz5+JCcMbKj0+kdn/DLUbITjy+DjT/N3ZhwGdjGxqW8h4vgVShjYkM2kbMYvQ82n9tFmMrnB3JEbhIF67id5zYjjVyhhYEM2k7IZvzw1G1X/EvO9byQ7hoHPvk337/rhxq9QWYUBAGB/wgAABCcMAEBwwgAABCcMAEBwwgAABCcMbMifpgFQImFgQ8IAACUSBjYkDABQImGgttE3fgkDAJQoqzBQ34rzVptpcxvQK7+SUxiYd8vxZZnxgbiEgZ56M7/me7OFgXk2m7wZH4hLGBhr7rJ12e01hYF5Npu8GR+I6/Zh4LD5TjluyM0tL/vHRpfzrz3e1z33gt8hEAYm5DC+jp8/vmZ8gLvnykCPfyZIyyfPvBkfiEsYOKhf++QT1RcJA/NsNnkzPhCXMFDzp4W7sNnkzfhAXFmFgdIJAwCUSBjYkDAAQImEgQ0JAwCUSBgAgOCEAQAIThgAgOCEAQAIThgAgOCEAQAIThjYkD8tnJd7/0QfP/MX4hIGNmQxnScM5M38hbiEgQ1ZTOcJA3kzfyEuYWBDFtN5wkDezF+ISxjYUMmLaX3Hum8PBxvcwXGKMJA3YQDiEgY2VOpi2gSBn7/P/rwVYSBvwgDEJQxsqMzF9Hf19PCjennvPfb+Wn1/eK5+DZ53PWEgb8IAxCUMbKjIxbTZ+Hv/RHA0CggbEAbyJgxAXMLAhspcTCeuDCQiDORNGIC4hIENlbqYpvodgTFhIG/CAMQlDGyo3MX0b/XyOPpnAr9AGI4wAHEJAxuymM4TBvJm/kJcwsCGLKbzhIG8mb8QlzCwIYvpPGEgb+YvxCUMAEBwwgAABCcMAEBwwgAABCcMAEBwwgAABCcMbMifZs3zp4V5M38hLmFgQxbTecJA3sxfiEsY2JDFdJ4wkDfzF+ISBjZkMZ0nDOTN/IW4hIENpVxMm9sMd3cUfHyt/kw8J3fX9M8e7Y8+fsIAxCUMbCjVYtpsJL1bCo9/LsWl/bNX+6OPnzAAcQkDG0qzmP6unh5+VC/vvcfeX6vvD8/Vr8Hz8ndZ/+zX/ujjJwxAXMLAhpIsps3G8fFJ8sRogynARf2zY/ujj58wAHEJAxtKs5hOfLIs1GX9s1/7o4+fMABxCQMbSrWYlvo7AmOX9s9e7Y8+fsIAxCUMbCjdYvq3ennsLi8fFBgOLu+ffdofffyEAYhLGNiQxXRe7v0TffzMX4hLGNiQxXSeMJA38xfiEgY2ZDGdJwzkzfyFuIQBAAhOGACA4IQBAAhOGACA4IQBAAhOGGA3fls9b8YH4hIG2I3NJm/GB+ISBtiNzSZvxgfiEgbYjc0mb8YH4hIGNlTfnc5iel7um03O49fc+bC7ydHja/Vn4jnXEgYgLmFgQ8LAPGHgMk0Q6N3lcPzzVoQBiEsY2JAwME8YuMTv6unhR/Xy3nvs/bX6/vBc/Ro873rCAMQlDFzr7Xl4n/qep7fDc5rFu39stJDf+/GDs5vNLeu3Zvxu6aTunVFA2IAwAHEJAxtyZWCeKwOXmLgykIgwAHEJAxsSBuYJA5ep65XidwTGhAGISxjYkDAwTxi41N/q5XH0zwR+gRDYkDDAbmw2eTM+EJcwwG5sNnkzPhCXMMBubDZ5Mz4QlzAAAMEJAwAQnDAAAMEJAwAQnDAAAMEJAwAQnDDAbvzpWt6MD8QlDLAbm03ejA/EJQywG5tN3owPxCUMsBubTd6MD8QlDLCbkjeb5jbC3R0DH1+rPxPPKZ0wAHEJA+ym1M2mCQK9WwaPf74XwgDEJQywmzI3m9/V08OP6uW999j7a/X94bn6NXhe+YQBiEsYYDdFbjbNxt/7J4KjUUC4A8IAxCUMsJu7uTJwp4QBiEsYYDelbjb3+jsCY8IAxCUMsJtyN5u/1cvj6J8J/AIhcEeEAXZjs8mb8YG4hAF2Y7PJm/GBuIQBdmOzyZvxgbiEAQAIThgAgOCEAQAIThgAgOCEAQAIThgAgOCEAXbjT9fyZnwgLmGA3dhs8mZ8IC5hgN3YbPJmfCAuYYDd2GzyZnwgLmGA3aTcbJrbDHd3FHx8rf5MPCdnOdRfGIC4hAF2k2qzaTbS3i2Fxz/nLpf6CwMQlzDAbtJsNr+rp4cf1ct777H31+r7w3P1a/C8XOVTf2EA4hIG2E2SzabZOD8+SZ8YbbC5yqj+wgDEJQywm92uDBQln/oLAxCXMMBuUm02pf2OwFgu9RcGIC5hgN2k22z+Vi+P/UvspYWDPOovDEBcwgC7sdnkzfhAXMIAu7HZ5M34QFzCALux2eTN+EBcwgAABCcMAEBwwgAABCcMAEBwwgAABCcMAEBwwgAABCcMAEBwwgAABCcMsJv67ny+4S5fxgfiEgbYjc0mb8YH4hIG2I3NJm/GB+ISBkjr7Xl4n/6ep7fDc95fq++DY8/Vr34Zjqc7vmZ8gLsnDLAbnzzzZnwgLmGA3dhs8mZ8IC5hgN3YbPJmfCAuYQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACA4YQAAghMGACC0/1X/DwIXXehl+9V1AAAAAElFTkSuQmCC" alt="" />
var context = contexts.game; var movables = context.GetGroup(GameMatcher.Movable);
var count = movables.count; // count is 0, the group is empty var entity1 = context.CreateEntity();
entity1.isMovable = true;
var entity2 = context.CreateEntity();
entity2.IsMovable = true; count = movables.count; // count is 2, the group contains the entity1 and entity2 // GetEntities() always provides an up to date list
var movableEntities = movables.GetEntities();
foreach (var e in movableEntities) {
// Do sth
} entity1.Destroy();
entity2.Destroy(); count = movables.count; // count is 0, the group is empty
var matcher = GameMatcher.Movable; GameMatcher.AllOf(GameMatcher.Movable, GameMatcher.Position); GameMatcher.AnyOf(GameMatcher.Move, GameMatcher.Position); GameMatcher
.AllOf(GameMatcher.Position)
.AnyOf(GameMatcher.Health, GameMatcher.Interactive)
.NoneOf(GameMatcher.Animating);
- IInitializeSystem: 只执行一次 (system.Initialize())
 - IExecuteSystem: 每帧执行 (system.Execute())
 - ICleanupSystem: 在其他系统完成后每一帧执行(system.Cleanup())
 - ReactiveSystem: 当观察的group改变时执行(system.Execute(Entity[]))
 
public class MoveSystem : IExecuteSystem {
    public void Execute() {
        // Do sth
    }
}
public class CreateLevelSystem : IInitializeSystem {
    public void Initialize() {
        // Do sth
    }
}
public class RenderPositionSystem: ReactiveSystem<GameEntity> {
    public RenderPositionSystem(Contexts contexts) : base(contexts.Game) {
    }
    protected override Collector<GameEntity> GetTrigger(IContext<GameEntity> context) {
        return context.CreateCollector(GameMatcher.Position);
    }
    protected override bool Filter(GameEntity entity) {
        // check for required components (here it is position and view)
        return entity.hasPosition && entity.hasView;
    }
    protected override void Execute(List<GameEntity> entities) {
        foreach (var e in entities) {
            // do stuff to the matched entities
            e.view.gameObject.transform.position = e.position.position;
        }
    }
}
var systems = new Systems(contexts)
.Add(new CreateLevelSystem(contexts))
.Add(new UpdateBoardSystem(contexts))
.Add(new MoveSystem(contexts))
.Add(new RenderPositionSystem(contexts)); // Call once on start
systems.Initialize(); // Call every frame
systems.Execute();
using Entitas;
public class MyInitSystem : IInitializeSystem {
    public void Initialize() {
        // Initialization code here
    }
}
using Entitas;
public class MyExecSystem : IExecuteSystem {
    public void Execute() {
        // per-frame code goes here
    }
}
public class MyCleanupSystem : ICleanupSystem {
    public void Cleanup() {
        // cleanup code here
        // runs after every execute and reactive system has completed
    }
}
using System.Collections.Generic;
using Entitas; public class MyReactiveSystem : ReactiveSystem<MyContextEntity> { public MyReactiveSystem (Contexts contexts) : base(contexts.MyContext) {
// pass the context of interest to the base constructor
} protected override ICollector<MyContextEntity> GetTrigger(IContext<MyContextEntity> context) {
// specify which component you are reacting to
// return context.CreateCollector(MyContextMatcher.MyComponent); // you can also specify which type of event you need to react to
// return context.CreateCollector(MyContextMatcher.MyComponent.Added()); // the default
// return context.CreateCollector(MyContextMatcher.MyComponent.Removed());
// return context.CreateCollector(MyContextMatcher.MyComponent.AddedOrRemoved()); // combine matchers with AnyOf and AllOf
// return context.CreateCollector(LevelMatcher.AnyOf(MyContextMatcher.Component1, MyContextMatcher.Component2)); // use multiple matchers
// return context.CreateCollector(LevelMatcher.MyContextMatcher, MyContextMatcher.Component2.Removed()); // or any combination of all the above
// return context.CreateCollector(LevelMatcher.AnyOf(MyContextMatcher.Component1, MyContextMatcher.Component2),
// LevelMatcher.Component3.Removed(),
// LevelMatcher.AllOf(MyContextMatcher.C4, MyContextMatcher.C5).Added());
} protected override bool Filter(MyContextEntity entity) {
// check for required components
} protected override void Execute(List<MyContextEntity> entities) {
foreach (var e in entities) {
// do stuff to the matched entities
}
}
}
public interface PositionViewEntity : IEntity, IPosition, IView {}
public partial class EnemyEntity : PositionViewEntity {}
public partial class ProjectileEntity : PositionViewEntity {}
public class ViewSystem : MultiReactiveSystem<PositionViewEntity, Contexts> {
    public ViewSystem(Contexts contexts) : base(contexts) {}
    protected override ICollector[] GetTrigger(Contexts contexts) {
        return new ICollector[] {
            contexts.Enemy.CreateCollector(EnemyMatcher.Position),
            contexts.Projectile.CreateCollector(ProjectileMatcher.Position)
        };
    }
    protected override bool Filter(PositionViewEntityentity) {
        return entity.hasView && entity.hasPosition;
    }
    protected override void Execute(List<PositionViewEntity> entities) {
        foreach(var e in entities) {
            e.View.transform.position = e.Position.value;
        }
    }
}
using Entitas; public class InputSystems : Feature
{
public InputSystems(Contexts contexts) : base("Input Systems")
{
// order is respected
Add(new EmitInputSystem(contexts));
Add(new ProcessInputSystem(contexts));
}
}
Systems createSystems(Contexts contexts) {
     // order is respected
     return new Feature("Systems")
         // Input executes first
         .Add(new InputSystems(contexts))
         // Update
         .Add(new GameBoardSystems(contexts))
         .Add(new GameStateSystems(contexts))
         // Render executes after game logic
         .Add(new ViewSystems(contexts))
         // Destroy executes last
         .Add(new DestroySystem(contexts));
}
- [Context]: 可以使用此特性使组件仅在指定的context中可用;例如 [MyContextName], [Enemies], [UI]....提高内存占用。它还可以创建组件。
 - [Unique]: 代码生成器将提供额外的方法,以确保最多存在一个具有该组件的实体。
 - [FlagPrefix]:仅可用于支持标记组件的自定义前缀。
 - [PrimaryEntityIndex]: 可用于将实体限制为唯一的组件值。
 - [EntityIndex]: 可用于搜索具有组件值的实体。
 - [CustomComponentName]: 为一个类或接口生成具有不同名称的多个组件。
 - [DontGenerate]: 代码生成器不会使用此属性处理组件。
 - [Cleanup]: 代码生成器将生成删除组件或销毁实体的系统。
 
- 遵循这个框架的规则去写代码,代码结构清晰。
 - ECS这种模式,耦合度就很低,所有的游戏物体都是组件的组合而已,可扩展性强,通过合理组合component就能配置出一个新的游戏物体。
 - 很方便的管理所有实体状态,entitas提供了类似状态机的功能,当感兴趣的某个属性发生变化时,能在System中很方便的做出响应,不管什么状态,都能很方便的做出对应处理。
 - unity本身的开发模式就类似ECS,unity2018更是推出了最新的ECS框架,entitas很符合这种开发模式
 - entitas自开源以来,一直在更新维护,并受到了unity官方的认可,在unite大会上都有提到。所以,这个框架还是很靠谱的。
 
- 国内资料少,上手难度高。国内用这个框架开发的特别少,遇到问题需要自己爬坑。
 - 不适合小项目。小项目用entitas反而麻烦
 - entitas更新太快,官方wiki文档更新没有跟上,比如,我在看官方Demo-MatchOne的时候,有个Event的Attribute, wiki上暂时还没有这个的
 - 代码热更方面是个问题, entitas基本对unity开发定了一套完整的规则,特别是有Code Generate,如果项目发布后想要更新加入新的代码会很麻烦,官方对此也没有说明,目前好像也没有人分享在entitas中加入lua热更的功能
 
unity游戏开发之entitas框架的更多相关文章
- Unity游戏开发之C#快速入门
		
C#是微软团队在开发.NET框架时开发的,它的构想接近于C.C++,也和JAVA十分相似,有许多强大的编程功能. 个人感受是C#吸收了众多编程语言的优点,从中可以看到C.C++.Java.Javasc ...
 - Unity游戏开发之“屏幕截图”
		
原地址:http://sygame.lofter.com/post/117105_791680 在unity游戏开发中,可能会遇到在游戏中截屏的效果.这儿提供两种截屏方法.(方法二提供显示截图缩略图代 ...
 - Unity游戏开发之“分层碰撞”
		
有没有同学遇到过这样的情况:在游戏开发3D游戏中非经常见,比方让一个物体能穿过一个物体 而还有一个物体不能穿过这个物体,并且3个物体都不能穿过地面.在unity中这样的情况的处理是通过分层碰撞来解决的 ...
 - unity游戏开发之NGUI的UISprite染色
		
游戏的UI开发中常常会遇到染色问题.比如button失效变灰的效果,同一个道具通过策划表配的颜色值染上红绿蓝紫等颜色,效果例如以下 最笨最挫的方法当然是让美术多出几个资源图.这种一个缺点是浪费资源,在 ...
 - Cocos2d-x 3.x游戏开发之旅
		
Cocos2d-x 3.x游戏开发之旅 钟迪龙 著 ISBN 978-7-121-24276-2 2014年10月出版 定价:79.00元 516页 16开 内容提要 <Cocos2d-x ...
 - 【转载】浅谈游戏开发之2D手游工具
		
浅谈游戏开发之2D手游工具 来源:http://www.gameres.com/459713.html 游戏程序 平台类型: iOS Android 程序设计: 其它 编程语言: 引擎/SDK ...
 - [整理]Unity3D游戏开发之Lua
		
原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...
 - [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读
		
---------------------------------------------------------------------------------------------------- ...
 - iOS游戏开发之UIDynamic
		
iOS游戏开发之UIDynamic 简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 ...
 
随机推荐
- Maven发布和管理项目
			
1 什么是Maven? 如果没有Maven,你可能不得不经历下面的过程: 1 如果使用了spring,去spring的官网下载jar包:如果使用hibernate,去hibernate的官网下载Jar ...
 - ActiveMq 配置多队列
			
一直在赶项目,好久没有写博文了,中间偶尔有些代码什么的,也都是放到github了,不过大多都是测试代码,毕竟有些成型的东西是给公司写的,鉴于职业道德,还是不好公开. 言归正传,这两天在接入第三方的收费 ...
 - 【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】
			
直插主题了,今天写了一下午,早就想要写这类似东西的,首先我不会选用CCLabelAtlas了,我直接用帧图片做. 首先我们要准备素材,我先把素材帖出来给大家: 这个是一张比较全的素材图,它包含了扣血的 ...
 - shell 多线程
			
不熟悉 io 重定向的童鞋,先学习一下相关知识 http://www.linuxplus.org/kb/io-redirection.html 下面是简单代码 #!/bin/bash tmpfile= ...
 - Elasticsearch安装与环境配置
			
Elasticsearch安装与环境配置 确保机器上已经安装了jdk7以上版本 下载:官网下载地址:https://www.elastic.co/downloads/elasticsearch 将下载 ...
 - JS - ECMAScript2015(ES6)新特性
			
友情提示:本文仅mark几个常用的新特性,详细请参见:ES6入门 - ryf: 碎片 var VS let VS const var:声明全局变量, let:声明块级变量,即局部变量 const:声明 ...
 - Gson简单使用
			
最近做个IM类型的Android 应用,由于有三种客户端(pc,ios,Android),所以底层使用的是C++与服务器通信,所以通信部分基本上有c++完成,封装好Jni即可,可以把底层c++通信看成 ...
 - Java基础之断言
			
断言是在Java 1.4中引入的.它能让你验证假设.如果断言失败(即返回false),就会抛出AssertionError(如果启用断言). 什么时候使用断言? 断言不应该用于验证输入数据到一个pub ...
 - oracle 转 mysql 最新有效法
			
关键字:Oracle 转 MySQL . Oracle TO MySQL 没事试用了一下Navicat家族的新产品Navicat Premium,他集 Oracle.MySQL和PostgreSQL管 ...
 - DIV+CSS 按比例等分
			
div { display: inline-block; /* 如需支持IE8以下版本,用浮动来做 */ width: calc(100% / 3.09); /* 此处运用了一个css3的表达式,将d ...