mirror of
https://github.com/Kaveinator/NetickProForUnity.git
synced 2025-10-26 09:49:06 -07:00
Fixed an issue with calculating the normal on a box HitShape.
This commit is contained in:
@@ -284,6 +284,11 @@ MonoBehaviour:
|
||||
AutoConnect: 0
|
||||
Port: 36728
|
||||
ServerIPAddress: 127.0.0.1
|
||||
Cap: 1
|
||||
FPS: 450
|
||||
ShowDisconnectButton: 1
|
||||
ShowConnectButton: 1
|
||||
Offset: {x: 36, y: 0}
|
||||
--- !u!1 &2037625649
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -7195,7 +7200,7 @@ MeshFilter:
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 1809360484}
|
||||
- {fileID: 2037625652}
|
||||
- {fileID: 1070948398}
|
||||
- {fileID: 1809360484}
|
||||
- {fileID: 3762179930698311635}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Netick.Samples.Bomberman
|
||||
{
|
||||
public class Block : NetworkBehaviour
|
||||
{
|
||||
// Networked properties
|
||||
// Networked Properties
|
||||
[Networked]
|
||||
public NetworkBool Visible { get; set; } = true;
|
||||
|
||||
|
||||
@@ -7,32 +7,29 @@ namespace Netick.Samples.Bomberman
|
||||
|
||||
public class Bomb : NetworkBehaviour
|
||||
{
|
||||
public GameObject ExplosionPrefab;
|
||||
public GameObject ExplosionPrefab;
|
||||
|
||||
public BombermanController Bomber;
|
||||
public float ExplosionDelay = 3.0f;
|
||||
public BombermanController Bomber;
|
||||
public float ExplosionDelay = 3.0f;
|
||||
|
||||
private readonly Vector3[] _directionsAroundBomb = new Vector3[4] { Vector3.right, Vector3.left, Vector3.up, Vector3.down };
|
||||
private readonly Vector3[] _directionsAroundBomb = new Vector3[4] { Vector3.right, Vector3.left, Vector3.up, Vector3.down };
|
||||
private static RaycastHit[] _hits = new RaycastHit[20];
|
||||
|
||||
public override void NetworkStart()
|
||||
{
|
||||
Bomber?.SpawnedBombs.Add(this);
|
||||
}
|
||||
GetComponent<Renderer>().enabled = true;
|
||||
}
|
||||
|
||||
public override void NetworkDestroy()
|
||||
{
|
||||
Bomber?.SpawnedBombs.Remove(this);
|
||||
|
||||
// spawn explosion
|
||||
// spawn explosion.
|
||||
if (ExplosionPrefab != null)
|
||||
Instantiate(ExplosionPrefab, transform.position, Quaternion.identity);
|
||||
}
|
||||
|
||||
public override void NetworkReset()
|
||||
{
|
||||
GetComponent<Renderer>().enabled = true;
|
||||
}
|
||||
|
||||
public override void NetworkFixedUpdate()
|
||||
{
|
||||
if (Sandbox.TickToTime(Sandbox.Tick - Object.SpawnTick) >= ExplosionDelay)
|
||||
@@ -41,47 +38,35 @@ namespace Netick.Samples.Bomberman
|
||||
|
||||
private void Explode()
|
||||
{
|
||||
// hide bomb after delay
|
||||
// hide bomb after delay.
|
||||
GetComponent<Renderer>().enabled = false;
|
||||
|
||||
// dealing damage is done on the server only
|
||||
// dealing damage is done on the server only.
|
||||
if (IsServer)
|
||||
{
|
||||
DamageTargetsAroundBomb(transform.position);
|
||||
|
||||
// only the server can destroy the bomb or the client but only when the Id of the bomb is -1, meaning it was a spawn-predicted but never was confirmed by the server
|
||||
if (IsServer || Id == -1)
|
||||
Sandbox.Destroy(Object);
|
||||
}
|
||||
|
||||
|
||||
private void DamageTargetsAroundBomb(Vector3 pos)
|
||||
{
|
||||
// Find all objects around the bomb position
|
||||
// Note: Causes GC
|
||||
foreach (var dir in _directionsAroundBomb)
|
||||
{
|
||||
var hits = Physics.RaycastAll(pos, dir, 1f);
|
||||
|
||||
foreach (var hit in hits)
|
||||
Damage(hit.collider.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void Damage(GameObject target)
|
||||
|
||||
private void DamageTargetsAroundBomb(Vector3 pos)
|
||||
{
|
||||
var obj = target.GetComponent<NetworkObject>();
|
||||
var block = target.GetComponent<Block>();
|
||||
var bomber = target.GetComponent<BombermanController>();
|
||||
// find all objects around the bomb position.
|
||||
foreach (var dir in _directionsAroundBomb)
|
||||
{
|
||||
var hitsCount = Sandbox.Physics.Raycast(pos, dir, _hits, 1f);
|
||||
|
||||
// make sure the object is not null and in the same sandbox as the bomb
|
||||
if (obj == null || obj.Sandbox != Sandbox)
|
||||
return;
|
||||
for (int i = 0; i < hitsCount; i++)
|
||||
{
|
||||
var target =_hits[i].collider.gameObject;
|
||||
var block = target.GetComponent<Block>();
|
||||
var bomber = target.GetComponent<BombermanController>();
|
||||
|
||||
if (block != null)
|
||||
block.Visible = false;
|
||||
|
||||
if (bomber != null)
|
||||
bomber.Die();
|
||||
if (block != null)
|
||||
block.Visible = false;
|
||||
bomber?.Die();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace Netick.Samples.Bomberman
|
||||
{
|
||||
public class BombermanController : NetworkBehaviour
|
||||
{
|
||||
public List<Bomb> SpawnedBombs = new List<Bomb>();
|
||||
public List<Bomb> SpawnedBombs = new(4);
|
||||
[HideInInspector]
|
||||
public Vector3 SpawnPos;
|
||||
[SerializeField]
|
||||
@@ -17,11 +17,10 @@ namespace Netick.Samples.Bomberman
|
||||
[SerializeField]
|
||||
private float _speedBoostMultiplayer = 2f;
|
||||
|
||||
|
||||
private GameObject _bombPrefab;
|
||||
private CharacterController _CC;
|
||||
|
||||
// Networked properties
|
||||
// Networked Properties
|
||||
[Networked]
|
||||
public int Score { get; set; } = 0;
|
||||
[Networked]
|
||||
@@ -33,23 +32,19 @@ namespace Netick.Samples.Bomberman
|
||||
public float SpeedPowerUpTimer { get; set; } = 0;
|
||||
[Networked(relevancy: Relevancy.InputSource)]
|
||||
public float BombPowerUpTimer { get; set; } = 0;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
// We store the spawn pos so that we use it later during respawn
|
||||
SpawnPos = transform.position;
|
||||
_CC = GetComponent<CharacterController>();
|
||||
}
|
||||
|
||||
public override void NetworkStart()
|
||||
{
|
||||
_bombPrefab = Sandbox.GetPrefab("Bomb");
|
||||
_bombPrefab = Sandbox.GetPrefab("Bomb");
|
||||
// we store the spawn pos so that we use it later during respawn.
|
||||
SpawnPos = transform.position;
|
||||
_CC = GetComponent<CharacterController>();
|
||||
}
|
||||
|
||||
public override void OnInputSourceLeft()
|
||||
{
|
||||
Sandbox.GetComponent<BombermanEventsHandler>().KillPlayer(this);
|
||||
// destroy the player object when its input source (controller player) leaves the game
|
||||
// destroy the player object when its input source (controller player) leaves the game.
|
||||
Sandbox.Destroy(Object);
|
||||
}
|
||||
|
||||
@@ -60,27 +55,30 @@ namespace Netick.Samples.Bomberman
|
||||
|
||||
if (FetchInput(out BombermanInput input))
|
||||
{
|
||||
// clamp movement inputs.
|
||||
input.Movement = new Vector3(Mathf.Clamp(input.Movement.x, -1f, 1f), Mathf.Clamp(input.Movement.y, -1f, 1f));
|
||||
|
||||
if (BombPowerUpTimer > 0)
|
||||
BombPowerUpTimer -= Sandbox.FixedDeltaTime;
|
||||
BombPowerUpTimer -= Sandbox.FixedDeltaTime;
|
||||
else
|
||||
MaxBombs = 1;
|
||||
MaxBombs = 1;
|
||||
|
||||
if (SpeedPowerUpTimer > 0)
|
||||
SpeedPowerUpTimer -= Sandbox.FixedDeltaTime;
|
||||
|
||||
var hasSpeedBoost = SpeedPowerUpTimer > 0;
|
||||
var speed = hasSpeedBoost ? _speed * _speedBoostMultiplayer : _speed;
|
||||
var hasSpeedBoost = SpeedPowerUpTimer > 0;
|
||||
var speed = hasSpeedBoost ? _speed * _speedBoostMultiplayer : _speed;
|
||||
|
||||
_CC.Move(input.Movement * speed * Sandbox.FixedDeltaTime);
|
||||
|
||||
// we make sure the z coord of the pos of the player is always zero
|
||||
transform.position = new Vector3(transform.position.x, transform.position.y, 0f);
|
||||
// we make sure the z coord of the pos of the player is always zero.
|
||||
transform.position = new Vector3(transform.position.x, transform.position.y, 0f);
|
||||
|
||||
if (IsServer && input.PlantBomb && SpawnedBombs.Count < MaxBombs)
|
||||
{
|
||||
// * round the bomb pos so that it snaps to the nearest square.
|
||||
var bomb = Sandbox.NetworkInstantiate(_bombPrefab, Round(transform.position), Quaternion.identity).GetComponent<Bomb>();
|
||||
bomb.Bomber = this;
|
||||
// round the bomb pos so that it snaps to the nearest square.
|
||||
var bomb = Sandbox.NetworkInstantiate(_bombPrefab, Round(transform.position), Quaternion.identity).GetComponent<Bomb>();
|
||||
bomb.Bomber = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,31 +98,31 @@ namespace Netick.Samples.Bomberman
|
||||
|
||||
public void Die()
|
||||
{
|
||||
Alive = false;
|
||||
Alive = false;
|
||||
Sandbox.GetComponent<BombermanEventsHandler>().KillPlayer(this);
|
||||
}
|
||||
|
||||
public void Respawn()
|
||||
{
|
||||
Alive = true;
|
||||
Sandbox.GetComponent<BombermanEventsHandler>().RespawnPlayer(this);
|
||||
|
||||
transform.position = SpawnPos;
|
||||
|
||||
|
||||
Alive = true;
|
||||
SpeedPowerUpTimer = 0;
|
||||
BombPowerUpTimer = 0;
|
||||
MaxBombs = 1;
|
||||
|
||||
transform.position = SpawnPos;
|
||||
}
|
||||
|
||||
[OnChanged(nameof(Alive))]
|
||||
private void OnAliveChanged(OnChangedData onChangedData)
|
||||
{
|
||||
// Based on state of Alive:
|
||||
// based on state of Alive:
|
||||
|
||||
// * Hide/show player object
|
||||
// * hide/show player object.
|
||||
GetComponentInChildren<Renderer>().SetEnabled(Sandbox,Alive);
|
||||
|
||||
// * Enable/disable the CharacterController
|
||||
// * enable/disable the CharacterController.
|
||||
_CC.enabled = Alive;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,99 +5,73 @@ using Netick.Unity;
|
||||
|
||||
namespace Netick.Samples.Bomberman
|
||||
{
|
||||
public class BombermanEventsHandler : NetworkEventsListener
|
||||
public class BombermanEventsHandler : NetworkBehaviour
|
||||
{
|
||||
public List<BombermanController> Players = new(4);
|
||||
public List<BombermanController> AlivePlayers = new(4);
|
||||
|
||||
public List<BombermanController> AlivePlayers = new List<BombermanController>();
|
||||
public Vector3[] SpawnPositions = new Vector3[4]
|
||||
{
|
||||
new Vector3(11, 9, 0),
|
||||
new Vector3(11, 1, 0),
|
||||
new Vector3(1, 9, 0),
|
||||
new Vector3(1, 1, 0)
|
||||
};
|
||||
|
||||
private GameObject _playerPrefab;
|
||||
private Queue<Vector3> _freePositions = new Queue<Vector3>(4);
|
||||
|
||||
// ******************* Netick Callbacks *******************
|
||||
|
||||
// This is called on the server and the clients when Netick has started.
|
||||
public override void OnStartup(NetworkSandbox sandbox)
|
||||
private GameObject _playerPrefab;
|
||||
private Vector3[] _spawnPositions = new Vector3[4] { new Vector3(11, 9, 0), new Vector3(11, 1, 0), new Vector3(1, 9, 0), new Vector3(1, 1, 0) };
|
||||
private Queue<Vector3> _freePositions = new(4);
|
||||
|
||||
public override void NetworkStart()
|
||||
{
|
||||
_playerPrefab = sandbox.GetPrefab("Bomberman Player");
|
||||
sandbox.InitializePool(sandbox.GetPrefab("Bomb"), 5);
|
||||
Sandbox.Events.OnInputRead += OnInput;
|
||||
Sandbox.Events.OnConnectRequest += OnConnectRequest;
|
||||
Sandbox.Events.OnPlayerConnected += OnPlayerConnected;
|
||||
Sandbox.Events.OnPlayerDisconnected += OnPlayerDisconnected;
|
||||
|
||||
_playerPrefab = Sandbox.GetPrefab("Bomberman Player");
|
||||
Sandbox.InitializePool(Sandbox.GetPrefab("Bomb"), 5);
|
||||
Sandbox.InitializePool(_playerPrefab,4);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
_freePositions.Enqueue(_spawnPositions[i]);
|
||||
|
||||
if (IsServer)
|
||||
RestartGame();
|
||||
}
|
||||
|
||||
public void OnConnectRequest(NetworkSandbox sandbox, NetworkConnectionRequest request)
|
||||
{
|
||||
if (Sandbox.ConnectedPlayers.Count >= 4)
|
||||
request.Refuse();
|
||||
}
|
||||
|
||||
// This is called on the server when a playerObj has connected.
|
||||
public void OnPlayerConnected(NetworkSandbox sandbox, NetworkPlayer player)
|
||||
{
|
||||
var playerObj = sandbox.NetworkInstantiate(_playerPrefab, _spawnPositions[Sandbox.ConnectedPlayers.Count], Quaternion.identity, player).GetComponent<BombermanController>();
|
||||
player.PlayerObject = playerObj.gameObject;
|
||||
AlivePlayers. Add(playerObj);
|
||||
Players. Add(playerObj);
|
||||
}
|
||||
|
||||
// This is called on the server when a client has disconnected.
|
||||
public void OnPlayerDisconnected(NetworkSandbox sandbox, Netick.NetworkPlayer player, TransportDisconnectReason reason)
|
||||
{
|
||||
_freePositions.Enqueue(((GameObject)player.PlayerObject).GetComponent<BombermanController>().SpawnPos);
|
||||
Players. Remove (((GameObject)player.PlayerObject).GetComponent<BombermanController>());
|
||||
}
|
||||
|
||||
// This is called to read inputs.
|
||||
public override void OnInput(NetworkSandbox sandbox)
|
||||
public void OnInput(NetworkSandbox sandbox)
|
||||
{
|
||||
var input = sandbox.GetInput<BombermanInput>();
|
||||
|
||||
var input = sandbox.GetInput<BombermanInput>();
|
||||
input.Movement = GetMovementDir();
|
||||
input.PlantBomb |= Input.GetKeyDown(KeyCode.Space);
|
||||
sandbox.SetInput(input);
|
||||
}
|
||||
|
||||
// This is called on the server when a player has connected.
|
||||
public override void OnPlayerConnected(NetworkSandbox sandbox, NetworkPlayer networkPlayer)
|
||||
{
|
||||
var player = sandbox.NetworkInstantiate(_playerPrefab, SpawnPositions[Sandbox.ConnectedPlayers.Count], Quaternion.identity, networkPlayer).GetComponent<BombermanController>();
|
||||
networkPlayer.PlayerObject = player.gameObject;
|
||||
AlivePlayers.Add(player);
|
||||
}
|
||||
|
||||
// This is called on the server when a client has disconnected.
|
||||
public override void OnClientDisconnected(NetworkSandbox sandbox, NetworkConnection client, TransportDisconnectReason reason)
|
||||
{
|
||||
_freePositions.Enqueue(((GameObject)client.PlayerObject).GetComponent<BombermanController>().SpawnPos);
|
||||
}
|
||||
|
||||
public override void OnConnectRequest(NetworkSandbox sandbox, NetworkConnectionRequest request)
|
||||
{
|
||||
if (_freePositions.Count < 1)
|
||||
request.Refuse();
|
||||
}
|
||||
|
||||
// This is called on the server and the clients when the scene has been loaded.
|
||||
public override void OnSceneLoaded(NetworkSandbox sandbox)
|
||||
{
|
||||
if (sandbox.IsClient)
|
||||
return;
|
||||
|
||||
_freePositions.Clear();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
_freePositions.Enqueue(SpawnPositions[i]);
|
||||
|
||||
RestartGame();
|
||||
}
|
||||
|
||||
// ******************* ********************
|
||||
|
||||
public void RestartGame()
|
||||
{
|
||||
DestroyLevel();
|
||||
CreateNewLevel();
|
||||
|
||||
foreach (var player in Sandbox.ConnectedPlayers)
|
||||
((GameObject)player.PlayerObject).GetComponent<BombermanController>().Respawn();
|
||||
}
|
||||
|
||||
private void DestroyLevel()
|
||||
{
|
||||
var blocks = Sandbox.FindObjectsOfType<Block>();
|
||||
var bombs = Sandbox.FindObjectsOfType<Bomb>();
|
||||
|
||||
foreach (var block in blocks)
|
||||
// destroy level.
|
||||
foreach (var block in Sandbox.FindObjectsOfType<Block>())
|
||||
Sandbox.Destroy(block.Object);
|
||||
foreach (var bomb in bombs)
|
||||
foreach (var bomb in Sandbox.FindObjectsOfType<Bomb>())
|
||||
Sandbox.Destroy(bomb.Object);
|
||||
}
|
||||
|
||||
|
||||
private void CreateNewLevel()
|
||||
{
|
||||
// create new level.
|
||||
var blockPrefab = Sandbox.GetPrefab("DestroyableBlock");
|
||||
var powerUpPrefab = Sandbox.GetPrefab("Power Up");
|
||||
var numberOfBoosters = Random.Range(2, 4+1);
|
||||
@@ -109,8 +83,8 @@ namespace Netick.Samples.Bomberman
|
||||
{
|
||||
for (int y = 1; y <= maxY; y++)
|
||||
{
|
||||
var spawn = Random.value > 0.5f;
|
||||
var pos = new Vector3(x, y);
|
||||
var spawn = Random.value > 0.5f;
|
||||
var pos = new Vector3(x, y);
|
||||
|
||||
if (spawn && IsValidPos(pos))
|
||||
{
|
||||
@@ -122,8 +96,8 @@ namespace Netick.Samples.Bomberman
|
||||
|
||||
while (numberOfBoosters > 0)
|
||||
{
|
||||
var randomPos = new Vector3(Random.Range(1, 11+1), Random.Range(1, 9+1), 0);
|
||||
var type = (Random.value > 0.5f) ? PowerUpType.Speed : PowerUpType.IncreaseBombs;
|
||||
var randomPos = new Vector3(Random.Range(1, 11+1), Random.Range(1, 9+1), 0);
|
||||
var type = (Random.value > 0.5f) ? PowerUpType.Speed : PowerUpType.IncreaseBombs;
|
||||
|
||||
if (!takenPositions.Contains(randomPos) && IsValidPos(randomPos))
|
||||
{
|
||||
@@ -132,24 +106,25 @@ namespace Netick.Samples.Bomberman
|
||||
numberOfBoosters--;
|
||||
}
|
||||
}
|
||||
|
||||
// reset players.
|
||||
foreach (var player in Players)
|
||||
player.Respawn();
|
||||
}
|
||||
|
||||
private bool IsValidPos(Vector3 pos)
|
||||
{
|
||||
// if the pos is the position of a static block, we ignore it
|
||||
// if the pos is the position of a static block, we ignore it.
|
||||
if ((pos.x >= 2 && pos.x <= 10) && (pos.y >= 2 && pos.y <= 8))
|
||||
if (pos.x % 2 == 0 && pos.y % 2 == 0)
|
||||
return false;
|
||||
|
||||
// if the pos is near the position of the spawn locations of the players, we ignore it
|
||||
foreach (var loc in SpawnPositions)
|
||||
// if the pos is near the position of the spawn locations of the players, we ignore it.
|
||||
foreach (var loc in _spawnPositions)
|
||||
{
|
||||
if (pos == loc)
|
||||
return false;
|
||||
if (pos == loc + Vector3.up || pos == loc + Vector3.down)
|
||||
return false;
|
||||
if (pos == loc + Vector3.left || pos == loc + Vector3.right)
|
||||
return false;
|
||||
if (pos == loc) return false;
|
||||
if (pos == loc + Vector3.up || pos == loc + Vector3.down) return false;
|
||||
if (pos == loc + Vector3.left || pos == loc + Vector3.right) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -168,24 +143,19 @@ namespace Netick.Samples.Bomberman
|
||||
else if (AlivePlayers.Count < 1)
|
||||
RestartGame();
|
||||
}
|
||||
|
||||
public void RespawnPlayer(BombermanController bomber)
|
||||
{
|
||||
if (!AlivePlayers.Contains(bomber))
|
||||
AlivePlayers.Add(bomber);
|
||||
}
|
||||
|
||||
private Vector2 GetMovementDir()
|
||||
{
|
||||
if (Input.GetKey(KeyCode.W))
|
||||
return Vector2.up;
|
||||
else if (Input.GetKey(KeyCode.D))
|
||||
return Vector2.right;
|
||||
else if (Input.GetKey(KeyCode.S))
|
||||
return Vector2.down;
|
||||
else if (Input.GetKey(KeyCode.A))
|
||||
return Vector2.left;
|
||||
else
|
||||
return Vector2.zero;
|
||||
if (Input.GetKey(KeyCode.W)) return Vector2.up;
|
||||
else if (Input.GetKey(KeyCode.D)) return Vector2.right;
|
||||
else if (Input.GetKey(KeyCode.S)) return Vector2.down;
|
||||
else if (Input.GetKey(KeyCode.A)) return Vector2.left;
|
||||
else return Vector2.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,11 @@ using Netick.Unity;
|
||||
|
||||
namespace Netick.Samples.Bomberman
|
||||
{
|
||||
[Networked]
|
||||
public struct BombermanInput : INetworkInput
|
||||
{
|
||||
public Vector2 Movement;
|
||||
[Networked]
|
||||
public Vector2 Movement { get; set; }
|
||||
public NetworkBool PlantBomb;
|
||||
}
|
||||
}
|
||||
@@ -15,26 +15,19 @@ namespace Netick.Samples.Bomberman
|
||||
public float PowerUpTime = 35;
|
||||
private Material _mat;
|
||||
|
||||
// Networked properties
|
||||
// Networked Properties
|
||||
[Networked]
|
||||
public PowerUpType Type { get; set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_mat = GetComponentInChildren<Renderer>().material;
|
||||
_mat = GetComponentInChildren<Renderer>().material;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
public override void NetworkRender()
|
||||
{
|
||||
if (Type == PowerUpType.IncreaseBombs)
|
||||
_mat.color = GetColor(Color.green);
|
||||
else
|
||||
_mat.color = GetColor(Color.blue);
|
||||
}
|
||||
|
||||
private Color GetColor(Color color)
|
||||
{
|
||||
return Color.Lerp(color, color * 0.5f, Mathf.InverseLerp(-1f, 1f, Mathf.Sin(15f * Time.time)));
|
||||
var color = Type == PowerUpType.IncreaseBombs ? Color.green : Color.blue;
|
||||
_mat.color = Color.Lerp(color, color * 0.5f, Mathf.InverseLerp(-1f, 1f, Mathf.Sin(15f * Time.time)));
|
||||
}
|
||||
|
||||
public void OnTriggerEnter(Collider other)
|
||||
@@ -44,7 +37,7 @@ namespace Netick.Samples.Bomberman
|
||||
|
||||
var player = other.gameObject.GetComponent<BombermanController>();
|
||||
|
||||
if (Sandbox.IsServer)
|
||||
if (Sandbox.IsServer && player != null)
|
||||
{
|
||||
player.ReceivePowerUp(Type, PowerUpTime);
|
||||
Sandbox.Destroy(Object);
|
||||
|
||||
@@ -158,8 +158,8 @@ GameObject:
|
||||
- component: {fileID: 7011933354638177220}
|
||||
- component: {fileID: 5100633453439203130}
|
||||
- component: {fileID: 3197551385548652812}
|
||||
- component: {fileID: 6851739389618402669}
|
||||
- component: {fileID: 1417749684482701243}
|
||||
- component: {fileID: 6918953610149222310}
|
||||
m_Layer: 0
|
||||
m_Name: FPS Player
|
||||
m_TagString: Untagged
|
||||
@@ -223,25 +223,13 @@ MonoBehaviour:
|
||||
TeleportDistance: 50
|
||||
PositionPrecision: 3
|
||||
Settings: 5
|
||||
TransformSpace: 0
|
||||
TransformSpace: 1
|
||||
EnablePredictionErrorCorrectionSmoothing: 0
|
||||
InterpolationMultiplier: 20
|
||||
CorrectionMultiplier: 3
|
||||
CorrectionMaxBlendAlpha: 0.7
|
||||
TeleportErrorThreshold: 50
|
||||
_interpolationSource: 0
|
||||
--- !u!114 &6851739389618402669
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7011933354638177272}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 754e582306c60a24eb1619b9878f55fd, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_movementSpeed: 10
|
||||
_sensitivityX: 1.6
|
||||
_sensitivityY: -1
|
||||
_cameraParent: {fileID: 3369032719007731524}
|
||||
<YawPitch>k__BackingField: {x: 0, y: 0}
|
||||
--- !u!143 &1417749684482701243
|
||||
CharacterController:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -268,3 +256,21 @@ CharacterController:
|
||||
m_SkinWidth: 0.08
|
||||
m_MinMoveDistance: 0.001
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &6918953610149222310
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7011933354638177272}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 754e582306c60a24eb1619b9878f55fd, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_renderTransform: {fileID: 4519677825914407182}
|
||||
_movementSpeed: 10
|
||||
_sensitivityX: 1.6
|
||||
_sensitivityY: -1
|
||||
_cameraParent: {fileID: 3369032719007731524}
|
||||
<YawPitch>k__BackingField: {x: 0, y: 0}
|
||||
|
||||
@@ -453,6 +453,11 @@ MonoBehaviour:
|
||||
AutoConnect: 0
|
||||
Port: 36339
|
||||
ServerIPAddress: 127.0.0.1
|
||||
Cap: 1
|
||||
FPS: 450
|
||||
ShowDisconnectButton: 1
|
||||
ShowConnectButton: 1
|
||||
Offset: {x: 36, y: 0}
|
||||
--- !u!4 &1293352709
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -480,6 +485,15 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: d6475ef2cc420914e87d5433265300cf, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
Offset: {x: 27, y: 20}
|
||||
MediumLatencyThreshold: 150
|
||||
HighLatencyThreshold: 250
|
||||
MediumPacketLossThreshold: 1
|
||||
HighPacketLossThreshold: 10
|
||||
PacketLossIconOffset: {x: -80, y: 30}
|
||||
LatencyIconOffset: {x: -80, y: 70}
|
||||
ServerLagIconOffset: {x: -80, y: 110}
|
||||
IconSize: 30
|
||||
--- !u!114 &1293352711
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -790,9 +804,9 @@ Transform:
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 1293352709}
|
||||
- {fileID: 1318413501}
|
||||
- {fileID: 2022675087}
|
||||
- {fileID: 1318413501}
|
||||
- {fileID: 1293352709}
|
||||
- {fileID: 476934809}
|
||||
- {fileID: 10129275}
|
||||
- {fileID: 1929588644}
|
||||
|
||||
@@ -6,6 +6,9 @@ namespace Netick.Samples.FPS
|
||||
{
|
||||
public class FPSController : NetworkBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private Transform _renderTransform;
|
||||
|
||||
[SerializeField]
|
||||
private float _movementSpeed = 10;
|
||||
[SerializeField]
|
||||
@@ -17,7 +20,7 @@ namespace Netick.Samples.FPS
|
||||
private CharacterController _CC;
|
||||
private Vector2 _camAngles;
|
||||
|
||||
// Networked properties
|
||||
// Networked Properties
|
||||
[Networked][Smooth]
|
||||
public Vector2 YawPitch { get; set; }
|
||||
|
||||
@@ -36,7 +39,7 @@ namespace Netick.Samples.FPS
|
||||
|
||||
public override void OnInputSourceLeft()
|
||||
{
|
||||
// destroy the player object when its input source (controller player) leaves the game
|
||||
// destroy the player object when its input source (controller player) leaves the game.
|
||||
Sandbox.Destroy(Object);
|
||||
}
|
||||
|
||||
@@ -45,15 +48,17 @@ namespace Netick.Samples.FPS
|
||||
if (!IsInputSource || !Sandbox.InputEnabled)
|
||||
return;
|
||||
|
||||
Vector2 input = new Vector2(Input.GetAxisRaw("Mouse X") * _sensitivityX, Input.GetAxisRaw("Mouse Y") * _sensitivityY);
|
||||
Vector2 mouseInputs = new Vector2(Input.GetAxisRaw("Mouse X") * _sensitivityX, Input.GetAxisRaw("Mouse Y") * _sensitivityY);
|
||||
|
||||
var networkInput = Sandbox.GetInput<FPSInput>();
|
||||
networkInput.YawPitch += input;
|
||||
Sandbox.SetInput<FPSInput>(networkInput);
|
||||
var networkInput = Sandbox.GetInput<FPSInput>();
|
||||
networkInput.Movement = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
|
||||
networkInput.ShootInput |= Input.GetMouseButton(0);
|
||||
networkInput.YawPitch += mouseInputs;
|
||||
Sandbox.SetInput(networkInput);
|
||||
|
||||
// we apply the rotation in update too to have smooth camera control
|
||||
_camAngles = ClampAngles(_camAngles.x + input.x, _camAngles.y + input.y);
|
||||
ApplyRotations(_camAngles);
|
||||
// we apply the rotation in update too to have smooth camera control.
|
||||
_camAngles = ClampAngles(_camAngles.x + mouseInputs.x, _camAngles.y + mouseInputs.y);
|
||||
ApplyRotations(_camAngles, false);
|
||||
}
|
||||
|
||||
public override void NetworkFixedUpdate()
|
||||
@@ -64,17 +69,20 @@ namespace Netick.Samples.FPS
|
||||
|
||||
private void MoveAndRotate(FPSInput input)
|
||||
{
|
||||
// rotation
|
||||
YawPitch = ClampAngles(YawPitch.x + input.YawPitch.x, YawPitch.y + input.YawPitch.y);
|
||||
ApplyRotations(YawPitch);
|
||||
// clamp movement inputs.
|
||||
input.Movement = new Vector3(Mathf.Clamp(input.Movement.x, -1f, 1f), Mathf.Clamp(input.Movement.y, -1f, 1f));
|
||||
|
||||
// movement direction
|
||||
var movement = transform.TransformVector(new Vector3(input.Movement.x, 0, input.Movement.y)) * _movementSpeed;
|
||||
movement.y = 0;
|
||||
// rotation.
|
||||
YawPitch = ClampAngles(YawPitch.x + input.YawPitch.x, YawPitch.y + input.YawPitch.y);
|
||||
ApplyRotations(YawPitch,false);
|
||||
|
||||
var gravity = 15f * Vector3.down;
|
||||
// movement direction.
|
||||
var movement = transform.TransformVector(new Vector3(input.Movement.x, 0, input.Movement.y)) * _movementSpeed;
|
||||
movement.y = 0;
|
||||
|
||||
// move
|
||||
var gravity = 15f * Vector3.down;
|
||||
|
||||
// move.
|
||||
_CC.Move((movement + gravity) * Sandbox.FixedDeltaTime);
|
||||
}
|
||||
|
||||
@@ -82,26 +90,28 @@ namespace Netick.Samples.FPS
|
||||
[OnChanged(nameof(YawPitch), invokeDuringResimulation: true)]
|
||||
private void OnYawPitchChanged(OnChangedData onChanged)
|
||||
{
|
||||
ApplyRotations(YawPitch);
|
||||
ApplyRotations(YawPitch, false);
|
||||
}
|
||||
|
||||
public override void NetworkRender()
|
||||
{
|
||||
if (IsProxy)
|
||||
ApplyRotations(YawPitch);
|
||||
ApplyRotations(YawPitch, true);
|
||||
}
|
||||
|
||||
private void ApplyRotations(Vector2 camAngles)
|
||||
private void ApplyRotations(Vector2 camAngles, bool isProxy)
|
||||
{
|
||||
// on the player transform, we apply yaw
|
||||
transform.rotation = Quaternion.Euler(new Vector3(0, camAngles.x, 0));
|
||||
// on the player transform, we apply yaw.
|
||||
if (isProxy)
|
||||
_renderTransform.rotation = Quaternion.Euler(new Vector3(0, camAngles.x, 0));
|
||||
else
|
||||
transform.rotation = Quaternion.Euler(new Vector3(0, camAngles.x, 0));
|
||||
|
||||
// on the weapon/camera holder, we apply the pitch angle
|
||||
// on the weapon/camera holder, we apply the pitch angle.
|
||||
_cameraParent.localEulerAngles = new Vector3(camAngles.y, 0, 0);
|
||||
_camAngles = camAngles;
|
||||
}
|
||||
|
||||
|
||||
private Vector2 ClampAngles(float yaw, float pitch)
|
||||
{
|
||||
return new Vector2(ClampAngle(yaw, -360, 360), ClampAngle(pitch, -80, 80));
|
||||
|
||||
@@ -9,16 +9,6 @@ namespace Netick.Samples.FPS
|
||||
public Transform SpawnPos;
|
||||
public GameObject PlayerPrefab;
|
||||
|
||||
// This is called to read inputs.
|
||||
public override void OnInput(NetworkSandbox sandbox)
|
||||
{
|
||||
var input = sandbox.GetInput<FPSInput>();
|
||||
|
||||
input.Movement = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
|
||||
input.ShootInput |= Input.GetMouseButton(0);
|
||||
sandbox.SetInput<FPSInput>(input);
|
||||
}
|
||||
|
||||
// This is called on the server when a player has connected.
|
||||
public override void OnPlayerConnected(NetworkSandbox sandbox, NetworkPlayer networkPlayer)
|
||||
{
|
||||
|
||||
@@ -3,10 +3,13 @@ using Netick;
|
||||
|
||||
namespace Netick.Samples.FPS
|
||||
{
|
||||
[Networked]
|
||||
public struct FPSInput : INetworkInput
|
||||
{
|
||||
public Vector2 YawPitch;
|
||||
public Vector2 Movement;
|
||||
[Networked]
|
||||
public Vector2 YawPitch { get; set; }
|
||||
[Networked]
|
||||
public Vector2 Movement { get; set; }
|
||||
public NetworkBool ShootInput;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user