Slide 1

Slide 1 text

Ͳ͔͜Β࢝ΊΔ Unity Test 2019/1/23 Gotanda Unity #10

Slide 2

Slide 2 text

͍΋Ͱ͢ • ͍΋(@adarapata) • https://adarapata.com • ϛΫγΟ XFLAG UnityΤϯδχΞ • εϚϒϥੈքઓಆྗ53ສ

Slide 3

Slide 3 text

ࠓ೔࿩͢͜ͱ • UnityͰ۩ମతʹͲ͏͍͏෩ʹςετॻ͖ਐΊ͍ͯͬͨΒ ͍͍ͷʁͱ͍͏࿩ • ͏ͪͷήʔϜʹࠓ͔ΒೖΕΔͷ͸ͳ͊ɾɾΈ͍ͨʹ᪳᪯ͬ ͍ͯΔਓΛޙԡ͢͠Δ࿩ • ςετ͋·Γॻ͍ͨ͜ͱͳ͍ਓ޲͚

Slide 4

Slide 4 text

ͳͥςετΛॻ͘ͷ͔ • ඼࣭ͷ೺Ѳ/ਫ਼ਆతোนͷഉআ • աڈʹهࣄΛॻ͍ͨͷͰࢀর͍ͩ͘͞ɻ • ʮςετίʔυʹ͍ͭͯͷจॻΛॻ͍͍ͯͨʯhttp:// adarapata.hatenablog.com/entry/2018/08/16/001607

Slide 5

Slide 5 text

UnityͰΑ͋͘Δίʔυʹରͯ͠ ϢχοτςετΛॻ͍ͯΈΔ • MonoBehaviorʹ৭ʑॻ͍ͯΔ΍ͭ • αϯϓϧͰ͋Γͦ͏ͳSTGͷࣗػ • খن໛ͳϓϩμΫτ ݁࿦Λઌʹݴ͏ͱ௒ઈ͠ΜͲ͍

Slide 6

Slide 6 text

public class PlayerUnit : MonoBehaviour { [SerializeField] private Bullet _bulletPrefab = null; [SerializeField] private float _interval; [SerializeField] private float _speed; [SerializeField] private int _hp; private float _reloadTime; void Update() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); transform.position += new Vector3(horizontal, vertical, 0F) * _speed * Time.deltaTime; if (Input.GetButton("Fire1") && _reloadTime < 0) { var bullet = Instantiate(_bulletPrefab, transform.position, Quaternion.identity); bullet.SetUp(Vector2.up); _reloadTime = _interval; } _reloadTime -= Time.deltaTime; } void OnTriggerEnter2D(Collider2D collider) { if (collider.tag == "Bullet") { _hp--; if (_hp <= 0) { Destroy(gameObject); } } } }

Slide 7

Slide 7 text

΍͍ͬͯͧ͘

Slide 8

Slide 8 text

PlayerUnitʹ΍ͬͯ΄͍͜͠ͱ Λࢥ͍ग़͢ • Ҡಈ͢Δ • ஄Λൃࣹ͢Δ • μϝʔδΛड͚Δ

Slide 9

Slide 9 text

PlayerUnitʹ΍ͬͯ΄͍͜͠ͱ Λࢥ͍ग़͢ • Ҡಈ͢Δ // ࠓ೔͸͚ͩ͜͜ • ஄Λൃࣹ͢Δ • μϝʔδΛड͚Δ

Slide 10

Slide 10 text

Ҡಈͷςετ • ೖྗ͕͋Δͱɺಈ͍ͯཉ͍͠ • ಈ͘ = transform.positionʹมԽ͕͋Δ

Slide 11

Slide 11 text

namespace Tests { public class PlayerUnitTest { [UnityTest] public IEnumrator MoveTest() { var gameObject = new GameObject(); var playerUnit = gameObject.AddComponent(); var beforePosition = playerUnit.transform.position; yield return null; Assert.AreNotEqual(beforePosition, playerUnit.transform.position); } } } ͜Μͳײ͡ʹॻ͚Δͱ͍͍ͳ

Slide 12

Slide 12 text

μϝͰ͢ • Position͕ಉҰ = ಈ͍͍ͯͳ͍ • άϦʔϯ໨ࢦͯ͠ؤுΔͧ

Slide 13

Slide 13 text

௨Βͳ͍ཧ༝Λߟ͑Δ public class PlayerUnit : MonoBehaviour { [SerializeField] private Bullet _bulletPrefab = null; [SerializeField] private float _interval; [SerializeField] private float _speed; [SerializeField] private int _hp; private float _reloadTime; void Update() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); transform.position += new Vector3(horizontal, vertical, 0F) * _speed * Time.deltaTime; ~~~~ } } • _speedʹ஋͕ೖͬͯͳ͍ • ΩʔೖྗͰ͖ͯͳ͍ͷͰ࣮࣭0ϕΫτϧ SerializeField΋Input΋Test͔Β͸ѻ͑ͳ͍

Slide 14

Slide 14 text

ςετ͠΍͍͢΋ͷͱ͠ʹ͍͘΋ͷΛ෼཭͢Δ • Unity APIʹґଘ͍ͯ͠ͳ͍Ϋϥε • Unity APIʹґଘ͍ͯ͠ΔΫϥε • RigidBody,Animator etc.. • MonoBehaviourΛܧঝͨ͠Ϋϥε • GUI෦෼ Unityଆʹۙͮ͘ʹͭΕͯςετͷ೉қ౓͸্͕͍ͬͯ͘ ςετ͠΍͍͢΋ͷ ςετ͠ʹ͍͘΋ͷ

Slide 15

Slide 15 text

ςετ͠΍͍͢ํ޲ʹدͤΔ public class PlayerUnit : MonoBehaviour { [SerializeField] private Bullet _bulletPrefab = null; [SerializeField] private float _interval; [SerializeField] private float _speed; [SerializeField] private int _hp; private float _reloadTime; void Update() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); transform.position += new Vector3(horizontal, vertical, 0F) * _speed * Time.deltaTime; ~~~~ } } • ܭࢉॲཧ͚ͩ੾Γग़ͤ͹ςετॻ͚ͦ͏ • Inputʹ௚઀ґଘ͠ͳ͚Ε͹ςετ࣌ͷೖྗΛ༻ҙͰ͖ͦ͏ ॻ͖ͮΒ͍ͱ͜Ζ͸ॻ͔ͳ͍

Slide 16

Slide 16 text

public class PlayerUnitMove { private float _speed; public PlayerUnitMove(float speed) { _speed = speed; } public Vector3 CalculateVelocity(Vector3 direction) => direction.normalized * _speed; } namespace Tests { public class PlayerUnitMoveTest { [Test] public void CalculateVelocityTest() { var move = new PlayerUnitMove(3); Assert.AreEqual(new Vector3(0, 3F,0), move.CalculateVelocity(Vector3.up)); } } } ܭࢉॲཧ͚ͩΫϥεΛ੾Γग़͢

Slide 17

Slide 17 text

public class PlayerUnit : MonoBehaviour { [SerializeField] private Bullet _bulletPrefab = null; [SerializeField] private float _interval; [SerializeField] private int _hp; private float _reloadTime; private PlayerUnitMove _move; public void Initialize(PlayerUnitMove move) { _move = move; } void Update() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); var direction = new Vector3(horizontal, vertical, 0F); transform.position += move.CalculateVelocity(direction) * Time.deltaTime; ~~~~ } } Ҡಈ஋ܭࢉ෦෼Λࠩ͠ସ͑ ΦϒδΣΫτ͸֎෦͔Β౉ͤΔΑ͏ʹ͢Δ

Slide 18

Slide 18 text

Input΁௚઀ґଘΛ΍ΊΔ public interface IPlayerUnitInput { Vector3 GetAxis(); } public class IUnityInput : IPlayerUnitInput { public Vector3 GetAxis() { float horizontal = Input.GetAxis("Horizontal"); float vertical = Input.GetAxis("Vertical"); return new Vector3(horizontal, vertical, 0); } } ೖྗ෦෼ΛΠϯλϑΣʔεʹͯ͠ɺPlayerUnitʹΩʔೖྗΛҙࣝͤ͞ͳ͍

Slide 19

Slide 19 text

Input΁௚઀ґଘΛ΍ΊΔ ·ͨ΋ΦϒδΣΫτ͸֎෦͔Β౉ͤΔΑ͏ʹ͢Δ public class PlayerUnit : MonoBehaviour { [SerializeField] private Bullet _bulletPrefab = null; [SerializeField] private float _interval; [SerializeField] private int _hp; private float _reloadTime; private PlayerUnitMove _move; private IPlayerUnitInput _input; public void Initialize(PlayerUnitMove move, IPlayerUnitInput input) { _move = move; _input = input; } void Update() { var direction = _input.GetAxis(); transform.position += move.CalculateVelocity(direction) * Time.deltaTime; ~~~~ } }

Slide 20

Slide 20 text

namespace Tests { public class PlayerUnitTest { class MockInput : IPlayerUnitInput { private Vector3 _axis; public MockInput(Vector3 axis) { _axis = axis; } public Vector3 GetAxis() => _axis; } [UnityTest] public IEnumerator MoveTest() { var gameObject = new GameObject(); var playerUnit = gameObject.AddComponent(); var mockInput = new MockInput(Vector3.up); playerUnit.Initialize(new PlayerUnitMove(1), mockInput); var beforePosition = playerUnit.transform.position; yield return null; Assert.AreNotEqual(beforePosition, playerUnit.transform.position); } } } ͪΐͬͱॻ͖௚ͯ͠ςετ࣮ߦ

Slide 21

Slide 21 text

Slide 22

Slide 22 text

ςετͱ͍͏͔ ϦϑΝΫλϦϯά͡Όͳ͍ʁ

Slide 23

Slide 23 text

͸͍

Slide 24

Slide 24 text

MonoBehaviorͷςετ͸͠ΜͲ͍ • MonoBehaviorϕλॻ͖͸ςετ͠ʹ͍͘ • ϏδωεϩδοΫΛMonoBehaviorʹॻ͍͍ͯ͘ͱҾͬு ΒΕͯςετ೉қ౓্͕͕Δ • ͭ·Γີ݁߹ • ີ݁߹͸Α͍ઃܭͱ͸ݴ͑ͳ͍ • ςετͷ͠ʹ͔͘͞Βઃܭͷ໰୊Λ೺Ѳ͢Δ

Slide 25

Slide 25 text

Humble Object ύλʔϯ • ςετ͠ʹ͍͘΋ͷͱͦ͏Ͱͳ͍ ΋ͷΛ໌֬ʹ෼͚ͯ෼ׂ͢Δύλ ʔϯ • GUIͷॲཧͷৄࡉ͸ςετ͠ʹ͍͘ ͕ɺGUIͷৼΔ෣͍͸ςετͰ͖Δ • ӈͷίʔυ͸ɺ஄ͷੜ੒෦෼ͷς ετ͸೉͍͕͠ɺʮੜ੒͢Δͱ͍ ͏ৼΔ෣͍͕ߦΘΕ͔ͨʯ·Ͱ͸ ςετͰ͖Δ • MonoBehaviorʹ͸༗ޮ͔΋͠Εͳ ͍ public class PlayerUnitPresenter { private IPlayerUnitView _view; public void Shot(Vector3 position) { _view.Shot(position); } } public interface IPlayerUnitView { void Shot(Vector3 position); } public class PlayerUnitView : MonoBehaviour, IPlayerUnitView { public void Shot(Vector3 position) { // ஄࡞ͬͨΓ͢Δ } }

Slide 26

Slide 26 text

ςετίʔυͷՁ஋ • ಈ࡞֬ೝͱ͍͏ࢹ఺͚ͩͳΒ͹ɺҰճॻ͍ͯऴΘΓͷݸਓ ϓϩμΫτʹೖΕΔҙٛ͸ബ͍ • ໨ࢹˍΤσΟλ࠶ੜͷ͕଎͍έʔε΋ଟ͍ • લड़ͷ௨Γઃܭͷ໰୊΁ͷؾ͖ͮΛಘΒΕΔࣄ΋ଟ͍ • ؾ͖ͮ͸ະདྷͷ։ൃ࣌ؒ୹ॖ

Slide 27

Slide 27 text

ؾ͖ͮͷΉ͔͠͹ͳ͠ • UserData(Ծ໊)ͱ͍͏Ϣʔβͷ͋ΒΏΔσʔλΛอ࣋ͨ͠Γ ॲཧͰ͖Δେ͖ͳΫϥε͕͋ͬͨ • ͋·Γྑ͘ͳ͍ΑͶͱ͍͏ೝࣝͰ͸͕࣮͋ͬͨ૷্͸ָͳͷ Ͱͦͷ··ͩͬͨ • ςετॻ͖࢝Ίͨஈ֊ͰUserData͕བྷΉςετ͸೉қ౓͕ߴ ͍͜ͱʹؾ͖ͮ࢝Ίͨ • νʔϜͰ໰୊ʹͳΓɺUserDataͷϦϑΝΫλϦϯά͕༏ઌత ʹߦΘΕ·ͨ͠ͱ͞

Slide 28

Slide 28 text

·ͱΊ • MonoBehaviorϕλॻ͖Ͱ΋ςετ͸ॻ͚·͢ • ςετ͠΍͍͢΋ͷɺ͠ʹ͍͘΋ͷΛ෼ׂ͍ͯ͜͠͏ • ໰୊ͷ೺Ѳͱ͍͏ࢹ఺Ͱςετॻ͍ͯΈΔͷ΋͍͍Α

Slide 29

Slide 29 text

͓ΘΓ