- ์ ๋๋ฅผ ํท๊ฐ๋ฆฌ๊ฒ ํ๋ ํด๋ก ๋ค์ ๋ง๋ค์ด์ฃผ์.
- ํ๋ ์ด์ด์ ๊ฐ์ ๋ชจ์์ Capsule์ ํ๋ ๋ง๋ค์ด์ฃผ๊ณ ์ด๋ฆ์ Clone์ด๋ผ ํด์ฃผ์.
- Clone์ rigidbody, PhotonView, PhotonTransformView, NavMeshAgent๋ฅผ ๋ฃ์ด์ฃผ์.
- Rigidbody์์ xyz๊ณ ์ ์ xyz์ถํ์ ๋ ๊ณ ์ ์ผ๋ก ํด์ฃผ์.
- NavMeshAgent๋ ํด๋ก ๋ค์ด ์์ฐฐํ ๋ ๋์์ ์ค๋ค.
- ClonePatrol์คํฌ๋ฆฝํธ๋ฅผ ๋ง๋ค์ด์ค๋ค.
- SpawnManager์์ ์คํฐํฌ์ธํธ๋ก ์ผ๋ ์์น๊ฐ์ ์์ฐฐํฌ์ธํธ๋ก ํด์ ๊ณ์ ์์ฐฐํ๊ฒ ์ฝ๋๋ฅผ ์์ฑํด์ฃผ์.
- Clone ํ๊ทธ๋ฅผ ๋ถ์ฌ์ฃผ๊ณ ํ๋ฆฌํฉํ ์์ผ์ค๋ค.
---------------------------------------------- ]

- Game Scene์์ ์งํ์ผ๋ก ์ธ ๋ฌผ์ฒด๋ค์ ๋ค ์ ํํด์ค๋ค.
- Navigation์์ object์ Bake ์ค์ ์ ๋คํด์ฃผ๊ณ Bake ๋ฒํผ์ ๋๋ฌ์ฃผ์.
- ์ด์ NavMeshAgent๊ฐ ๊ฑธ์ด๋ค๋ ์ ์๋ ๋ฒ์๊ฐ ์๊น๋ก ํํ๋๋ค.
- Game Scene์ Clone๋ค์ ์ฌ๋ฌ๊ฐ ์ฌ๋ ค๋๊ณ ์คํํด๋ณด๋ฉด ์์ฐฐ์ ์ํ๋๊ฑธ ๋ณผ ์ ์๋ค.
- Single Shot Gun ์คํฌ๋ฆฝํธ๋ฅผ ์์ ํด์ฃผ์.
- Clone๋ค์ ์ด๋ง์ผ๋ฉด ๋ฐ๋ก ์ฌ๋ผ์ง๋๋ก ์ฝ๋๋ฅผ ์์ ํด์ฃผ์.
- ๋ํ ์ ๋๊ฐ ํด๋ก ์ธ์ฒํ๋ ์ฌ๋์ ๋ง์ถ๋ฉด ์ฒด๋ ฅ์ด ํ๋ณต๋๋๋ก ์ฝ๋๋ฅผ ์์ ํด์ฃผ์.
- PlayerController ํ๋ฆฌํฉ์์๋ Rifle๊ณผ Pistol์ shooter๋ฅผ ์ถ๊ฐํด์ฃผ์.
- PlayerController์ Playerํ๊ทธ๋ฅผ ์ถ๊ฐํด์ฃผ์.
- ์คํํด๋ณด๋ฉด ์ด์ ๋ง์ผ๋ฉด Clone๋ค์ ์ฌ๋ผ์ง๊ณ Player๋ฅผ ๋ง์ถ๋ฉด ์ฒด๋ ฅ์ด ํ๋ณต๋๋๊ฑธ ๋ณผ ์ ์๋ค.
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class ClonePatrol : MonoBehaviour
{
private NavMeshAgent agent;
//์์ฐฐ์ ์ํ ๋ค๋น๊ฒ์ด์
๋ฉ์ฌ ์์ด์ ํธ
PhotonView PV;
//์์น ๋๊ธฐํ์ค PV
void Awake()
{
PV = GetComponent<PhotonView>();
agent = GetComponent<NavMeshAgent>();
}
void Start()
{
agent.autoBraking = false;
//์์ฐฐ ๊ณ์ํจ
GotoNextPoint();
}
void GotoNextPoint()
{
Transform Patrolpoint = SpawnManager.Instance.GetSpawnpoint();
//์คํฐ ํฌ์ธํธ๋ก ์ผ๋ ์์น๋ค์ ์์ฐฐ ํฌ์ธํธ๋ก ์
agent.destination = Patrolpoint.position;
//๋ค๋น๊ฒ์ด์
๋ค์ ๋ชฉ์ ์ง๋ฅผ ๋๋ค ์์ฐฐํฌ์ธํธ๋ก
}
void Update()
{
if (!agent.pathPending && agent.remainingDistance < 0.5f)
GotoNextPoint();
//๊ทผ์ฒ์๊ฐ๋ฉด ๋ค์ ๋ชฉ์ ์ง๋ก
}
}
- Clone Patrol ์คํฌ๋ฆฝํธ์ ์ ๋ฌธ์ด๋ค.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class SingleShotGun : Gun
//Gun์ผ๋ก๋ถํฐ ์ ๋ณด๋ฐ๊ธฐ
{
[SerializeField] Camera cam;
PhotonView PV;
public GameObject shooter;
void Awake()
{
PV = GetComponent<PhotonView>();
}
public override void Use()
{
Debug.Log("using gun " + itemInfo.itemName);
Shoot();
}
void Shoot()
{
Ray ray = cam.ViewportPointToRay(new Vector3(0.5f, 0.5f));
//์นด๋ฉ๋ผ๋ก๋ถํฐ ๋ ์ด์ ๋ฐ์ฌ
ray.origin = cam.transform.position;
//๋ฐ์ฌ์ง์ ์นด๋ฉ๋ผ๋ก๋ถํฐ
if (Physics.Raycast(ray, out RaycastHit hit))
{
hit.collider.gameObject.GetComponent<IDamageable>()?.TakeDamage(((GunInfo)itemInfo).damage);
//๋ ์ด์ ์ ๋ง์ ๋ฌผ์ฒด๊ฐ ๋ฐ๋ฏธ์ง๋ฅผ ์
์ ์ ์๋ ๋ฌผ์ฒด์ธ๊ฐ? ๋ง๋ค๋ฉด ์์ดํ
์ ๋ณด์ ๋ง๋ ๋ฐ๋ฏธ์ง ๋ฐ๊ธฐ
if (hit.transform.tag == "Player")
{
shooter.GetComponent<PlayerController>()?.TakeDamage(-30);
//์์๊ฐ์ ๋ฐ๋ฏธ์ง๋ฅผ ์
์ผ๋๊น ์ฒด๋ ฅ ํ๋ณต์ด๋ค.
}
if (hit.transform.tag == "Clone")
{
Destroy(hit.transform.gameObject);
}
PV.RPC("RPC_Shoot", RpcTarget.All, hit.point,hit.normal );
//๋ง์ถ๋ฉด ์๋๋ฐฉํํ
๋ง์๋ค๊ณ ์๋ ค์ฃผ๊ธฐ
}
}
[PunRPC]//Pun Remote Procedure Call์ ์ฝ์๋ก์จ ์๊ฒฉ์ ์ด๋ฅผ ํตํด ํจ์๋ฅผ ์คํ์ํค๋ ๊ธฐ๋ฅ์ด๋ค.
void RPC_Shoot(Vector3 hitPosition,Vector3 hitNoraml)
{//hitNormal์ ๋ง๋ ๋ฉด์ด ํฅํ๋ ๋ฐฉํฅ์ด๋ค.
Collider[] colliders = Physics.OverlapSphere(hitPosition, 0.3f);
//0.3f ๋ฐ๊ฒฝ๋ด์ collider๋ค์ ๊ฒ์ถํ๋ค.
if (colliders.Length != 0)//์ฝ๋ผ์ด๋๊ฐ ์กด์ฌํ๋ค๋ฉด
{
GameObject bulletImpactObj=Instantiate(bulletImpactPrefab, hitPosition + hitNoraml * 0.001f, Quaternion.LookRotation(hitNoraml, Vector3.up) * bulletImpactPrefab.transform.rotation);
//hitPosition+hitNormal*0.001f๋ฅผ ํด์ฃผ๋ฉด ์ด์ ์๊ตญ์ด ๋์ํ๋ฉด ๋ณด๋ค ์์ฃผ ์ด์ง ์์์๊ฒ๋์ ๊ฒน์ณ๋ณด์ด์ง ์๋๋ค.
Destroy(bulletImpactObj, 10f);
//์ด์ ์๊ตญ์ 10์ดํ์๋ ์ฌ๋ผ์ง๋ค.
bulletImpactObj.transform.SetParent(colliders[0].transform);
//์ฃผ๋ณ์ ์๋ ์ฝ๋ผ์ด๋๋ฅผ ๋ถ๋ชจ๋ก ์ค์ ํ๋ค.
//๋ถ๋ชจ๊ฐ ์ฌ๋ผ์ง๋ฉด ์์๋ฌผ์ฒด๋ค๋ ๋ค ์ฌ๋ผ์ง๋ฏ๋ก ์ด์์๊ตญ๋ง ๋ฅ๋ฅ๋ ๋ค๋๋๊ฑธ ํด๊ฒฐ ํ ์ ์๋ค.
}
}
}
- Single Shot Gun ์คํฌ๋ฆฝํธ์ ์ ๋ฌธ์ด๋ค.




