일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- map design
- 언리얼 엔진
- stride
- photon fusion2
- ability task
- listen server
- 운영체제
- Unreal Engine
- unity
- Delegate
- 메카님
- Rr
- MAC
- gas
- Multiplay
- dirty cow
- 유니티
- DP
- 유스케이스
- animation
- 게임 개발
- MLFQ
- Race condition
- Security
- CTF
- Replication
- 언리얼엔진
- 게임개발
- DSP
- ret2libc
Archives
- Today
- Total
다양한 기록
[Fortress Craft] Unit AutoSpawning In Network 본문
using Fusion;
using UnityEngine;
namespace Agit.FortressCraft
{
public class NormalUnitGenerator : NetworkBehaviour
{
private TickTimer spawnTimer { get; set; }
public float SpawnTime { get; set; }
NormalUnitSpawner spawner;
public override void Spawned()
{
spawner = GetComponent<NormalUnitSpawner>();
SpawnTime = NormalUnitDataManager.Instance.SpawnTime;
if (spawner.Usable) SetWaitingTime();
}
public override void FixedUpdateNetwork()
{
//Debug.Log("Generating");
//Debug.Log( Id );
if (spawnTimer.Expired(Runner))
{
//Debug.Log(Id);
SetWaitingTime();
spawner.SpawnUnit();
}
}
private void SetWaitingTime()
{
spawnTimer = TickTimer.CreateFromSeconds(Runner, SpawnTime);
}
}
}
제네레이터가 스포너를 가지고, FixedUpdateNetwork에서 타이머 Expire 되면 스폰 시킴
using Fusion;
using FusionHelpers;
using UnityEngine;
namespace Agit.FortressCraft
{
public class NormalUnitSpawner : NetworkBehaviour
{
public NetworkObject UnitPrefab_A;
public NetworkObject UnitPrefab_B;
public NetworkObject UnitPrefab_C;
public NetworkObject UnitPrefab_D;
private NetworkObject UnitPrefab;
public NetworkObject UnitPrefab_A_Team;
public NetworkObject UnitPrefab_B_Team;
public NetworkObject Arrow;
public Player player = null;
public bool Usable { get; private set; }
public NetworkObjectPoolManager poolManager;
public Transform Center { get; set; }
[SerializeField] public string SpawnerType { get; set; }
[SerializeField] private int maxUnitCount = 5;
public int NowUnitCount { get; set; }
// RPC property
public string Target { get; set; }
public bool AttackEnabled { get; set; }
public float Damage { get; set; }
public float Defense { get; set; }
public NetworkPrefabId id;
public NetworkPrefabId arrowId;
private int idx = -1;
public Mode mode;
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
public void RPCTargetChange(string t)
{
Debug.Log("target: " + t);
Target = t;
}
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
public void RPCChangeAttackEnabled()
{
AttackEnabled = !AttackEnabled;
}
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
public void RPCSettingDamage(float newDamage)
{
Damage = newDamage;
Debug.Log("Damage: " + newDamage);
}
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
public void RPCSettingDefense(float newDefense)
{
Defense = newDefense;
Debug.Log("Defense: " + Damage);
}
public override void Spawned()
{
Usable = false;
if (!HasStateAuthority) return;
poolManager = NetworkObjectPoolManager.Instance;
//AttackEnabled = true;
Damage = NormalUnitDataManager.Instance.Attack;
Defense = NormalUnitDataManager.Instance.Defense;
NowUnitCount = 0;
Center = GameObject.Find("Center").transform;
ChangeTarget changeTarget = GameObject.FindObjectOfType<ChangeTarget>();
if (Runner.TryGetSingleton<GameManager>(out GameManager gameManager))
{
idx = gameManager.TryGetPlayerId(Runner.LocalPlayer);
if (gameManager.mode == Mode.Survival)
{
Debug.Log("idx: " + idx);
switch (idx)
{
case 0:
SpawnerType = "A";
UnitPrefab = UnitPrefab_A;
break;
case 1:
SpawnerType = "B";
UnitPrefab = UnitPrefab_B;
break;
case 2:
SpawnerType = "C";
UnitPrefab = UnitPrefab_C;
break;
case 3:
SpawnerType = "D";
UnitPrefab = UnitPrefab_D;
break;
}
}
else
{
string team = gameManager.TryGetPlayerTeam(Runner.LocalPlayer);
if (team == "A")
{
SpawnerType = "A";
UnitPrefab = UnitPrefab_A;
}
else
{
SpawnerType = "B";
UnitPrefab = UnitPrefab_B;
}
}
if (changeTarget.OwnType == "")
{
changeTarget.OwnType = SpawnerType;
string targetBtnName = "";
switch (SpawnerType)
{
case "A":
targetBtnName = "Button_1";
break;
case "B":
targetBtnName = "Button_2";
break;
case "C":
targetBtnName = "Button_3";
break;
case "D":
targetBtnName = "Button_4";
break;
}
changeTarget.UpdateTargetButtonColor(targetBtnName);
}
if (idx > -1)
{
Usable = true;
if (changeTarget.Target == null)
{
switch (idx)
{
case 0:
Target = "A";
break;
case 1:
Target = "B";
break;
case 2:
Target = "C";
break;
case 3:
Target = "D";
break;
}
changeTarget.Target = Target;
}
else
{
Target = changeTarget.Target;
}
}
}
AttackEnabled = changeTarget.IsAttackOn;
NetworkObject temp = Runner.Spawn(UnitPrefab, (Vector2)transform.position, Quaternion.identity);
id = temp.NetworkTypeId.AsPrefabId;
Destroy(temp.gameObject);
poolManager.AddPoolTable(id);
temp = null;
temp = Runner.Spawn(Arrow, (Vector2)transform.position, Quaternion.identity);
arrowId = temp.NetworkTypeId.AsPrefabId;
Destroy(temp.gameObject);
poolManager.AddPoolTable(arrowId);
}
public void SpawnUnit()
{
if (NowUnitCount >= maxUnitCount) return;
SpawnUnitNoLimit();
}
public void SpawnUnitNoLimit()
{
if (Object.HasStateAuthority)
{
NetworkObject unitObj = null;
NetworkPrefabAcquireContext context = new NetworkPrefabAcquireContext(id);
var result = poolManager.AcquirePrefabInstance(Runner, context, out unitObj);
if (result == NetworkObjectAcquireResult.Success)
{
unitObj.transform.position = transform.position;
NormalUnitRigidBodyMovement unit = unitObj.GetComponent<NormalUnitRigidBodyMovement>();
NetworkMecanimAnimator animator = unitObj.GetComponent<NetworkMecanimAnimator>();
unit.TargetString = Target;
unit.AttackEnabled = AttackEnabled;
unit.Damage = Damage;
unit.Defense = Defense;
unit.Spawner = this;
unit.OwnType = SpawnerType;
unit.HP = GoogleSheetManager.GetUnitData(1).HP;
RPCUnitSetting(unit);
animator.Animator.Play("IdleState");
unit.Initializing();
float range = 0.4f;
Vector3 offset = new Vector3(Random.Range(-range, range),
Random.Range(-range, range),
0.0f);
RPCSetPos(unit, transform.position + offset);
//unit.RPCSetActive();
RPCSetActive(unit);
++NowUnitCount;
BattleBarUIManager.Instance.RPCPlusUnitCount(SpawnerType);
}
else
{
Debug.LogError("Pooling Failed");
}
}
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPCUnitSetting(NormalUnitRigidBodyMovement normal)
{
normal.NoReward = false;
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPCSetActive(NormalUnitRigidBodyMovement normal)
{
normal.gameObject.SetActive(true);
}
[Rpc(RpcSources.All, RpcTargets.All)]
public void RPCSetPos(NormalUnitRigidBodyMovement normal, Vector3 pos)
{
normal.transform.position = pos;
}
}
}
현재 플레이어가 몇 번째 플레이어인지 알아내서 스폰하는 유닛을 변경시킴
네트워크 상에서 작동하는 것이기도 하고, Photon이라는 외부 플러그인을 쓰는 것이다 보니
플레이어 ID를 통한 기타 설정들의 타이밍이 꼬여서 코드가 복잡함
소환 위치가 일정하면 재미없으니 난수 처리 조금 하고, 하나의 스포너에서 소환될 수 있는 유닛 수 제한을 뒀음
이런식으로 스폰이 됨
'유니티 엔진 > Fortress Craft' 카테고리의 다른 글
[Fortress Craft] Target Setting / Attack Enabled (0) | 2025.02.05 |
---|---|
[Fortess Craft] Path Finding (0) | 2025.02.05 |
[Fortress Craft] Damage System (0) | 2025.02.05 |
[Fortress Craft] Animation - Damaged (Flash White) (0) | 2025.02.05 |
[Fortress Craft] 개요 (0) | 2024.10.12 |