Compare commits
8 Commits
c8d8b6b802
...
keyinsertm
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ae5d28cc9 | |||
| e55aa6b258 | |||
| 2f86bab336 | |||
| 8948cbdb14 | |||
| f9ceea4992 | |||
| 666f731b6d | |||
| 3879c0879d | |||
| 9defaa314a |
@@ -1,285 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace GeoSus.Client
|
|
||||||
{
|
|
||||||
// Klientská strana šifrování - generuje session key, šifruje RSA, AES-CBC session
|
|
||||||
// Používá AES-CBC místo AES-GCM pro kompatibilitu s Unity
|
|
||||||
public class ClientEncryption : IDisposable
|
|
||||||
{
|
|
||||||
private byte[] _sessionKey;
|
|
||||||
private byte[] _sessionIv;
|
|
||||||
private long _nonceCounter;
|
|
||||||
private readonly object _lock = new object();
|
|
||||||
|
|
||||||
// Kontrola, zda je session key nastaven
|
|
||||||
public bool HasSessionKey => _sessionKey != null && _sessionIv != null;
|
|
||||||
|
|
||||||
// Generuje nový session key a IV
|
|
||||||
public void GenerateSessionKey()
|
|
||||||
{
|
|
||||||
_sessionKey = new byte[32]; // AES-256
|
|
||||||
_sessionIv = new byte[16]; // CBC IV (16 bytes)
|
|
||||||
|
|
||||||
using (var rng = RandomNumberGenerator.Create())
|
|
||||||
{
|
|
||||||
rng.GetBytes(_sessionKey);
|
|
||||||
rng.GetBytes(_sessionIv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] SessionKey => _sessionKey ?? throw new InvalidOperationException("Session key not generated");
|
|
||||||
public byte[] SessionIV => _sessionIv ?? throw new InvalidOperationException("Session IV not generated");
|
|
||||||
|
|
||||||
// Zašifruje session key pomocí RSA public key serveru
|
|
||||||
public (string EncryptedKey, string EncryptedIV) EncryptSessionKeyForServer(string rsaPublicKeyPem)
|
|
||||||
{
|
|
||||||
if (_sessionKey == null || _sessionIv == null)
|
|
||||||
throw new InvalidOperationException("Session key not generated");
|
|
||||||
|
|
||||||
using (var rsa = RSA.Create())
|
|
||||||
{
|
|
||||||
// Parse PEM - extrahuj Base64 obsah
|
|
||||||
var pemLines = rsaPublicKeyPem.Split('\n');
|
|
||||||
var base64 = new StringBuilder();
|
|
||||||
foreach (var line in pemLines)
|
|
||||||
{
|
|
||||||
var trimmed = line.Trim();
|
|
||||||
if (!trimmed.StartsWith("-----") && !string.IsNullOrEmpty(trimmed))
|
|
||||||
{
|
|
||||||
base64.Append(trimmed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var keyBytes = Convert.FromBase64String(base64.ToString());
|
|
||||||
|
|
||||||
// Unity kompatibilní import - parsujeme SubjectPublicKeyInfo ručně
|
|
||||||
ImportSubjectPublicKeyInfoManual(rsa, keyBytes);
|
|
||||||
|
|
||||||
// Používáme OaepSHA1 pro Unity kompatibilitu (OaepSHA256 není podporován)
|
|
||||||
var encryptedKey = rsa.Encrypt(_sessionKey, RSAEncryptionPadding.OaepSHA1);
|
|
||||||
var encryptedIv = rsa.Encrypt(_sessionIv, RSAEncryptionPadding.OaepSHA1);
|
|
||||||
|
|
||||||
return (Convert.ToBase64String(encryptedKey), Convert.ToBase64String(encryptedIv));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ručně parsuje SubjectPublicKeyInfo (DER) a importuje RSA klíč - Unity kompatibilní
|
|
||||||
private static void ImportSubjectPublicKeyInfoManual(RSA rsa, byte[] subjectPublicKeyInfo)
|
|
||||||
{
|
|
||||||
// SubjectPublicKeyInfo ::= SEQUENCE {
|
|
||||||
// algorithm AlgorithmIdentifier,
|
|
||||||
// subjectPublicKey BIT STRING }
|
|
||||||
// RSAPublicKey ::= SEQUENCE { modulus INTEGER, publicExponent INTEGER }
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
// Outer SEQUENCE
|
|
||||||
if (subjectPublicKeyInfo[index++] != 0x30)
|
|
||||||
throw new InvalidOperationException("Invalid SubjectPublicKeyInfo");
|
|
||||||
ReadLength(subjectPublicKeyInfo, ref index);
|
|
||||||
|
|
||||||
// AlgorithmIdentifier SEQUENCE - skip it
|
|
||||||
if (subjectPublicKeyInfo[index++] != 0x30)
|
|
||||||
throw new InvalidOperationException("Invalid AlgorithmIdentifier");
|
|
||||||
int algLen = ReadLength(subjectPublicKeyInfo, ref index);
|
|
||||||
index += algLen;
|
|
||||||
|
|
||||||
// BIT STRING containing RSAPublicKey
|
|
||||||
if (subjectPublicKeyInfo[index++] != 0x03)
|
|
||||||
throw new InvalidOperationException("Invalid BIT STRING");
|
|
||||||
ReadLength(subjectPublicKeyInfo, ref index);
|
|
||||||
index++; // Skip unused bits byte (should be 0)
|
|
||||||
|
|
||||||
// RSAPublicKey SEQUENCE
|
|
||||||
if (subjectPublicKeyInfo[index++] != 0x30)
|
|
||||||
throw new InvalidOperationException("Invalid RSAPublicKey");
|
|
||||||
ReadLength(subjectPublicKeyInfo, ref index);
|
|
||||||
|
|
||||||
// Modulus INTEGER
|
|
||||||
byte[] modulus = ReadInteger(subjectPublicKeyInfo, ref index);
|
|
||||||
|
|
||||||
// Exponent INTEGER
|
|
||||||
byte[] exponent = ReadInteger(subjectPublicKeyInfo, ref index);
|
|
||||||
|
|
||||||
var parameters = new RSAParameters
|
|
||||||
{
|
|
||||||
Modulus = modulus,
|
|
||||||
Exponent = exponent
|
|
||||||
};
|
|
||||||
rsa.ImportParameters(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int ReadLength(byte[] data, ref int index)
|
|
||||||
{
|
|
||||||
int length = data[index++];
|
|
||||||
if ((length & 0x80) != 0)
|
|
||||||
{
|
|
||||||
int numBytes = length & 0x7F;
|
|
||||||
length = 0;
|
|
||||||
for (int i = 0; i < numBytes; i++)
|
|
||||||
{
|
|
||||||
length = (length << 8) | data[index++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] ReadInteger(byte[] data, ref int index)
|
|
||||||
{
|
|
||||||
if (data[index++] != 0x02)
|
|
||||||
throw new InvalidOperationException("Expected INTEGER");
|
|
||||||
int length = ReadLength(data, ref index);
|
|
||||||
|
|
||||||
// Skip leading zero if present (used for positive sign in DER)
|
|
||||||
int originalLength = length;
|
|
||||||
int start = index;
|
|
||||||
if (length > 1 && data[start] == 0x00)
|
|
||||||
{
|
|
||||||
start++;
|
|
||||||
length--;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] result = new byte[length];
|
|
||||||
Buffer.BlockCopy(data, start, result, 0, length);
|
|
||||||
index += originalLength;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Šifruje zprávu pomocí AES-256-CBC s HMAC
|
|
||||||
public byte[] Encrypt(byte[] plaintext)
|
|
||||||
{
|
|
||||||
if (_sessionKey == null || _sessionIv == null)
|
|
||||||
throw new InvalidOperationException("Session key not set");
|
|
||||||
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
// Generuj unikátní IV pro tuto zprávu
|
|
||||||
var iv = GetNextIV();
|
|
||||||
|
|
||||||
using (var aes = Aes.Create())
|
|
||||||
{
|
|
||||||
aes.Key = _sessionKey;
|
|
||||||
aes.IV = iv;
|
|
||||||
aes.Mode = CipherMode.CBC;
|
|
||||||
aes.Padding = PaddingMode.PKCS7;
|
|
||||||
|
|
||||||
byte[] ciphertext;
|
|
||||||
using (var encryptor = aes.CreateEncryptor())
|
|
||||||
using (var ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
|
|
||||||
{
|
|
||||||
cs.Write(plaintext, 0, plaintext.Length);
|
|
||||||
}
|
|
||||||
ciphertext = ms.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute HMAC pro integritu
|
|
||||||
byte[] hmac;
|
|
||||||
using (var hmacSha = new HMACSHA256(_sessionKey))
|
|
||||||
{
|
|
||||||
var toSign = new byte[iv.Length + ciphertext.Length];
|
|
||||||
Buffer.BlockCopy(iv, 0, toSign, 0, iv.Length);
|
|
||||||
Buffer.BlockCopy(ciphertext, 0, toSign, iv.Length, ciphertext.Length);
|
|
||||||
hmac = hmacSha.ComputeHash(toSign);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Výstup: [16 bytes IV][32 bytes HMAC][ciphertext]
|
|
||||||
var result = new byte[16 + 32 + ciphertext.Length];
|
|
||||||
Buffer.BlockCopy(iv, 0, result, 0, 16);
|
|
||||||
Buffer.BlockCopy(hmac, 0, result, 16, 32);
|
|
||||||
Buffer.BlockCopy(ciphertext, 0, result, 48, ciphertext.Length);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dešifruje zprávu pomocí AES-256-CBC s HMAC ověřením
|
|
||||||
public byte[] Decrypt(byte[] encrypted)
|
|
||||||
{
|
|
||||||
if (_sessionKey == null)
|
|
||||||
throw new InvalidOperationException("Session key not set");
|
|
||||||
|
|
||||||
if (encrypted.Length < 48) return null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var iv = new byte[16];
|
|
||||||
var hmac = new byte[32];
|
|
||||||
var ciphertext = new byte[encrypted.Length - 48];
|
|
||||||
|
|
||||||
Buffer.BlockCopy(encrypted, 0, iv, 0, 16);
|
|
||||||
Buffer.BlockCopy(encrypted, 16, hmac, 0, 32);
|
|
||||||
Buffer.BlockCopy(encrypted, 48, ciphertext, 0, ciphertext.Length);
|
|
||||||
|
|
||||||
// Ověř HMAC
|
|
||||||
byte[] expectedHmac;
|
|
||||||
using (var hmacSha = new HMACSHA256(_sessionKey))
|
|
||||||
{
|
|
||||||
var toVerify = new byte[iv.Length + ciphertext.Length];
|
|
||||||
Buffer.BlockCopy(iv, 0, toVerify, 0, iv.Length);
|
|
||||||
Buffer.BlockCopy(ciphertext, 0, toVerify, iv.Length, ciphertext.Length);
|
|
||||||
expectedHmac = hmacSha.ComputeHash(toVerify);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constant-time compare
|
|
||||||
var diff = 0;
|
|
||||||
for (int i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
diff |= hmac[i] ^ expectedHmac[i];
|
|
||||||
}
|
|
||||||
if (diff != 0) return null; // HMAC mismatch
|
|
||||||
|
|
||||||
using (var aes = Aes.Create())
|
|
||||||
{
|
|
||||||
aes.Key = _sessionKey;
|
|
||||||
aes.IV = iv;
|
|
||||||
aes.Mode = CipherMode.CBC;
|
|
||||||
aes.Padding = PaddingMode.PKCS7;
|
|
||||||
|
|
||||||
using (var decryptor = aes.CreateDecryptor())
|
|
||||||
using (var ms = new MemoryStream(ciphertext))
|
|
||||||
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
|
|
||||||
using (var output = new MemoryStream())
|
|
||||||
{
|
|
||||||
cs.CopyTo(output);
|
|
||||||
return output.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (CryptographicException)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] GetNextIV()
|
|
||||||
{
|
|
||||||
if (_sessionIv == null)
|
|
||||||
throw new InvalidOperationException("Session IV not set");
|
|
||||||
|
|
||||||
var iv = new byte[16];
|
|
||||||
Buffer.BlockCopy(_sessionIv, 0, iv, 0, 8);
|
|
||||||
|
|
||||||
var counter = System.Threading.Interlocked.Increment(ref _nonceCounter);
|
|
||||||
var counterBytes = BitConverter.GetBytes(counter);
|
|
||||||
Buffer.BlockCopy(counterBytes, 0, iv, 8, 8);
|
|
||||||
|
|
||||||
return iv;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_sessionKey != null)
|
|
||||||
{
|
|
||||||
Array.Clear(_sessionKey, 0, _sessionKey.Length);
|
|
||||||
_sessionKey = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: bc06bb57786c7e142b06ec231e5cf709
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace GeoSus.Client
|
|
||||||
{
|
|
||||||
// Event dispatcher pro Unity main thread
|
|
||||||
// Unity může přidat SynchronizationContext, nebo polling z Update()
|
|
||||||
public class EventDispatcher
|
|
||||||
{
|
|
||||||
private readonly Queue<Action> _pendingActions = new Queue<Action>();
|
|
||||||
private readonly object _lock = new object();
|
|
||||||
private SynchronizationContext? _syncContext;
|
|
||||||
|
|
||||||
public EventDispatcher()
|
|
||||||
{
|
|
||||||
// Pokusíme se zachytit aktuální synchronization context (Unity main thread)
|
|
||||||
_syncContext = SynchronizationContext.Current;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volat z networking vlákna - naplánuje callback na main thread
|
|
||||||
public void Post(Action action)
|
|
||||||
{
|
|
||||||
if (_syncContext != null)
|
|
||||||
{
|
|
||||||
_syncContext.Post(_ => action(), null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fallback - přidáme do fronty pro polling
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
_pendingActions.Enqueue(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volat z Unity Update() pokud není SynchronizationContext
|
|
||||||
public void ProcessPendingActions()
|
|
||||||
{
|
|
||||||
Action[] actions;
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
if (_pendingActions.Count == 0) return;
|
|
||||||
actions = _pendingActions.ToArray();
|
|
||||||
_pendingActions.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var action in actions)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
action();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"EventDispatcher error: {ex}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int PendingCount
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
return _pendingActions.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1d2251b279edb0147bd274a884ac878b
|
|
||||||
@@ -1,607 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace GeoSus.Client
|
|
||||||
{
|
|
||||||
// Hlavní klientská třída pro připojení k serveru
|
|
||||||
public class GameClient : IDisposable
|
|
||||||
{
|
|
||||||
private TcpClient? _tcpClient;
|
|
||||||
private NetworkStream? _stream;
|
|
||||||
private ClientEncryption? _encryption;
|
|
||||||
private CancellationTokenSource? _cts;
|
|
||||||
private Task? _receiveTask;
|
|
||||||
private int _clientSeq;
|
|
||||||
private readonly object _sendLock = new object();
|
|
||||||
private bool _handshakeComplete;
|
|
||||||
|
|
||||||
public string ClientUuid { get; }
|
|
||||||
public string DisplayName { get; set; }
|
|
||||||
public bool IsConnected => _tcpClient?.Connected ?? false;
|
|
||||||
public bool IsReady => IsConnected && _handshakeComplete && (_encryption?.HasSessionKey ?? false);
|
|
||||||
public EventDispatcher Dispatcher { get; }
|
|
||||||
|
|
||||||
// Events - voláno na main thread přes dispatcher
|
|
||||||
public event Action? OnConnected;
|
|
||||||
public event Action<string>? OnDisconnected;
|
|
||||||
public event Action<string>? OnError;
|
|
||||||
public event Action<Message>? OnMessage;
|
|
||||||
public event Action<GameEvent>? OnGameEvent;
|
|
||||||
|
|
||||||
// Lobby state
|
|
||||||
public string? LobbyId { get; private set; }
|
|
||||||
public string? JoinCode { get; private set; }
|
|
||||||
public LobbyState? CurrentLobbyState { get; private set; }
|
|
||||||
public PlayerRole? MyRole { get; private set; }
|
|
||||||
public List<GameTask> MyTasks { get; } = new List<GameTask>();
|
|
||||||
public Position MyPosition { get; set; }
|
|
||||||
public Dictionary<string, PlayerPositionInfo> PlayerPositions { get; } = new Dictionary<string, PlayerPositionInfo>();
|
|
||||||
public List<Body> Bodies { get; } = new List<Body>();
|
|
||||||
public int Ping { get; private set; }
|
|
||||||
public long LastEventId { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>Returns true if this client is the current lobby owner</summary>
|
|
||||||
public bool IsOwner => CurrentLobbyState?.OwnerId == ClientUuid;
|
|
||||||
|
|
||||||
public GameClient(string clientUuid, string displayName)
|
|
||||||
{
|
|
||||||
ClientUuid = clientUuid;
|
|
||||||
DisplayName = displayName;
|
|
||||||
Dispatcher = new EventDispatcher();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Connection
|
|
||||||
|
|
||||||
public async Task<bool> ConnectAsync(string host, int port)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_tcpClient = new TcpClient();
|
|
||||||
await _tcpClient.ConnectAsync(host, port);
|
|
||||||
_stream = _tcpClient.GetStream();
|
|
||||||
_encryption = new ClientEncryption();
|
|
||||||
_cts = new CancellationTokenSource();
|
|
||||||
|
|
||||||
// Handshake
|
|
||||||
if (!await PerformHandshakeAsync())
|
|
||||||
{
|
|
||||||
Disconnect("Handshake failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spustíme příjem zpráv
|
|
||||||
_receiveTask = Task.Run(() => ReceiveLoopAsync(_cts.Token));
|
|
||||||
|
|
||||||
Dispatcher.Post(() => OnConnected?.Invoke());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Dispatcher.Post(() => OnError?.Invoke(ex.Message));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<bool> PerformHandshakeAsync()
|
|
||||||
{
|
|
||||||
if (_stream == null || _encryption == null) return false;
|
|
||||||
|
|
||||||
// 1. ClientHello
|
|
||||||
var hello = new ClientHello
|
|
||||||
{
|
|
||||||
ClientUuid = ClientUuid,
|
|
||||||
DisplayName = DisplayName
|
|
||||||
};
|
|
||||||
await SendPlainAsync(hello);
|
|
||||||
|
|
||||||
// 2. ServerHello
|
|
||||||
var serverHelloData = await ReadMessageAsync();
|
|
||||||
if (serverHelloData == null) return false;
|
|
||||||
|
|
||||||
var serverHello = MessageSerializer.Deserialize(serverHelloData) as ServerHello;
|
|
||||||
if (serverHello == null) return false;
|
|
||||||
|
|
||||||
// 3. Generujeme session key a šifrujeme RSA
|
|
||||||
_encryption.GenerateSessionKey();
|
|
||||||
var (encKey, encIv) = _encryption.EncryptSessionKeyForServer(serverHello.RsaPublicKeyPem);
|
|
||||||
|
|
||||||
var keyExchange = new KeyExchange
|
|
||||||
{
|
|
||||||
EncryptedSessionKey = encKey,
|
|
||||||
EncryptedIV = encIv
|
|
||||||
};
|
|
||||||
await SendPlainAsync(keyExchange);
|
|
||||||
|
|
||||||
// 4. KeyExchangeAck (šifrovaně)
|
|
||||||
var ackData = await ReadMessageAsync();
|
|
||||||
if (ackData == null) return false;
|
|
||||||
|
|
||||||
var decrypted = _encryption.Decrypt(ackData);
|
|
||||||
if (decrypted == null) return false;
|
|
||||||
|
|
||||||
var ack = MessageSerializer.Deserialize(decrypted) as KeyExchangeAck;
|
|
||||||
if (ack?.Status == "success")
|
|
||||||
{
|
|
||||||
_handshakeComplete = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Disconnect(string reason = "User disconnected")
|
|
||||||
{
|
|
||||||
_cts?.Cancel();
|
|
||||||
_tcpClient?.Close();
|
|
||||||
_tcpClient = null;
|
|
||||||
_stream = null;
|
|
||||||
_encryption?.Dispose();
|
|
||||||
_encryption = null;
|
|
||||||
|
|
||||||
LobbyId = null;
|
|
||||||
JoinCode = null;
|
|
||||||
CurrentLobbyState = null;
|
|
||||||
MyRole = null;
|
|
||||||
MyTasks.Clear();
|
|
||||||
PlayerPositions.Clear();
|
|
||||||
Bodies.Clear();
|
|
||||||
|
|
||||||
Dispatcher.Post(() => OnDisconnected?.Invoke(reason));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Sending
|
|
||||||
|
|
||||||
public void Send(Message message)
|
|
||||||
{
|
|
||||||
if (_stream == null || _encryption == null || !IsConnected) return;
|
|
||||||
|
|
||||||
message.ClientSeq = Interlocked.Increment(ref _clientSeq);
|
|
||||||
if (string.IsNullOrEmpty(message.ActionId))
|
|
||||||
{
|
|
||||||
message.ActionId = Guid.NewGuid().ToString("N").Substring(0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
var plain = MessageSerializer.Serialize(message);
|
|
||||||
var encrypted = _encryption.Encrypt(plain);
|
|
||||||
|
|
||||||
lock (_sendLock)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SendData(encrypted);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Dispatcher.Post(() => OnError?.Invoke($"Send error: {ex.Message}"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SendPlainAsync(Message message)
|
|
||||||
{
|
|
||||||
if (_stream == null) return;
|
|
||||||
var data = MessageSerializer.Serialize(message);
|
|
||||||
await SendDataAsync(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SendData(byte[] data)
|
|
||||||
{
|
|
||||||
if (_stream == null) return;
|
|
||||||
|
|
||||||
var lengthBuffer = BitConverter.GetBytes(data.Length);
|
|
||||||
if (BitConverter.IsLittleEndian)
|
|
||||||
Array.Reverse(lengthBuffer);
|
|
||||||
|
|
||||||
_stream.Write(lengthBuffer, 0, 4);
|
|
||||||
_stream.Write(data, 0, data.Length);
|
|
||||||
_stream.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SendDataAsync(byte[] data)
|
|
||||||
{
|
|
||||||
if (_stream == null) return;
|
|
||||||
|
|
||||||
var lengthBuffer = BitConverter.GetBytes(data.Length);
|
|
||||||
if (BitConverter.IsLittleEndian)
|
|
||||||
Array.Reverse(lengthBuffer);
|
|
||||||
|
|
||||||
await _stream.WriteAsync(lengthBuffer, 0, 4);
|
|
||||||
await _stream.WriteAsync(data, 0, data.Length);
|
|
||||||
await _stream.FlushAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Receiving
|
|
||||||
|
|
||||||
private async Task ReceiveLoopAsync(CancellationToken ct)
|
|
||||||
{
|
|
||||||
int decryptFailures = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
while (!ct.IsCancellationRequested && IsConnected)
|
|
||||||
{
|
|
||||||
var data = await ReadMessageAsync();
|
|
||||||
if (data == null) break;
|
|
||||||
|
|
||||||
var decrypted = _encryption?.Decrypt(data);
|
|
||||||
if (decrypted == null)
|
|
||||||
{
|
|
||||||
decryptFailures++;
|
|
||||||
if (decryptFailures >= 3)
|
|
||||||
{
|
|
||||||
Disconnect("Too many decryption failures");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
decryptFailures = 0;
|
|
||||||
|
|
||||||
var message = MessageSerializer.Deserialize(decrypted);
|
|
||||||
if (message != null)
|
|
||||||
{
|
|
||||||
ProcessMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex) when (!ct.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Disconnect($"Connection error: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<byte[]?> ReadMessageAsync()
|
|
||||||
{
|
|
||||||
if (_stream == null) return null;
|
|
||||||
|
|
||||||
var lengthBuffer = new byte[4];
|
|
||||||
var read = await _stream.ReadAsync(lengthBuffer, 0, 4);
|
|
||||||
if (read < 4) return null;
|
|
||||||
|
|
||||||
if (BitConverter.IsLittleEndian)
|
|
||||||
Array.Reverse(lengthBuffer);
|
|
||||||
var length = BitConverter.ToInt32(lengthBuffer, 0);
|
|
||||||
|
|
||||||
if (length <= 0 || length > 1048576) return null;
|
|
||||||
|
|
||||||
var buffer = new byte[length];
|
|
||||||
var totalRead = 0;
|
|
||||||
while (totalRead < length)
|
|
||||||
{
|
|
||||||
read = await _stream.ReadAsync(buffer, totalRead, length - totalRead);
|
|
||||||
if (read == 0) return null;
|
|
||||||
totalRead += read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessMessage(Message message)
|
|
||||||
{
|
|
||||||
// Zpracujeme speciální typy
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case CreateLobbyResponse r:
|
|
||||||
if (r.Success)
|
|
||||||
{
|
|
||||||
LobbyId = r.LobbyId;
|
|
||||||
JoinCode = r.JoinCode;
|
|
||||||
CurrentLobbyState = r.LobbyState;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JoinLobbyResponse r:
|
|
||||||
if (r.Success)
|
|
||||||
{
|
|
||||||
LobbyId = r.LobbyId;
|
|
||||||
CurrentLobbyState = r.LobbyState;
|
|
||||||
JoinCode = r.LobbyState?.JoinCode;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PositionBroadcast b:
|
|
||||||
ProcessPositionBroadcast(b);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Pong p:
|
|
||||||
var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
|
||||||
Ping = (int)(now - p.ClientTime);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GameEvent evt:
|
|
||||||
ProcessGameEvent(evt);
|
|
||||||
Dispatcher.Post(() => OnGameEvent?.Invoke(evt));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dispatcher.Post(() => OnMessage?.Invoke(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessPositionBroadcast(PositionBroadcast broadcast)
|
|
||||||
{
|
|
||||||
PlayerPositions.Clear();
|
|
||||||
foreach (var player in broadcast.Players)
|
|
||||||
{
|
|
||||||
PlayerPositions[player.ClientUuid] = player;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessGameEvent(GameEvent evt)
|
|
||||||
{
|
|
||||||
LastEventId = evt.EventId;
|
|
||||||
|
|
||||||
switch (evt.EventType)
|
|
||||||
{
|
|
||||||
case "PlayerJoined":
|
|
||||||
// Add player to lobby state
|
|
||||||
var joinedPayload = evt.GetPayload<PlayerJoinedPayload>();
|
|
||||||
if (joinedPayload != null && CurrentLobbyState?.Players != null)
|
|
||||||
{
|
|
||||||
// Check if player already exists
|
|
||||||
bool exists = CurrentLobbyState.Players.Any(p => p.ClientUuid == joinedPayload.ClientUuid);
|
|
||||||
if (!exists)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Players.Add(new PlayerInfo
|
|
||||||
{
|
|
||||||
ClientUuid = joinedPayload.ClientUuid,
|
|
||||||
DisplayName = joinedPayload.DisplayName,
|
|
||||||
IsOwner = false,
|
|
||||||
IsReady = false,
|
|
||||||
State = PlayerState.Alive
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "PlayerLeft":
|
|
||||||
// Remove player from lobby state
|
|
||||||
var leftPayload = evt.GetPayload<PlayerLeftPayload>();
|
|
||||||
if (leftPayload != null && CurrentLobbyState?.Players != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Players.RemoveAll(p => p.ClientUuid == leftPayload.ClientUuid);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "HostChanged":
|
|
||||||
// Update lobby owner
|
|
||||||
var hostPayload = evt.GetPayload<HostChangedPayload>();
|
|
||||||
if (hostPayload != null && CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.OwnerId = hostPayload.NewHostId;
|
|
||||||
// Update IsOwner flag on all players
|
|
||||||
foreach (var player in CurrentLobbyState.Players)
|
|
||||||
{
|
|
||||||
player.IsOwner = player.ClientUuid == hostPayload.NewHostId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "GameStarting":
|
|
||||||
// Game is entering loading phase - update lobby state if available
|
|
||||||
if (CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Phase = GamePhase.Loading;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "MapDataReady":
|
|
||||||
// Map data received - store it and send confirmation
|
|
||||||
var mapDataPayload = evt.GetPayload<MapDataReadyPayload>();
|
|
||||||
if (mapDataPayload != null && CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.MapData = mapDataPayload.MapData;
|
|
||||||
CurrentLobbyState.MapDataReady = true;
|
|
||||||
}
|
|
||||||
// Send confirmation to server
|
|
||||||
Send(new MapDataReceived());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "GameStarted":
|
|
||||||
// Game officially started - update phase
|
|
||||||
if (CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Phase = GamePhase.Playing;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "RoleAssigned":
|
|
||||||
var rolePayload = evt.GetPayload<RoleAssignedPayload>();
|
|
||||||
if (rolePayload != null && rolePayload.ClientUuid == ClientUuid)
|
|
||||||
{
|
|
||||||
MyRole = rolePayload.Role;
|
|
||||||
MyTasks.Clear();
|
|
||||||
if (rolePayload.Tasks != null)
|
|
||||||
{
|
|
||||||
MyTasks.AddRange(rolePayload.Tasks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "PlayerKilled":
|
|
||||||
var killPayload = evt.GetPayload<PlayerKilledPayload>();
|
|
||||||
if (killPayload != null)
|
|
||||||
{
|
|
||||||
Bodies.Add(new Body
|
|
||||||
{
|
|
||||||
BodyId = killPayload.BodyId,
|
|
||||||
VictimId = killPayload.VictimId,
|
|
||||||
Location = killPayload.Location
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "MeetingStarted":
|
|
||||||
if (CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Phase = GamePhase.Meeting;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "VotingClosed":
|
|
||||||
Bodies.Clear(); // Bodies zmizí po meetingu
|
|
||||||
if (CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Phase = GamePhase.Playing;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "GameEnded":
|
|
||||||
if (CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
CurrentLobbyState.Phase = GamePhase.Ended;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Game Actions
|
|
||||||
|
|
||||||
public void CreateLobby(Position? center = null, int impostorCount = 1, int taskCount = 5, string? password = null, double playAreaRadius = 500)
|
|
||||||
{
|
|
||||||
Send(new CreateLobby
|
|
||||||
{
|
|
||||||
PlayAreaCenter = center,
|
|
||||||
PlayAreaRadius = playAreaRadius,
|
|
||||||
ImpostorCount = impostorCount,
|
|
||||||
TaskCount = taskCount,
|
|
||||||
Password = password
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void JoinLobby(string joinCode, string? password = null)
|
|
||||||
{
|
|
||||||
Send(new JoinLobby
|
|
||||||
{
|
|
||||||
JoinCode = joinCode.ToUpperInvariant(),
|
|
||||||
Password = password
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LeaveLobby()
|
|
||||||
{
|
|
||||||
Send(new LeaveLobby());
|
|
||||||
LobbyId = null;
|
|
||||||
JoinCode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartGame()
|
|
||||||
{
|
|
||||||
Send(new StartGame());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReturnToLobby()
|
|
||||||
{
|
|
||||||
Send(new ReturnToLobby());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdatePosition(Position position)
|
|
||||||
{
|
|
||||||
MyPosition = position;
|
|
||||||
Send(new UpdatePosition { Position = position });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Kill(string targetUuid)
|
|
||||||
{
|
|
||||||
Send(new KillAttempt { TargetClientUuid = targetUuid });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReportBody(string bodyId)
|
|
||||||
{
|
|
||||||
Send(new ReportBody { BodyId = bodyId });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CallEmergencyMeeting()
|
|
||||||
{
|
|
||||||
Send(new CallEmergencyMeeting());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Vote(string? targetUuid)
|
|
||||||
{
|
|
||||||
Send(new CastVote { TargetClientUuid = targetUuid });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Pokus o dokončení tasku. Server ověří že hráč je na správné pozici.
|
|
||||||
/// </summary>
|
|
||||||
public void CompleteTask(string taskId)
|
|
||||||
{
|
|
||||||
Send(new TaskComplete { TaskId = taskId });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendPing()
|
|
||||||
{
|
|
||||||
Send(new Ping { ClientTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reconnect(string lobbyId)
|
|
||||||
{
|
|
||||||
Send(new Reconnect { LobbyId = lobbyId, LastEventId = LastEventId });
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Helpers
|
|
||||||
|
|
||||||
public Body? FindNearbyBody(double maxDistance)
|
|
||||||
{
|
|
||||||
foreach (var body in Bodies)
|
|
||||||
{
|
|
||||||
if (MyPosition.DistanceTo(body.Location) <= maxDistance)
|
|
||||||
{
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string? FindNearbyPlayer(double maxDistance, bool aliveOnly = true)
|
|
||||||
{
|
|
||||||
foreach (var (uuid, info) in PlayerPositions)
|
|
||||||
{
|
|
||||||
if (uuid == ClientUuid) continue;
|
|
||||||
if (aliveOnly && info.State != PlayerState.Alive) continue;
|
|
||||||
|
|
||||||
if (MyPosition.DistanceTo(info.Position) <= maxDistance)
|
|
||||||
{
|
|
||||||
return uuid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameTask? FindNearbyTask(double maxDistance)
|
|
||||||
{
|
|
||||||
foreach (var task in MyTasks)
|
|
||||||
{
|
|
||||||
if (MyPosition.DistanceTo(task.Location) <= maxDistance)
|
|
||||||
{
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Volat z Unity Update() pro zpracování callbacků
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
Dispatcher.ProcessPendingActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Disconnect("Disposed");
|
|
||||||
_encryption?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 91e0f647c37b0b94b83f53bb854db28c
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 14463228dfea2264ebfc36c3a7dc4b99
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 80ef0979df5d1fe489225f3e5edadc5c
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: AreaMat
|
|
||||||
m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _AlphaTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- PixelSnap: 0
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _EnableExternalAlpha: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 0.0813297, g: 1, b: 0, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
- _Flip: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
- _RendererColor: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 5a46533bdf4003449bc9146ccef44e27
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using GeoSus.Client;
|
|
||||||
using Subsystems;
|
|
||||||
using System.Collections;
|
|
||||||
using System;
|
|
||||||
using TMPro;
|
|
||||||
/*
|
|
||||||
GameManager - hlavní tøida pro správu hry
|
|
||||||
GameManager_Network - subsystém pro správu komunikace se serverem
|
|
||||||
GameManager_Game - subsystém pro správu logiky hry (sabotáže, tasky, atd.)
|
|
||||||
GameManager_Map - subsystém pro správu mapy a prostøedí
|
|
||||||
GameManager_Input - subsystém pro správu vstupu od hráèe
|
|
||||||
GameManager_UI - subsystém pro správu uživatelského rozhraní
|
|
||||||
GamaManager_Stats - subsystém pro správu statistik pro server
|
|
||||||
*/
|
|
||||||
public class GameManager : MonoBehaviour
|
|
||||||
{
|
|
||||||
[Header("Subsystems")]
|
|
||||||
protected GameManager_Network networkSubsystem;
|
|
||||||
protected GameManager_UI uiSubsystem;
|
|
||||||
protected GameManager_Map mapSubsystem;
|
|
||||||
protected GameManager_Input inputSubsystem;
|
|
||||||
|
|
||||||
protected GameClient gameClient;
|
|
||||||
|
|
||||||
[Header("Player Info")]
|
|
||||||
public string displayName;
|
|
||||||
|
|
||||||
[Header("UI Elements")]
|
|
||||||
public Canvas JoinCreateLobby;
|
|
||||||
public Canvas InLobby;
|
|
||||||
public Canvas LoadingScreen;
|
|
||||||
public Canvas GameScreen;
|
|
||||||
|
|
||||||
|
|
||||||
[Header("Map")]
|
|
||||||
public GameObject MapCenterPoint;
|
|
||||||
public BuildingSettings buildingSettings;
|
|
||||||
public PathwaySettings pathwaySettings;
|
|
||||||
public AreaSettings areaSettings;
|
|
||||||
|
|
||||||
[Header("GPS")]
|
|
||||||
public GameObject Player;
|
|
||||||
|
|
||||||
[Header("Debug")]
|
|
||||||
public bool testMode = false;
|
|
||||||
private GameClient _secondClient;
|
|
||||||
private GameClient _thirdClient;
|
|
||||||
private GameManager_Network _secondNetwork;
|
|
||||||
private GameManager_Network _thirdNetwork;
|
|
||||||
|
|
||||||
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
DontDestroyOnLoad(this);
|
|
||||||
if (displayName == null || displayName == "")
|
|
||||||
{
|
|
||||||
displayName = GenerateUsername();
|
|
||||||
}
|
|
||||||
if (testMode)
|
|
||||||
{
|
|
||||||
_secondClient = new GameClient(GenerateUUID(), GenerateUsername());
|
|
||||||
_secondNetwork = new GameManager_Network(_secondClient);
|
|
||||||
_thirdClient = new GameClient(GenerateUUID(), GenerateUsername());
|
|
||||||
_thirdNetwork = new GameManager_Network(_thirdClient);
|
|
||||||
|
|
||||||
_secondNetwork.OpenConection();
|
|
||||||
_thirdNetwork.OpenConection();
|
|
||||||
}
|
|
||||||
gameClient = new GameClient(GenerateUUID(), displayName);
|
|
||||||
uiSubsystem = new GameManager_UI(gameClient, JoinCreateLobby, InLobby, LoadingScreen, GameScreen);
|
|
||||||
networkSubsystem = new GameManager_Network(gameClient);
|
|
||||||
mapSubsystem = new GameManager_Map(gameClient, MapCenterPoint, buildingSettings, pathwaySettings, areaSettings);
|
|
||||||
inputSubsystem = new GameManager_Input(gameClient, Player, testMode);
|
|
||||||
networkSubsystem.OpenConection();
|
|
||||||
}
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (gameClient.CurrentLobbyState != null)
|
|
||||||
{
|
|
||||||
uiSubsystem.UpdateLobbyUI();
|
|
||||||
}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (gameClient.CurrentLobbyState.MapDataReady)
|
|
||||||
{
|
|
||||||
mapSubsystem.BuildMap();
|
|
||||||
gameClient.CurrentLobbyState.MapDataReady = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (NullReferenceException ex) { }
|
|
||||||
inputSubsystem.positionCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected string GenerateUUID()
|
|
||||||
{
|
|
||||||
string UUID = System.Guid.NewGuid().ToString();
|
|
||||||
Debug.Log(UUID);
|
|
||||||
return UUID;
|
|
||||||
}
|
|
||||||
protected string GenerateUsername()
|
|
||||||
{
|
|
||||||
string Username = UnityEngine.Random.Range(0,10).ToString() + UnityEngine.Random.Range(0, 10).ToString() + UnityEngine.Random.Range(0, 10).ToString() + UnityEngine.Random.Range(0, 10).ToString();
|
|
||||||
Debug.Log(Username);
|
|
||||||
return Username;
|
|
||||||
}
|
|
||||||
public void CreateLobbyButton()
|
|
||||||
{
|
|
||||||
networkSubsystem.CrateLobby(50.7727264, 15.0719876);
|
|
||||||
if (testMode)
|
|
||||||
{
|
|
||||||
StartCoroutine(ConnectTestClients());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void JoinLobbyButton()
|
|
||||||
{
|
|
||||||
TMP_InputField joinCode = JoinCreateLobby.transform.Find("InputCode").GetComponent<TMP_InputField>();
|
|
||||||
if (joinCode.text != null && joinCode.text != "")
|
|
||||||
{
|
|
||||||
networkSubsystem.JoinLobby(joinCode.text);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.Log("Join code is empty!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void LeaveLobbyButton()
|
|
||||||
{
|
|
||||||
networkSubsystem.LeaveLobby();
|
|
||||||
}
|
|
||||||
public void StartGameButton()
|
|
||||||
{
|
|
||||||
networkSubsystem.StartGame();
|
|
||||||
}
|
|
||||||
void OnApplicationQuit()
|
|
||||||
{
|
|
||||||
gameClient.Disconnect();
|
|
||||||
_secondClient?.Disconnect();
|
|
||||||
_thirdClient?.Disconnect();
|
|
||||||
}
|
|
||||||
IEnumerator ConnectTestClients()
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(2f);
|
|
||||||
_secondNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode);
|
|
||||||
_thirdNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 22bf82e679cf6e1419440d236360ba3b
|
|
||||||
@@ -1,926 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using GeoSus.Client;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace Subsystems
|
|
||||||
{
|
|
||||||
internal class CoroutineHost : MonoBehaviour
|
|
||||||
{
|
|
||||||
public CoroutineHost() { }
|
|
||||||
}
|
|
||||||
internal enum GPSState
|
|
||||||
{
|
|
||||||
Uninitialized,
|
|
||||||
Initializing,
|
|
||||||
Running,
|
|
||||||
Failed
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Position source backend. Selectable at runtime via the GPS overlay
|
|
||||||
/// "Source" button so the user can recover when one path misbehaves on
|
|
||||||
/// their phone:
|
|
||||||
/// Auto - JNI: subscribe to gps + network, pick most recent fix.
|
|
||||||
/// GpsOnly - JNI: subscribe to gps only (network's frequent indoor
|
|
||||||
/// fixes don't drown out the slower-but-precise gps fix).
|
|
||||||
/// NetworkOnly - JNI: subscribe to network only (cell tower / WiFi).
|
|
||||||
/// Useful indoors when no satellite lock is possible.
|
|
||||||
/// UnityInput - Unity's Input.location wrapper. Verified to hang on
|
|
||||||
/// Mi 9T / A20e (which is why JNI exists), but works on
|
|
||||||
/// newer Android where the JNI streaming-callbacks path
|
|
||||||
/// silently doesn't fire (MIUI/HyperOS battery saver,
|
|
||||||
/// approximate-vs-precise permission split, minDistance
|
|
||||||
/// gating on stationary phones).
|
|
||||||
/// EditorWasd - WASD-driven simulated position. Available regardless
|
|
||||||
/// of testMode flag so desktop builds and editor sessions
|
|
||||||
/// can navigate the map without real GPS.
|
|
||||||
/// </summary>
|
|
||||||
public enum PositionSource
|
|
||||||
{
|
|
||||||
Auto,
|
|
||||||
GpsOnly,
|
|
||||||
NetworkOnly,
|
|
||||||
UnityInput,
|
|
||||||
EditorWasd,
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
/// <summary>
|
|
||||||
/// Bridges android.location.LocationListener to managed code. The method
|
|
||||||
/// names here must match Java's LocationListener interface exactly so
|
|
||||||
/// AndroidJavaProxy's reflection dispatcher can find them.
|
|
||||||
/// </summary>
|
|
||||||
internal class AndroidLocationProxy : AndroidJavaProxy
|
|
||||||
{
|
|
||||||
public AndroidLocationProvider Owner { get; set; }
|
|
||||||
public AndroidLocationProxy() : base("android.location.LocationListener") { }
|
|
||||||
|
|
||||||
// Called by Android each time a new fix arrives from the registered provider.
|
|
||||||
public void onLocationChanged(AndroidJavaObject location)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (location == null) return;
|
|
||||||
double lat = location.Call<double>("getLatitude");
|
|
||||||
double lon = location.Call<double>("getLongitude");
|
|
||||||
long t = location.Call<long>("getTime");
|
|
||||||
string provider = "";
|
|
||||||
try { provider = location.Call<string>("getProvider"); } catch { }
|
|
||||||
// Streaming callbacks are LIVE (never cached). The cached path
|
|
||||||
// calls UpdateLocation directly with isCached=true.
|
|
||||||
Owner?.UpdateLocation(lat, lon, t, provider, isCached: false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[GPS-JNI] onLocationChanged failed: " + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Required by the LocationListener interface even if we don't use them.
|
|
||||||
// Missing methods cause java.lang.AbstractMethodError at runtime.
|
|
||||||
public void onStatusChanged(string provider, int status, AndroidJavaObject extras) { }
|
|
||||||
public void onProviderEnabled(string provider) { }
|
|
||||||
public void onProviderDisabled(string provider) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Direct wrapper around android.location.LocationManager via JNI, used as
|
|
||||||
/// a replacement for Unity's Input.location on Android when the user picks
|
|
||||||
/// Auto/GpsOnly/NetworkOnly. Subscribed providers are configurable so the
|
|
||||||
/// position-source picker can rewire live without restart.
|
|
||||||
/// </summary>
|
|
||||||
internal class AndroidLocationProvider
|
|
||||||
{
|
|
||||||
private AndroidJavaObject _activity;
|
|
||||||
private AndroidJavaObject _locationManager;
|
|
||||||
private AndroidLocationProxy _gpsListener;
|
|
||||||
private AndroidLocationProxy _networkListener;
|
|
||||||
private double _lat, _lon;
|
|
||||||
private long _lastTimeMillis;
|
|
||||||
private long _lastLiveTimeMillis; // Time of most recent NON-cached fix.
|
|
||||||
private bool _hasFix;
|
|
||||||
private bool _hasLiveFix; // True once any streaming callback fired.
|
|
||||||
private string _activeProvider = "";
|
|
||||||
|
|
||||||
// Captured at Initialize() so the diagnostic can report
|
|
||||||
// "GPS provider DISABLED, only network enabled" etc.
|
|
||||||
private bool _gpsProviderEnabled;
|
|
||||||
private bool _networkProviderEnabled;
|
|
||||||
private bool _gpsLastKnownExists;
|
|
||||||
private bool _networkLastKnownExists;
|
|
||||||
private string _enabledProvidersList = "";
|
|
||||||
|
|
||||||
// Subscription scope - set in Initialize, used in Shutdown to know
|
|
||||||
// which listeners we registered.
|
|
||||||
private bool _subscribedGps;
|
|
||||||
private bool _subscribedNetwork;
|
|
||||||
|
|
||||||
public bool HasFix => _hasFix;
|
|
||||||
public bool HasLiveFix => _hasLiveFix;
|
|
||||||
public long LastLiveTimeMillis => _lastLiveTimeMillis;
|
|
||||||
public long LastTimeMillis => _lastTimeMillis;
|
|
||||||
public double Lat => _lat;
|
|
||||||
public double Lon => _lon;
|
|
||||||
public string ActiveProvider => _activeProvider;
|
|
||||||
public bool GpsProviderEnabled => _gpsProviderEnabled;
|
|
||||||
public bool NetworkProviderEnabled => _networkProviderEnabled;
|
|
||||||
public bool GpsLastKnownExists => _gpsLastKnownExists;
|
|
||||||
public bool NetworkLastKnownExists => _networkLastKnownExists;
|
|
||||||
public string EnabledProvidersList => _enabledProvidersList;
|
|
||||||
public bool SubscribedGps => _subscribedGps;
|
|
||||||
public bool SubscribedNetwork => _subscribedNetwork;
|
|
||||||
|
|
||||||
public bool Initialize(out string error, bool useGps, bool useNetwork)
|
|
||||||
{
|
|
||||||
error = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
|
|
||||||
{
|
|
||||||
_activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
|
||||||
}
|
|
||||||
if (_activity == null) { error = "no current activity"; return false; }
|
|
||||||
|
|
||||||
_locationManager = _activity.Call<AndroidJavaObject>("getSystemService", "location");
|
|
||||||
if (_locationManager == null) { error = "getSystemService(\"location\") returned null"; return false; }
|
|
||||||
|
|
||||||
// Capture provider enable state up front so the diagnostic
|
|
||||||
// can distinguish "provider disabled at OS level" from
|
|
||||||
// "provider enabled but produced no fix yet".
|
|
||||||
_gpsProviderEnabled = SafeIsProviderEnabled("gps");
|
|
||||||
_networkProviderEnabled = SafeIsProviderEnabled("network");
|
|
||||||
_enabledProvidersList = SafeGetEnabledProviders();
|
|
||||||
|
|
||||||
Debug.Log($"[GPS-JNI] init useGps={useGps} useNetwork={useNetwork} gps enabled={_gpsProviderEnabled} network enabled={_networkProviderEnabled} all enabled=[{_enabledProvidersList}]");
|
|
||||||
|
|
||||||
// Try cached last-known fixes from the providers we're about
|
|
||||||
// to subscribe to. If the OS already knows where we are
|
|
||||||
// (e.g. from another app that recently used GPS), we get a
|
|
||||||
// fix at zero cost and zero wait time. Tagged isCached so
|
|
||||||
// the diagnostic can mark them and we know we still need
|
|
||||||
// to wait for a streaming callback.
|
|
||||||
if (useNetwork) TryLastKnown("network", out _networkLastKnownExists);
|
|
||||||
if (useGps) TryLastKnown("gps", out _gpsLastKnownExists);
|
|
||||||
|
|
||||||
_subscribedGps = useGps;
|
|
||||||
_subscribedNetwork = useNetwork;
|
|
||||||
|
|
||||||
if (useGps) _gpsListener = new AndroidLocationProxy { Owner = this };
|
|
||||||
if (useNetwork) _networkListener = new AndroidLocationProxy { Owner = this };
|
|
||||||
|
|
||||||
// requestLocationUpdates must be called on a thread with a
|
|
||||||
// Looper. Use the Activity's UI thread, which always has one.
|
|
||||||
// minTime=1000ms, minDistance=0f - we want updates on every
|
|
||||||
// fix the OS produces. Previously this was 1f which gated
|
|
||||||
// out updates from a stationary phone (MIUI/newer Android
|
|
||||||
// are stricter about this and that's the suspected cause of
|
|
||||||
// "via gps (cached)" sticking forever).
|
|
||||||
_activity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
|
|
||||||
{
|
|
||||||
if (useGps)
|
|
||||||
{
|
|
||||||
try { _locationManager.Call("requestLocationUpdates", "gps", 1000L, 0f, _gpsListener); }
|
|
||||||
catch (Exception ex) { Debug.LogWarning("[GPS-JNI] gps subscribe failed: " + ex.Message); }
|
|
||||||
}
|
|
||||||
if (useNetwork)
|
|
||||||
{
|
|
||||||
try { _locationManager.Call("requestLocationUpdates", "network", 1000L, 0f, _networkListener); }
|
|
||||||
catch (Exception ex) { Debug.LogWarning("[GPS-JNI] network subscribe failed: " + ex.Message); }
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
error = "JNI init exception: " + ex.Message;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TryLastKnown(string provider, out bool nonNullReturned)
|
|
||||||
{
|
|
||||||
nonNullReturned = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var loc = _locationManager.Call<AndroidJavaObject>("getLastKnownLocation", provider);
|
|
||||||
if (loc != null)
|
|
||||||
{
|
|
||||||
nonNullReturned = true;
|
|
||||||
double lat = loc.Call<double>("getLatitude");
|
|
||||||
double lon = loc.Call<double>("getLongitude");
|
|
||||||
long t = loc.Call<long>("getTime");
|
|
||||||
UpdateLocation(lat, lon, t, provider, isCached: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[GPS-JNI] getLastKnownLocation({provider}) failed: " + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SafeIsProviderEnabled(string provider)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return _locationManager.Call<bool>("isProviderEnabled", provider);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[GPS-JNI] isProviderEnabled({provider}) failed: " + ex.Message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a comma-separated list of currently-enabled providers via
|
|
||||||
// LocationManager.getProviders(true). We iterate the returned
|
|
||||||
// java.util.List by index because AndroidJavaObject does not
|
|
||||||
// implement IEnumerable.
|
|
||||||
string SafeGetEnabledProviders()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var list = _locationManager.Call<AndroidJavaObject>("getProviders", true);
|
|
||||||
if (list == null) return "";
|
|
||||||
int size = list.Call<int>("size");
|
|
||||||
var parts = new System.Text.StringBuilder();
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
var name = list.Call<string>("get", i);
|
|
||||||
if (i > 0) parts.Append(",");
|
|
||||||
parts.Append(name);
|
|
||||||
}
|
|
||||||
return parts.ToString();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[GPS-JNI] getProviders failed: " + ex.Message);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateLocation(double lat, double lon, long timeMillis, string provider, bool isCached)
|
|
||||||
{
|
|
||||||
// Ignore older fixes if a newer one is already in hand. This lets
|
|
||||||
// both gps + network listeners feed us without ping-ponging
|
|
||||||
// between stale and fresh data.
|
|
||||||
if (timeMillis < _lastTimeMillis) return;
|
|
||||||
_lat = lat;
|
|
||||||
_lon = lon;
|
|
||||||
_lastTimeMillis = timeMillis;
|
|
||||||
// Active-provider name carries cached/live state in the diagnostic
|
|
||||||
// banner so the user can see at a glance whether streaming has
|
|
||||||
// kicked in or we're still on the initial cached snapshot.
|
|
||||||
_activeProvider = (provider ?? "") + (isCached ? " (cached)" : "");
|
|
||||||
_hasFix = true;
|
|
||||||
if (!isCached)
|
|
||||||
{
|
|
||||||
_hasLiveFix = true;
|
|
||||||
_lastLiveTimeMillis = timeMillis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Shutdown()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_locationManager != null)
|
|
||||||
{
|
|
||||||
if (_gpsListener != null) _locationManager.Call("removeUpdates", _gpsListener);
|
|
||||||
if (_networkListener != null) _locationManager.Call("removeUpdates", _networkListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogWarning("[GPS-JNI] Shutdown failed: " + ex.Message);
|
|
||||||
}
|
|
||||||
_gpsListener = null;
|
|
||||||
_networkListener = null;
|
|
||||||
_locationManager = null;
|
|
||||||
_activity = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
public static class PositonExtensions
|
|
||||||
{
|
|
||||||
public static Position ToLocal(this Position position, Position center)
|
|
||||||
{
|
|
||||||
double latDiff = position.Lat - center.Lat;
|
|
||||||
double lonDiff = position.Lon - center.Lon;
|
|
||||||
double metersPerDegreeLat = 111320.0;
|
|
||||||
double metersPerDegreeLon = 111320.0 * Math.Cos(center.Lat * Math.PI / 180.0);
|
|
||||||
float x = (float)(lonDiff * metersPerDegreeLon);
|
|
||||||
float z = (float)(latDiff * metersPerDegreeLat);
|
|
||||||
return new Position(z, x);
|
|
||||||
}
|
|
||||||
public static Vector3 ToLocalVector3(this Position position, Position center)
|
|
||||||
{
|
|
||||||
return position.ToLocal(center).ToVector3(); //TODO: Implementace v subsystemech
|
|
||||||
}
|
|
||||||
public static Vector3 ToVector3(this Position position)
|
|
||||||
{
|
|
||||||
return new Vector3((float)position.Lon, 0, (float)position.Lat); //TODO: Implementace v subsystemech
|
|
||||||
}
|
|
||||||
public static double DistanceTo(this Vector3 pos, Vector3 other)
|
|
||||||
{
|
|
||||||
return Math.Sqrt((other.x - pos.x) * (other.x - pos.x) + (other.z - pos.z) * (other.z - pos.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GameManager_Input
|
|
||||||
{
|
|
||||||
private GameClient _gameClient;
|
|
||||||
private Position _currentPosition;
|
|
||||||
private Position _lastSentPosition;
|
|
||||||
private GameObject _player;
|
|
||||||
private bool _testMode;
|
|
||||||
|
|
||||||
// PlayerPrefs key for the user's chosen position source. Persists
|
|
||||||
// across app restarts so a user who flipped to UnityInput because
|
|
||||||
// their phone hated the JNI path doesn't have to flip again every
|
|
||||||
// launch.
|
|
||||||
private const string PrefsSourceKey = "PositionSource_v1";
|
|
||||||
private PositionSource _currentSource = PositionSource.Auto;
|
|
||||||
|
|
||||||
// When the multi-client editor test mode picks a non-host bot as
|
|
||||||
// active, we need the host's WASD path to NOT also move. Set true
|
|
||||||
// by GameManager when active slot != 0.
|
|
||||||
public bool SuppressWasd = false;
|
|
||||||
|
|
||||||
private GPSState _GPSState = GPSState.Uninitialized;
|
|
||||||
private float _speed = 0.00001f;
|
|
||||||
private Position _mapCenter;
|
|
||||||
private CoroutineHost _coroutineHost;
|
|
||||||
|
|
||||||
private int _gpsRetryCount = 0;
|
|
||||||
private const int _maxGpsRetries = 5;
|
|
||||||
private float _lastPositionSendTime;
|
|
||||||
private const float _positionKeepAliveSeconds = 1.0f;
|
|
||||||
|
|
||||||
// Diagnostic state. We capture *why* GPS init failed so the UI can
|
|
||||||
// surface it to the user without requiring logcat. Older Android
|
|
||||||
// phones (Mi 9T, A20e) hit silent failure modes that are impossible
|
|
||||||
// to distinguish from "still warming up" without this.
|
|
||||||
private string _lastGpsError = "";
|
|
||||||
private float _gpsInitStartTime = -1f;
|
|
||||||
// Bump from the original 20s. Cold-start GPS on older Android can
|
|
||||||
// easily exceed 20s indoors or under cloud cover - by the time the
|
|
||||||
// user notices nothing is happening, we've already given up.
|
|
||||||
private const int _gpsInitTimeoutSeconds = 60;
|
|
||||||
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
// JNI-backed location provider, used for Auto/GpsOnly/NetworkOnly.
|
|
||||||
// UnityInput uses Input.location instead and leaves this null.
|
|
||||||
private AndroidLocationProvider _androidProvider;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>Last known GPS position (for CreateLobby centre point)</summary>
|
|
||||||
public Position? LastKnownPosition => _currentPosition.Lat != 0 || _currentPosition.Lon != 0 ? _currentPosition : (Position?)null;
|
|
||||||
|
|
||||||
/// <summary>Current GPS state machine value (debug/diagnostic).</summary>
|
|
||||||
public string GpsStateName => _GPSState.ToString();
|
|
||||||
|
|
||||||
/// <summary>Last GPS error reason captured during init (empty if none).</summary>
|
|
||||||
public string LastGpsError => _lastGpsError ?? "";
|
|
||||||
|
|
||||||
/// <summary>Retry count out of max (debug/diagnostic).</summary>
|
|
||||||
public string GpsRetryProgress => $"{_gpsRetryCount}/{_maxGpsRetries}";
|
|
||||||
|
|
||||||
/// <summary>Currently selected position source (for UI cycle button).</summary>
|
|
||||||
public PositionSource CurrentSource => _currentSource;
|
|
||||||
|
|
||||||
/// <summary>Display name for the current source (for UI label).</summary>
|
|
||||||
public string CurrentSourceName
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (_currentSource)
|
|
||||||
{
|
|
||||||
case PositionSource.Auto: return "Auto (GPS+Net)";
|
|
||||||
case PositionSource.GpsOnly: return "GPS only";
|
|
||||||
case PositionSource.NetworkOnly: return "Network only";
|
|
||||||
case PositionSource.UnityInput: return "Unity Input";
|
|
||||||
case PositionSource.EditorWasd: return "WASD";
|
|
||||||
default: return _currentSource.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Human-readable one-line GPS status for on-screen overlay. Designed
|
|
||||||
/// to be visible without ADB so users can self-diagnose permission
|
|
||||||
/// vs. timeout vs. device-disabled vs. running-but-no-fix-yet.
|
|
||||||
/// </summary>
|
|
||||||
public string GpsDiagnostic
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_currentSource == PositionSource.EditorWasd)
|
|
||||||
{
|
|
||||||
if (_currentPosition.Lat == 0 && _currentPosition.Lon == 0)
|
|
||||||
return "WASD: waiting for map center";
|
|
||||||
return $"WASD lat={_currentPosition.Lat:F5} lon={_currentPosition.Lon:F5}";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (_GPSState)
|
|
||||||
{
|
|
||||||
case GPSState.Uninitialized:
|
|
||||||
return "Uninitialized (will start on first lobby action)";
|
|
||||||
case GPSState.Initializing:
|
|
||||||
{
|
|
||||||
float elapsed = _gpsInitStartTime >= 0 ? Time.time - _gpsInitStartTime : 0;
|
|
||||||
string providers = "";
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
if (_androidProvider != null && !string.IsNullOrEmpty(_androidProvider.EnabledProvidersList))
|
|
||||||
providers = $" providers=[{_androidProvider.EnabledProvidersList}]";
|
|
||||||
#endif
|
|
||||||
return $"Initializing ({elapsed:F1}s / max {_gpsInitTimeoutSeconds}s){providers}";
|
|
||||||
}
|
|
||||||
case GPSState.Running:
|
|
||||||
{
|
|
||||||
string suffix = "";
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
if (_androidProvider != null)
|
|
||||||
{
|
|
||||||
string p = _androidProvider.ActiveProvider;
|
|
||||||
if (!string.IsNullOrEmpty(p)) suffix = " via " + p;
|
|
||||||
// Show how stale the most recent fix is (ms-level
|
|
||||||
// resolution) so "stuck on cached" is obvious at
|
|
||||||
// a glance: "via gps (cached) [no live, 47s old]".
|
|
||||||
if (!_androidProvider.HasLiveFix)
|
|
||||||
{
|
|
||||||
long now = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
|
|
||||||
long ageMs = now - _androidProvider.LastTimeMillis;
|
|
||||||
if (_androidProvider.LastTimeMillis > 0 && ageMs > 0)
|
|
||||||
suffix += $" [no live, {ageMs / 1000}s old]";
|
|
||||||
else
|
|
||||||
suffix += " [no live]";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
long now = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
|
|
||||||
long ageMs = now - _androidProvider.LastLiveTimeMillis;
|
|
||||||
if (ageMs > 5000) suffix += $" [live {ageMs / 1000}s old]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (_currentPosition.Lat == 0 && _currentPosition.Lon == 0)
|
|
||||||
return "Running but no fix yet (waiting for satellites)" + suffix;
|
|
||||||
return $"Running lat={_currentPosition.Lat:F5} lon={_currentPosition.Lon:F5}" + suffix;
|
|
||||||
}
|
|
||||||
case GPSState.Failed:
|
|
||||||
return $"Failed: {(_lastGpsError ?? "unknown")} (retries {GpsRetryProgress})";
|
|
||||||
default:
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameManager_Input(GameClient gameClient, GameObject player, bool testMode)
|
|
||||||
{
|
|
||||||
_gameClient = gameClient;
|
|
||||||
_player = player;
|
|
||||||
_testMode = testMode;
|
|
||||||
// CoroutineHost needs a MonoBehaviour on a real GameObject
|
|
||||||
var hostGO = new UnityEngine.GameObject("_CoroutineHost");
|
|
||||||
UnityEngine.Object.DontDestroyOnLoad(hostGO);
|
|
||||||
_coroutineHost = hostGO.AddComponent<CoroutineHost>();
|
|
||||||
|
|
||||||
// Restore the user's last picked source. Default depends on
|
|
||||||
// platform: editor defaults to EditorWasd (no GPS hardware in
|
|
||||||
// editor anyway); device defaults to Auto.
|
|
||||||
string saved = PlayerPrefs.GetString(PrefsSourceKey, "");
|
|
||||||
if (!string.IsNullOrEmpty(saved) && Enum.TryParse(saved, out PositionSource parsed))
|
|
||||||
{
|
|
||||||
_currentSource = parsed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
_currentSource = PositionSource.EditorWasd;
|
|
||||||
#else
|
|
||||||
_currentSource = PositionSource.Auto;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy testMode flag forces EditorWasd. New code paths should
|
|
||||||
// use SwitchPositionSource(EditorWasd) instead, but we keep the
|
|
||||||
// old behavior for backward compatibility with the inspector flag.
|
|
||||||
if (_testMode) _currentSource = PositionSource.EditorWasd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Called from OnSceneLoaded when Client.unity loads so the
|
|
||||||
/// Player capsule (which lives in Client.unity) can be wired at runtime.</summary>
|
|
||||||
public void SetPlayerObject(GameObject player) { _player = player; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Switch the active position source backend live. Tears down the
|
|
||||||
/// current backend's listeners (JNI proxies, Input.location), resets
|
|
||||||
/// the state machine, and kicks off init for the new source. Persists
|
|
||||||
/// the choice to PlayerPrefs.
|
|
||||||
/// </summary>
|
|
||||||
public void SwitchPositionSource(PositionSource newSource)
|
|
||||||
{
|
|
||||||
if (_currentSource == newSource) return;
|
|
||||||
Debug.Log($"[GPS] SwitchPositionSource {_currentSource} -> {newSource}");
|
|
||||||
|
|
||||||
// Tear down whatever's running.
|
|
||||||
ShutdownCurrentBackend();
|
|
||||||
|
|
||||||
_currentSource = newSource;
|
|
||||||
PlayerPrefs.SetString(PrefsSourceKey, newSource.ToString());
|
|
||||||
PlayerPrefs.Save();
|
|
||||||
|
|
||||||
_GPSState = GPSState.Uninitialized;
|
|
||||||
_gpsRetryCount = 0;
|
|
||||||
_lastGpsError = "";
|
|
||||||
_gpsInitStartTime = -1f;
|
|
||||||
// Don't clear _currentPosition - the user has presumably been
|
|
||||||
// playing somewhere. Map markers/avatar position can stay until
|
|
||||||
// the next fix arrives from the new source.
|
|
||||||
|
|
||||||
EnsureGPSStarted();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Cycle through the available sources for tap-to-cycle UI.</summary>
|
|
||||||
public void CycleNextPositionSource()
|
|
||||||
{
|
|
||||||
var values = (PositionSource[])Enum.GetValues(typeof(PositionSource));
|
|
||||||
int idx = Array.IndexOf(values, _currentSource);
|
|
||||||
var next = values[(idx + 1) % values.Length];
|
|
||||||
SwitchPositionSource(next);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShutdownCurrentBackend()
|
|
||||||
{
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
if (_androidProvider != null)
|
|
||||||
{
|
|
||||||
_androidProvider.Shutdown();
|
|
||||||
_androidProvider = null;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// Stop Unity Input.location too, in case it was running.
|
|
||||||
try { Input.location.Stop(); } catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Kick off GPS initialization if it hasn't started yet. Safe to call
|
|
||||||
/// repeatedly. Hosts must call this from the lobby setup screen so
|
|
||||||
/// that by the time they click "Create Lobby" we have a real GPS
|
|
||||||
/// fix to use as the play-area center, instead of falling back to
|
|
||||||
/// the hardcoded coordinates.
|
|
||||||
/// </summary>
|
|
||||||
public void EnsureGPSStarted()
|
|
||||||
{
|
|
||||||
if (_currentSource == PositionSource.EditorWasd) return;
|
|
||||||
if (_coroutineHost == null) return;
|
|
||||||
// Allow tapping "Create Lobby" again (or any caller of this
|
|
||||||
// method) to retry from Failed up to _maxGpsRetries times.
|
|
||||||
if (_GPSState == GPSState.Uninitialized)
|
|
||||||
{
|
|
||||||
_coroutineHost.StartCoroutine(InitiallizeGPS());
|
|
||||||
}
|
|
||||||
else if (_GPSState == GPSState.Failed && _gpsRetryCount < _maxGpsRetries)
|
|
||||||
{
|
|
||||||
_gpsRetryCount++;
|
|
||||||
_coroutineHost.StartCoroutine(InitiallizeGPS());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void positionCheck()
|
|
||||||
{
|
|
||||||
var state = _gameClient?.CurrentLobbyState;
|
|
||||||
if (state == null || state.Phase != GamePhase.Playing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_currentSource == PositionSource.EditorWasd)
|
|
||||||
{
|
|
||||||
if (_currentPosition == new Position(0, 0))
|
|
||||||
{
|
|
||||||
if (state.MapData == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//Init blok
|
|
||||||
_currentPosition = state.MapData.Center;
|
|
||||||
_mapCenter = state.MapData.Center;
|
|
||||||
_lastSentPosition = _currentPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SuppressWasd)
|
|
||||||
TestPlayerPosition();
|
|
||||||
else
|
|
||||||
TrySendCurrentPosition(); // keep-alive only
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_GPSState == GPSState.Uninitialized)
|
|
||||||
{
|
|
||||||
_coroutineHost.StartCoroutine(InitiallizeGPS());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (_GPSState == GPSState.Initializing)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (_GPSState == GPSState.Running)
|
|
||||||
{
|
|
||||||
EnsureMapCenter();
|
|
||||||
TrySendCurrentPosition();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.Log("GPS failed, trying again...");
|
|
||||||
if (_gpsRetryCount < _maxGpsRetries)
|
|
||||||
{
|
|
||||||
_gpsRetryCount++;
|
|
||||||
_GPSState = GPSState.Uninitialized;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogWarning("GPS unavailable after max retries. Using last known position.");
|
|
||||||
// Keep _GPSState = Failed so we stop retrying
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"[Input] positionCheck failed: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureMapCenter()
|
|
||||||
{
|
|
||||||
if (_mapCenter.Lat != 0 || _mapCenter.Lon != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var md = _gameClient?.CurrentLobbyState?.MapData;
|
|
||||||
if (md != null)
|
|
||||||
_mapCenter = md.Center;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TrySendCurrentPosition()
|
|
||||||
{
|
|
||||||
bool moved = _currentPosition != _lastSentPosition;
|
|
||||||
bool keepAliveDue = (Time.time - _lastPositionSendTime) >= _positionKeepAliveSeconds;
|
|
||||||
if (!moved && !keepAliveDue)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var previous = _lastSentPosition;
|
|
||||||
_gameClient.UpdatePosition(_currentPosition);
|
|
||||||
_lastSentPosition = _currentPosition;
|
|
||||||
_lastPositionSendTime = Time.time;
|
|
||||||
|
|
||||||
if (_player == null || (_mapCenter.Lat == 0 && _mapCenter.Lon == 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var localCurrent = _currentPosition.ToLocalVector3(_mapCenter);
|
|
||||||
_player.transform.position = localCurrent;
|
|
||||||
|
|
||||||
if (previous.Lat == 0 && previous.Lon == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var heading = CalculateHeading(previous.ToLocalVector3(_mapCenter), localCurrent);
|
|
||||||
if (heading.HasValue)
|
|
||||||
_player.transform.rotation = Quaternion.Euler(0, (float)heading.Value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TestPlayerPosition()
|
|
||||||
{
|
|
||||||
double x = Input.GetAxis("Horizontal");
|
|
||||||
double y = Input.GetAxis("Vertical");
|
|
||||||
_currentPosition = new Position( _lastSentPosition.Lat + y * _speed, _lastSentPosition.Lon + x * _speed);
|
|
||||||
var localCurrent = _currentPosition.ToLocalVector3(_mapCenter);
|
|
||||||
var heading = CalculateHeading(_lastSentPosition.ToLocalVector3(_mapCenter), localCurrent);
|
|
||||||
if (heading != null)
|
|
||||||
{
|
|
||||||
if (_player != null)
|
|
||||||
_player.transform.rotation = Quaternion.Euler(0, (float)heading, 0);
|
|
||||||
}
|
|
||||||
if (_player != null)
|
|
||||||
_player.transform.position = localCurrent;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TrySendCurrentPosition();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
_gameClient.UpdatePosition(_currentPosition);
|
|
||||||
_lastSentPosition = _currentPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private double? CalculateHeading(Vector3 first, Vector3 second)
|
|
||||||
{
|
|
||||||
if ((first - second).magnitude < 0.0001f) return null;
|
|
||||||
float dx = second.x - first.x;
|
|
||||||
float dz = second.z - first.z;
|
|
||||||
float heading = Mathf.Atan2(dx, dz) * Mathf.Rad2Deg;
|
|
||||||
if (heading < 0) heading += 360f;
|
|
||||||
return heading;
|
|
||||||
}
|
|
||||||
IEnumerator InitiallizeGPS()
|
|
||||||
{
|
|
||||||
_GPSState = GPSState.Initializing;
|
|
||||||
_gpsInitStartTime = Time.time;
|
|
||||||
_lastGpsError = "";
|
|
||||||
|
|
||||||
#if UNITY_ANDROID
|
|
||||||
// Request fine location permission if not already granted.
|
|
||||||
// On Android 12+ a "precise" toggle exists separately from coarse,
|
|
||||||
// but Unity's FineLocation request covers both for our purposes.
|
|
||||||
if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(UnityEngine.Android.Permission.FineLocation))
|
|
||||||
{
|
|
||||||
UnityEngine.Android.Permission.RequestUserPermission(UnityEngine.Android.Permission.FineLocation);
|
|
||||||
// Wait up to 10 seconds for user to respond to the permission dialog
|
|
||||||
float waited = 0f;
|
|
||||||
while (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(UnityEngine.Android.Permission.FineLocation) && waited < 10f)
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
waited += 0.5f;
|
|
||||||
}
|
|
||||||
if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(UnityEngine.Android.Permission.FineLocation))
|
|
||||||
{
|
|
||||||
_lastGpsError = "Permission denied (fine location)";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
// Choose subscription scope based on selected source. UnityInput
|
|
||||||
// skips JNI entirely and falls through to the Input.location path
|
|
||||||
// below (the same path iOS / editor use).
|
|
||||||
if (_currentSource == PositionSource.Auto ||
|
|
||||||
_currentSource == PositionSource.GpsOnly ||
|
|
||||||
_currentSource == PositionSource.NetworkOnly)
|
|
||||||
{
|
|
||||||
bool useGps = (_currentSource != PositionSource.NetworkOnly);
|
|
||||||
bool useNetwork = (_currentSource != PositionSource.GpsOnly);
|
|
||||||
|
|
||||||
if (_androidProvider != null)
|
|
||||||
{
|
|
||||||
_androidProvider.Shutdown();
|
|
||||||
_androidProvider = null;
|
|
||||||
}
|
|
||||||
_androidProvider = new AndroidLocationProvider();
|
|
||||||
if (!_androidProvider.Initialize(out var initError, useGps, useNetwork))
|
|
||||||
{
|
|
||||||
_lastGpsError = "Native LocationManager failed: " + initError;
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_androidProvider = null;
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fast-fail if neither subscribed provider is enabled at OS
|
|
||||||
// level. Waiting 60s for fixes from disabled providers is
|
|
||||||
// pointless - tell the user immediately what's wrong.
|
|
||||||
bool anyUsableEnabled =
|
|
||||||
(useGps && _androidProvider.GpsProviderEnabled) ||
|
|
||||||
(useNetwork && _androidProvider.NetworkProviderEnabled);
|
|
||||||
if (!anyUsableEnabled)
|
|
||||||
{
|
|
||||||
string which = useGps && useNetwork ? "gps + network"
|
|
||||||
: useGps ? "gps"
|
|
||||||
: "network";
|
|
||||||
_lastGpsError = $"{which} provider DISABLED at OS level. Open Settings > Location and switch it ON. Or tap [Source] to try a different backend.";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_androidProvider.Shutdown();
|
|
||||||
_androidProvider = null;
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the first fix (cached or live).
|
|
||||||
int maxWaitJni = _gpsInitTimeoutSeconds;
|
|
||||||
while (!_androidProvider.HasFix && maxWaitJni > 0)
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(1);
|
|
||||||
maxWaitJni--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_androidProvider.HasFix)
|
|
||||||
{
|
|
||||||
string enabled = _androidProvider.EnabledProvidersList ?? "";
|
|
||||||
string gpsState = _androidProvider.GpsProviderEnabled ? "ON" : "OFF";
|
|
||||||
string netState = _androidProvider.NetworkProviderEnabled ? "ON" : "OFF";
|
|
||||||
string lastKnown = $"lastKnown[gps={(_androidProvider.GpsLastKnownExists ? "yes" : "no")}, net={(_androidProvider.NetworkLastKnownExists ? "yes" : "no")}]";
|
|
||||||
|
|
||||||
_lastGpsError = $"Timeout {_gpsInitTimeoutSeconds}s on {_currentSource}. enabled=[{enabled}] gps={gpsState} net={netState} {lastKnown}. Try [Source] cycle to switch backends.";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_androidProvider.Shutdown();
|
|
||||||
_androidProvider = null;
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentPosition = new Position(_androidProvider.Lat, _androidProvider.Lon);
|
|
||||||
_GPSState = GPSState.Running;
|
|
||||||
_gpsRetryCount = 0;
|
|
||||||
_coroutineHost.StartCoroutine(AndroidGPSService());
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _currentSource == UnityInput on Android: fall through to the
|
|
||||||
// Input.location path below. This is the recovery path for
|
|
||||||
// newer Android phones where JNI's streaming-callbacks don't
|
|
||||||
// fire (MIUI/HyperOS background restrictions, approximate-vs-
|
|
||||||
// precise permission, minDistance gating on stationary phones).
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// iOS / editor / non-Android / Android-with-UnityInput-source:
|
|
||||||
// use Unity's Input.location.
|
|
||||||
if (!Input.location.isEnabledByUser)
|
|
||||||
{
|
|
||||||
_lastGpsError = "Location services not enabled by user";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
float desiredAccuracyInMeters = 5f;
|
|
||||||
float updateDistanceInMeters = 1f;
|
|
||||||
|
|
||||||
Input.location.Start(desiredAccuracyInMeters, updateDistanceInMeters);
|
|
||||||
|
|
||||||
int maxWait = _gpsInitTimeoutSeconds;
|
|
||||||
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(1);
|
|
||||||
maxWait--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxWait < 1)
|
|
||||||
{
|
|
||||||
_lastGpsError = $"Timed out after {_gpsInitTimeoutSeconds}s waiting for first fix (try moving outdoors, or tap [Source] to try a different backend)";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input.location.status == LocationServiceStatus.Failed)
|
|
||||||
{
|
|
||||||
_lastGpsError = "Unity Input.location reported Failed status";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_GPSState = GPSState.Running;
|
|
||||||
_gpsRetryCount = 0;
|
|
||||||
_coroutineHost.StartCoroutine(GPSService());
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
||||||
/// <summary>
|
|
||||||
/// Mirrors the JNI provider's most recent fix into _currentPosition
|
|
||||||
/// every 0.5s so the rest of the game (which polls _currentPosition
|
|
||||||
/// indirectly via LastKnownPosition / TrySendCurrentPosition) keeps
|
|
||||||
/// working unchanged. Replaces GPSService on Android.
|
|
||||||
/// </summary>
|
|
||||||
IEnumerator AndroidGPSService()
|
|
||||||
{
|
|
||||||
while (_GPSState == GPSState.Running && _androidProvider != null)
|
|
||||||
{
|
|
||||||
if (_androidProvider.HasFix)
|
|
||||||
{
|
|
||||||
_currentPosition = new Position(_androidProvider.Lat, _androidProvider.Lon);
|
|
||||||
}
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop ended (state != Running or provider disposed). Clean up
|
|
||||||
// listeners so we don't leak across retries.
|
|
||||||
if (_androidProvider != null)
|
|
||||||
{
|
|
||||||
_androidProvider.Shutdown();
|
|
||||||
_androidProvider = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
IEnumerator GPSService()
|
|
||||||
{
|
|
||||||
while (_GPSState == GPSState.Running)
|
|
||||||
{
|
|
||||||
if (Input.location.status == LocationServiceStatus.Failed)
|
|
||||||
{
|
|
||||||
_lastGpsError = "Location service died after init (provider stopped)";
|
|
||||||
Debug.LogError("[GPS] " + _lastGpsError);
|
|
||||||
_GPSState = GPSState.Failed;
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep current GPS position fresh; sending is throttled in positionCheck().
|
|
||||||
var data = Input.location.lastData;
|
|
||||||
_currentPosition = new Position(data.latitude, data.longitude);
|
|
||||||
yield return new WaitForSeconds(0.5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2ef1abfb1e85a7943925f9dc3cfea742
|
|
||||||
@@ -1,375 +0,0 @@
|
|||||||
using GeoSus.Client;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Subsystems{
|
|
||||||
[System.Serializable]
|
|
||||||
public class BuildingSettings
|
|
||||||
{
|
|
||||||
public Material ResidentalBuildingsMat;
|
|
||||||
public float ResidentalBuildingHeight;
|
|
||||||
public Material CommercialBuildingsMat;
|
|
||||||
public float CommercialBuildingHeight;
|
|
||||||
public Material IndustrialBuildingsMat;
|
|
||||||
public float IndustrialBuildingHeight;
|
|
||||||
public Material DefaultBuildingMat;
|
|
||||||
public float DefaultBuildingHeight;
|
|
||||||
}
|
|
||||||
[System.Serializable]
|
|
||||||
public class PathwaySettings
|
|
||||||
{
|
|
||||||
public Material FootwayMat;
|
|
||||||
public float FootwayWidth;
|
|
||||||
public Material PathMat;
|
|
||||||
public float PathWidth;
|
|
||||||
public Material StepsMat;
|
|
||||||
public float StepsWidth;
|
|
||||||
public Material CyclewayMat;
|
|
||||||
public float CyclewayWidth;
|
|
||||||
public Material PedestrianMat;
|
|
||||||
public float PedestrianWidth;
|
|
||||||
public Material RoadMat;
|
|
||||||
public float RoadWidth;
|
|
||||||
public Material ServiceMat;
|
|
||||||
public float ServiceWidth;
|
|
||||||
public Material ResidentialMat;
|
|
||||||
public float ResidentialWidth;
|
|
||||||
public Material TrackMat;
|
|
||||||
public float TrackWidth;
|
|
||||||
public Material DefaultMat;
|
|
||||||
public float DefaultWidth;
|
|
||||||
}
|
|
||||||
[System.Serializable]
|
|
||||||
public class AreaSettings
|
|
||||||
{
|
|
||||||
public Material ParkMat;
|
|
||||||
public Material GardenMat;
|
|
||||||
public Material PlaygroundMat;
|
|
||||||
public Material ForestMat;
|
|
||||||
public Material GrassMat;
|
|
||||||
public Material WaterMat;
|
|
||||||
public Material DefaultMat;
|
|
||||||
}
|
|
||||||
public class GameManager_Map
|
|
||||||
{
|
|
||||||
private GameClient _gameClient;
|
|
||||||
private GameObject _mapCenterPoint;
|
|
||||||
private Position _centerPosition;
|
|
||||||
private BuildingSettings _buildingSettings;
|
|
||||||
private PathwaySettings _pathwaySettings;
|
|
||||||
private AreaSettings _areaSettings;
|
|
||||||
private const float _metersPerUnit = 1f;
|
|
||||||
public GameManager_Map(GameClient gameClient, GameObject mapCenterPoint, BuildingSettings buildingSettings, PathwaySettings pathwaySettings, AreaSettings areaSettings)
|
|
||||||
{
|
|
||||||
_gameClient = gameClient;
|
|
||||||
_mapCenterPoint = mapCenterPoint;
|
|
||||||
_buildingSettings = buildingSettings;
|
|
||||||
_pathwaySettings = pathwaySettings;
|
|
||||||
_areaSettings = areaSettings;
|
|
||||||
}
|
|
||||||
public void BuildMap()
|
|
||||||
{
|
|
||||||
ClearChildren();
|
|
||||||
_centerPosition = _gameClient.CurrentLobbyState.MapData.Center;
|
|
||||||
GameObject buildingsRoot = new GameObject("Buildings");
|
|
||||||
buildingsRoot.transform.parent = _mapCenterPoint.transform;
|
|
||||||
|
|
||||||
GameObject pathRoot = new GameObject("Pathways");
|
|
||||||
pathRoot.transform.parent = _mapCenterPoint.transform;
|
|
||||||
|
|
||||||
GameObject areaRoot = new GameObject("Areas");
|
|
||||||
areaRoot.transform.parent = _mapCenterPoint.transform;
|
|
||||||
|
|
||||||
foreach (var building in _gameClient.CurrentLobbyState.MapData.GetBuildings())
|
|
||||||
{
|
|
||||||
string buildingType = "Unknown";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
buildingType = _gameClient.CurrentLobbyState.MapData.BuildingTypes[_gameClient.CurrentLobbyState.MapData.GetBuildings().IndexOf(building)];
|
|
||||||
}
|
|
||||||
catch (Exception ex) { Debug.Log($"Error: {ex.Message}"); }
|
|
||||||
building.Name = buildingType;
|
|
||||||
GameObject b = BuildBuildingMesh(building);
|
|
||||||
b.transform.parent = buildingsRoot.transform;
|
|
||||||
}
|
|
||||||
foreach (var path in _gameClient.CurrentLobbyState.MapData.GetPathways())
|
|
||||||
{
|
|
||||||
GameObject p = BuildPathwayMesh(path);
|
|
||||||
p.transform.parent = pathRoot.transform;
|
|
||||||
}
|
|
||||||
foreach (var area in _gameClient.CurrentLobbyState.MapData.GetAreas())
|
|
||||||
{
|
|
||||||
GameObject a = BuildAreaMesh(area);
|
|
||||||
a.transform.parent = areaRoot.transform;
|
|
||||||
}
|
|
||||||
//TODO: POIs
|
|
||||||
}
|
|
||||||
void ClearChildren()
|
|
||||||
{
|
|
||||||
List<GameObject> toDestroy = new List<GameObject>();
|
|
||||||
foreach (Transform t in _mapCenterPoint.transform)
|
|
||||||
toDestroy.Add(t.gameObject);
|
|
||||||
foreach (var g in toDestroy)
|
|
||||||
{
|
|
||||||
UnityEngine.Object.DestroyImmediate(g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#region Mesh Building
|
|
||||||
GameObject BuildBuildingMesh(MapBuilding b)
|
|
||||||
{
|
|
||||||
var building = new GameObject($"Building_{b.Name ?? "Unknown"}");
|
|
||||||
|
|
||||||
// Výpočet středu budovy
|
|
||||||
Vector3 center = CalculatePolygonCenter(b.Outline);
|
|
||||||
building.transform.position = center;
|
|
||||||
|
|
||||||
// Vytvoření mesh pro budovu
|
|
||||||
MeshFilter meshFilter = building.AddComponent<MeshFilter>();
|
|
||||||
MeshRenderer meshRenderer = building.AddComponent<MeshRenderer>();
|
|
||||||
|
|
||||||
float height;
|
|
||||||
Material mat;
|
|
||||||
switch (b.BuildingType.ToLower())
|
|
||||||
{
|
|
||||||
case "residential":
|
|
||||||
mat = _buildingSettings.ResidentalBuildingsMat;
|
|
||||||
height = _buildingSettings.ResidentalBuildingHeight;
|
|
||||||
break;
|
|
||||||
case "commercial":
|
|
||||||
mat = _buildingSettings.CommercialBuildingsMat;
|
|
||||||
height = _buildingSettings.CommercialBuildingHeight;
|
|
||||||
break;
|
|
||||||
case "industrial":
|
|
||||||
mat = _buildingSettings.IndustrialBuildingsMat;
|
|
||||||
height = _buildingSettings.IndustrialBuildingHeight;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mat = _buildingSettings.DefaultBuildingMat;
|
|
||||||
height = _buildingSettings.DefaultBuildingHeight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Mesh mesh = CreateExtrudedPolygonMesh(b.Outline, height);
|
|
||||||
meshFilter.mesh = mesh;
|
|
||||||
|
|
||||||
//TODO: material by type
|
|
||||||
// Použijeme barvu podle typu budovy
|
|
||||||
meshRenderer.material = mat;
|
|
||||||
|
|
||||||
// Přidání collideru pro interakci
|
|
||||||
building.AddComponent<MeshCollider>();
|
|
||||||
return building;
|
|
||||||
}
|
|
||||||
GameObject BuildPathwayMesh(MapPathway w)
|
|
||||||
{
|
|
||||||
var path = new GameObject($"Path_{w.Name ?? "Unknown"}");
|
|
||||||
|
|
||||||
// Použijeme LineRenderer pro jednoduchost
|
|
||||||
LineRenderer line = path.AddComponent<LineRenderer>();
|
|
||||||
float width;
|
|
||||||
Material mat;
|
|
||||||
|
|
||||||
switch (w.PathType)
|
|
||||||
{
|
|
||||||
case PathType.Footway:
|
|
||||||
mat = _pathwaySettings.FootwayMat;
|
|
||||||
width = _pathwaySettings.FootwayWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Path:
|
|
||||||
mat = _pathwaySettings.PathMat;
|
|
||||||
width = _pathwaySettings.PathWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Steps:
|
|
||||||
mat = _pathwaySettings.StepsMat;
|
|
||||||
width = _pathwaySettings.PathWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Cycleway:
|
|
||||||
mat = _pathwaySettings.CyclewayMat;
|
|
||||||
width = _pathwaySettings.CyclewayWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Pedestrian:
|
|
||||||
mat = _pathwaySettings.PedestrianMat;
|
|
||||||
width = _pathwaySettings.PedestrianWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Road:
|
|
||||||
mat = _pathwaySettings.RoadMat;
|
|
||||||
width = _pathwaySettings.RoadWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Service:
|
|
||||||
mat = _pathwaySettings.ServiceMat;
|
|
||||||
width = _pathwaySettings.ServiceWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Residential:
|
|
||||||
mat = _pathwaySettings.ResidentialMat;
|
|
||||||
width = _pathwaySettings.ResidentialWidth;
|
|
||||||
break;
|
|
||||||
case PathType.Track:
|
|
||||||
mat = _pathwaySettings.TrackMat;
|
|
||||||
width = _pathwaySettings.TrackWidth;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mat = _pathwaySettings.DefaultMat;
|
|
||||||
width = _pathwaySettings.DefaultWidth;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
line.material = mat;
|
|
||||||
line.widthMultiplier = width;
|
|
||||||
|
|
||||||
// Nastavení bodů cesty
|
|
||||||
line.positionCount = w.Points.Count;
|
|
||||||
for (int i = 0; i < w.Points.Count; i++)
|
|
||||||
{
|
|
||||||
Vector3 pos = w.Points[i].ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center);
|
|
||||||
pos.y = 0.1f; // Mírně nad zemí
|
|
||||||
line.SetPosition(i, pos);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
GameObject BuildAreaMesh(MapArea a)
|
|
||||||
{
|
|
||||||
var area = new GameObject($"Area_{a.Name ?? "Unknown"}");
|
|
||||||
|
|
||||||
MeshFilter meshFilter = area.AddComponent<MeshFilter>();
|
|
||||||
MeshRenderer meshRenderer = area.AddComponent<MeshRenderer>();
|
|
||||||
|
|
||||||
// Vytvoření plochého mesh
|
|
||||||
Mesh mesh = CreateFlatPolygonMesh(a.Outline);
|
|
||||||
meshFilter.mesh = mesh;
|
|
||||||
|
|
||||||
|
|
||||||
Material mat;
|
|
||||||
switch (a.AreaType)
|
|
||||||
{
|
|
||||||
case MapAreaType.Park:
|
|
||||||
mat = _areaSettings.ParkMat;
|
|
||||||
break;
|
|
||||||
case MapAreaType.Garden:
|
|
||||||
mat = _areaSettings.GardenMat;
|
|
||||||
break;
|
|
||||||
case MapAreaType.Playground:
|
|
||||||
mat = _areaSettings.PlaygroundMat;
|
|
||||||
break;
|
|
||||||
case MapAreaType.Forest:
|
|
||||||
mat = _areaSettings.ForestMat;
|
|
||||||
break;
|
|
||||||
case MapAreaType.Grass:
|
|
||||||
mat = _areaSettings.GrassMat;
|
|
||||||
break;
|
|
||||||
case MapAreaType.Water:
|
|
||||||
mat = _areaSettings.WaterMat;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mat = _areaSettings.DefaultMat;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
meshRenderer.material = mat;
|
|
||||||
|
|
||||||
area.transform.position = new Vector3(0, 0.05f, 0); // Těsně nad zemí
|
|
||||||
|
|
||||||
return area;
|
|
||||||
}
|
|
||||||
//TODO: POIs
|
|
||||||
#endregion
|
|
||||||
#region Polygon Utils
|
|
||||||
private Vector3 CalculatePolygonCenter(List<Position> points)
|
|
||||||
{
|
|
||||||
Vector3 center = Vector3.zero;
|
|
||||||
foreach (var point in points)
|
|
||||||
{
|
|
||||||
center += point.ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center);
|
|
||||||
}
|
|
||||||
return center / points.Count;
|
|
||||||
}
|
|
||||||
private Mesh CreateExtrudedPolygonMesh(List<Position> outline, float height)
|
|
||||||
{
|
|
||||||
Mesh mesh = new Mesh();
|
|
||||||
|
|
||||||
int vertexCount = outline.Count;
|
|
||||||
|
|
||||||
// Vertices - spodní a horní podstava
|
|
||||||
Vector3[] vertices = new Vector3[vertexCount * 2];
|
|
||||||
Vector3 center = CalculatePolygonCenter(outline);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++)
|
|
||||||
{
|
|
||||||
Vector3 pos = outline[i].ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center) - center;
|
|
||||||
vertices[i] = pos; // Spodní
|
|
||||||
vertices[i + vertexCount] = pos + Vector3.up * height; // Horní
|
|
||||||
}
|
|
||||||
|
|
||||||
// Triangles - jen boční stěny pro jednoduchost
|
|
||||||
List<int> triangles = new List<int>();
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++)
|
|
||||||
{
|
|
||||||
int next = (i + 1) % vertexCount;
|
|
||||||
|
|
||||||
// Boční stěna - dva trojúhelníky
|
|
||||||
triangles.Add(i);
|
|
||||||
triangles.Add(i + vertexCount);
|
|
||||||
triangles.Add(next);
|
|
||||||
|
|
||||||
triangles.Add(next);
|
|
||||||
triangles.Add(i + vertexCount);
|
|
||||||
triangles.Add(next + vertexCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Horní podstava - zjednodušená triangulace (fan)
|
|
||||||
if (vertexCount >= 3)
|
|
||||||
{
|
|
||||||
for (int i = 1; i < vertexCount - 1; i++)
|
|
||||||
{
|
|
||||||
triangles.Add(vertexCount); // Střed (první bod horní)
|
|
||||||
triangles.Add(vertexCount + i);
|
|
||||||
triangles.Add(vertexCount + i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.vertices = vertices;
|
|
||||||
mesh.triangles = triangles.ToArray();
|
|
||||||
mesh.RecalculateNormals();
|
|
||||||
mesh.RecalculateBounds();
|
|
||||||
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
private Mesh CreateFlatPolygonMesh(List<Position> outline)
|
|
||||||
{
|
|
||||||
Mesh mesh = new Mesh();
|
|
||||||
|
|
||||||
int vertexCount = outline.Count;
|
|
||||||
Vector3[] vertices = new Vector3[vertexCount];
|
|
||||||
Vector3 center = CalculatePolygonCenter(outline);
|
|
||||||
|
|
||||||
for (int i = 0; i < vertexCount; i++)
|
|
||||||
{
|
|
||||||
vertices[i] = outline[i].ToLocalVector3(_gameClient.CurrentLobbyState.MapData.Center) - center;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Triangulace - fan pattern
|
|
||||||
List<int> triangles = new List<int>();
|
|
||||||
if (vertexCount >= 3)
|
|
||||||
{
|
|
||||||
for (int i = 1; i < vertexCount - 1; i++)
|
|
||||||
{
|
|
||||||
triangles.Add(0);
|
|
||||||
triangles.Add(i);
|
|
||||||
triangles.Add(i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.vertices = vertices;
|
|
||||||
mesh.triangles = triangles.ToArray();
|
|
||||||
mesh.RecalculateNormals();
|
|
||||||
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 71870ee18b89dd7438e5362ff9e02a3b
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
using GeoSus.Client;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Subsystems;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Subsystems
|
|
||||||
{
|
|
||||||
public class GameManager_Network
|
|
||||||
{
|
|
||||||
private const string _serverAddress = "geosus.honzuvkod.dev";
|
|
||||||
private const int _serverPort = 7777;
|
|
||||||
private GameClient _gameClient;
|
|
||||||
private GameManager_Map _mapSubsystem;
|
|
||||||
public async void OpenConection()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Task<bool> state = _gameClient.ConnectAsync(_serverAddress, _serverPort);
|
|
||||||
await state;
|
|
||||||
if (state.Result)
|
|
||||||
{
|
|
||||||
Debug.Log("Connected to server.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.Log("Failed to connect to server");
|
|
||||||
}
|
|
||||||
await Task.Delay(5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public GameManager_Network(GameClient gameClient)
|
|
||||||
{
|
|
||||||
_gameClient = gameClient;
|
|
||||||
RegisterEventHandlers();
|
|
||||||
}
|
|
||||||
public void RegisterEventHandlers()
|
|
||||||
{
|
|
||||||
_gameClient.OnConnected += OnConnected;
|
|
||||||
_gameClient.OnDisconnected += OnDisconnected;
|
|
||||||
_gameClient.OnError += OnError;
|
|
||||||
_gameClient.OnMessage += OnMessage;
|
|
||||||
_gameClient.OnGameEvent += OnGameEvent;
|
|
||||||
}
|
|
||||||
private void OnConnected()
|
|
||||||
{
|
|
||||||
Debug.Log("Successfully connected to the server.");
|
|
||||||
}
|
|
||||||
private void OnDisconnected(string reason)
|
|
||||||
{
|
|
||||||
Debug.Log($"Host disconnected due to {reason}");
|
|
||||||
}
|
|
||||||
private void OnError(string error)
|
|
||||||
{
|
|
||||||
Debug.LogError($"Network error: {error}");
|
|
||||||
}
|
|
||||||
private void OnMessage(Message message)
|
|
||||||
{
|
|
||||||
switch (message.Type)
|
|
||||||
{
|
|
||||||
case "GameEvent":
|
|
||||||
OnGameEvent(message as GameEvent);
|
|
||||||
break;
|
|
||||||
case "CreateLobbyResponse":
|
|
||||||
Debug.Log("Received CreateLobbyResponse message");
|
|
||||||
HandleCreateLobbyResponse(message as CreateLobbyResponse);
|
|
||||||
break;
|
|
||||||
case "JoinLobbyResponse":
|
|
||||||
Debug.Log("Received JoinLobbyResponse message");
|
|
||||||
HandleJoinLobbyResponse(message as JoinLobbyResponse);
|
|
||||||
break;
|
|
||||||
case "Ack":
|
|
||||||
Debug.Log("Received Ack message");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Debug.Log("Received message of type: " + message.Type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void OnGameEvent(GameEvent gameEvent)
|
|
||||||
{
|
|
||||||
switch (gameEvent.EventType)
|
|
||||||
{
|
|
||||||
case "PlayerJoined":
|
|
||||||
Debug.Log($"Player {gameEvent.GetPayload<PlayerJoinedPayload>().DisplayName} joined");
|
|
||||||
break;
|
|
||||||
case "PlayerLeft":
|
|
||||||
Debug.Log($"Player {gameEvent.GetPayload<PlayerLeftPayload>()} left");
|
|
||||||
break;
|
|
||||||
case "GameStarting":
|
|
||||||
Debug.Log("Game is starting!");
|
|
||||||
break;
|
|
||||||
case "GameStarted":
|
|
||||||
Debug.Log("Game started");
|
|
||||||
break;
|
|
||||||
case "MapDataReady":
|
|
||||||
Debug.Log("Map data ready");
|
|
||||||
break;
|
|
||||||
case "PlayerMapDataReceived":
|
|
||||||
Debug.Log("Player map data recieved");
|
|
||||||
break;
|
|
||||||
case "MapDataError":
|
|
||||||
Debug.Log("Received MapData server error");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Debug.Log("Received GameEvent of type: " + gameEvent.EventType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void HandleCreateLobbyResponse(CreateLobbyResponse message)
|
|
||||||
{
|
|
||||||
if (message.Success)
|
|
||||||
{
|
|
||||||
Debug.Log("Lobby created successfully. Join Code: " + message.JoinCode + ", Lobby ID: " + message.LobbyId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError("Failed to create lobby: " + message.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void HandleJoinLobbyResponse(JoinLobbyResponse message)
|
|
||||||
{
|
|
||||||
if (message.Success)
|
|
||||||
{
|
|
||||||
Debug.Log("Lobby created successfully." + ", Lobby ID: " + message.LobbyId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError("Failed to create lobby: " + message.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void CrateLobby(double lat, double lon)
|
|
||||||
{
|
|
||||||
_gameClient.CreateLobby(new Position(lat, lon));
|
|
||||||
}
|
|
||||||
public void JoinLobby(string joinCode)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_gameClient.JoinLobby(joinCode);
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError("Error joining lobby: " + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void LeaveLobby()
|
|
||||||
{
|
|
||||||
_gameClient.Disconnect();
|
|
||||||
Application.Quit();
|
|
||||||
}
|
|
||||||
public void StartGame()
|
|
||||||
{
|
|
||||||
_gameClient.StartGame();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 989e9292fe24c2a4ba95ceae191dd330
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using Subsystems;
|
|
||||||
using GeoSus.Client;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Subsystems
|
|
||||||
{
|
|
||||||
public class GameManager_UI
|
|
||||||
{
|
|
||||||
private GameClient _gameClient;
|
|
||||||
private Canvas _CreateJoinLobby;
|
|
||||||
private Canvas _InLobby;
|
|
||||||
private Canvas _LoadingScreen;
|
|
||||||
private Canvas _GameScreen;
|
|
||||||
public GameManager_UI(GameClient gameClient, Canvas CreateJoinLobby, Canvas InLobby, Canvas LoadingScreen, Canvas GameScreen)
|
|
||||||
{
|
|
||||||
_gameClient = gameClient;
|
|
||||||
_CreateJoinLobby = CreateJoinLobby;
|
|
||||||
_LoadingScreen = LoadingScreen;
|
|
||||||
_GameScreen = GameScreen;
|
|
||||||
_InLobby = InLobby;
|
|
||||||
_CreateJoinLobby.enabled = true;
|
|
||||||
_InLobby.enabled = false;
|
|
||||||
_GameScreen.enabled = false;
|
|
||||||
_LoadingScreen.enabled = false;
|
|
||||||
}
|
|
||||||
public void UpdateLobbyUI()
|
|
||||||
{
|
|
||||||
if (_gameClient.CurrentLobbyState == null)
|
|
||||||
{
|
|
||||||
_CreateJoinLobby.enabled = true;
|
|
||||||
_InLobby.enabled = false;
|
|
||||||
_GameScreen.enabled = false;
|
|
||||||
_LoadingScreen.enabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (_gameClient.CurrentLobbyState.Phase == GamePhase.Loading)
|
|
||||||
{
|
|
||||||
_CreateJoinLobby.enabled = false;
|
|
||||||
_InLobby.enabled = false;
|
|
||||||
_GameScreen.enabled = false;
|
|
||||||
_LoadingScreen.enabled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (_gameClient.CurrentLobbyState.Phase == GamePhase.Lobby)
|
|
||||||
{
|
|
||||||
_InLobby.enabled = true;
|
|
||||||
_CreateJoinLobby.enabled = false;
|
|
||||||
var playerList = _InLobby.transform.Find("PlayerList").GetComponent<TMPro.TMP_Text>();
|
|
||||||
playerList.text = "";
|
|
||||||
foreach (var player in _gameClient.CurrentLobbyState.Players)
|
|
||||||
{
|
|
||||||
playerList.text += player.DisplayName + "\n";
|
|
||||||
}
|
|
||||||
_InLobby.transform.Find("JoinCode").GetComponent<TMPro.TMP_Text>().text = _gameClient.CurrentLobbyState.JoinCode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (_gameClient.CurrentLobbyState.Phase == GamePhase.Playing)
|
|
||||||
{
|
|
||||||
_CreateJoinLobby.enabled = false;
|
|
||||||
_InLobby.enabled = false;
|
|
||||||
_GameScreen.enabled = true;
|
|
||||||
_LoadingScreen.enabled = false;
|
|
||||||
_GameScreen.transform.Find("Role").GetComponent<TMPro.TMP_Text>().text = _gameClient.MyRole.ToString() ;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: cbe0afd6cfb57b44781533cfa4ce4196
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: TestMaterial
|
|
||||||
m_Shader: {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _AlphaTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- PixelSnap: 0
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _EnableExternalAlpha: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
- _Flip: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
- _RendererColor: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e8c70d2b2080681448d8f781f73c73a0
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 52b482693f234054aa4d20f92fbef10d
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: BLUE
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 0, g: 0, b: 1, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 09c36d1bce0ccb84183ec9ae484ad36f
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: GREEN
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 0, g: 1, b: 0, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6470170d7e4563b409ffaafee7ce3972
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: RED
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 1, g: 0, b: 0, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7652d0434e406234994330fe5849208d
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: YELLOW
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8e2c8411c69b47e47a22c9c7cd45fa37
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
Before Width: | Height: | Size: 411 KiB |
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: ede5307c01f3e5040a9f4724e9a83a81
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 38 KiB |
@@ -1,117 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3b4d688ffa74073459cae80fc6fa7d27
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable: []
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
mipmaps:
|
|
||||||
mipMapMode: 0
|
|
||||||
enableMipMap: 0
|
|
||||||
sRGBTexture: 1
|
|
||||||
linearTexture: 0
|
|
||||||
fadeOut: 0
|
|
||||||
borderMipMap: 0
|
|
||||||
mipMapsPreserveCoverage: 0
|
|
||||||
alphaTestReferenceValue: 0.5
|
|
||||||
mipMapFadeDistanceStart: 1
|
|
||||||
mipMapFadeDistanceEnd: 3
|
|
||||||
bumpmap:
|
|
||||||
convertToNormalMap: 0
|
|
||||||
externalNormalMap: 0
|
|
||||||
heightScale: 0.25
|
|
||||||
normalMapFilter: 0
|
|
||||||
flipGreenChannel: 0
|
|
||||||
isReadable: 0
|
|
||||||
streamingMipmaps: 0
|
|
||||||
streamingMipmapsPriority: 0
|
|
||||||
vTOnly: 0
|
|
||||||
ignoreMipmapLimit: 0
|
|
||||||
grayScaleToAlpha: 0
|
|
||||||
generateCubemap: 6
|
|
||||||
cubemapConvolution: 0
|
|
||||||
seamlessCubemap: 0
|
|
||||||
textureFormat: 1
|
|
||||||
maxTextureSize: 2048
|
|
||||||
textureSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
filterMode: 1
|
|
||||||
aniso: 1
|
|
||||||
mipBias: 0
|
|
||||||
wrapU: 1
|
|
||||||
wrapV: 1
|
|
||||||
wrapW: 0
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 1
|
|
||||||
alignment: 0
|
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
|
||||||
spritePixelsToUnits: 100
|
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
|
||||||
alphaUsage: 1
|
|
||||||
alphaIsTransparency: 1
|
|
||||||
spriteTessellationDetail: -1
|
|
||||||
textureType: 8
|
|
||||||
textureShape: 1
|
|
||||||
singleChannelComponent: 0
|
|
||||||
flipbookRows: 1
|
|
||||||
flipbookColumns: 1
|
|
||||||
maxTextureSizeSet: 0
|
|
||||||
compressionQualitySet: 0
|
|
||||||
textureFormatSet: 0
|
|
||||||
ignorePngGamma: 0
|
|
||||||
applyGammaDecoding: 0
|
|
||||||
swizzle: 50462976
|
|
||||||
cookieLightType: 0
|
|
||||||
platformSettings:
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: Standalone
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
spriteSheet:
|
|
||||||
serializedVersion: 2
|
|
||||||
sprites: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
Before Width: | Height: | Size: 38 KiB |
@@ -1,117 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e7d5261b0db4c3940bfe9b6a8c1e109b
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable: []
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
mipmaps:
|
|
||||||
mipMapMode: 0
|
|
||||||
enableMipMap: 0
|
|
||||||
sRGBTexture: 1
|
|
||||||
linearTexture: 0
|
|
||||||
fadeOut: 0
|
|
||||||
borderMipMap: 0
|
|
||||||
mipMapsPreserveCoverage: 0
|
|
||||||
alphaTestReferenceValue: 0.5
|
|
||||||
mipMapFadeDistanceStart: 1
|
|
||||||
mipMapFadeDistanceEnd: 3
|
|
||||||
bumpmap:
|
|
||||||
convertToNormalMap: 0
|
|
||||||
externalNormalMap: 0
|
|
||||||
heightScale: 0.25
|
|
||||||
normalMapFilter: 0
|
|
||||||
flipGreenChannel: 0
|
|
||||||
isReadable: 0
|
|
||||||
streamingMipmaps: 0
|
|
||||||
streamingMipmapsPriority: 0
|
|
||||||
vTOnly: 0
|
|
||||||
ignoreMipmapLimit: 0
|
|
||||||
grayScaleToAlpha: 0
|
|
||||||
generateCubemap: 6
|
|
||||||
cubemapConvolution: 0
|
|
||||||
seamlessCubemap: 0
|
|
||||||
textureFormat: 1
|
|
||||||
maxTextureSize: 2048
|
|
||||||
textureSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
filterMode: 1
|
|
||||||
aniso: 1
|
|
||||||
mipBias: 0
|
|
||||||
wrapU: 1
|
|
||||||
wrapV: 1
|
|
||||||
wrapW: 0
|
|
||||||
nPOTScale: 0
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 1
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 1
|
|
||||||
alignment: 0
|
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
|
||||||
spritePixelsToUnits: 100
|
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
|
||||||
alphaUsage: 1
|
|
||||||
alphaIsTransparency: 1
|
|
||||||
spriteTessellationDetail: -1
|
|
||||||
textureType: 8
|
|
||||||
textureShape: 1
|
|
||||||
singleChannelComponent: 0
|
|
||||||
flipbookRows: 1
|
|
||||||
flipbookColumns: 1
|
|
||||||
maxTextureSizeSet: 0
|
|
||||||
compressionQualitySet: 0
|
|
||||||
textureFormatSet: 0
|
|
||||||
ignorePngGamma: 0
|
|
||||||
applyGammaDecoding: 0
|
|
||||||
swizzle: 50462976
|
|
||||||
cookieLightType: 0
|
|
||||||
platformSettings:
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: Standalone
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
spriteSheet:
|
|
||||||
serializedVersion: 2
|
|
||||||
sprites: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 50a0b21c151e150428fd2803d6b95db0
|
guid: 2005d7546a411924586e723d043decdd
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 3a4035bdb812fee4f96cb1aa1b24c999
|
guid: ae0db95c5de76e04aba3aac1ea3ee4d7
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
BIN
Assets/KeyInsertMinigameAssets/GameObjects/Key.fbx
Normal file
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 0e125acbe6e192344a3f1c6d4a54f131
|
guid: 56e0065a74e418b4fb1e4e7d2236b645
|
||||||
ModelImporter:
|
ModelImporter:
|
||||||
serializedVersion: 24200
|
serializedVersion: 24200
|
||||||
internalIDToNameTable: []
|
internalIDToNameTable: []
|
||||||
BIN
Assets/KeyInsertMinigameAssets/GameObjects/KeyHole.fbx
Normal file
110
Assets/KeyInsertMinigameAssets/GameObjects/KeyHole.fbx.meta
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3cb302613fc70fa48b0d1ab0b0783be5
|
||||||
|
ModelImporter:
|
||||||
|
serializedVersion: 24200
|
||||||
|
internalIDToNameTable: []
|
||||||
|
externalObjects: {}
|
||||||
|
materials:
|
||||||
|
materialImportMode: 2
|
||||||
|
materialName: 0
|
||||||
|
materialSearch: 1
|
||||||
|
materialLocation: 1
|
||||||
|
animations:
|
||||||
|
legacyGenerateAnimations: 4
|
||||||
|
bakeSimulation: 0
|
||||||
|
resampleCurves: 1
|
||||||
|
optimizeGameObjects: 0
|
||||||
|
removeConstantScaleCurves: 0
|
||||||
|
motionNodeName:
|
||||||
|
animationImportErrors:
|
||||||
|
animationImportWarnings:
|
||||||
|
animationRetargetingWarnings:
|
||||||
|
animationDoRetargetingWarnings: 0
|
||||||
|
importAnimatedCustomProperties: 0
|
||||||
|
importConstraints: 0
|
||||||
|
animationCompression: 1
|
||||||
|
animationRotationError: 0.5
|
||||||
|
animationPositionError: 0.5
|
||||||
|
animationScaleError: 0.5
|
||||||
|
animationWrapMode: 0
|
||||||
|
extraExposedTransformPaths: []
|
||||||
|
extraUserProperties: []
|
||||||
|
clipAnimations: []
|
||||||
|
isReadable: 0
|
||||||
|
meshes:
|
||||||
|
lODScreenPercentages: []
|
||||||
|
globalScale: 1
|
||||||
|
meshCompression: 0
|
||||||
|
addColliders: 0
|
||||||
|
useSRGBMaterialColor: 1
|
||||||
|
sortHierarchyByName: 1
|
||||||
|
importPhysicalCameras: 1
|
||||||
|
importVisibility: 1
|
||||||
|
importBlendShapes: 1
|
||||||
|
importCameras: 1
|
||||||
|
importLights: 1
|
||||||
|
nodeNameCollisionStrategy: 1
|
||||||
|
fileIdsGeneration: 2
|
||||||
|
swapUVChannels: 0
|
||||||
|
generateSecondaryUV: 0
|
||||||
|
useFileUnits: 1
|
||||||
|
keepQuads: 0
|
||||||
|
weldVertices: 1
|
||||||
|
bakeAxisConversion: 0
|
||||||
|
preserveHierarchy: 0
|
||||||
|
skinWeightsMode: 0
|
||||||
|
maxBonesPerVertex: 4
|
||||||
|
minBoneWeight: 0.001
|
||||||
|
optimizeBones: 1
|
||||||
|
generateMeshLods: 0
|
||||||
|
meshLodGenerationFlags: 0
|
||||||
|
maximumMeshLod: -1
|
||||||
|
meshOptimizationFlags: -1
|
||||||
|
indexFormat: 0
|
||||||
|
secondaryUVAngleDistortion: 8
|
||||||
|
secondaryUVAreaDistortion: 15.000001
|
||||||
|
secondaryUVHardAngle: 88
|
||||||
|
secondaryUVMarginMethod: 1
|
||||||
|
secondaryUVMinLightmapResolution: 40
|
||||||
|
secondaryUVMinObjectScale: 1
|
||||||
|
secondaryUVPackMargin: 4
|
||||||
|
useFileScale: 1
|
||||||
|
strictVertexDataChecks: 0
|
||||||
|
tangentSpace:
|
||||||
|
normalSmoothAngle: 60
|
||||||
|
normalImportMode: 0
|
||||||
|
tangentImportMode: 3
|
||||||
|
normalCalculationMode: 4
|
||||||
|
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
|
||||||
|
blendShapeNormalImportMode: 1
|
||||||
|
normalSmoothingSource: 0
|
||||||
|
referencedClips: []
|
||||||
|
importAnimation: 1
|
||||||
|
humanDescription:
|
||||||
|
serializedVersion: 3
|
||||||
|
human: []
|
||||||
|
skeleton: []
|
||||||
|
armTwist: 0.5
|
||||||
|
foreArmTwist: 0.5
|
||||||
|
upperLegTwist: 0.5
|
||||||
|
legTwist: 0.5
|
||||||
|
armStretch: 0.05
|
||||||
|
legStretch: 0.05
|
||||||
|
feetSpacing: 0
|
||||||
|
globalScale: 1
|
||||||
|
rootMotionBoneName:
|
||||||
|
hasTranslationDoF: 0
|
||||||
|
hasExtraRoot: 0
|
||||||
|
skeletonHasParents: 1
|
||||||
|
lastHumanDescriptionAvatarSource: {instanceID: 0}
|
||||||
|
autoGenerateAvatarMappingIfUnspecified: 1
|
||||||
|
animationType: 2
|
||||||
|
humanoidOversampling: 1
|
||||||
|
avatarSetup: 0
|
||||||
|
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
|
||||||
|
importBlendShapeDeformPercent: 1
|
||||||
|
remapMaterialsIfMaterialImportModeIsNone: 0
|
||||||
|
additionalBone: 0
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 75857465ac3a7394db0ff208711dadc4
|
guid: 0e54d21010e6a1540ad7c8947bbbbac1
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
@@ -7,7 +7,7 @@ Material:
|
|||||||
m_CorrespondingSourceObject: {fileID: 0}
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
m_PrefabInstance: {fileID: 0}
|
m_PrefabInstance: {fileID: 0}
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_Name: Zeme_Textura
|
m_Name: Texture - Key
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||||
m_Parent: {fileID: 0}
|
m_Parent: {fileID: 0}
|
||||||
m_ModifiedSerializedProperties: 0
|
m_ModifiedSerializedProperties: 0
|
||||||
@@ -44,7 +44,7 @@ Material:
|
|||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MainTex:
|
- _MainTex:
|
||||||
m_Texture: {fileID: 2800000, guid: d1443c0777d81e24caecc3991b8bf225, type: 3}
|
m_Texture: {fileID: 2800000, guid: c275383f4ebe5cf4e9a189c70d5506f7, type: 3}
|
||||||
m_Scale: {x: 1, y: 1}
|
m_Scale: {x: 1, y: 1}
|
||||||
m_Offset: {x: 0, y: 0}
|
m_Offset: {x: 0, y: 0}
|
||||||
- _MetallicGlossMap:
|
- _MetallicGlossMap:
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 6744524496c8e1549882277283c132cc
|
guid: 7dfdaf4b8e44aea4f8977b529dfbc5a4
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 2100000
|
mainObjectFileID: 2100000
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 131d9de257c8edc49991d792c6e702f6
|
guid: 90fff9b6ab80fd944a66bc5413a9a0aa
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
BIN
Assets/KeyInsertMinigameAssets/SFX/LockClickSFX.mp3
Normal file
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: fa27202025a24b6418e644af57608959
|
guid: 315f8d4589bf64343a7d4dabcba22331
|
||||||
AudioImporter:
|
AudioImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 8
|
serializedVersion: 8
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: ccd0fd31a63984d46b31bf364f5bf0ce
|
guid: 018181274a5e0dd4e94629d9bf4fc143
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
47
Assets/KeyInsertMinigameAssets/Scripts/InsertKeysManager.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class InserKeysMinigameManager : MonoBehaviour, ITask
|
||||||
|
{
|
||||||
|
public int correctIndex;
|
||||||
|
public bool isInputLocked = false;
|
||||||
|
|
||||||
|
public string TaskID { get; set; }
|
||||||
|
|
||||||
|
public TaskType TaskType { get; set; }
|
||||||
|
|
||||||
|
public string TaskName { get; set; }
|
||||||
|
|
||||||
|
public (double, double) TaskLocation { get; set; }
|
||||||
|
public bool IsCompleted { get; private set; }
|
||||||
|
private Action<ITask> _onCompleted;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
correctIndex = UnityEngine.Random.Range(0, 9);
|
||||||
|
Debug.Log("The correct keyhole is: " + correctIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CheckKeyHole(int index)
|
||||||
|
{
|
||||||
|
return index == correctIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(System.Action<ITask> onCompleted)
|
||||||
|
{
|
||||||
|
IsCompleted = false;
|
||||||
|
_onCompleted = onCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExitTask(System.Action<ITask> onExit)
|
||||||
|
{
|
||||||
|
onExit.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Complete()
|
||||||
|
{
|
||||||
|
IsCompleted = true;
|
||||||
|
_onCompleted?.Invoke(this);
|
||||||
|
ExitTask(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3cd9b947f2376eb4da79d8910a5b588e
|
||||||
89
Assets/KeyInsertMinigameAssets/Scripts/Key.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using NUnit.Framework.Constraints;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class Key : MonoBehaviour
|
||||||
|
{
|
||||||
|
public bool isSelected = false;
|
||||||
|
public Vector3 insertedRotation;
|
||||||
|
public Vector3 insertedOffset;
|
||||||
|
public Vector3 wiggleOffset = new Vector3(0, 0, 10);
|
||||||
|
public Vector3 winRotation = new Vector3(0, 0, 180);
|
||||||
|
private Vector3 startPosition;
|
||||||
|
private Vector3 startRotation;
|
||||||
|
public float WinRotDuration = 1.0f;
|
||||||
|
public float lockoutDuration = 3;
|
||||||
|
|
||||||
|
public GameObject winText;
|
||||||
|
public AudioSource lockSound;
|
||||||
|
public InserKeysMinigameManager manager;
|
||||||
|
private Light keyLight;
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
startPosition = transform.position;
|
||||||
|
startRotation = transform.eulerAngles;
|
||||||
|
keyLight = GetComponentInChildren<Light>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnMouseDown()
|
||||||
|
{
|
||||||
|
if (manager.isInputLocked) return;
|
||||||
|
isSelected = true;
|
||||||
|
keyLight.enabled = true;
|
||||||
|
Debug.Log("Key tapped - isSelected is now: " + isSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator HandleWrongAttempt()
|
||||||
|
{
|
||||||
|
manager.isInputLocked = true;
|
||||||
|
|
||||||
|
Vector3 baseRot = transform.eulerAngles;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
transform.eulerAngles = baseRot + wiggleOffset;
|
||||||
|
yield return new WaitForSeconds(0.1f);
|
||||||
|
transform.eulerAngles = baseRot - wiggleOffset;
|
||||||
|
yield return new WaitForSeconds(0.1f);
|
||||||
|
}
|
||||||
|
transform.eulerAngles = baseRot;
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(lockoutDuration - 0.48f);
|
||||||
|
|
||||||
|
transform.position = startPosition;
|
||||||
|
transform.eulerAngles = startRotation;
|
||||||
|
isSelected = false;
|
||||||
|
keyLight.enabled = false;
|
||||||
|
manager.isInputLocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator HandleWin()
|
||||||
|
{
|
||||||
|
manager.isInputLocked = true;
|
||||||
|
if (lockSound != null) lockSound.Play();
|
||||||
|
|
||||||
|
Vector3 startRot = transform.eulerAngles;
|
||||||
|
Vector3 endRot = startRot + winRotation;
|
||||||
|
float elapsed = 0f;
|
||||||
|
|
||||||
|
while (elapsed < WinRotDuration)
|
||||||
|
{
|
||||||
|
elapsed += Time.deltaTime;
|
||||||
|
float t = elapsed / WinRotDuration;
|
||||||
|
transform.eulerAngles = Vector3.Lerp(startRot, endRot, t);
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
transform.eulerAngles = endRot;
|
||||||
|
|
||||||
|
Debug.Log("You win");
|
||||||
|
if (winText != null) winText.SetActive(true);
|
||||||
|
manager.Complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
2
Assets/KeyInsertMinigameAssets/Scripts/Key.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4aae5484fa5ce7d42a5ab54ccd82bc19
|
||||||
45
Assets/KeyInsertMinigameAssets/Scripts/KeyHole.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class KeyHole : MonoBehaviour
|
||||||
|
{
|
||||||
|
public int index;
|
||||||
|
public Key key;
|
||||||
|
public InserKeysMinigameManager manager;
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnMouseDown()
|
||||||
|
{
|
||||||
|
if (manager.isInputLocked) return;
|
||||||
|
|
||||||
|
Debug.Log("Keyhole " + index + " was tapped.");
|
||||||
|
|
||||||
|
if (key.isSelected)
|
||||||
|
{
|
||||||
|
key.transform.position = transform.position + key.insertedOffset;
|
||||||
|
key.transform.eulerAngles = key.insertedRotation;
|
||||||
|
Debug.Log("Key teleported to keyhole " + index);
|
||||||
|
|
||||||
|
if (manager.CheckKeyHole(index))
|
||||||
|
{
|
||||||
|
key.StartCoroutine(key.HandleWin());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("Wrong");
|
||||||
|
key.StartCoroutine(key.HandleWrongAttempt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
2
Assets/KeyInsertMinigameAssets/Scripts/KeyHole.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b0bafb5095ab5f74bac503b56548b6c9
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 4d6a7ccfa008f3143a55bb782ba75e2b
|
guid: afd0db8912502274ea36978b07199362
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
|
After Width: | Height: | Size: 5.4 MiB |
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 417078fae7f3c4f4e8e5e4b178f58065
|
guid: 68ec230eb85a28348add569042bd9d1d
|
||||||
TextureImporter:
|
TextureImporter:
|
||||||
internalIDToNameTable: []
|
internalIDToNameTable: []
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
BIN
Assets/KeyInsertMinigameAssets/Textures/Texture - Key.png
Normal file
|
After Width: | Height: | Size: 213 KiB |
@@ -1,12 +1,12 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 6dfbe74d5c339ee42b604c40d9fd06fb
|
guid: c275383f4ebe5cf4e9a189c70d5506f7
|
||||||
TextureImporter:
|
TextureImporter:
|
||||||
internalIDToNameTable: []
|
internalIDToNameTable: []
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 13
|
serializedVersion: 13
|
||||||
mipmaps:
|
mipmaps:
|
||||||
mipMapMode: 0
|
mipMapMode: 0
|
||||||
enableMipMap: 0
|
enableMipMap: 1
|
||||||
sRGBTexture: 1
|
sRGBTexture: 1
|
||||||
linearTexture: 0
|
linearTexture: 0
|
||||||
fadeOut: 0
|
fadeOut: 0
|
||||||
@@ -37,13 +37,13 @@ TextureImporter:
|
|||||||
filterMode: 1
|
filterMode: 1
|
||||||
aniso: 1
|
aniso: 1
|
||||||
mipBias: 0
|
mipBias: 0
|
||||||
wrapU: 1
|
wrapU: 0
|
||||||
wrapV: 1
|
wrapV: 0
|
||||||
wrapW: 0
|
wrapW: 0
|
||||||
nPOTScale: 0
|
nPOTScale: 1
|
||||||
lightmap: 0
|
lightmap: 0
|
||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 1
|
spriteMode: 0
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 1
|
||||||
alignment: 0
|
alignment: 0
|
||||||
@@ -52,9 +52,9 @@ TextureImporter:
|
|||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
alphaUsage: 1
|
alphaUsage: 1
|
||||||
alphaIsTransparency: 1
|
alphaIsTransparency: 0
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
textureType: 8
|
textureType: 0
|
||||||
textureShape: 1
|
textureShape: 1
|
||||||
singleChannelComponent: 0
|
singleChannelComponent: 0
|
||||||
flipbookRows: 1
|
flipbookRows: 1
|
||||||
@@ -100,7 +100,7 @@ TextureImporter:
|
|||||||
customData:
|
customData:
|
||||||
physicsShape: []
|
physicsShape: []
|
||||||
bones: []
|
bones: []
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
spriteID:
|
||||||
internalID: 0
|
internalID: 0
|
||||||
vertices: []
|
vertices: []
|
||||||
indices:
|
indices:
|
||||||
BIN
Assets/KeyInsertMinigameAssets/Textures/Texture - KeyHole.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
@@ -1,12 +1,12 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 49ba03ac2a3e61443a363a1d73febbe9
|
guid: ea70ab3e736c5e74391b290e546b2928
|
||||||
TextureImporter:
|
TextureImporter:
|
||||||
internalIDToNameTable: []
|
internalIDToNameTable: []
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 13
|
serializedVersion: 13
|
||||||
mipmaps:
|
mipmaps:
|
||||||
mipMapMode: 0
|
mipMapMode: 0
|
||||||
enableMipMap: 0
|
enableMipMap: 1
|
||||||
sRGBTexture: 1
|
sRGBTexture: 1
|
||||||
linearTexture: 0
|
linearTexture: 0
|
||||||
fadeOut: 0
|
fadeOut: 0
|
||||||
@@ -37,13 +37,13 @@ TextureImporter:
|
|||||||
filterMode: 1
|
filterMode: 1
|
||||||
aniso: 1
|
aniso: 1
|
||||||
mipBias: 0
|
mipBias: 0
|
||||||
wrapU: 1
|
wrapU: 0
|
||||||
wrapV: 1
|
wrapV: 0
|
||||||
wrapW: 0
|
wrapW: 0
|
||||||
nPOTScale: 0
|
nPOTScale: 1
|
||||||
lightmap: 0
|
lightmap: 0
|
||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 1
|
spriteMode: 0
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 1
|
||||||
alignment: 0
|
alignment: 0
|
||||||
@@ -52,9 +52,9 @@ TextureImporter:
|
|||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 1
|
||||||
alphaUsage: 1
|
alphaUsage: 1
|
||||||
alphaIsTransparency: 1
|
alphaIsTransparency: 0
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
textureType: 8
|
textureType: 0
|
||||||
textureShape: 1
|
textureShape: 1
|
||||||
singleChannelComponent: 0
|
singleChannelComponent: 0
|
||||||
flipbookRows: 1
|
flipbookRows: 1
|
||||||
@@ -100,7 +100,7 @@ TextureImporter:
|
|||||||
customData:
|
customData:
|
||||||
physicsShape: []
|
physicsShape: []
|
||||||
bones: []
|
bones: []
|
||||||
spriteID: 5e97eb03825dee720800000000000000
|
spriteID:
|
||||||
internalID: 0
|
internalID: 0
|
||||||
vertices: []
|
vertices: []
|
||||||
indices:
|
indices:
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 1bc3c07f160332843b2a60af3513f7f6
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 299795d658d037841b1552f783d462c3
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
//clankr
|
|
||||||
public class RotaceZeme : MonoBehaviour
|
|
||||||
{
|
|
||||||
public float rychlost = 20f;
|
|
||||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update is called once per frame
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
transform.Rotate(Vector3.up, rychlost * Time.deltaTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2167308ece2e6664fa472e3dff700350
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: Zeme_Material
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 2800000, guid: d1443c0777d81e24caecc3991b8bf225, type: 3}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.414
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 4cf6d1d65bc4af24fa762f6801fcc7c4
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
Before Width: | Height: | Size: 404 KiB |
@@ -1,143 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: d1443c0777d81e24caecc3991b8bf225
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable: []
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
mipmaps:
|
|
||||||
mipMapMode: 0
|
|
||||||
enableMipMap: 1
|
|
||||||
sRGBTexture: 1
|
|
||||||
linearTexture: 0
|
|
||||||
fadeOut: 0
|
|
||||||
borderMipMap: 0
|
|
||||||
mipMapsPreserveCoverage: 0
|
|
||||||
alphaTestReferenceValue: 0.5
|
|
||||||
mipMapFadeDistanceStart: 1
|
|
||||||
mipMapFadeDistanceEnd: 3
|
|
||||||
bumpmap:
|
|
||||||
convertToNormalMap: 0
|
|
||||||
externalNormalMap: 0
|
|
||||||
heightScale: 0.25
|
|
||||||
normalMapFilter: 0
|
|
||||||
flipGreenChannel: 0
|
|
||||||
isReadable: 0
|
|
||||||
streamingMipmaps: 0
|
|
||||||
streamingMipmapsPriority: 0
|
|
||||||
vTOnly: 0
|
|
||||||
ignoreMipmapLimit: 0
|
|
||||||
grayScaleToAlpha: 0
|
|
||||||
generateCubemap: 6
|
|
||||||
cubemapConvolution: 0
|
|
||||||
seamlessCubemap: 0
|
|
||||||
textureFormat: 1
|
|
||||||
maxTextureSize: 2048
|
|
||||||
textureSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
filterMode: 1
|
|
||||||
aniso: 1
|
|
||||||
mipBias: 0
|
|
||||||
wrapU: 0
|
|
||||||
wrapV: 0
|
|
||||||
wrapW: 0
|
|
||||||
nPOTScale: 1
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 0
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 1
|
|
||||||
alignment: 0
|
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
|
||||||
spritePixelsToUnits: 100
|
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
|
||||||
alphaUsage: 1
|
|
||||||
alphaIsTransparency: 0
|
|
||||||
spriteTessellationDetail: -1
|
|
||||||
textureType: 0
|
|
||||||
textureShape: 1
|
|
||||||
singleChannelComponent: 0
|
|
||||||
flipbookRows: 1
|
|
||||||
flipbookColumns: 1
|
|
||||||
maxTextureSizeSet: 0
|
|
||||||
compressionQualitySet: 0
|
|
||||||
textureFormatSet: 0
|
|
||||||
ignorePngGamma: 0
|
|
||||||
applyGammaDecoding: 0
|
|
||||||
swizzle: 50462976
|
|
||||||
cookieLightType: 0
|
|
||||||
platformSettings:
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 2
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: Standalone
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: Android
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: iOS
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
spriteSheet:
|
|
||||||
serializedVersion: 2
|
|
||||||
sprites: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID:
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!84 &8400000
|
|
||||||
RenderTexture:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: Zeme_vystup
|
|
||||||
m_ImageContentsHash:
|
|
||||||
serializedVersion: 2
|
|
||||||
Hash: 00000000000000000000000000000000
|
|
||||||
m_IsAlphaChannelOptional: 0
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Width: 1048
|
|
||||||
m_Height: 1048
|
|
||||||
m_AntiAliasing: 1
|
|
||||||
m_MipCount: -1
|
|
||||||
m_DepthStencilFormat: 94
|
|
||||||
m_ColorFormat: 8
|
|
||||||
m_MipMap: 0
|
|
||||||
m_GenerateMips: 1
|
|
||||||
m_SRGB: 0
|
|
||||||
m_UseDynamicScale: 0
|
|
||||||
m_UseDynamicScaleExplicit: 0
|
|
||||||
m_BindMS: 0
|
|
||||||
m_EnableCompatibleFormat: 1
|
|
||||||
m_EnableRandomWrite: 0
|
|
||||||
m_TextureSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_FilterMode: 1
|
|
||||||
m_Aniso: 0
|
|
||||||
m_MipBias: 0
|
|
||||||
m_WrapU: 1
|
|
||||||
m_WrapV: 1
|
|
||||||
m_WrapW: 1
|
|
||||||
m_Dimension: 2
|
|
||||||
m_VolumeDepth: 1
|
|
||||||
m_ShadowSamplingMode: 2
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 4d595312cdcdd094cbe411227603ceea
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 8400000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: textik
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.583
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: e00f6447ca0dc7646b73cb387d282a47
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 2230bf768ecb84610af77bea6cdd7074
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: HDR_multi_nebulae_1
|
|
||||||
m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _Tex:
|
|
||||||
m_Texture: {fileID: 8900000, guid: bbe6dc8ab03108a488246bb64d4078ff, type: 3}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _Exposure: 1
|
|
||||||
- _Rotation: 0
|
|
||||||
m_Colors:
|
|
||||||
- _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: b8ea26def9472484b87d08513faa2756
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: New Material
|
|
||||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _BumpMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailAlbedoMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailMask:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _DetailNormalMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _EmissionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MainTex:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _MetallicGlossMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _OcclusionMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
- _ParallaxMap:
|
|
||||||
m_Texture: {fileID: 0}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _BumpScale: 1
|
|
||||||
- _Cutoff: 0.5
|
|
||||||
- _DetailNormalMapScale: 1
|
|
||||||
- _DstBlend: 0
|
|
||||||
- _GlossMapScale: 1
|
|
||||||
- _Glossiness: 0.5
|
|
||||||
- _GlossyReflections: 1
|
|
||||||
- _Metallic: 0
|
|
||||||
- _Mode: 0
|
|
||||||
- _OcclusionStrength: 1
|
|
||||||
- _Parallax: 0.02
|
|
||||||
- _SmoothnessTextureChannel: 0
|
|
||||||
- _SpecularHighlights: 1
|
|
||||||
- _SrcBlend: 1
|
|
||||||
- _UVSec: 0
|
|
||||||
- _ZWrite: 1
|
|
||||||
m_Colors:
|
|
||||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
|
||||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
34
Assets/Readme.asset
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: fcf7219bab7fe46a1ad266029b2fee19, type: 3}
|
||||||
|
m_Name: Readme
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
icon: {fileID: 2800000, guid: 727a75301c3d24613a3ebcec4a24c2c8, type: 3}
|
||||||
|
title: URP Empty Template
|
||||||
|
sections:
|
||||||
|
- heading: Welcome to the Universal Render Pipeline
|
||||||
|
text: This template includes the settings and assets you need to start creating with the Universal Render Pipeline.
|
||||||
|
linkText:
|
||||||
|
url:
|
||||||
|
- heading: URP Documentation
|
||||||
|
text:
|
||||||
|
linkText: Read more about URP
|
||||||
|
url: https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@latest
|
||||||
|
- heading: Forums
|
||||||
|
text:
|
||||||
|
linkText: Get answers and support
|
||||||
|
url: https://forum.unity.com/forums/universal-render-pipeline.383/
|
||||||
|
- heading: Report bugs
|
||||||
|
text:
|
||||||
|
linkText: Submit a report
|
||||||
|
url: https://unity3d.com/unity/qa/bug-reporting
|
||||||
|
loadedLayout: 1
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 7142a58f80866aba3ae4ffeb79d5f67c
|
guid: 2651bd22cf5764e4eb358f11641edca2
|
||||||
NativeFormatImporter:
|
NativeFormatImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
mainObjectFileID: 0
|
mainObjectFileID: 0
|
||||||
@@ -1,316 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!29 &1
|
|
||||||
OcclusionCullingSettings:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
serializedVersion: 2
|
|
||||||
m_OcclusionBakeSettings:
|
|
||||||
smallestOccluder: 5
|
|
||||||
smallestHole: 0.25
|
|
||||||
backfaceThreshold: 100
|
|
||||||
m_SceneGUID: 00000000000000000000000000000000
|
|
||||||
m_OcclusionCullingData: {fileID: 0}
|
|
||||||
--- !u!104 &2
|
|
||||||
RenderSettings:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
serializedVersion: 10
|
|
||||||
m_Fog: 0
|
|
||||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
|
||||||
m_FogMode: 3
|
|
||||||
m_FogDensity: 0.01
|
|
||||||
m_LinearFogStart: 0
|
|
||||||
m_LinearFogEnd: 300
|
|
||||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
|
||||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
|
||||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
|
||||||
m_AmbientIntensity: 1
|
|
||||||
m_AmbientMode: 0
|
|
||||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
|
||||||
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_HaloStrength: 0.5
|
|
||||||
m_FlareStrength: 1
|
|
||||||
m_FlareFadeSpeed: 3
|
|
||||||
m_HaloTexture: {fileID: 0}
|
|
||||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
|
||||||
m_DefaultReflectionMode: 0
|
|
||||||
m_DefaultReflectionResolution: 128
|
|
||||||
m_ReflectionBounces: 1
|
|
||||||
m_ReflectionIntensity: 1
|
|
||||||
m_CustomReflection: {fileID: 0}
|
|
||||||
m_Sun: {fileID: 0}
|
|
||||||
m_UseRadianceAmbientProbe: 0
|
|
||||||
--- !u!157 &3
|
|
||||||
LightmapSettings:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
serializedVersion: 13
|
|
||||||
m_BakeOnSceneLoad: 0
|
|
||||||
m_GISettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_BounceScale: 1
|
|
||||||
m_IndirectOutputScale: 1
|
|
||||||
m_AlbedoBoost: 1
|
|
||||||
m_EnvironmentLightingMode: 0
|
|
||||||
m_EnableBakedLightmaps: 1
|
|
||||||
m_EnableRealtimeLightmaps: 0
|
|
||||||
m_LightmapEditorSettings:
|
|
||||||
serializedVersion: 12
|
|
||||||
m_Resolution: 2
|
|
||||||
m_BakeResolution: 40
|
|
||||||
m_AtlasSize: 1024
|
|
||||||
m_AO: 0
|
|
||||||
m_AOMaxDistance: 1
|
|
||||||
m_CompAOExponent: 1
|
|
||||||
m_CompAOExponentDirect: 0
|
|
||||||
m_ExtractAmbientOcclusion: 0
|
|
||||||
m_Padding: 2
|
|
||||||
m_LightmapParameters: {fileID: 0}
|
|
||||||
m_LightmapsBakeMode: 1
|
|
||||||
m_TextureCompression: 1
|
|
||||||
m_ReflectionCompression: 2
|
|
||||||
m_MixedBakeMode: 2
|
|
||||||
m_BakeBackend: 1
|
|
||||||
m_PVRSampling: 1
|
|
||||||
m_PVRDirectSampleCount: 32
|
|
||||||
m_PVRSampleCount: 512
|
|
||||||
m_PVRBounces: 2
|
|
||||||
m_PVREnvironmentSampleCount: 256
|
|
||||||
m_PVREnvironmentReferencePointCount: 2048
|
|
||||||
m_PVRFilteringMode: 1
|
|
||||||
m_PVRDenoiserTypeDirect: 1
|
|
||||||
m_PVRDenoiserTypeIndirect: 1
|
|
||||||
m_PVRDenoiserTypeAO: 1
|
|
||||||
m_PVRFilterTypeDirect: 0
|
|
||||||
m_PVRFilterTypeIndirect: 0
|
|
||||||
m_PVRFilterTypeAO: 0
|
|
||||||
m_PVREnvironmentMIS: 1
|
|
||||||
m_PVRCulling: 1
|
|
||||||
m_PVRFilteringGaussRadiusDirect: 1
|
|
||||||
m_PVRFilteringGaussRadiusIndirect: 1
|
|
||||||
m_PVRFilteringGaussRadiusAO: 1
|
|
||||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
|
||||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
|
||||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
|
||||||
m_ExportTrainingData: 0
|
|
||||||
m_TrainingDataDestination: TrainingData
|
|
||||||
m_LightProbeSampleCountMultiplier: 4
|
|
||||||
m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_LightingSettings: {fileID: 0}
|
|
||||||
--- !u!196 &4
|
|
||||||
NavMeshSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_BuildSettings:
|
|
||||||
serializedVersion: 3
|
|
||||||
agentTypeID: 0
|
|
||||||
agentRadius: 0.5
|
|
||||||
agentHeight: 2
|
|
||||||
agentSlope: 45
|
|
||||||
agentClimb: 0.4
|
|
||||||
ledgeDropHeight: 0
|
|
||||||
maxJumpAcrossDistance: 0
|
|
||||||
minRegionArea: 2
|
|
||||||
manualCellSize: 0
|
|
||||||
cellSize: 0.16666667
|
|
||||||
manualTileSize: 0
|
|
||||||
tileSize: 256
|
|
||||||
buildHeightMesh: 0
|
|
||||||
maxJobWorkers: 0
|
|
||||||
preserveTilesOutsideBounds: 0
|
|
||||||
debug:
|
|
||||||
m_Flags: 0
|
|
||||||
m_NavMeshData: {fileID: 0}
|
|
||||||
--- !u!1 &303202696
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 303202698}
|
|
||||||
- component: {fileID: 303202697}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: Directional Light
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!108 &303202697
|
|
||||||
Light:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 303202696}
|
|
||||||
m_Enabled: 1
|
|
||||||
serializedVersion: 11
|
|
||||||
m_Type: 1
|
|
||||||
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
|
|
||||||
m_Intensity: 1
|
|
||||||
m_Range: 10
|
|
||||||
m_SpotAngle: 30
|
|
||||||
m_InnerSpotAngle: 21.80208
|
|
||||||
m_CookieSize: 10
|
|
||||||
m_Shadows:
|
|
||||||
m_Type: 2
|
|
||||||
m_Resolution: -1
|
|
||||||
m_CustomResolution: -1
|
|
||||||
m_Strength: 1
|
|
||||||
m_Bias: 0.05
|
|
||||||
m_NormalBias: 0.4
|
|
||||||
m_NearPlane: 0.2
|
|
||||||
m_CullingMatrixOverride:
|
|
||||||
e00: 1
|
|
||||||
e01: 0
|
|
||||||
e02: 0
|
|
||||||
e03: 0
|
|
||||||
e10: 0
|
|
||||||
e11: 1
|
|
||||||
e12: 0
|
|
||||||
e13: 0
|
|
||||||
e20: 0
|
|
||||||
e21: 0
|
|
||||||
e22: 1
|
|
||||||
e23: 0
|
|
||||||
e30: 0
|
|
||||||
e31: 0
|
|
||||||
e32: 0
|
|
||||||
e33: 1
|
|
||||||
m_UseCullingMatrixOverride: 0
|
|
||||||
m_Cookie: {fileID: 0}
|
|
||||||
m_DrawHalo: 0
|
|
||||||
m_Flare: {fileID: 0}
|
|
||||||
m_RenderMode: 0
|
|
||||||
m_CullingMask:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 4294967295
|
|
||||||
m_RenderingLayerMask: 1
|
|
||||||
m_Lightmapping: 4
|
|
||||||
m_LightShadowCasterMode: 0
|
|
||||||
m_AreaSize: {x: 1, y: 1}
|
|
||||||
m_BounceIntensity: 1
|
|
||||||
m_ColorTemperature: 6570
|
|
||||||
m_UseColorTemperature: 0
|
|
||||||
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
m_UseBoundingSphereOverride: 0
|
|
||||||
m_UseViewFrustumForShadowCasterCull: 1
|
|
||||||
m_ForceVisible: 0
|
|
||||||
m_ShadowRadius: 0
|
|
||||||
m_ShadowAngle: 0
|
|
||||||
m_LightUnit: 1
|
|
||||||
m_LuxAtDistance: 1
|
|
||||||
m_EnableSpotReflector: 1
|
|
||||||
--- !u!4 &303202698
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 303202696}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
|
||||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
|
||||||
--- !u!1 &878892785
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 878892788}
|
|
||||||
- component: {fileID: 878892787}
|
|
||||||
- component: {fileID: 878892786}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: Main Camera
|
|
||||||
m_TagString: MainCamera
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!81 &878892786
|
|
||||||
AudioListener:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 878892785}
|
|
||||||
m_Enabled: 1
|
|
||||||
--- !u!20 &878892787
|
|
||||||
Camera:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 878892785}
|
|
||||||
m_Enabled: 1
|
|
||||||
serializedVersion: 2
|
|
||||||
m_ClearFlags: 1
|
|
||||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
|
||||||
m_projectionMatrixMode: 1
|
|
||||||
m_GateFitMode: 2
|
|
||||||
m_FOVAxisMode: 0
|
|
||||||
m_Iso: 200
|
|
||||||
m_ShutterSpeed: 0.005
|
|
||||||
m_Aperture: 16
|
|
||||||
m_FocusDistance: 10
|
|
||||||
m_FocalLength: 50
|
|
||||||
m_BladeCount: 5
|
|
||||||
m_Curvature: {x: 2, y: 11}
|
|
||||||
m_BarrelClipping: 0.25
|
|
||||||
m_Anamorphism: 0
|
|
||||||
m_SensorSize: {x: 36, y: 24}
|
|
||||||
m_LensShift: {x: 0, y: 0}
|
|
||||||
m_NormalizedViewPortRect:
|
|
||||||
serializedVersion: 2
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
width: 1
|
|
||||||
height: 1
|
|
||||||
near clip plane: 0.3
|
|
||||||
far clip plane: 1000
|
|
||||||
field of view: 60
|
|
||||||
orthographic: 0
|
|
||||||
orthographic size: 5
|
|
||||||
m_Depth: -1
|
|
||||||
m_CullingMask:
|
|
||||||
serializedVersion: 2
|
|
||||||
m_Bits: 4294967295
|
|
||||||
m_RenderingPath: -1
|
|
||||||
m_TargetTexture: {fileID: 0}
|
|
||||||
m_TargetDisplay: 0
|
|
||||||
m_TargetEye: 3
|
|
||||||
m_HDR: 1
|
|
||||||
m_AllowMSAA: 1
|
|
||||||
m_AllowDynamicResolution: 0
|
|
||||||
m_ForceIntoRT: 0
|
|
||||||
m_OcclusionCulling: 1
|
|
||||||
m_StereoConvergence: 10
|
|
||||||
m_StereoSeparation: 0.022
|
|
||||||
--- !u!4 &878892788
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 878892785}
|
|
||||||
serializedVersion: 2
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_ConstrainProportionsScale: 0
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!1660057539 &9223372036854775807
|
|
||||||
SceneRoots:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_Roots:
|
|
||||||
- {fileID: 878892788}
|
|
||||||
- {fileID: 303202698}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: a8455b5835249e44d931c30790f60381
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0d2bf6fbc15c94c4db51c326dbaa84ee
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 42774ddf02ffd1747898d12625c667b0
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3347745980e97824f9dda5b6043b57e7
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6b025445e5a6de74780d752e5354a0a9
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: bbe6dc8ab03108a488246bb64d4078ff
|
|
||||||
TextureImporter:
|
|
||||||
internalIDToNameTable: []
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 13
|
|
||||||
mipmaps:
|
|
||||||
mipMapMode: 0
|
|
||||||
enableMipMap: 1
|
|
||||||
sRGBTexture: 1
|
|
||||||
linearTexture: 0
|
|
||||||
fadeOut: 0
|
|
||||||
borderMipMap: 0
|
|
||||||
mipMapsPreserveCoverage: 0
|
|
||||||
alphaTestReferenceValue: 0.5
|
|
||||||
mipMapFadeDistanceStart: 1
|
|
||||||
mipMapFadeDistanceEnd: 3
|
|
||||||
bumpmap:
|
|
||||||
convertToNormalMap: 0
|
|
||||||
externalNormalMap: 0
|
|
||||||
heightScale: 0.25
|
|
||||||
normalMapFilter: 0
|
|
||||||
flipGreenChannel: 0
|
|
||||||
isReadable: 0
|
|
||||||
streamingMipmaps: 0
|
|
||||||
streamingMipmapsPriority: 0
|
|
||||||
vTOnly: 0
|
|
||||||
ignoreMipmapLimit: 0
|
|
||||||
grayScaleToAlpha: 0
|
|
||||||
generateCubemap: 6
|
|
||||||
cubemapConvolution: 0
|
|
||||||
seamlessCubemap: 0
|
|
||||||
textureFormat: 1
|
|
||||||
maxTextureSize: 2048
|
|
||||||
textureSettings:
|
|
||||||
serializedVersion: 2
|
|
||||||
filterMode: 1
|
|
||||||
aniso: 1
|
|
||||||
mipBias: 0
|
|
||||||
wrapU: 0
|
|
||||||
wrapV: 0
|
|
||||||
wrapW: 0
|
|
||||||
nPOTScale: 1
|
|
||||||
lightmap: 0
|
|
||||||
compressionQuality: 50
|
|
||||||
spriteMode: 0
|
|
||||||
spriteExtrude: 1
|
|
||||||
spriteMeshType: 1
|
|
||||||
alignment: 0
|
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
|
||||||
spritePixelsToUnits: 100
|
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
|
||||||
alphaUsage: 1
|
|
||||||
alphaIsTransparency: 0
|
|
||||||
spriteTessellationDetail: -1
|
|
||||||
textureType: 0
|
|
||||||
textureShape: 2
|
|
||||||
singleChannelComponent: 0
|
|
||||||
flipbookRows: 1
|
|
||||||
flipbookColumns: 1
|
|
||||||
maxTextureSizeSet: 0
|
|
||||||
compressionQualitySet: 0
|
|
||||||
textureFormatSet: 0
|
|
||||||
ignorePngGamma: 0
|
|
||||||
applyGammaDecoding: 0
|
|
||||||
swizzle: 50462976
|
|
||||||
cookieLightType: 0
|
|
||||||
platformSettings:
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: DefaultTexturePlatform
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: Standalone
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: Android
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
- serializedVersion: 4
|
|
||||||
buildTarget: iOS
|
|
||||||
maxTextureSize: 2048
|
|
||||||
resizeAlgorithm: 0
|
|
||||||
textureFormat: -1
|
|
||||||
textureCompression: 1
|
|
||||||
compressionQuality: 50
|
|
||||||
crunchedCompression: 0
|
|
||||||
allowsAlphaSplitting: 0
|
|
||||||
overridden: 0
|
|
||||||
ignorePlatformSupport: 0
|
|
||||||
androidETC2FallbackOverride: 0
|
|
||||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
|
||||||
spriteSheet:
|
|
||||||
serializedVersion: 2
|
|
||||||
sprites: []
|
|
||||||
outline: []
|
|
||||||
customData:
|
|
||||||
physicsShape: []
|
|
||||||
bones: []
|
|
||||||
spriteID:
|
|
||||||
internalID: 0
|
|
||||||
vertices: []
|
|
||||||
indices:
|
|
||||||
edges: []
|
|
||||||
weights: []
|
|
||||||
secondaryTextures: []
|
|
||||||
spriteCustomMetadata:
|
|
||||||
entries: []
|
|
||||||
nameFileIdTable: {}
|
|
||||||
mipmapLimitGroupName:
|
|
||||||
pSDRemoveMatte: 0
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 0cff73c6845b7cb40877239c2a7e25fc
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!21 &2100000
|
|
||||||
Material:
|
|
||||||
serializedVersion: 8
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: HDR_multi_nebulae_1
|
|
||||||
m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0}
|
|
||||||
m_Parent: {fileID: 0}
|
|
||||||
m_ModifiedSerializedProperties: 0
|
|
||||||
m_ValidKeywords: []
|
|
||||||
m_InvalidKeywords: []
|
|
||||||
m_LightmapFlags: 4
|
|
||||||
m_EnableInstancingVariants: 0
|
|
||||||
m_DoubleSidedGI: 0
|
|
||||||
m_CustomRenderQueue: -1
|
|
||||||
stringTagMap: {}
|
|
||||||
disabledShaderPasses: []
|
|
||||||
m_LockedProperties:
|
|
||||||
m_SavedProperties:
|
|
||||||
serializedVersion: 3
|
|
||||||
m_TexEnvs:
|
|
||||||
- _Tex:
|
|
||||||
m_Texture: {fileID: 8900000, guid: bbe6dc8ab03108a488246bb64d4078ff, type: 3}
|
|
||||||
m_Scale: {x: 1, y: 1}
|
|
||||||
m_Offset: {x: 0, y: 0}
|
|
||||||
m_Ints: []
|
|
||||||
m_Floats:
|
|
||||||
- _Exposure: 1
|
|
||||||
- _Rotation: 0
|
|
||||||
m_Colors:
|
|
||||||
- _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
|
||||||
m_BuildTextureStacks: []
|
|
||||||
m_AllowLocking: 1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 628af2744593aaf4fbadc7aec37b8b41
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 2100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||