ç©çåŠ
Urho3Dã¯ãBox2DãšBulletã®2ã€ã®ç©çã©ã€ãã©ãªããµããŒãããŠããŸãã ããããæäœããåçã¯éåžžã«äŒŒãŠããŸãããæåã®æ¹æ³ã¯ããŒãã®ç§»åãXYå¹³é¢ã§ã®ã¿å®è£ ãã2çªç®ã®æ¹æ³ã¯3次å 空éã§å®è£ ããŸãã Box2Dã³ã³ããŒãã³ãã¯ã[äœæ]-> [ã³ã³ããŒãã³ã]-> [Urho2D]ã¡ãã¥ãŒã«ããã[匟䞞]ã¡ãã¥ãŒã¯[äœæ]-> [ã³ã³ããŒãã³ã]-> [ç©ç]ã¡ãã¥ãŒã«ãããŸãã
ãã®ããã ååã®ã¬ãã¹ã³ã®GameData \ Scenes \ Level01.xmlã·ãŒã³ãããŒãããŸãïŒ[ãã¡ã€ã«]-> [æè¿ã®ã·ãŒã³ãéã]ãŸãã¯[ãã¡ã€ã«]-> [ã·ãŒã³ãéã...]ïŒã åºãšéããããŸãã ç ²åŒŸãã·ãŒã³ã«è¿œå ããŸãããã ãªãœãŒã¹ãã©ãŠã¶ã§ãModelsãã©ã«ããéããCannonball.mdlã[éå±€]ãŠã£ã³ããŠã«ã·ãŒã³ã«ãŒãããŒãã«ãã©ãã°ããŸãã éãšåºãäœæ¥ã«å¹²æžããªãããã«ããã«ã¯ã[éå±€]ãŠã£ã³ããŠã§ããŒããå³ã¯ãªãã¯ãã[æå¹å/ç¡å¹å]ãéžæããŸãã åæã«ããããã¯ã·ãŒã³ããæ¶ããããŒãã¯èµ€ãå¡ãããŸãã ã«ãŒãã«ã®ããããŒããããã«ã¯ãªãã¯ãããšãç»é¢ã®äžå€®ã«ã«ãŒãã«ïŒã«ãŒãã«ïŒã衚瀺ãããŸãã
ããã§ããªãœãŒã¹ãã©ãŠã¶ã§ã[ãããªã¢ã«]ãã©ã«ããéãã[éå±€]ãŠã£ã³ããŠãŸãã¯[å±æ§ã€ã³ã¹ãã¯ã¿ãŒ]ãŠã£ã³ããŠã®[ãããªã¢ã«]åã®StaticModelã³ã³ããŒãã³ãã«ãããªã¢ã«ããã©ãã°ããŸãã ããŒãã«ååãä»ããŠãã圱ãèœãšãããªãã·ã§ã³ãæå¹ã«ããŸãã
RigidBodyããã³CollisionShapeã³ã³ããŒãã³ãïŒäœæ->ã³ã³ããŒãã³ã->ç©çïŒããã£ãã³ããŒã«ã³ã¢ã«è¿œå ããŸãã ãã®å Žåãç©çåŠã®äœæ¥ã«å¿ èŠãªPhysicsWorldã³ã³ããŒãã³ããã·ãŒã³ã«èªåçã«è¿œå ãããŸãã
RigidBodyã¯ããªããžã§ã¯ãã®ç©ççç¹æ§ãå®çŸ©ããŸãã ããã£ã¯éçããã³åçã§ãã éçãªç©äœã¯åãããé害ç©ã«éãããåçãªç©äœã¯å€åïŒéåãå«ãïŒã®åœ±é¿ãåããŸãã ããã£ã«è³ªéãããå Žå-åçã§ããã質éããŒãã®å Žåãããã£ã¯éçã§ãã
以äžã®ã¹ã¯ãªãŒã³ã·ã§ããã®ããã«ãRigidBodyã®è³ªéãæ»ãæ©æŠãããã³è»¢ããæ©æŠãèšå®ããŸãã CCD Radiusããã³CCD Motion Thresholdãã©ã¡ãŒã¿ãŒã«æ³šç®ããŠãã ããã å°ããªç©äœãé害ç©ãé«éã§æ»ãå Žåããããã®ãã©ã¡ãŒã¿ãŒãèšå®ãããšåœ¹ç«ã¡ãŸãã
CollisionShapeã¯ãè¡çªã®èšç®ã«äœ¿çšããããªããžã§ã¯ãã®åœ¢ç¶ãå®çŸ©ããŸãã 3Dã¢ãã«èªäœã䜿çšããªãã®ã¯ãªãã§ããïŒ æé©åããããã ããšãã°ãçãšã®äº€ç¹ãç¹å®ããã«ã¯ãçã®äžå¿ãŸã§ã®è·é¢ãšãã®çã®ååŸãæ¯èŒããã ãã§ååã§ãã ããã¯ãå€ãã®äžè§åœ¢ã®äº€ç¹ãèšç®ãããããã¯ããã«é«éã§ãã ãªããžã§ã¯ãã«ã¯ã圢ç¶ãããæ£ç¢ºã«èšè¿°ããããã«è€æ°ã®åœ¢ç¶ãå«ããããšãã§ããŸãã
CollisionShapeã³ã³ããŒãã³ãã®Sphereã¿ã€ããéžæããäžã®ã¹ã¯ãªãŒã³ã·ã§ããã®ããã«ããã£ãã³ããŒã«ã®ååŸã«è¿ãååŸãèšå®ããŸãã
RevertOnPauseã¹ã€ãããæå¹ã«ãªã£ãŠããããšã確èªããRunUpdatePlayãã¿ã³ãã¯ãªãã¯ããŸãã éåã®åœ±é¿äžã«ããç ²åŒŸã¯èœäžãå§ããŸãã äžæåæ¢ãæŒããšãã³ã¢ãå ã®å Žæã«æ»ããŸãã
ãã¬ãã
Unityã§äœæ¥ããããšããã人ã¯ããã®æŠå¿µã«ç²ŸéããŠããã§ãããã ãã¬ããã¯ãã·ãŒã³ã«ç¹°ãè¿ãæ¿å ¥ã§ãããªããžã§ã¯ããã³ãã¬ãŒãã§ãã GameDataãã£ã¬ã¯ããªã«Objectsãã©ã«ããŒãäœæããŸãã CannonballããŒããéžæããã¡ãã¥ãŒé ç®File-> Save node as ...ãéžæãããã¡ã€ã«GameData / Objects / Cannonball.xmlã«ä¿åããŸãã ããã§ãç ²åŒŸãã·ãŒã³ããåé€ã§ããŸãã ãã¬ãããã·ãŒã³ã«è¿œå ããã«ã¯ãã¡ãã¥ãŒé ç®[ãã¡ã€ã«]-> [ããŒãã®ããŒã]ã䜿çšããŸãã
éãæãŠïŒ
ã¬ã³ãšããã¢ããŒãããªã³ã«ããŠãèŠããããã«ããŸãã RigidBodyããã³CollisionShapeã³ã³ããŒãã³ããäœæããŸãã åºã®å ŽåãStaticPlaneã·ã§ã€ãã¿ã€ãïŒç¡éå¹³é¢ïŒãéžæããã¹ãªããããªã¯ã·ã§ã³ãšããŒãªã³ã°ããªã¯ã·ã§ã³ã1ã«èšå®ããŸãïŒããããªããšãæ¥è§Šæã«ãªããžã§ã¯ãã®æ©æŠãå¢å ãããããããã£ãç¡éã«ç§»åããŸãïŒã ã¬ã³ã®å Žåãã«ãã»ã«åœ¢ç¶ã®åœ¢ç¶ãéžæãã圢ç¶ïŒããŒãã§ã¯ãªãïŒããµã€ãº=ïŒ2ã4.3ã1ïŒããã³ãªãã»ãããªãã»ããäœçœ®=ïŒ0ã1.12ã0ïŒã«èšå®ããŸãã éã®å ŽåãAnimationControllerã³ã³ããŒãã³ããè¿œå ããŸãïŒäœæ->ã³ã³ããŒãã³ã->ããžãã¯ïŒãããã«ããã3Dãšãã£ã¿ãŒã§äœæãããã·ã§ããã¢ãã¡ãŒã·ã§ã³ãåçã§ããŸãã
次ã«ãéã¹ã¯ãªããGameData \ Scripts \ Cannon.asãå€æŽããŸãïŒã¯ãªãã¯ããŠå±éããŸãïŒã
class Cannon : ScriptObject { // . int direction = 1; // . float shootDelay = 0.0f; // . void Update(float timeStep) { // x (node , ). float pitch = node.rotation.pitch; // , . if (pitch >= 70.0f) direction = -1; else if (pitch <= -10.0f) direction = 1; pitch += 30.0f * direction * timeStep; node.rotation = Quaternion(pitch, 0.0f, 0.0f); if (shootDelay > 0.0f) shootDelay -= timeStep; // , if (input.keyDown[KEY_SPACE] && shootDelay <= 0.0f) { Shoot(); // shootDelay = 1.0f; // . AnimationController@ animCtrl = node.GetComponent("AnimationController"); animCtrl.SetTime("Models/Shoot.ani", 0.0f); // . animCtrl.PlayExclusive("Models/Shoot.ani", 0, false, 0.0f); // . SoundSource3D@ source = node.CreateComponent("SoundSource3D"); // . Sound@ sound = cache.GetResource("Sound", "Sounds/Shoot.wav"); source.autoRemove = true; // . source.Play(sound); } } void Shoot() { // CannonballPlace . Vector3 position = node.GetChild("CannonballPlace", true).worldPosition; // . XMLFile@ xml = cache.GetResource("XMLFile", "Objects/Cannonball.xml"); Node@ newNode = scene.InstantiateXML(xml, position, Quaternion()); // RigidBody. RigidBody@ body = newNode.GetComponent("RigidBody"); // , // . . body.ApplyImpulse(node.rotation * Vector3(0.0f, 1.0f, 0.0f) * 15.0f); } }
ã¹ããŒã¹ããŒãæŒããšãéãæ žãèšããŸããŠåãåºããŸãã
æ žãååšããŠãã10ç§åŸã«æ žãèªå·±ç Žå£ãããŸãããã 次ã®ããã¹ããå«ãCannonBall.asãã¡ã€ã«ãGameData \ Scriptsãã©ã«ããŒã«äœæããŸãã
class Dying : ScriptObject { float time = 0.0f; void Update(float timeStep) { time += timeStep; if (time > 10.0f) node.Remove(); } }
次ã«ããã¬ããGameData / Objects / Cannonball.xmlãã·ãŒã³ã«ããŒããïŒFile-> Load node-> As replicated / local ...ïŒãããã«ScriptInstanceã³ã³ããŒãã³ããè¿œå ããæ°ããäœæããããã¡ã€ã«ãæå®ããDyingã¯ã©ã¹ã®ååãå ¥åããŸãïŒEnterãæŒãããšãå¿ããªãã§ãã ããïŒã ããã§ããã¬ãããä¿åããŠã·ãŒã³ããåé€ã§ããŸãã å®è¡ããŠãæ žãæ¶ããæ§åã芳å¯ããŸãã
ãããã®çº
å€§ç ²ããçºå°ãããã¥ãŒãã®å»ºç©ãã·ãŒã³ã«è¿œå ããŸãã éåžžã©ãããGameData / Models / Cube.mdlã¢ãã«ãSceneã«ãŒãããŒãã«ãã©ãã°ããGameData / Materials / Cube.xmlã«èšå®ããŸãã 圱ãèœãšããªãã·ã§ã³ãæå¹ã«ããŸãã RigidBodyã³ã³ããŒãã³ãïŒè³ªé= 1ãæ©æŠ= 1ãããŒãªã³ã°æ©æŠ= 0.2ïŒãšCollisionShapeã³ã³ããŒãã³ãïŒåœ¢ç¶ã¿ã€ã=ããã¯ã¹ããµã€ãº=ïŒ2ã2ã2ïŒïŒãè¿œå ããŸãã ãã¥ãŒããå°é¢ã®å°ãäžã«çœ®ããŸãïŒå°é¢ã«æµžããšãèµ·åæã«é£ã³åºããŸãïŒã Ctrl + DãæŒããŠãã¥ãŒããè€è£œããã³ããŒã暪ã«ç§»åããŸãã å¥ã®ã³ããŒãäœæããŸãã
ãšããã§ãå±æ§ã€ã³ã¹ãã¯ã¿ãŒãŠã£ã³ããŠã§ã¯ãããã©ã«ããšç°ãªããã¹ãŠã®å€ãéè²ã§ããŒã¯ãããŠããããšã«æ°ä»ããŸãããïŒ
次ã«ãCtrlãã¿ã³ãæŒããªãããã¥ãŒãã®è¡å šäœãéžæããå šäœãè€ââ補ããŸãã æåã®è¡ã®äžã«ã³ããŒãæã¡äžããŸãïŒã®ã£ãããå¿ããªãã§ãã ããïŒã 次ã«ãå¥ã®è¡ãäœæããŸãã
ãããå®è¡ããŸãã èµ·ååŸã«ãã¥ãŒããå°ãèœã¡ããšããåé¡ããããŸãããããã¥ãŒããæäœæ¥ã§éåžžã«æ£ç¢ºã«éããããšã¯å°é£ã§ãã ããã§ãRevertOnPauseã¹ã€ããã圹ç«ã¡ãŸãã ããããªãã«ãããŸããéã§ScriptInstanceã³ã³ããŒãã³ããç¡å¹ã«ããŸãïŒä»¥åã«ããŒãå šäœããªãã«ããããã«ãããŒãã§ã¯ãªãã³ã³ããŒãã³ããå³ã¯ãªãã¯ããŸããå¥ã®æ¹æ³ã¯ãå±æ§ã€ã³ã¹ãã¯ã¿ãŒãŠã£ã³ããŠã§ååãã¯ãªãã¯ããããšã§ãïŒã
ä»ããã¬ã€ãéå§ãããã¥ãŒããèœã¡ããšã-åæ¢ããŸãã ã·ãŒã³ã¯æ°ããç¶æ ã®ãŸãŸã§ããã RevertOnPauseãšScriptInstanceãå床æå¹ã«ããŠãã ããã
ç²å
ãã£ãã³ããŒã«ã®ããŒãã£ã¯ã«ã®è»è·¡ãäœæããŸãããã ã¡ãã¥ãŒé ç®ã®è¡šç€º->ããŒãã£ã¯ã«ãšãã£ã¿ããããŒãã£ã¯ã«ãšãã£ã¿ãéããŸãã 次ã®ãªãã·ã§ã³ãèšå®ããŸãã
- æ¹åïŒåïŒ=ïŒ-0.1ã-0.1ã-0.1ïŒ
- æ¹åïŒæ倧ïŒ=ïŒ0.1ã0.1ã0.1ïŒ-ããã2ã€ã®å€ã¯ãç°ãªãæ¹åã§ã®ç²åã®èšåŒµé床ã決å®ããŸãïŒåç²åã«ã€ããŠãç¹å®ã®ç¯å²ã§ã©ã³ãã ãªå€ãéžæãããŸãïŒ
- ç²åãµã€ãºïŒæå°ïŒ=ç²åãµã€ãºïŒæ倧ïŒ=ïŒ0.3ã0.3ïŒ-ãã¹ãŠã®éå§ç²åãµã€ãºã¯åãã§ã
- ãµã€ãºè¿œå = -0.8-æéãçµã€ã«ã€ããŠãç²åãµã€ãºãæžå°ããŸã
- ç²åæ°= 1000-åæã«ååšããç²åã®æ倧æ°
- æŸåºé床ïŒæå°ïŒ=æŸåºé床ïŒæ倧ïŒ= 80-ç²åæŸåºé »åºŠ
- çžå¯Ÿå€æ=ãªã -芪ããŒãã«é¢ä¿ãªããããŒãã£ã¯ã«ãã¯ãŒã«ã座æšã§ç§»åããããã«
ããã§ãç²åã®çµæçãªè²ã®å€åãè¿œå ããŸãã Color Framesãããã¯ã®äžã®[New]ãã¿ã³ãããã«ã¯ãªãã¯ããŠã2ã€ã®æ°ããè¡ãäœæããäžã®ã¹ã¯ãªãŒã³ã·ã§ããã®ããã«ãã£ãŒã«ãã«å ¥åããŸãã æåã®å€ã¯æéã§ãããè²ã¯RGBA圢åŒã§ãã
[ååãä»ããŠä¿å]ãã¿ã³ãã¯ãªãã¯ããŠããšãã§ã¯ããGameData \ Particle \ Sparks.xmlãã¡ã€ã«ã«ä¿åããããŒãã£ã¯ã«ãšãã£ã¿ãŒãŠã£ã³ããŠãéããŸãã ç ²åŒŸã®ãã¬ãããã·ãŒã³ã«ããŒãããParticleEmitterã³ã³ããŒãã³ããè¿œå ããŠïŒäœæ->ã³ã³ããŒãã³ã->ãžãªã¡ããªïŒãæ°ããäœæããå¹æãæå®ãããã¬ããããã¡ã€ã«ã«ä¿åããŠãç ²åŒŸãã·ãŒã³ããåé€ããŸãã ã²ãŒã ã®æºåãã§ããŸããã
次ã¯ïŒ
ãšãã£ã¿ãŒã®ãã¹ãŠã®æ©èœãèæ ®ããŸããã§ããã ããšãã°ãã€ã³ã¿ãŒãã§ã€ã¹ã®äœæããããªã¢ã«ãšãã£ã¿ã«ã€ããŠã®èšèã¯ãããŸããã§ããã ãã ããäžè¬ååãç解ãããããã«å¯ŸåŠããããšã¯é£ãããããŸããã
次ã«ãã²ãŒã ãåå¥ã®ããã°ã©ã ãšããŠé 眮ããå¿ èŠããããŸãã èšç»ã¯éåžžã«åçŽã§ããã·ãŒã³ãããŒãããŠéå§ããæå°éã®ã¹ã¯ãªãããäœæããŸãã ãã ããã·ãŒã³ã«ã¯ååãªã«ã¡ã©ããªãããšãã£ã¿ãŒã®å éšã«ã¡ã©ã䜿çšãããŸããå€éšã«ã¡ã©ã¯äœ¿çšã§ããŸããã éåžžã©ãããæ°ããããŒããäœæããã«ã¡ã©ã³ã³ããŒãã³ããè¿œå ããŸãïŒäœæ->ã³ã³ããŒãã³ã->ã·ãŒã³ïŒã ã¹ã¯ãªããã§ã¢ã¯ã»ã¹ã§ããããã«ãå¿ ãããŒãåãCameraã«èšå®ããŠãã ããã ã«ã¡ã©ã奜ããªããã«é 眮ããŠå転ãããŸãïŒå³äžé ã«è¡šç€ºãããã«ã¡ã©ããã®ãã¥ãŒã圹ç«ã¡ãŸãïŒã ãŸããSoundListenerã³ã³ããŒãã³ãïŒCreate-> Component-> AudioïŒãã«ã¡ã©ã®ããããŒãã«ã¢ã¿ããããŸããããããªããšã空éã«é 眮ããããµãŠã³ããèãããªããªããŸãã ã·ãŒã³ãä¿åãã次ã®å 容ã®GameData \ Scripts \ Main.asãã¡ã€ã«ãäœæããŸãã
Scene@ scene_; void Start() { scene_ = Scene(); // . scene_.LoadXML(cache.GetFile("Scenes/Level01.xml")); // . Node@ cameraNode = scene_.GetChild("Camera"); // , . Viewport@ viewport = Viewport(scene_, cameraNode.GetComponent("Camera")); renderer.viewports[0] = viewport; // , . renderer.shadowMapSize = 2048; // , . audio.listener = cameraNode.GetComponent("SoundListener"); }
CoreDataãã©ã«ããŒãšUrho3DPlayer.exeã©ã³ãã£ãŒãã²ãŒã ãã©ã«ããŒã«ã³ããŒããŸãã ãŸããStart.batãèµ·åããããã®ããããã¡ã€ã«ãæ¢ã«ãããŸãïŒUrho3DHabrahabr02Start.zipã¢ãŒã«ã€ãããïŒã ã²ãŒã ã®ãªãœãŒã¹ããŠã£ã³ããŠãµã€ãºãèµ·åã¹ã¯ãªãããå«ããã©ã«ããŒãã©ã³ãã£ãŒã«ç€ºããŸãã
start "" Urho3DPlayer.exe Scripts/Main.as -p "GameData;CoreData" -w -x 800 -y 600
æçµçµæã¯ããããããŠã³ããŒãã§ããŸã ã
çŽæã®ããŒãã¹
ãŸããã³ãã³ããScriptCompiler.exe GameData / Scripts / *ãAsãã§ãã¹ãŠã®ã¹ã¯ãªãããã³ã³ãã€ã«ããŸãã ãã®çµæãæ¡åŒµåã.ascã®ãã¡ã€ã«ãååŸããŸãã æè¿ã ããããè¿œå ãããŸãããããã«ãããèŠæ±ããã.asãã¡ã€ã«ããªãå Žåã.ascãã¡ã€ã«ãããŒããããŸããããã¯ãååã®å€æŽã«å¯ŸåŠããå¿ èŠããªãããšãæå³ããŸãã ãœãŒã¹.asãã¡ã€ã«ãGameData \ Scriptsãã©ã«ããŒããå¥ã®å Žæã«ç§»åããã ãã§ã.ascãã¡ã€ã«ã®ã¿ãæ®ããŸãã
ããã±ãŒãžåã«ã¯ãBuild \ bin \ tool \ PackageTool.exeãŠãŒãã£ãªãã£ãå¿ èŠã§ãã ã³ãã³ããå®è¡ããŸãã
PackageTool.exe CoreData CoreData.pak -c PackageTool.exe GameData GameData.pak -c
-cãªãã·ã§ã³ã¯ããã¡ã€ã«å§çž®ãã¢ã¯ãã£ãã«ããŸãïŒé«éLZ4ã¢ã«ãŽãªãºã ã䜿çšïŒã
ããã§ãCoreDataããã³GameDataãã©ã«ããŒãåé€ã§ããŸãã ãã®çµæã次ã®ããšãã§ããŸãã
ããŠãéåžžã«çŸããããããã«ãããããã¡ã€ã«Start.batãåé€ã§ããŸãã ãã ãããã®ããã«ã¯ãã©ã³ãã£ãŒã®ãœãŒã¹ã³ãŒããå€æŽããå¿ èŠããããŸãïŒUrho3D \ Source \ Tools \ Urho3DPlayerãã©ã«ããŒã«ãããŸãïŒã äºåã«æãããªãã§ãã ãã-ã©ã³ãã£ãŒãœãŒã¹ã¯éåžžã«å°ããã§ããããã¯ãã©ã³ãã£ãŒãã©ã¡ãŒã¿ãŒããšã³ãžã³ã«èµ·åââãã©ã¡ãŒã¿ãŒã転éãããšããäºå®ã®ã¿ãåŠçããããã§ãã ãããã¯ãæå®ããå¿ èŠããããã©ã¡ãŒã¿ãŒã§ãã åæã«ãã¢ããªã±ãŒã·ã§ã³çšã«ç¬èªã®ã¢ã€ã³ã³ãäœæã§ããŸãã
çµè«ã®ä»£ããã«
ãã®æ©äŒã«ã ãã·ã¢èªçWikiã®å 容ã«åå ããã人ãæåŸ ããŸãã ãæž èŽããããšãããããŸããïŒ