포스트

Mirror to FishNet 변환하기

안녕하세요, 오늘은 서버로 Mirror network를 사용한 기존 코드를 FishNet으로 변환하는 연습을 해보고 가져왔습니다. 저를 따라하실 분은 아래 유투브를 보시면 됩니다!

https://youtu.be/ZhEMh5RjEjs

[영상]

시작하겠습니다.


먼저 유니티에서 빈 3D프로젝트 하나 만들고, Mirror 유니티 무료 패키지를 임포트해줍니다. 그리고 FishNet도 임포트해줍니다.

mirror, and Fishnet

Mirror 폴더에 들어가보면 Example에 Tanks라는 예제가 있습니다. 따라서 하시면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Tanks.cs
using FishNet.Managing.Logging;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using UnityEngine;
using UnityEngine.AI;

namespace Mirror.Examples.Tanks
{
    public class Tank : NetworkBehaviour
    {
        [Header("Components")]
        public NavMeshAgent agent;
        public Animator  animator;
        public TextMesh  healthBar;
        public Transform turret;

        [Header("Movement")]
        public float rotationSpeed = 100;

        [Header("Firing")]
        public KeyCode shootKey = KeyCode.Space;
        public GameObject projectilePrefab;
        public Transform  projectileMount;

        [Header("Stats")]
        [SyncVar] public int health = 4;

        void Update()
        {
            // always update health bar.
            // (SyncVar hook would only update on clients, not on server)
            healthBar.text = new string('-', health);
            
            // take input from focused window only
            if(!Application.isFocused) return; 

            // movement for local player
            if (base.IsOwner)
            {
                // rotate
                float horizontal = Input.GetAxis("Horizontal");
                transform.Rotate(0, horizontal * rotationSpeed * Time.deltaTime, 0);

                //s move
                float vertical = Input.GetAxis("Vertical");
                Vector3 forward = transform.TransformDirection(Vector3.forward);
                agent.velocity = forward * Mathf.Max(vertical, 0) * agent.speed;
                animator.SetBool("Moving", agent.velocity != Vector3.zero);

                // shoot
                if (Input.GetKeyDown(shootKey))
                {
                    CmdFire();
                }

                RotateTurret();
            }
        }

        // this is called on the server
        [ServerRpc]
        void CmdFire()
        {
            GameObject projectile = Instantiate(projectilePrefab, projectileMount.position, projectileMount.rotation);
            base.Spawn(projectile);
            RpcOnFire();
        }

        // this is called on the tank that fired for all observers
        [ObserversRpc]
        void RpcOnFire()
        {
            animator.SetTrigger("Shoot");
        }

        [Server(Logging = LoggingType.Off)]
        void OnTriggerEnter(Collider other)
        {
            if (other.GetComponent() != null)
            {
                --health;
                if (health == 0)
                    base.Despawn();
            }
        }

        void RotateTurret()
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out RaycastHit hit, 100))
            {
                Debug.DrawLine(ray.origin, hit.point);
                Vector3 lookRotation = new Vector3(hit.point.x, turret.transform.position.y, hit.point.z);
                turret.transform.LookAt(lookRotation);
            }
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//Projectile.cs
using FishNet.Managing.Logging;
using FishNet.Object;
using UnityEngine;

namespace Mirror.Examples.Tanks
{
    public class Projectile : NetworkBehaviour
    {
        public float destroyAfter = 2;
        public Rigidbody rigidBody;
        public float force = 1000;

        public override void OnStartServer()
        {
            base.OnStartServer();
            Invoke(nameof(DestroySelf), destroyAfter);
        }

        // set velocity for server and client. this way we don't have to sync the
        // position, because both the server and the client simulate it.
        void Start()
        {
            rigidBody.AddForce(transform.forward * force);
        }

        // destroy for everyone on the server
        [Server]
        void DestroySelf()
        {
            base.Despawn();
        }

        // Server(Logging = LoggingType.Off) because we don't want a warning
        // if OnTriggerEnter is called on the client
        [Server(Logging = LoggingType.Off)]
        void OnTriggerEnter(Collider co) => DestroySelf();
    }
}

그 외에는 NetworkManager를 Fishnet의 NetworkManager로 바꿔주고, Tank와 Turret, Projectile에 모두NetworkObject를, Tank와 Turret에 Network Transform을 넣어주면 됩니다.

[영상]

저는 Mirror프로젝트 내의 다른 예제도 Fishnet으로 변경하려고 하고 있는데 좀다 복잡하네요.ㅠ Tanks예제가 제일 쉬운 듯 합니다! 제일 먼저 이 예제부터 시작하시면 될 것 같습니다.

감사합니다.

sticker


참고자료) https://fish-networking.gitbook.io/docs/manual/general/upgrading-to-fish-net

Upgrading To Fish-Networking

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.