Implement the playable first counting puzzle with committed input, persistence and Korean voice
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MagnetismHeroes.Core
|
||||
{
|
||||
public enum SessionScreen { Home, StageSelection, Puzzle, FreePlay }
|
||||
|
||||
// Owns committed game state. A gesture preview never reaches this class.
|
||||
public sealed class GameSession
|
||||
{
|
||||
private readonly StageDefinition[] _definitions;
|
||||
private readonly IProgressStore _store;
|
||||
private ProgressSave _progress;
|
||||
public SessionScreen Screen { get; private set; } = SessionScreen.Home;
|
||||
public BoardRules Board { get; private set; }
|
||||
public CameraState Camera { get; private set; } = DefaultCamera();
|
||||
public string LastSaveError { get; private set; }
|
||||
public bool HasFreePlay => _progress.latestFreePlay != null;
|
||||
public int[] CompletedStageIds => (int[])_progress.completedStageIds.Clone();
|
||||
public IReadOnlyList<StageDefinition> Definitions => Array.AsReadOnly(_definitions);
|
||||
|
||||
public GameSession(IEnumerable<StageDefinition> definitions, IProgressStore store)
|
||||
{
|
||||
_definitions = definitions.ToArray();
|
||||
_store = store ?? throw new ArgumentNullException(nameof(store));
|
||||
if (!_store.TryLoad(out var loaded, out var error)) loaded = new ProgressSave();
|
||||
LastSaveError = error;
|
||||
if (!SaveValidator.TryValidate(loaded, _definitions, out error))
|
||||
{ loaded = new ProgressSave(); LastSaveError = error; }
|
||||
_progress = loaded;
|
||||
}
|
||||
|
||||
public bool IsUnlocked(int stageId) => stageId == 1 || _progress.completedStageIds.Contains(stageId)
|
||||
|| (stageId >= 2 && stageId <= 30 && _progress.completedStageIds.Contains(stageId - 1));
|
||||
|
||||
public void ShowSelection() { SaveCurrent(); Screen = SessionScreen.StageSelection; Board = null; }
|
||||
public void ShowHome() { SaveCurrent(); Screen = SessionScreen.Home; Board = null; }
|
||||
|
||||
public bool StartStage(int stageId)
|
||||
{
|
||||
var definition = _definitions.FirstOrDefault(value => value.Id == stageId);
|
||||
if (definition == null || !IsUnlocked(stageId)) return false;
|
||||
SaveCurrent();
|
||||
var restored = _progress.puzzleStates.FirstOrDefault(state => state.stageId == stageId);
|
||||
Board = new BoardRules(definition, restored);
|
||||
Camera = restored == null ? DefaultCamera() : CopyCamera(restored.camera);
|
||||
Screen = SessionScreen.Puzzle;
|
||||
SaveCurrent();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ContinueFreePlay()
|
||||
{
|
||||
if (_progress.latestFreePlay == null) return false;
|
||||
SaveCurrent();
|
||||
Board = BoardRules.CreateFreePlay(_progress.latestFreePlay);
|
||||
Camera = CopyCamera(_progress.latestFreePlay.camera);
|
||||
Screen = SessionScreen.FreePlay;
|
||||
return true;
|
||||
}
|
||||
|
||||
public RuleResult MoveGroup(string groupId, Position3 delta) => Commit(() => Board.TryMoveGroup(groupId, delta));
|
||||
public RuleResult Merge(string first, string second) => Commit(() => Board.TryMerge(first, second));
|
||||
public RuleResult Count(string ballId) => Commit(() => Board.TryCount(ballId));
|
||||
|
||||
public void CommitCamera(CameraState camera)
|
||||
{
|
||||
// Board snapshot methods validate all camera coordinates and rotation.
|
||||
Camera = Board == null ? CopyCamera(camera) : Board.ToFreePlayState(camera).camera;
|
||||
SaveCurrent();
|
||||
}
|
||||
|
||||
private RuleResult Commit(Func<RuleResult> mutation)
|
||||
{
|
||||
if (Board == null) return RuleResult.Reject(RejectionReason.InvalidGroup);
|
||||
var result = mutation();
|
||||
if (!result.Accepted) return result;
|
||||
if (Screen == SessionScreen.Puzzle && Board.IsSolved)
|
||||
{
|
||||
// Completion, removing that unfinished puzzle, and creating free play are one saved update.
|
||||
_progress.completedStageIds = _progress.completedStageIds.Concat(new[] { Board.StageId }).Distinct().OrderBy(id => id).ToArray();
|
||||
_progress.puzzleStates = _progress.puzzleStates.Where(state => state.stageId != Board.StageId).ToArray();
|
||||
_progress.latestFreePlay = Board.ToFreePlayState(Camera);
|
||||
Board = BoardRules.CreateFreePlay(_progress.latestFreePlay);
|
||||
Screen = SessionScreen.FreePlay;
|
||||
}
|
||||
SaveCurrent();
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool SaveCurrent()
|
||||
{
|
||||
if (Board != null)
|
||||
{
|
||||
if (Screen == SessionScreen.Puzzle)
|
||||
_progress.puzzleStates = _progress.puzzleStates.Where(state => state.stageId != Board.StageId)
|
||||
.Concat(new[] { Board.ToPuzzleState(Camera) }).OrderBy(state => state.stageId).ToArray();
|
||||
else if (Screen == SessionScreen.FreePlay) _progress.latestFreePlay = Board.ToFreePlayState(Camera);
|
||||
}
|
||||
var success = _store.TrySave(_progress, out var error);
|
||||
LastSaveError = error;
|
||||
return success;
|
||||
}
|
||||
|
||||
public static CameraState DefaultCamera() => new CameraState {
|
||||
target = new Position3(0, 0.6f, 0), rotation = new Rotation4(0, 0, 0, 1), distance = 8 };
|
||||
private static CameraState CopyCamera(CameraState camera) => new CameraState {
|
||||
target = camera.target, rotation = camera.rotation, distance = camera.distance };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85fdaf062aa4ff042b6d37c003441435
|
||||
@@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using MagnetismHeroes.UnityRuntime.Bootstrap;
|
||||
using MagnetismHeroes.UnityRuntime.Interaction;
|
||||
using MagnetismHeroes.UnityRuntime.Presentation;
|
||||
using MagnetismHeroes.UnityRuntime.StageAssets;
|
||||
using TMPro;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.InputSystem.UI;
|
||||
using UnityEngine.TextCore.LowLevel;
|
||||
|
||||
namespace MagnetismHeroes.Editor
|
||||
{
|
||||
public static class FirstSliceAssets
|
||||
{
|
||||
public const string AppPrefabPath = "Assets/MagnetismHeroes/UnityRuntime/Presentation/Prefabs/GameApp.prefab";
|
||||
public const string StageOnePath = "Assets/MagnetismHeroes/UnityRuntime/StageAssets/Stage01.asset";
|
||||
private const string Presentation = "Assets/MagnetismHeroes/UnityRuntime/Presentation/";
|
||||
private static readonly Color Ink = new Color(0.12f, 0.2f, 0.31f);
|
||||
private static TMP_FontAsset _font;
|
||||
|
||||
[MenuItem("Magnetism Heroes/Build First Slice Assets")]
|
||||
public static void Build()
|
||||
{
|
||||
foreach (var directory in new[] { "Prefabs", "Materials", "Fonts", "Audio" }) Directory.CreateDirectory(Presentation + directory);
|
||||
AssetDatabase.Refresh();
|
||||
if (TMP_Settings.instance == null)
|
||||
{
|
||||
var package = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(TMP_Settings).Assembly);
|
||||
// uGUI 2.6's canonical helper does not resolve registry PackageCache paths.
|
||||
UnityEditor.AssetPackage.Package.Import(Path.Combine(package.resolvedPath, "Package Resources/TMP Essential Resources.unitypackage"), false);
|
||||
EditorApplication.wantsToQuit += WaitForResources;
|
||||
EditorApplication.update += ContinueAfterResources;
|
||||
return;
|
||||
}
|
||||
AssetDatabase.Refresh();
|
||||
_font = FontAsset();
|
||||
var stage = AssetDatabase.LoadAssetAtPath<StageAsset>(StageOnePath);
|
||||
if (stage == null) { stage = ScriptableObject.CreateInstance<StageAsset>(); AssetDatabase.CreateAsset(stage, StageOnePath); }
|
||||
var sphereMaterial = Material("MagnetBlue", new Color(0.15f, 0.68f, 0.92f));
|
||||
var markerMaterial = Material("CountGold", new Color(1, 0.76f, 0.14f));
|
||||
var faceMaterial = Material("FaceInk", Ink);
|
||||
var baseMaterial = Material("PlaygroundMint", new Color(0.65f, 0.88f, 0.73f));
|
||||
var propMaterial = Material("ToyCoral", new Color(1, 0.57f, 0.43f));
|
||||
var ballPrefab = BallPrefab(sphereMaterial, markerMaterial);
|
||||
var badgePrefab = BadgePrefab(faceMaterial);
|
||||
|
||||
var root = new GameObject("MagnetismHeroesApp");
|
||||
var app = root.AddComponent<GameApp>();
|
||||
var world = new GameObject("Playground"); world.transform.SetParent(root.transform);
|
||||
var cameraObject = new GameObject("GameCamera", typeof(Camera), typeof(AudioListener)); cameraObject.transform.SetParent(root.transform);
|
||||
var camera = cameraObject.GetComponent<Camera>(); camera.tag = "MainCamera"; camera.backgroundColor = new Color(0.84f, 0.94f, 1);
|
||||
camera.clearFlags = CameraClearFlags.SolidColor; camera.fieldOfView = 46;
|
||||
var light = new GameObject("Sun", typeof(Light)); light.transform.SetParent(root.transform);
|
||||
light.transform.rotation = Quaternion.Euler(45, -25, 0); light.GetComponent<Light>().type = LightType.Directional;
|
||||
light.GetComponent<Light>().intensity = 1.3f;
|
||||
var island = Prop("PlaygroundIsland", PrimitiveType.Cylinder, world.transform, new Vector3(0, -0.7f, 0), new Vector3(6, 0.35f, 4.5f), baseMaterial);
|
||||
// The primitive capsule grows to the widest scaled radius and hides the floating sphere.
|
||||
UnityEngine.Object.DestroyImmediate(island.GetComponent<Collider>());
|
||||
island.AddComponent<MeshCollider>().sharedMesh = island.GetComponent<MeshFilter>().sharedMesh;
|
||||
Prop("ToyStep", PrimitiveType.Cube, world.transform, new Vector3(1.8f, -0.1f, 1.1f), new Vector3(1, 0.5f, 1), propMaterial);
|
||||
Prop("ToyArchPost", PrimitiveType.Cylinder, world.transform, new Vector3(-2.4f, -0.05f, 1), new Vector3(0.45f, 0.65f, 0.45f), propMaterial);
|
||||
var boardObject = new GameObject("Friends"); boardObject.transform.SetParent(world.transform);
|
||||
var presenter = boardObject.AddComponent<BoardPresenter>();
|
||||
Set(presenter, "_ballPrefab", ballPrefab); Set(presenter, "_badgePrefab", badgePrefab); Set(presenter, "_camera", camera);
|
||||
var orbit = root.AddComponent<OrbitCamera>(); Set(orbit, "_camera", camera);
|
||||
var input = root.AddComponent<BoardInput>(); Set(input, "_app", app); Set(input, "_presenter", presenter); Set(input, "_orbit", orbit);
|
||||
var voice = root.AddComponent<VoicePlayer>();
|
||||
var source = root.AddComponent<AudioSource>(); source.playOnAwake = false; source.spatialBlend = 0;
|
||||
Set(voice, "_source", source); ConfigureVoices(voice);
|
||||
source.outputAudioMixerGroup = Mixer().FindMatchingGroups("Voice").Single();
|
||||
|
||||
var events = new GameObject("EventSystem", typeof(EventSystem), typeof(InputSystemUIInputModule)); events.transform.SetParent(root.transform);
|
||||
events.GetComponent<InputSystemUIInputModule>().AssignDefaultActions();
|
||||
var canvasObject = new GameObject("Interface", typeof(RectTransform), typeof(Canvas), typeof(UnityEngine.UI.CanvasScaler), typeof(UnityEngine.UI.GraphicRaycaster));
|
||||
canvasObject.transform.SetParent(root.transform); canvasObject.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
var scaler = canvasObject.GetComponent<UnityEngine.UI.CanvasScaler>(); scaler.uiScaleMode = UnityEngine.UI.CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
scaler.referenceResolution = new Vector2(1280, 720); scaler.matchWidthOrHeight = 0.5f;
|
||||
var safe = Panel("SafeArea", canvasObject.transform); safe.AddComponent<SafeAreaPanel>();
|
||||
var home = Panel("Home", safe.transform); var selection = Panel("StageSelection", safe.transform); var play = Panel("Play", safe.transform);
|
||||
Label("Title", home.transform, "자석 영웅", new Vector2(0.5f, 0.78f), new Vector2(660, 110), 66);
|
||||
Label("Subtitle", home.transform, "숫자 친구와 입체 놀이터", new Vector2(0.5f, 0.63f), new Vector2(720, 70), 30);
|
||||
var playButton = Button("PlayButton", home.transform, "친구 찾기", new Vector2(0.5f, 0.43f));
|
||||
var continueButton = Button("ContinueButton", home.transform, "자유 놀이 이어하기", new Vector2(0.5f, 0.25f));
|
||||
var saveNotice = Label("SaveNotice", home.transform, "", new Vector2(0.5f, 0.07f), new Vector2(1040, 55), 24);
|
||||
Label("SelectionTitle", selection.transform, "숫자 친구를 만나 볼까?", new Vector2(0.5f, 0.78f), new Vector2(820, 90), 42);
|
||||
var stageButton = Button("Stage01Button", selection.transform, "1 친구 찾기", new Vector2(0.5f, 0.48f));
|
||||
var selectionHomeButton = Button("SelectionHomeButton", selection.transform, "처음으로", new Vector2(0.5f, 0.24f));
|
||||
var stageTitle = Label("StageTitle", play.transform, "숫자 1 친구 찾기", new Vector2(0.5f, 0.92f), new Vector2(580, 60), 34);
|
||||
var instruction = Label("Instruction", play.transform, "친구를 찾아 끌어와 볼까?", new Vector2(0.5f, 0.12f), new Vector2(960, 70), 32);
|
||||
var counter = Label("Counter", play.transform, "센 친구 0 / 1", new Vector2(0.83f, 0.9f), new Vector2(330, 70), 28);
|
||||
var homeButton = Button("HomeButton", play.transform, "처음으로", new Vector2(0.13f, 0.9f), new Vector2(230, 72), 28);
|
||||
Label("CameraHelp", play.transform, "빈 곳을 쓸면 회전 · 두 손가락으로 확대", new Vector2(0.5f, 0.035f), new Vector2(1010, 36), 23);
|
||||
Set(app, "_homePanel", home); Set(app, "_selectionPanel", selection); Set(app, "_playPanel", play); Set(app, "_world", world);
|
||||
Set(app, "_instruction", instruction); Set(app, "_counter", counter); Set(app, "_stageTitle", stageTitle); Set(app, "_saveNotice", saveNotice);
|
||||
Set(app, "_playButton", playButton); Set(app, "_continueButton", continueButton); Set(app, "_stageOneButton", stageButton);
|
||||
Set(app, "_homeButton", homeButton); Set(app, "_selectionHomeButton", selectionHomeButton);
|
||||
Set(app, "_presenter", presenter); Set(app, "_orbit", orbit); Set(app, "_input", input); Set(app, "_voice", voice);
|
||||
var serialized = new SerializedObject(app); var stages = serialized.FindProperty("_stages"); stages.arraySize = 1;
|
||||
stages.GetArrayElementAtIndex(0).objectReferenceValue = stage; serialized.ApplyModifiedPropertiesWithoutUndo();
|
||||
home.SetActive(true); selection.SetActive(false); play.SetActive(false); world.SetActive(false);
|
||||
PrefabUtility.SaveAsPrefabAsset(root, AppPrefabPath); UnityEngine.Object.DestroyImmediate(root);
|
||||
AssetDatabase.SaveAssets(); Debug.Log("[FirstSlice] Real Stage01 and GameApp assets created. Main scene remains root-owned.");
|
||||
}
|
||||
|
||||
private static bool WaitForResources() => false;
|
||||
private static void ContinueAfterResources()
|
||||
{
|
||||
if (Resources.Load<TMP_Settings>("TMP Settings") == null || EditorApplication.isUpdating) return;
|
||||
EditorApplication.update -= ContinueAfterResources; EditorApplication.wantsToQuit -= WaitForResources;
|
||||
try { Build(); if (Application.isBatchMode) EditorApplication.Exit(0); }
|
||||
catch (Exception exception) { Debug.LogException(exception); if (Application.isBatchMode) EditorApplication.Exit(1); }
|
||||
}
|
||||
|
||||
private static TMP_FontAsset FontAsset()
|
||||
{
|
||||
const string path = Presentation + "Fonts/NotoSansCJKkr-FirstSlice.asset";
|
||||
var font = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(path);
|
||||
bool created = font == null;
|
||||
if (created)
|
||||
{
|
||||
var source = AssetDatabase.LoadAssetAtPath<Font>(Presentation + "Fonts/NotoSansCJKkr-Regular.otf");
|
||||
font = TMP_FontAsset.CreateFontAsset(source, 48, 5, GlyphRenderMode.SDFAA, 1024, 1024, AtlasPopulationMode.Dynamic, false);
|
||||
}
|
||||
if (font == null) throw new InvalidOperationException("Could not create Korean font.");
|
||||
font.name = "NotoSansCJKkr-FirstSlice";
|
||||
var characters = "0123456789 자석 영웅 숫자 친구와 입체 놀이터 친구 찾기 자유 놀이 이어하기 숫자 친구를 만나 볼까? 처음으로 숫자 1 친구 찾기 친구를 찾아 끌어와 볼까? 센 친구 0 / 1 빈 곳을 쓸면 회전 · 두 손가락으로 확대 이전 기록으로 이어서 시작할게요. 기록을 읽지 못해 처음부터 시작할게요. 친구를 먼저 끌어와 볼까? 자유 놀이터 해냈어! 친구와 자유롭게 놀아 보자. 모두 모았네! 하나씩 눌러 세어 보자.";
|
||||
typeof(TMP_FontAsset).GetProperty("SourceFont_EditorRef", BindingFlags.Instance | BindingFlags.NonPublic)
|
||||
.SetValue(font, AssetDatabase.LoadAssetAtPath<Font>(Presentation + "Fonts/NotoSansCJKkr-Regular.otf"));
|
||||
font.atlasPopulationMode = AtlasPopulationMode.Dynamic;
|
||||
var serializedFont = new SerializedObject(font);
|
||||
serializedFont.FindProperty("m_SourceFontFilePath").stringValue = Presentation + "Fonts/NotoSansCJKkr-Regular.otf";
|
||||
serializedFont.ApplyModifiedPropertiesWithoutUndo();
|
||||
if (!font.TryAddCharacters(characters, out var missing)) throw new InvalidOperationException("Missing font glyphs: " + missing);
|
||||
font.atlasPopulationMode = AtlasPopulationMode.Static; font.faceInfo = SetFaceScale(font.faceInfo);
|
||||
if (created)
|
||||
{
|
||||
AssetDatabase.CreateAsset(font, path); AssetDatabase.AddObjectToAsset(font.material, font);
|
||||
foreach (var atlas in font.atlasTextures) AssetDatabase.AddObjectToAsset(atlas, font);
|
||||
}
|
||||
EditorUtility.SetDirty(font);
|
||||
return font;
|
||||
}
|
||||
private static UnityEngine.TextCore.FaceInfo SetFaceScale(UnityEngine.TextCore.FaceInfo face) { face.scale = 1; return face; }
|
||||
private static Material Material(string name, Color color)
|
||||
{
|
||||
string path = Presentation + "Materials/" + name + ".mat";
|
||||
var material = AssetDatabase.LoadAssetAtPath<Material>(path);
|
||||
if (material == null) { material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); AssetDatabase.CreateAsset(material, path); }
|
||||
material.color = color; return material;
|
||||
}
|
||||
private static BallView BallPrefab(Material body, Material marker)
|
||||
{
|
||||
var root = GameObject.CreatePrimitive(PrimitiveType.Sphere); root.name = "MagnetFriend";
|
||||
root.GetComponent<Renderer>().sharedMaterial = body;
|
||||
var view = root.AddComponent<BallView>(); Set(view, "_body", root.GetComponent<Renderer>());
|
||||
var counted = Prop("CountMarker", PrimitiveType.Cube, root.transform, new Vector3(0, 0.55f, 0), new Vector3(0.24f, 0.08f, 0.24f), marker);
|
||||
UnityEngine.Object.DestroyImmediate(counted.GetComponent<Collider>()); counted.SetActive(false); Set(view, "_countMarker", counted);
|
||||
var prefab = PrefabUtility.SaveAsPrefabAsset(root, Presentation + "Prefabs/MagnetFriend.prefab"); UnityEngine.Object.DestroyImmediate(root);
|
||||
return prefab.GetComponent<BallView>();
|
||||
}
|
||||
private static GroupBadge BadgePrefab(Material ink)
|
||||
{
|
||||
var root = new GameObject("GroupBadge"); var badge = root.AddComponent<GroupBadge>();
|
||||
var label = new GameObject("Number", typeof(TextMeshPro)); label.transform.SetParent(root.transform);
|
||||
var text = label.GetComponent<TextMeshPro>(); text.font = _font; text.fontSize = 5; text.alignment = TextAlignmentOptions.Center;
|
||||
text.color = Ink; text.rectTransform.sizeDelta = new Vector2(2, 0.7f); text.text = "1"; text.enableAutoSizing = false;
|
||||
var face = new GameObject("RepresentativeFace"); face.transform.SetParent(root.transform);
|
||||
var left = Prop("LeftEye", PrimitiveType.Quad, face.transform, new Vector3(-0.15f, 0.05f, 0), new Vector3(0.08f, 0.11f, 1), ink);
|
||||
var right = Prop("RightEye", PrimitiveType.Quad, face.transform, new Vector3(0.15f, 0.05f, 0), new Vector3(0.08f, 0.11f, 1), ink);
|
||||
UnityEngine.Object.DestroyImmediate(left.GetComponent<Collider>()); UnityEngine.Object.DestroyImmediate(right.GetComponent<Collider>());
|
||||
var smile = new GameObject("Smile", typeof(LineRenderer)); smile.transform.SetParent(face.transform); smile.transform.localPosition = Vector3.zero;
|
||||
var line = smile.GetComponent<LineRenderer>(); line.sharedMaterial = ink; line.useWorldSpace = false; line.positionCount = 9; line.widthMultiplier = 0.035f;
|
||||
for (int i = 0; i < 9; i++) { float x = (i - 4) * 0.035f; line.SetPosition(i, new Vector3(x, x * x * 3 - 0.14f, 0)); }
|
||||
Set(badge, "_number", text); Set(badge, "_face", face.transform);
|
||||
var prefab = PrefabUtility.SaveAsPrefabAsset(root, Presentation + "Prefabs/GroupBadge.prefab"); UnityEngine.Object.DestroyImmediate(root);
|
||||
return prefab.GetComponent<GroupBadge>();
|
||||
}
|
||||
private static GameObject Prop(string name, PrimitiveType primitive, Transform parent, Vector3 position, Vector3 scale, Material material)
|
||||
{
|
||||
var prop = GameObject.CreatePrimitive(primitive); prop.name = name; prop.transform.SetParent(parent);
|
||||
prop.transform.localPosition = position; prop.transform.localScale = scale; prop.GetComponent<Renderer>().sharedMaterial = material; return prop;
|
||||
}
|
||||
private static GameObject Panel(string name, Transform parent)
|
||||
{
|
||||
var panel = new GameObject(name, typeof(RectTransform)); panel.transform.SetParent(parent, false);
|
||||
var rect = (RectTransform)panel.transform; rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = rect.offsetMax = Vector2.zero; return panel;
|
||||
}
|
||||
private static TMP_Text Label(string name, Transform parent, string content, Vector2 anchor, Vector2 size, int fontSize)
|
||||
{
|
||||
var label = new GameObject(name, typeof(RectTransform), typeof(TextMeshProUGUI)); label.transform.SetParent(parent, false);
|
||||
var text = label.GetComponent<TextMeshProUGUI>(); text.font = _font; text.fontSize = fontSize; text.text = content;
|
||||
text.color = Ink; text.alignment = TextAlignmentOptions.Center; text.raycastTarget = false; text.enableAutoSizing = false;
|
||||
var rect = (RectTransform)label.transform; rect.anchorMin = rect.anchorMax = anchor; rect.anchoredPosition = Vector2.zero; rect.sizeDelta = size; return text;
|
||||
}
|
||||
private static UnityEngine.UI.Button Button(string name, Transform parent, string content, Vector2 anchor, Vector2? size = null, int fontSize = 34)
|
||||
{
|
||||
var buttonObject = new GameObject(name, typeof(RectTransform), typeof(UnityEngine.UI.Image), typeof(UnityEngine.UI.Button)); buttonObject.transform.SetParent(parent, false);
|
||||
var rect = (RectTransform)buttonObject.transform; rect.anchorMin = rect.anchorMax = anchor; rect.sizeDelta = size ?? new Vector2(460, 90); rect.anchoredPosition = Vector2.zero;
|
||||
var image = buttonObject.GetComponent<UnityEngine.UI.Image>(); image.color = new Color(1, 0.8f, 0.3f); image.raycastTarget = true;
|
||||
var button = buttonObject.GetComponent<UnityEngine.UI.Button>(); button.targetGraphic = image;
|
||||
var text = Label("Label", buttonObject.transform, content, new Vector2(0.5f, 0.5f), rect.sizeDelta, fontSize); return button;
|
||||
}
|
||||
private static void Set(UnityEngine.Object target, string field, UnityEngine.Object value)
|
||||
{ var serialized = new SerializedObject(target); serialized.FindProperty(field).objectReferenceValue = value; serialized.ApplyModifiedPropertiesWithoutUndo(); }
|
||||
private static void ConfigureVoices(VoicePlayer voice)
|
||||
{
|
||||
var clips = AssetDatabase.FindAssets("t:AudioClip", new[] { Presentation + "Audio" })
|
||||
.Select(guid => AssetDatabase.LoadAssetAtPath<AudioClip>(AssetDatabase.GUIDToAssetPath(guid))).Where(clip => clip != null).ToArray();
|
||||
foreach (var clip in clips)
|
||||
{
|
||||
var importer = (AudioImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(clip));
|
||||
var settings = importer.defaultSampleSettings; settings.loadType = AudioClipLoadType.DecompressOnLoad;
|
||||
settings.compressionFormat = AudioCompressionFormat.PCM; settings.preloadAudioData = true;
|
||||
importer.defaultSampleSettings = settings; importer.forceToMono = true; importer.SaveAndReimport();
|
||||
}
|
||||
var serialized = new SerializedObject(voice); var property = serialized.FindProperty("_clips"); property.arraySize = clips.Length;
|
||||
for (int i = 0; i < clips.Length; i++)
|
||||
{ var entry = property.GetArrayElementAtIndex(i); entry.FindPropertyRelative("id").stringValue = clips[i].name; entry.FindPropertyRelative("clip").objectReferenceValue = clips[i]; }
|
||||
serialized.ApplyModifiedPropertiesWithoutUndo();
|
||||
}
|
||||
private static AudioMixer Mixer()
|
||||
{
|
||||
const string path = Presentation + "Audio/GameAudio.mixer";
|
||||
var mixer = AssetDatabase.LoadAssetAtPath<AudioMixer>(path);
|
||||
var controllerType = typeof(UnityEditor.Editor).Assembly.GetType("UnityEditor.Audio.AudioMixerController");
|
||||
var flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
if (mixer == null) mixer = (AudioMixer)controllerType.GetMethod("CreateMixerControllerAtPath", flags).Invoke(null, new object[] { path });
|
||||
var instanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
var master = controllerType.GetProperty("masterGroup", instanceFlags).GetValue(mixer);
|
||||
var childrenProperty = master.GetType().GetProperty("children", instanceFlags);
|
||||
var children = (Array)childrenProperty.GetValue(master);
|
||||
var newChildren = children.Cast<object>().ToList();
|
||||
foreach (var groupName in new[] { "Voice", "SFX", "Music" })
|
||||
{
|
||||
if (mixer.FindMatchingGroups(groupName).Length != 0) continue;
|
||||
var group = controllerType.GetMethod("CreateNewGroup", instanceFlags).Invoke(mixer, new object[] { groupName, false });
|
||||
newChildren.Add(group);
|
||||
}
|
||||
var array = Array.CreateInstance(master.GetType(), newChildren.Count);
|
||||
for (int index = 0; index < newChildren.Count; index++) array.SetValue(newChildren[index], index);
|
||||
childrenProperty.SetValue(master, array); EditorUtility.SetDirty(mixer); EditorUtility.SetDirty((UnityEngine.Object)master);
|
||||
return mixer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c21a9cea2d948bd4185448d90d4da2e8
|
||||
@@ -0,0 +1,41 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using MagnetismHeroes.UnityRuntime.StageAssets;
|
||||
using MagnetismHeroes.UnityRuntime.Bootstrap;
|
||||
|
||||
namespace MagnetismHeroes.Tests
|
||||
{
|
||||
public sealed class FirstSliceAssetTests
|
||||
{
|
||||
[Test] public void FirstPuzzleHasAnExecutableAppPrefab()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/MagnetismHeroes/UnityRuntime/Presentation/Prefabs/GameApp.prefab");
|
||||
Assert.That(prefab, Is.Not.Null, "The first puzzle must have a real Inspector-editable app prefab.");
|
||||
Assert.That(prefab.GetComponent<GameApp>(), Is.Not.Null);
|
||||
var serialized = new SerializedObject(prefab.GetComponent<GameApp>());
|
||||
foreach (var field in new[] { "_homePanel", "_selectionPanel", "_playPanel", "_world", "_instruction", "_counter", "_stageTitle", "_saveNotice",
|
||||
"_playButton", "_continueButton", "_stageOneButton", "_homeButton", "_selectionHomeButton", "_presenter", "_orbit", "_input", "_voice" })
|
||||
Assert.That(serialized.FindProperty(field).objectReferenceValue, Is.Not.Null, field);
|
||||
}
|
||||
[Test] public void StaticKoreanFontContainsEveryVisibleFirstSliceCharacter()
|
||||
{
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/MagnetismHeroes/UnityRuntime/Presentation/Prefabs/GameApp.prefab");
|
||||
var texts = prefab.GetComponentsInChildren<TMP_Text>(true);
|
||||
foreach (var text in texts)
|
||||
{
|
||||
Assert.That(text.font.atlasPopulationMode, Is.EqualTo(AtlasPopulationMode.Static));
|
||||
Assert.That(text.enableAutoSizing, Is.False);
|
||||
foreach (var character in text.text) Assert.That(text.font.HasCharacter(character), Is.True, text.name + ": " + character);
|
||||
}
|
||||
}
|
||||
[Test] public void StageAssetConvertsToAnIndependentDefinition()
|
||||
{
|
||||
var stage = AssetDatabase.LoadAssetAtPath<StageAsset>("Assets/MagnetismHeroes/UnityRuntime/StageAssets/Stage01.asset");
|
||||
var before = EditorJsonUtility.ToJson(stage); var definition = stage.ToDefinition();
|
||||
Assert.That(definition.Id, Is.EqualTo(1)); Assert.That(definition.Total, Is.EqualTo(1));
|
||||
Assert.That(EditorJsonUtility.ToJson(stage), Is.EqualTo(before));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 599347c36cd01ad4fa166c4c6b6f3b77
|
||||
@@ -0,0 +1,72 @@
|
||||
using System.Linq;
|
||||
using MagnetismHeroes.Core;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace MagnetismHeroes.Tests
|
||||
{
|
||||
public sealed class GameSessionTests
|
||||
{
|
||||
private sealed class MemoryStore : IProgressStore
|
||||
{
|
||||
public ProgressSave Save = new ProgressSave();
|
||||
public string LoadWarning;
|
||||
public bool TryLoad(out ProgressSave save, out string error) { save = Save; error = LoadWarning; return true; }
|
||||
public bool TrySave(ProgressSave save, out string error) { Save = save; error = null; return true; }
|
||||
}
|
||||
private static StageDefinition One() => new StageDefinition(1, StageKind.Counting, new[] { 1 }, new[] { 1 });
|
||||
|
||||
[Test] public void LoadRecoveryWarningIsRetainedForDiagnostics()
|
||||
{
|
||||
var session = new GameSession(new[] { One() }, new MemoryStore { LoadWarning = "Recovered valid backup" });
|
||||
Assert.That(session.LastSaveError, Is.EqualTo("Recovered valid backup"));
|
||||
}
|
||||
[Test] public void FirstStageCannotCompleteWithoutACommittedCollection()
|
||||
{
|
||||
var store = new MemoryStore(); var session = new GameSession(new[] { One() }, store);
|
||||
Assert.That(session.StartStage(1), Is.True);
|
||||
var ball = session.Board.Balls.Single(); var group = session.Board.Groups.Single();
|
||||
Assert.That(session.Count(ball.id).Reason, Is.EqualTo(RejectionReason.NotCollected));
|
||||
Assert.That(session.MoveGroup(group.id, new Position3()).Accepted, Is.False);
|
||||
Assert.That(store.Save.completedStageIds, Is.Empty);
|
||||
Assert.That(session.Screen, Is.EqualTo(SessionScreen.Puzzle));
|
||||
}
|
||||
[Test] public void MoveAndCountCreateOneAtomicCompletionAndKeepTheSameBoard()
|
||||
{
|
||||
var store = new MemoryStore(); var session = new GameSession(new[] { One() }, store); session.StartStage(1);
|
||||
var ballId = session.Board.Balls.Single().id; var groupId = session.Board.Groups.Single().id;
|
||||
session.MoveGroup(groupId, new Position3(1, 2, -1));
|
||||
var position = session.Board.Balls.Single().position;
|
||||
Assert.That(session.Count(ballId).Count, Is.EqualTo(1));
|
||||
Assert.That(session.Screen, Is.EqualTo(SessionScreen.FreePlay));
|
||||
Assert.That(store.Save.completedStageIds, Is.EqualTo(new[] { 1 }));
|
||||
Assert.That(store.Save.puzzleStates, Is.Empty);
|
||||
Assert.That(store.Save.latestFreePlay.balls.Single().position, Is.EqualTo(position));
|
||||
Assert.That(session.Count(ballId).Accepted, Is.False);
|
||||
Assert.That(store.Save.completedStageIds, Is.EqualTo(new[] { 1 }));
|
||||
}
|
||||
[Test] public void IncompleteBoardRestoresCommittedPositionCameraAndCollection()
|
||||
{
|
||||
var store = new MemoryStore(); var session = new GameSession(new[] { One() }, store); session.StartStage(1);
|
||||
session.MoveGroup(session.Board.Groups.Single().id, new Position3(1, 2, 3));
|
||||
var camera = GameSession.DefaultCamera(); camera.distance = 11;
|
||||
session.CommitCamera(camera); session.ShowHome();
|
||||
var resumed = new GameSession(new[] { One() }, store); resumed.StartStage(1);
|
||||
Assert.That(resumed.Board.Balls.Single().position, Is.EqualTo(new Position3(1, 2, 3)));
|
||||
Assert.That(resumed.Board.CollectedBallIds.Length, Is.EqualTo(1));
|
||||
Assert.That(resumed.Board.CountedCount, Is.Zero);
|
||||
Assert.That(resumed.Camera.distance, Is.EqualTo(11));
|
||||
Assert.That(resumed.Screen, Is.EqualTo(SessionScreen.Puzzle));
|
||||
}
|
||||
[Test] public void CompletedStageReplayKeepsCompletionAndItsPreviousFreePlaySeparately()
|
||||
{
|
||||
var store = new MemoryStore(); var session = new GameSession(new[] { One() }, store); session.StartStage(1);
|
||||
session.MoveGroup(session.Board.Groups.Single().id, new Position3(2, 0, 0)); session.Count(session.Board.Balls.Single().id);
|
||||
var freePosition = store.Save.latestFreePlay.balls.Single().position;
|
||||
Assert.That(session.IsUnlocked(2), Is.True); Assert.That(session.IsUnlocked(3), Is.False);
|
||||
session.StartStage(1); session.MoveGroup(session.Board.Groups.Single().id, new Position3(1, 0, 0));
|
||||
Assert.That(store.Save.completedStageIds, Is.EqualTo(new[] { 1 }));
|
||||
Assert.That(store.Save.latestFreePlay.balls.Single().position, Is.EqualTo(freePosition));
|
||||
Assert.That(store.Save.puzzleStates.Single().stageId, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39eee6770356bc246bc854f34306e1fb
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MagnetismHeroes.Core;
|
||||
using MagnetismHeroes.UnityRuntime.Persistence;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace MagnetismHeroes.Tests
|
||||
{
|
||||
public sealed class LocalProgressStoreTests
|
||||
{
|
||||
private string _directory, _path;
|
||||
private StageDefinition _stage;
|
||||
[SetUp] public void SetUp()
|
||||
{
|
||||
_directory = Path.Combine(Path.GetTempPath(), "MagnetismHeroes-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(_directory);
|
||||
_path = Path.Combine(_directory, "progress.json");
|
||||
_stage = new StageDefinition(1, StageKind.Counting, new[] { 1 }, new[] { 1 });
|
||||
}
|
||||
[TearDown] public void TearDown() => Directory.Delete(_directory, true);
|
||||
private LocalProgressStore Store() => new LocalProgressStore(_path, new[] { _stage });
|
||||
private ProgressSave Puzzle()
|
||||
{ var board = new BoardRules(_stage); return new ProgressSave { puzzleStates = new[] { board.ToPuzzleState(GameSession.DefaultCamera()) } }; }
|
||||
|
||||
[Test] public void CommittedPositionAndCameraRoundTripWithoutPartialLoad()
|
||||
{
|
||||
var progress = Puzzle(); progress.puzzleStates[0].balls[0].position = new Position3(1, -2, 3);
|
||||
progress.puzzleStates[0].camera.distance = 10;
|
||||
Assert.That(Store().TrySave(progress, out var error), Is.True, error);
|
||||
Assert.That(Store().TryLoad(out var loaded, out error), Is.True, error);
|
||||
Assert.That(loaded.puzzleStates[0].balls[0].position, Is.EqualTo(new Position3(1, -2, 3)));
|
||||
Assert.That(loaded.puzzleStates[0].camera.distance, Is.EqualTo(10));
|
||||
}
|
||||
[TestCase("position")]
|
||||
[TestCase("x")]
|
||||
[TestCase("camera")]
|
||||
[TestCase("countedBallIds")]
|
||||
[TestCase("latestFreePlay")]
|
||||
public void MissingRequiredFieldsAreRejectedInsteadOfDefaulted(string field)
|
||||
{
|
||||
Assert.That(Store().TrySave(Puzzle(), out _), Is.True);
|
||||
var json = File.ReadAllText(_path).Replace("\"" + field + "\":", "\"removed_" + field + "\":");
|
||||
File.WriteAllText(_path, json);
|
||||
Assert.That(Store().TryLoad(out var loaded, out var error), Is.False);
|
||||
Assert.That(loaded, Is.Null); Assert.That(error, Does.Contain(field));
|
||||
}
|
||||
[Test] public void DuplicateJsonKeysAndTrailingContentAreRejected()
|
||||
{
|
||||
File.WriteAllText(_path, "{\"schemaVersion\":1,\"schemaVersion\":1}");
|
||||
Assert.That(Store().TryLoad(out _, out _), Is.False);
|
||||
File.Delete(_path); Assert.That(Store().TrySave(Puzzle(), out _), Is.True);
|
||||
File.WriteAllText(_path, File.ReadAllText(_path) + " {}");
|
||||
Assert.That(Store().TryLoad(out _, out _), Is.False);
|
||||
}
|
||||
[Test] public void ValidBackupRecoversWholeBoardAndDamagedOriginalSurvivesNextSave()
|
||||
{
|
||||
var store = Store(); var progress = Puzzle(); Assert.That(store.TrySave(progress, out _), Is.True);
|
||||
progress.puzzleStates[0].camera.distance = 12; Assert.That(store.TrySave(progress, out _), Is.True);
|
||||
File.WriteAllText(_path, "broken-primary");
|
||||
Assert.That(store.TryLoad(out var loaded, out var error), Is.True, error);
|
||||
Assert.That(loaded.puzzleStates[0].camera.distance, Is.EqualTo(8));
|
||||
Assert.That(error, Does.Contain("Recovered"));
|
||||
Assert.That(store.TrySave(loaded, out error), Is.True, error);
|
||||
var damaged = Directory.GetFiles(_directory, "*.damaged-*").Single();
|
||||
Assert.That(File.ReadAllText(damaged), Is.EqualTo("broken-primary"));
|
||||
Assert.That(File.ReadAllText(_path + ".bak"), Does.Not.Contain("broken-primary"));
|
||||
Assert.That(File.Exists(_path + ".tmp"), Is.False);
|
||||
}
|
||||
[Test] public void WithoutValidBackupLoaderDoesNotOverwriteDamagedEvidence()
|
||||
{
|
||||
File.WriteAllText(_path, "broken-primary"); File.WriteAllText(_path + ".bak", "broken-backup");
|
||||
var store = Store(); Assert.That(store.TryLoad(out _, out _), Is.False);
|
||||
Assert.That(File.ReadAllText(_path), Is.EqualTo("broken-primary"));
|
||||
Assert.That(store.TrySave(new ProgressSave(), out var error), Is.True, error);
|
||||
Assert.That(Directory.GetFiles(_directory, "*.damaged-*").Select(File.ReadAllText), Does.Contain("broken-primary"));
|
||||
}
|
||||
[Test] public void InvalidGroupMembershipDoesNotReplaceAValidSave()
|
||||
{
|
||||
var store = Store(); var progress = Puzzle(); Assert.That(store.TrySave(progress, out _), Is.True);
|
||||
var before = File.ReadAllBytes(_path); progress.puzzleStates[0].groups[0].ballIds = new[] { "missing" };
|
||||
Assert.That(store.TrySave(progress, out _), Is.False); Assert.That(File.ReadAllBytes(_path), Is.EqualTo(before));
|
||||
}
|
||||
[TestCase("schemaVersion", "null")]
|
||||
[TestCase("schemaVersion", "\"1\"")]
|
||||
[TestCase("schemaVersion", "1.5")]
|
||||
[TestCase("distance", "null")]
|
||||
[TestCase("distance", "\"8\"")]
|
||||
[TestCase("x", "null")]
|
||||
[TestCase("x", "\"0\"")]
|
||||
public void WrongScalarTypesAreRejected(string field, string value)
|
||||
{
|
||||
Assert.That(Store().TrySave(Puzzle(), out _), Is.True);
|
||||
var json = File.ReadAllText(_path);
|
||||
json = System.Text.RegularExpressions.Regex.Replace(json, "\"" + field + "\":\\s*-?[0-9]+(?:\\.[0-9]+)?", "\"" + field + "\":" + value);
|
||||
File.WriteAllText(_path, json); Assert.That(Store().TryLoad(out var loaded, out _), Is.False); Assert.That(loaded, Is.Null);
|
||||
}
|
||||
[Test] public void SavedJsonContainsOnlyContractFields()
|
||||
{
|
||||
Assert.That(Store().TrySave(Puzzle(), out _), Is.True);
|
||||
Assert.That(File.ReadAllText(_path), Does.Not.Contain("IsValid"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d3b301c187eab84086f1a6504b44942
|
||||
@@ -0,0 +1,213 @@
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using MagnetismHeroes.Core;
|
||||
using MagnetismHeroes.UnityRuntime.Bootstrap;
|
||||
using MagnetismHeroes.UnityRuntime.StageAssets;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.LowLevel;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace MagnetismHeroes.Tests
|
||||
{
|
||||
public sealed class FirstPuzzlePlayTests
|
||||
{
|
||||
private sealed class MemoryStore : IProgressStore
|
||||
{
|
||||
public ProgressSave Saved = new ProgressSave();
|
||||
public bool TryLoad(out ProgressSave save, out string error) { save = Saved; error = null; return true; }
|
||||
public bool TrySave(ProgressSave save, out string error) { Saved = save; error = null; return true; }
|
||||
}
|
||||
private GameApp _app; private MemoryStore _store; private Touchscreen _touchscreen;
|
||||
private InputSettings _originalInputSettings, _testInputSettings;
|
||||
private HideFlags _originalSettingsFlags;
|
||||
[UnitySetUp] public IEnumerator SetUp()
|
||||
{
|
||||
// Batch tests have no focused Game View; route synthetic pointers into the actual player loop.
|
||||
_originalInputSettings = InputSystem.settings; _originalSettingsFlags = _originalInputSettings.hideFlags;
|
||||
// InputManager destroys its HideAndDontSave default on replacement; keep it for exact restoration.
|
||||
_originalInputSettings.hideFlags = HideFlags.DontSave;
|
||||
_testInputSettings = Object.Instantiate(_originalInputSettings); _testInputSettings.hideFlags = HideFlags.DontSave;
|
||||
_testInputSettings.editorInputBehaviorInPlayMode = InputSettings.EditorInputBehaviorInPlayMode.AllDeviceInputAlwaysGoesToGameView;
|
||||
_testInputSettings.backgroundBehavior = InputSettings.BackgroundBehavior.IgnoreFocus;
|
||||
InputSystem.settings = _testInputSettings;
|
||||
foreach (var listener in Object.FindObjectsByType<AudioListener>(FindObjectsSortMode.None)) listener.enabled = false;
|
||||
foreach (var camera in Object.FindObjectsByType<Camera>(FindObjectsSortMode.None)) camera.enabled = false;
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/MagnetismHeroes/UnityRuntime/Presentation/Prefabs/GameApp.prefab");
|
||||
Assert.That(prefab, Is.Not.Null); _app = Object.Instantiate(prefab).GetComponent<GameApp>();
|
||||
_store = new MemoryStore(); _app.Initialize(_store); yield return null;
|
||||
}
|
||||
[UnityTearDown] public IEnumerator TearDown()
|
||||
{
|
||||
if (_touchscreen != null) InputSystem.RemoveDevice(_touchscreen); Object.Destroy(_app.gameObject);
|
||||
InputSystem.settings = _originalInputSettings; _originalInputSettings.hideFlags = _originalSettingsFlags;
|
||||
Object.Destroy(_testInputSettings); yield return null;
|
||||
}
|
||||
private Vector2 BallPoint()
|
||||
{
|
||||
var ball = _app.Presenter.Balls.Values.Single();
|
||||
Vector2 point = _app.Presenter.Camera.WorldToScreenPoint(ball.transform.position);
|
||||
var ray = _app.Presenter.Camera.ScreenPointToRay(point);
|
||||
Assert.That(Physics.Raycast(ray, out var hit, 100), Is.True,
|
||||
$"Ball ray miss: screen={Screen.width}x{Screen.height}, point={point}, ball={ball.transform.position}, camera={_app.Presenter.Camera.transform.position}, active={ball.gameObject.activeInHierarchy}");
|
||||
Assert.That(hit.collider.gameObject, Is.EqualTo(ball.gameObject), $"First visible ball ray must hit sphere: hit={hit.collider.name} point={hit.point}, screen={Screen.width}x{Screen.height} ballPoint={point}, ray={ray}, ball={ball.transform.position}, camera={_app.Presenter.Camera.transform.position}, collider={ball.GetComponent<Collider>().bounds}, active={ball.gameObject.activeInHierarchy}");
|
||||
return point;
|
||||
}
|
||||
private void Drag(Vector2 start, Vector2 end) { _app.Input.Begin(start, false); _app.Input.Move(end); _app.Input.End(end); }
|
||||
private void Tap(Vector2 point) { _app.Input.Begin(point, false); _app.Input.End(point); }
|
||||
|
||||
[UnityTest] public IEnumerator InspectorButtonsNavigateAndHomeKeepsACameraAndListener()
|
||||
{
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.Home));
|
||||
Assert.That(_app.Presenter.Camera.isActiveAndEnabled, Is.True);
|
||||
Assert.That(_app.GetComponentInChildren<AudioListener>().isActiveAndEnabled, Is.True);
|
||||
_app.transform.Find("Interface/SafeArea/Home/PlayButton").GetComponent<UnityEngine.UI.Button>().onClick.Invoke();
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.StageSelection));
|
||||
_app.transform.Find("Interface/SafeArea/StageSelection/Stage01Button").GetComponent<UnityEngine.UI.Button>().onClick.Invoke();
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.Puzzle));
|
||||
Assert.That(_app.Presenter.Balls.Count, Is.EqualTo(1)); yield return null;
|
||||
}
|
||||
[UnityTest] public IEnumerator TapBeforeCollectionIsRejectedThenDragAndTapCompleteOnTheSameBoard()
|
||||
{
|
||||
_app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var point = BallPoint(); Tap(point);
|
||||
Assert.That(_app.Session.Board.CountedCount, Is.Zero); Assert.That(_app.Instruction, Does.Contain("먼저"));
|
||||
Drag(point, point + new Vector2(90, 25)); yield return null; Physics.SyncTransforms();
|
||||
Assert.That(_app.Session.Board.CollectedBallIds.Length, Is.EqualTo(1));
|
||||
var ball = _app.Session.Board.Balls.Single(); Tap(BallPoint());
|
||||
Assert.That(_app.Session.Screen, Is.EqualTo(SessionScreen.FreePlay));
|
||||
Assert.That(_store.Saved.completedStageIds, Is.EqualTo(new[] { 1 })); Assert.That(_store.Saved.puzzleStates, Is.Empty);
|
||||
Assert.That(_app.Session.Board.Balls.Single().position, Is.EqualTo(ball.position));
|
||||
Assert.That(_app.Voice.PendingCount, Is.EqualTo(1), "The success boundary must keep the last count voice.");
|
||||
Tap(BallPoint()); Assert.That(_app.Voice.PendingCount, Is.EqualTo(1));
|
||||
yield return null;
|
||||
}
|
||||
[UnityTest] public IEnumerator CanceledAndOffscreenDragsRestoreOnlyCommittedPositions()
|
||||
{
|
||||
_app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var original = _app.Session.Board.Balls.Single().position; var point = BallPoint();
|
||||
_app.Input.Begin(point, false); _app.Input.Move(point + new Vector2(100, 30));
|
||||
Assert.That(_app.Presenter.Balls.Values.Single().transform.position, Is.Not.EqualTo(new Vector3(original.x, original.y, original.z)));
|
||||
_app.Session.SaveCurrent(); Assert.That(_store.Saved.puzzleStates.Single().balls.Single().position, Is.EqualTo(original));
|
||||
_app.Input.End(point + new Vector2(100, 30), true);
|
||||
Assert.That(_app.Session.Board.CollectedBallIds, Is.Empty);
|
||||
Assert.That(_app.Presenter.Balls.Values.Single().transform.position, Is.EqualTo(new Vector3(original.x, original.y, original.z)));
|
||||
_app.Input.Begin(point, false); _app.Input.Move(point + new Vector2(100, 30)); _app.Input.End(new Vector2(-1, point.y));
|
||||
Assert.That(_app.Session.Board.Balls.Single().position, Is.EqualTo(original)); yield return null;
|
||||
}
|
||||
[UnityTest] public IEnumerator ButtonBlockedGestureAndPinchNeverCollectOrCountAFriend()
|
||||
{
|
||||
_app.StartStage(1); yield return null; Physics.SyncTransforms(); var point = BallPoint();
|
||||
_app.Input.Begin(point, true); _app.Input.Move(point + new Vector2(100, 20)); _app.Input.End(point + new Vector2(100, 20));
|
||||
Assert.That(_app.Session.Board.CollectedBallIds, Is.Empty);
|
||||
_app.Input.Begin(point, false); _app.Input.Move(point + new Vector2(100, 20)); _app.Input.BeginPinch(100, false);
|
||||
_app.Input.Pinch(200); _app.Input.End(point);
|
||||
Assert.That(_app.Session.Board.CollectedBallIds, Is.Empty); Assert.That(_app.Session.Board.CountedCount, Is.Zero);
|
||||
Assert.That(_app.Session.Camera.distance, Is.EqualTo(4).Within(0.01)); yield return null;
|
||||
}
|
||||
[UnityTest] public IEnumerator OrbitIsCommittedAtEndAndCanInspectEveryDirection()
|
||||
{
|
||||
_app.StartStage(1); yield return null;
|
||||
var original = _app.Session.Camera.rotation; var empty = new Vector2(Screen.width * 0.5f, Screen.height * 0.6f);
|
||||
_app.Input.Begin(empty, false); _app.Input.Move(empty + new Vector2(150, 80));
|
||||
Assert.That(_app.Session.Camera.rotation, Is.EqualTo(original)); _app.Input.Cancel();
|
||||
Assert.That(_app.Session.Camera.rotation, Is.EqualTo(original));
|
||||
_app.Orbit.Orbit(new Vector2(720, 360)); _app.Session.CommitCamera(_app.Orbit.Snapshot());
|
||||
Assert.That(_store.Saved.puzzleStates.Single().camera.rotation.IsValid, Is.True);
|
||||
_app.Orbit.Zoom(1000); Assert.That(_app.Orbit.Snapshot().distance, Is.EqualTo(3));
|
||||
_app.Orbit.Zoom(0.001f); Assert.That(_app.Orbit.Snapshot().distance, Is.EqualTo(15)); yield return null;
|
||||
}
|
||||
[UnityTest] public IEnumerator RestartRestoresOnlyCommittedPuzzleStateAndDoesNotReplayCounts()
|
||||
{
|
||||
var stage = AssetDatabase.LoadAssetAtPath<StageAsset>("Assets/MagnetismHeroes/UnityRuntime/StageAssets/Stage01.asset"); var assetBefore = EditorJsonUtility.ToJson(stage);
|
||||
_app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var point = BallPoint(); Drag(point, point + new Vector2(90, -15));
|
||||
_app.Orbit.Zoom(0.8f); _app.Session.CommitCamera(_app.Orbit.Snapshot()); _app.ShowHome();
|
||||
var position = _store.Saved.puzzleStates.Single().balls.Single().position;
|
||||
Object.Destroy(_app.gameObject); yield return null;
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/MagnetismHeroes/UnityRuntime/Presentation/Prefabs/GameApp.prefab");
|
||||
_app = Object.Instantiate(prefab).GetComponent<GameApp>(); _app.Initialize(_store); _app.StartStage(1); yield return null;
|
||||
Assert.That(_app.Session.Board.Balls.Single().position, Is.EqualTo(position));
|
||||
Assert.That(_app.Session.Board.CollectedBallIds.Length, Is.EqualTo(1)); Assert.That(_app.Session.Board.CountedCount, Is.Zero);
|
||||
Assert.That(_app.Session.Camera.distance, Is.EqualTo(10).Within(0.01)); Assert.That(_app.Voice.PendingCount, Is.Zero);
|
||||
Assert.That(EditorJsonUtility.ToJson(stage), Is.EqualTo(assetBefore));
|
||||
}
|
||||
[UnityTest] public IEnumerator ActualTouchPinchDoesNotStartANewDragUntilBothFingersAreLifted()
|
||||
{
|
||||
_touchscreen = InputSystem.AddDevice<Touchscreen>(); _app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var point = BallPoint(); var second = point + new Vector2(100, 0);
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 1, phase = UnityEngine.InputSystem.TouchPhase.Began, position = point });
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 2, phase = UnityEngine.InputSystem.TouchPhase.Began, position = second }); yield return null; yield return null;
|
||||
Assert.That(_touchscreen.touches.Count(touch => touch.press.isPressed), Is.EqualTo(2));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 2, phase = UnityEngine.InputSystem.TouchPhase.Moved, position = second + new Vector2(70, 0) }); yield return null; yield return null;
|
||||
Assert.That(_app.Orbit.Snapshot().distance, Is.LessThan(8));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 2, phase = UnityEngine.InputSystem.TouchPhase.Ended, position = second }); yield return null; yield return null;
|
||||
var committedCamera = _app.Session.Camera.rotation;
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 1, phase = UnityEngine.InputSystem.TouchPhase.Moved, position = point + new Vector2(90, 0) }); yield return null; yield return null;
|
||||
Assert.That(_app.Orbit.Snapshot().rotation, Is.EqualTo(committedCamera));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 1, phase = UnityEngine.InputSystem.TouchPhase.Ended, position = point + new Vector2(90, 0) }); yield return null;
|
||||
Assert.That(_app.Session.Board.CollectedBallIds, Is.Empty); Assert.That(_app.Session.Board.CountedCount, Is.Zero);
|
||||
}
|
||||
[UnityTest] public IEnumerator ActualBundledVoicePlaysThroughVoiceMixerAndClearsOnNavigation()
|
||||
{
|
||||
var source = _app.GetComponent<AudioSource>(); Assert.That(source.outputAudioMixerGroup.name, Is.EqualTo("Voice"));
|
||||
Assert.That(source.spatialBlend, Is.Zero);
|
||||
_app.StartStage(1); yield return null; Assert.That(source.clip.name, Is.EqualTo("guide_collect")); Assert.That(source.isPlaying, Is.True);
|
||||
Physics.SyncTransforms(); var point = BallPoint(); Drag(point, point + new Vector2(80, 0)); yield return null;
|
||||
Physics.SyncTransforms(); Tap(BallPoint()); yield return null;
|
||||
Assert.That(source.clip.name, Is.EqualTo("count_01")); Assert.That(source.isPlaying, Is.True);
|
||||
_app.ShowHome(); Assert.That(source.isPlaying, Is.False); Assert.That(_app.Voice.PendingCount, Is.Zero);
|
||||
}
|
||||
[UnityTest] public IEnumerator CanceledPinchRestoresCommittedCameraAndIgnoresTheRemainingFinger()
|
||||
{
|
||||
_touchscreen = InputSystem.AddDevice<Touchscreen>(); _app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var point = BallPoint(); var second = point + new Vector2(90, 0); float initial = _app.Session.Camera.distance;
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 11, phase = UnityEngine.InputSystem.TouchPhase.Began, position = point });
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 12, phase = UnityEngine.InputSystem.TouchPhase.Began, position = second }); yield return null; yield return null;
|
||||
Assert.That(_touchscreen.touches.Count(touch => touch.press.isPressed), Is.EqualTo(2));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 12, phase = UnityEngine.InputSystem.TouchPhase.Moved, position = second + new Vector2(90, 0) }); yield return null; yield return null;
|
||||
Assert.That(_app.Orbit.Snapshot().distance, Is.LessThan(initial));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 12, phase = UnityEngine.InputSystem.TouchPhase.Canceled, position = second }); yield return null; yield return null;
|
||||
Assert.That(_app.Orbit.Snapshot().distance, Is.EqualTo(initial)); Assert.That(_app.Session.Camera.distance, Is.EqualTo(initial));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 11, phase = UnityEngine.InputSystem.TouchPhase.Moved, position = point + new Vector2(70, 0) }); yield return null;
|
||||
Assert.That(_app.Orbit.Snapshot().rotation, Is.EqualTo(_app.Session.Camera.rotation));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 11, phase = UnityEngine.InputSystem.TouchPhase.Ended, position = point + new Vector2(70, 0) }); yield return null;
|
||||
Assert.That(_app.Session.Board.CollectedBallIds, Is.Empty);
|
||||
}
|
||||
[UnityTest] public IEnumerator CountVoicesStayOrderedUnderFastInputAndNeverOverlapAGuide()
|
||||
{
|
||||
var source = _app.GetComponent<AudioSource>();
|
||||
_app.Voice.Guide("guide_collect"); _app.Voice.EnqueueCount(1); _app.Voice.EnqueueCount(2); _app.Voice.EnqueueCount(3);
|
||||
Assert.That(source.clip.name, Is.EqualTo("count_01")); Assert.That(_app.Voice.PendingCount, Is.EqualTo(3));
|
||||
float deadline = Time.realtimeSinceStartup + 5;
|
||||
while (source.clip.name == "count_01" && Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(source.clip.name, Is.EqualTo("count_02")); Assert.That(source.isPlaying, Is.True);
|
||||
while (source.clip.name == "count_02" && Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(source.clip.name, Is.EqualTo("count_03")); Assert.That(source.isPlaying, Is.True);
|
||||
while (_app.Voice.PendingCount > 0 && Time.realtimeSinceStartup < deadline) yield return null;
|
||||
Assert.That(_app.Voice.PendingCount, Is.Zero); Assert.That(source.isPlaying, Is.False);
|
||||
}
|
||||
[UnityTest] public IEnumerator TouchReleaseOutsideTheScreenCancelsAnOtherwiseValidDrag()
|
||||
{
|
||||
_touchscreen = InputSystem.AddDevice<Touchscreen>(); _app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var point = BallPoint(); var initial = _app.Session.Board.Balls.Single().position;
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 41, phase = UnityEngine.InputSystem.TouchPhase.Began, position = point }); yield return null; yield return null;
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 41, phase = UnityEngine.InputSystem.TouchPhase.Moved, position = point + new Vector2(50, 10) }); yield return null; yield return null;
|
||||
Assert.That(_app.Presenter.Balls.Values.Single().transform.position, Is.Not.EqualTo(new Vector3(initial.x, initial.y, initial.z)));
|
||||
InputSystem.QueueStateEvent(_touchscreen, new TouchState { touchId = 41, phase = UnityEngine.InputSystem.TouchPhase.Ended, position = new Vector2(-1, point.y) }); yield return null; yield return null;
|
||||
Assert.That(_app.Session.Board.Balls.Single().position, Is.EqualTo(initial)); Assert.That(_app.Session.Board.CollectedBallIds, Is.Empty);
|
||||
}
|
||||
[UnityTest] public IEnumerator FlatFloorColliderMatchesTheVisibleMeshAndKeepsTheFriendReachable()
|
||||
{
|
||||
_app.StartStage(1); yield return null; Physics.SyncTransforms();
|
||||
var floor = _app.transform.Find("Playground/PlaygroundIsland");
|
||||
Assert.That(floor.GetComponent<Collider>(), Is.TypeOf<MeshCollider>());
|
||||
Assert.That(floor.GetComponent<Collider>().bounds.max.y, Is.EqualTo(floor.GetComponent<Renderer>().bounds.max.y).Within(0.01));
|
||||
Assert.That(floor.GetComponent<Collider>().bounds.max.y, Is.LessThan(0)); BallPoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f105e98652f6b64881959d4aed6a120
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using MagnetismHeroes.Core;
|
||||
using MagnetismHeroes.UnityRuntime.Interaction;
|
||||
using MagnetismHeroes.UnityRuntime.Persistence;
|
||||
using MagnetismHeroes.UnityRuntime.Presentation;
|
||||
using MagnetismHeroes.UnityRuntime.StageAssets;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Bootstrap
|
||||
{
|
||||
public sealed class GameApp : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private StageAsset[] _stages;
|
||||
[SerializeField] private GameObject _homePanel;
|
||||
[SerializeField] private GameObject _selectionPanel;
|
||||
[SerializeField] private GameObject _playPanel;
|
||||
[SerializeField] private GameObject _world;
|
||||
[SerializeField] private TMP_Text _instruction;
|
||||
[SerializeField] private TMP_Text _counter;
|
||||
[SerializeField] private TMP_Text _stageTitle;
|
||||
[SerializeField] private TMP_Text _saveNotice;
|
||||
[SerializeField] private UnityEngine.UI.Button _playButton;
|
||||
[SerializeField] private UnityEngine.UI.Button _continueButton;
|
||||
[SerializeField] private UnityEngine.UI.Button _stageOneButton;
|
||||
[SerializeField] private UnityEngine.UI.Button _homeButton;
|
||||
[SerializeField] private UnityEngine.UI.Button _selectionHomeButton;
|
||||
[SerializeField] private BoardPresenter _presenter;
|
||||
[SerializeField] private OrbitCamera _orbit;
|
||||
[SerializeField] private BoardInput _input;
|
||||
[SerializeField] private VoicePlayer _voice;
|
||||
public GameSession Session { get; private set; }
|
||||
public BoardPresenter Presenter => _presenter;
|
||||
public BoardInput Input => _input;
|
||||
public OrbitCamera Orbit => _orbit;
|
||||
public VoicePlayer Voice => _voice;
|
||||
public string Instruction => _instruction.text;
|
||||
public string Counter => _counter.text;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_playButton.onClick.AddListener(ShowSelection);
|
||||
_continueButton.onClick.AddListener(ContinueFreePlay);
|
||||
_stageOneButton.onClick.AddListener(() => StartStage(1));
|
||||
_homeButton.onClick.AddListener(ShowHome);
|
||||
_selectionHomeButton.onClick.AddListener(ShowHome);
|
||||
}
|
||||
private void Start()
|
||||
{
|
||||
if (Session == null) Initialize(new LocalProgressStore(Path.Combine(Application.persistentDataPath, "progress.json"),
|
||||
_stages.Select(stage => stage.ToDefinition()).ToArray()));
|
||||
}
|
||||
public void Initialize(IProgressStore store)
|
||||
{
|
||||
Session = new GameSession(_stages.Select(stage => stage.ToDefinition()), store);
|
||||
_saveNotice.text = Session.LastSaveError == null ? "" : Session.LastSaveError.StartsWith("Recovered", StringComparison.Ordinal)
|
||||
? "이전 기록으로 이어서 시작할게요." : "기록을 읽지 못해 처음부터 시작할게요.";
|
||||
if (Session.LastSaveError != null) Debug.LogWarning("[ProgressLoad] " + Session.LastSaveError);
|
||||
Refresh(true);
|
||||
}
|
||||
public void ShowSelection()
|
||||
{ _input.Cancel(); _voice.Clear(); Session.ShowSelection(); Refresh(true); }
|
||||
public void ShowHome()
|
||||
{ _input.Cancel(); _voice.Clear(); Session.ShowHome(); Refresh(true); }
|
||||
public void StartStage(int id)
|
||||
{
|
||||
_input.Cancel(); _voice.Clear();
|
||||
if (!Session.StartStage(id)) return;
|
||||
Refresh(true);
|
||||
// Restoring never replays historical count/celebration clips.
|
||||
if (Session.Board.CollectedBallIds.Length == 0) _voice.Guide("guide_collect");
|
||||
}
|
||||
public void ContinueFreePlay()
|
||||
{ _input.Cancel(); _voice.Clear(); if (Session.ContinueFreePlay()) Refresh(true); }
|
||||
public void CommitMove(string groupId, Position3 delta)
|
||||
{
|
||||
var result = Session.MoveGroup(groupId, delta);
|
||||
Refresh(false);
|
||||
if (result.Accepted && Session.Screen == SessionScreen.Puzzle && Session.Board.CanCount) _voice.Guide("guide_count");
|
||||
}
|
||||
public void CountBall(string ballId)
|
||||
{
|
||||
var result = Session.Count(ballId);
|
||||
if (result.Accepted) _voice.EnqueueCount(result.Count);
|
||||
if (result.Accepted) Refresh(false);
|
||||
if (!result.Accepted && result.Reason == RejectionReason.NotCollected)
|
||||
{
|
||||
_instruction.text = "친구를 먼저 끌어와 볼까?";
|
||||
if (_presenter.Balls.TryGetValue(ballId, out var friend)) friend.Encourage();
|
||||
}
|
||||
}
|
||||
private void Refresh(bool applyCamera)
|
||||
{
|
||||
var screen = Session.Screen;
|
||||
_homePanel.SetActive(screen == SessionScreen.Home);
|
||||
_selectionPanel.SetActive(screen == SessionScreen.StageSelection);
|
||||
bool playing = screen == SessionScreen.Puzzle || screen == SessionScreen.FreePlay;
|
||||
_playPanel.SetActive(playing); _world.SetActive(playing);
|
||||
_continueButton.gameObject.SetActive(Session.HasFreePlay);
|
||||
if (applyCamera) _orbit.Apply(Session.Camera);
|
||||
_presenter.Render(Session.Board);
|
||||
if (!playing) return;
|
||||
_stageTitle.text = screen == SessionScreen.FreePlay ? "자유 놀이터" : $"숫자 {Session.Board.BallCount} 친구 찾기";
|
||||
_counter.text = screen == SessionScreen.FreePlay ? $"친구 {Session.Board.BallCount}" : $"센 친구 {Session.Board.CountedCount} / {Session.Board.BallCount}";
|
||||
_instruction.text = screen == SessionScreen.FreePlay ? "해냈어! 친구와 자유롭게 놀아 보자."
|
||||
: Session.Board.CanCount ? "모두 모았네! 하나씩 눌러 세어 보자." : "친구를 찾아 끌어와 볼까?";
|
||||
}
|
||||
private void OnApplicationPause(bool paused)
|
||||
{ if (paused && Session != null) { _input.Cancel(); _voice.Clear(); Session.SaveCurrent(); } }
|
||||
private void OnApplicationQuit() { if (Session != null) { _input.Cancel(); Session.SaveCurrent(); } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d19ee043fa8f8da4e96eec5e9b810d96
|
||||
@@ -0,0 +1,170 @@
|
||||
using System.Collections.Generic;
|
||||
using MagnetismHeroes.Core;
|
||||
using MagnetismHeroes.UnityRuntime.Bootstrap;
|
||||
using MagnetismHeroes.UnityRuntime.Presentation;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Interaction
|
||||
{
|
||||
public sealed class BoardInput : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private GameApp _app;
|
||||
[SerializeField] private BoardPresenter _presenter;
|
||||
[SerializeField] private OrbitCamera _orbit;
|
||||
[SerializeField] private float _dragThreshold = 14;
|
||||
private enum Gesture { None, Blocked, Friend, Orbit, Pinch }
|
||||
private Gesture _gesture;
|
||||
private Vector2 _start, _last;
|
||||
private string _ballId, _groupId;
|
||||
private bool _dragged;
|
||||
private Plane _dragPlane;
|
||||
private Vector3 _grabPoint, _previewDelta;
|
||||
private float _pinchDistance;
|
||||
private int _fingerId = -1;
|
||||
private bool _waitForAllTouchesReleased;
|
||||
private int _pinchFirstId = -1, _pinchSecondId = -1;
|
||||
public bool AcceptInput => _app.Session != null && _app.Session.Board != null;
|
||||
|
||||
public void Begin(Vector2 point, bool uiBlocked)
|
||||
{
|
||||
Cancel();
|
||||
if (!AcceptInput) return;
|
||||
_start = _last = point;
|
||||
if (uiBlocked) { _gesture = Gesture.Blocked; return; }
|
||||
Physics.SyncTransforms();
|
||||
var ray = _orbit.Camera.ScreenPointToRay(point);
|
||||
if (Physics.Raycast(ray, out var hit, 100) && hit.collider.TryGetComponent<BallView>(out var ball))
|
||||
{
|
||||
_gesture = Gesture.Friend; _ballId = ball.BallId; _groupId = ball.GroupId;
|
||||
_dragPlane = new Plane(_orbit.Camera.transform.forward, hit.point);
|
||||
_grabPoint = hit.point;
|
||||
}
|
||||
else _gesture = Gesture.Orbit;
|
||||
}
|
||||
|
||||
public void Move(Vector2 point)
|
||||
{
|
||||
if (_gesture == Gesture.None || _gesture == Gesture.Blocked || _gesture == Gesture.Pinch) return;
|
||||
_dragged |= (point - _start).sqrMagnitude >= _dragThreshold * _dragThreshold;
|
||||
if (_dragged && _gesture == Gesture.Friend)
|
||||
{
|
||||
var ray = _orbit.Camera.ScreenPointToRay(point);
|
||||
if (_dragPlane.Raycast(ray, out var distance)) { _previewDelta = ray.GetPoint(distance) - _grabPoint; _presenter.PreviewGroup(_groupId, _previewDelta); }
|
||||
}
|
||||
else if (_dragged && _gesture == Gesture.Orbit) _orbit.Orbit(point - _last);
|
||||
_last = point;
|
||||
}
|
||||
|
||||
public void End(Vector2 point, bool canceled = false)
|
||||
{
|
||||
bool inside = point.x >= 0 && point.x < Screen.width && point.y >= 0 && point.y < Screen.height;
|
||||
if (canceled || !inside) { Cancel(); return; }
|
||||
if (_gesture == Gesture.Friend)
|
||||
{
|
||||
if (_dragged) _app.CommitMove(_groupId, BoardPresenter.ToPosition(_previewDelta));
|
||||
else _app.CountBall(_ballId);
|
||||
}
|
||||
else if (_gesture == Gesture.Orbit && _dragged) _app.Session.CommitCamera(_orbit.Snapshot());
|
||||
else if (_gesture == Gesture.Pinch) _app.Session.CommitCamera(_orbit.Snapshot());
|
||||
_gesture = Gesture.None; _dragged = false; _previewDelta = Vector3.zero; _fingerId = -1;
|
||||
}
|
||||
|
||||
public void BeginPinch(float distance, bool uiBlocked)
|
||||
{
|
||||
Cancel();
|
||||
_gesture = uiBlocked || !AcceptInput ? Gesture.Blocked : Gesture.Pinch;
|
||||
_pinchDistance = distance;
|
||||
}
|
||||
public void Pinch(float distance)
|
||||
{
|
||||
if (_gesture != Gesture.Pinch || distance <= 0 || _pinchDistance <= 0) return;
|
||||
_orbit.Zoom(distance / _pinchDistance); _pinchDistance = distance;
|
||||
}
|
||||
public void Cancel()
|
||||
{
|
||||
if (_gesture == Gesture.Friend) _presenter.CancelPreview();
|
||||
if ((_gesture == Gesture.Orbit || _gesture == Gesture.Pinch) && _app.Session != null) _orbit.Apply(_app.Session.Camera);
|
||||
_gesture = Gesture.None; _dragged = false; _previewDelta = Vector3.zero; _fingerId = -1;
|
||||
_waitForAllTouchesReleased = false; _pinchFirstId = _pinchSecondId = -1;
|
||||
}
|
||||
|
||||
private bool IsUI(Vector2 point)
|
||||
{
|
||||
if (EventSystem.current == null) return false;
|
||||
var hits = new List<RaycastResult>(); EventSystem.current.RaycastAll(new PointerEventData(EventSystem.current) { position = point }, hits);
|
||||
return hits.Count > 0;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!AcceptInput) return;
|
||||
var touchscreen = Touchscreen.current;
|
||||
if (touchscreen != null)
|
||||
{
|
||||
if (_gesture == Gesture.Pinch)
|
||||
{
|
||||
foreach (var touch in touchscreen.touches)
|
||||
{
|
||||
var id = touch.touchId.ReadValue();
|
||||
if ((id == _pinchFirstId || id == _pinchSecondId) && touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Canceled)
|
||||
{ Cancel(); _waitForAllTouchesReleased = true; return; }
|
||||
}
|
||||
}
|
||||
var active = new List<UnityEngine.InputSystem.Controls.TouchControl>();
|
||||
foreach (var touch in touchscreen.touches) if (touch.press.isPressed) active.Add(touch);
|
||||
// A canceled/finished pinch cannot restart when a third finger joins a remaining finger.
|
||||
if (_waitForAllTouchesReleased && _gesture == Gesture.None && active.Count > 0) return;
|
||||
if (active.Count >= 2)
|
||||
{
|
||||
var a = active[0].position.ReadValue(); var b = active[1].position.ReadValue();
|
||||
if (_gesture != Gesture.Pinch && _gesture != Gesture.Blocked)
|
||||
{
|
||||
BeginPinch(Vector2.Distance(a, b), IsUI(a) || IsUI(b));
|
||||
_pinchFirstId = active[0].touchId.ReadValue(); _pinchSecondId = active[1].touchId.ReadValue();
|
||||
}
|
||||
else Pinch(Vector2.Distance(a, b));
|
||||
_waitForAllTouchesReleased = true;
|
||||
return;
|
||||
}
|
||||
if (_waitForAllTouchesReleased)
|
||||
{
|
||||
if (_gesture == Gesture.Pinch) End(_last);
|
||||
if (active.Count == 0) { _waitForAllTouchesReleased = false; _gesture = Gesture.None; _fingerId = -1; }
|
||||
return;
|
||||
}
|
||||
if (_gesture == Gesture.Pinch || (active.Count == 0 && _gesture == Gesture.Blocked))
|
||||
{ End(_last); _fingerId = -1; return; }
|
||||
if (active.Count == 1)
|
||||
{
|
||||
var touch = active[0]; var point = touch.position.ReadValue();
|
||||
if (_fingerId == -1)
|
||||
{ Begin(point, IsUI(point)); _fingerId = touch.touchId.ReadValue(); }
|
||||
else Move(point);
|
||||
return;
|
||||
}
|
||||
if (_fingerId != -1)
|
||||
{
|
||||
bool canceled = false;
|
||||
Vector2 releasePoint = _last;
|
||||
foreach (var touch in touchscreen.touches)
|
||||
if (touch.touchId.ReadValue() == _fingerId)
|
||||
{ canceled = touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Canceled; releasePoint = touch.position.ReadValue(); break; }
|
||||
if (!canceled) Move(releasePoint);
|
||||
End(releasePoint, canceled); return;
|
||||
}
|
||||
}
|
||||
var mouse = Mouse.current;
|
||||
if (mouse == null) return;
|
||||
var position = mouse.position.ReadValue();
|
||||
if (mouse.leftButton.wasPressedThisFrame) Begin(position, IsUI(position));
|
||||
if (mouse.leftButton.isPressed) Move(position);
|
||||
if (mouse.leftButton.wasReleasedThisFrame) End(position);
|
||||
if (mouse.scroll.ReadValue().y != 0 && !IsUI(position))
|
||||
{ _orbit.Zoom(Mathf.Exp(mouse.scroll.ReadValue().y * 0.001f)); _app.Session.CommitCamera(_orbit.Snapshot()); }
|
||||
}
|
||||
private void OnApplicationPause(bool paused) { if (paused) Cancel(); }
|
||||
private void OnDisable() => Cancel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 38cf3d2ad1224c244a0e1ad7b52602c1
|
||||
@@ -0,0 +1,36 @@
|
||||
using MagnetismHeroes.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Interaction
|
||||
{
|
||||
public sealed class OrbitCamera : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Camera _camera;
|
||||
[SerializeField] private float _minDistance = 3;
|
||||
[SerializeField] private float _maxDistance = 15;
|
||||
[SerializeField] private float _degreesPerPixel = 0.25f;
|
||||
private Vector3 _target;
|
||||
private Quaternion _rotation;
|
||||
private float _distance;
|
||||
public Camera Camera => _camera;
|
||||
|
||||
public void Apply(CameraState state)
|
||||
{
|
||||
_target = new Vector3(state.target.x, state.target.y, state.target.z);
|
||||
_rotation = new Quaternion(state.rotation.x, state.rotation.y, state.rotation.z, state.rotation.w);
|
||||
_distance = Mathf.Clamp(state.distance, _minDistance, _maxDistance); UpdateCamera();
|
||||
}
|
||||
public void Orbit(Vector2 delta)
|
||||
{
|
||||
_rotation = Quaternion.AngleAxis(delta.x * _degreesPerPixel, Vector3.up) * _rotation
|
||||
* Quaternion.AngleAxis(-delta.y * _degreesPerPixel, Vector3.right);
|
||||
UpdateCamera();
|
||||
}
|
||||
public void Zoom(float ratio)
|
||||
{ if (ratio > 0 && float.IsFinite(ratio)) { _distance = Mathf.Clamp(_distance / ratio, _minDistance, _maxDistance); UpdateCamera(); } }
|
||||
public CameraState Snapshot() => new CameraState { target = new Position3(_target.x, _target.y, _target.z),
|
||||
rotation = new Rotation4(_rotation.x, _rotation.y, _rotation.z, _rotation.w), distance = _distance };
|
||||
private void UpdateCamera()
|
||||
{ _camera.transform.SetPositionAndRotation(_target + _rotation * new Vector3(0, 0, -_distance), _rotation); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a79bcabf76823224fae318cd87bc186d
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MagnetismHeroes.Core;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Persistence
|
||||
{
|
||||
public sealed class LocalProgressStore : IProgressStore
|
||||
{
|
||||
private readonly string _path;
|
||||
private readonly IReadOnlyList<StageDefinition> _definitions;
|
||||
private bool _preserveDamagedOriginal;
|
||||
private sealed class SaveFieldsResolver : DefaultContractResolver
|
||||
{
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization serialization)
|
||||
=> base.CreateProperties(type, serialization).Where(property => type.GetField(property.UnderlyingName) != null).ToList();
|
||||
}
|
||||
private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings { ContractResolver = new SaveFieldsResolver() };
|
||||
public LocalProgressStore(string path, IReadOnlyList<StageDefinition> definitions)
|
||||
{ _path = path; _definitions = definitions; }
|
||||
|
||||
public bool TryLoad(out ProgressSave save, out string error)
|
||||
{
|
||||
save = null; error = null;
|
||||
if (!File.Exists(_path)) { save = new ProgressSave(); return true; }
|
||||
if (Read(_path, out save, out error)) return true;
|
||||
var originalError = error;
|
||||
if (Read(_path + ".bak", out save, out var backupError))
|
||||
{ error = "Recovered valid backup: " + originalError; _preserveDamagedOriginal = true; return true; }
|
||||
_preserveDamagedOriginal = true;
|
||||
error = "Invalid primary and backup: " + originalError + "; " + backupError;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool Read(string path, out ProgressSave save, out string error)
|
||||
{
|
||||
save = null;
|
||||
try
|
||||
{
|
||||
using var reader = new JsonTextReader(new StringReader(File.ReadAllText(path))) { DateParseHandling = DateParseHandling.None };
|
||||
var root = JObject.Load(reader, new JsonLoadSettings { DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error });
|
||||
if (reader.Read()) throw new InvalidDataException("Trailing JSON content.");
|
||||
Require(root, "schemaVersion", "completedStageIds", "seenTutorialIds", "puzzleStates", "latestFreePlay");
|
||||
Scalar(root["schemaVersion"], JTokenType.Integer);
|
||||
foreach (var id in Array(root["completedStageIds"])) Scalar(id, JTokenType.Integer);
|
||||
foreach (var id in Array(root["seenTutorialIds"])) Scalar(id, JTokenType.String);
|
||||
foreach (var state in Array(root["puzzleStates"]))
|
||||
{
|
||||
Require(state, "stageId", "balls", "groups", "collectedBallIds", "countedBallIds", "camera");
|
||||
Scalar(state["stageId"], JTokenType.Integer);
|
||||
foreach (var id in Array(state["collectedBallIds"])) Scalar(id, JTokenType.String);
|
||||
foreach (var id in Array(state["countedBallIds"])) Scalar(id, JTokenType.String);
|
||||
RequireBoard(state);
|
||||
}
|
||||
if (root["latestFreePlay"].Type != JTokenType.Null)
|
||||
{ Require(root["latestFreePlay"], "sourceStageId", "balls", "groups", "camera"); Scalar(root["latestFreePlay"]["sourceStageId"], JTokenType.Integer); RequireBoard(root["latestFreePlay"]); }
|
||||
save = root.ToObject<ProgressSave>(JsonSerializer.Create(SerializerSettings));
|
||||
if (!SaveValidator.TryValidate(save, _definitions, out error)) { save = null; return false; }
|
||||
return true;
|
||||
}
|
||||
catch (Exception exception) when (exception is IOException || exception is UnauthorizedAccessException
|
||||
|| exception is JsonException || exception is InvalidDataException || exception is ArgumentException)
|
||||
{ save = null; error = exception.Message; return false; }
|
||||
}
|
||||
|
||||
private static void RequireBoard(JToken board)
|
||||
{
|
||||
foreach (var ball in Array(board["balls"]))
|
||||
{ Require(ball, "id", "position"); Scalar(ball["id"], JTokenType.String); Vector(ball["position"], "x", "y", "z"); }
|
||||
foreach (var group in Array(board["groups"]))
|
||||
{ Require(group, "id", "ballIds"); Scalar(group["id"], JTokenType.String); foreach (var id in Array(group["ballIds"])) Scalar(id, JTokenType.String); }
|
||||
Require(board["camera"], "target", "rotation", "distance");
|
||||
Vector(board["camera"]["target"], "x", "y", "z");
|
||||
Vector(board["camera"]["rotation"], "x", "y", "z", "w"); Number(board["camera"]["distance"]);
|
||||
}
|
||||
private static void Vector(JToken token, params string[] fields)
|
||||
{ Require(token, fields); foreach (var field in fields) Number(token[field]); }
|
||||
private static void Number(JToken token)
|
||||
{ if (token == null || (token.Type != JTokenType.Integer && token.Type != JTokenType.Float)) throw new InvalidDataException("Expected a JSON number."); }
|
||||
private static void Scalar(JToken token, JTokenType type)
|
||||
{ if (token == null || token.Type != type) throw new InvalidDataException("Expected a JSON " + type + "."); }
|
||||
private static JArray Array(JToken token) => token as JArray ?? throw new InvalidDataException("Expected a JSON array.");
|
||||
private static void Require(JToken token, params string[] fields)
|
||||
{
|
||||
if (!(token is JObject objectValue)) throw new InvalidDataException("Expected a JSON object.");
|
||||
foreach (var field in fields)
|
||||
if (objectValue.Property(field) == null || (field != "latestFreePlay" && objectValue[field].Type == JTokenType.Null))
|
||||
throw new InvalidDataException("Missing or null field: " + field);
|
||||
}
|
||||
|
||||
public bool TrySave(ProgressSave save, out string error)
|
||||
{
|
||||
if (!SaveValidator.TryValidate(save, _definitions, out error)) return false;
|
||||
string temporary = _path + ".tmp";
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(_path)));
|
||||
if (_preserveDamagedOriginal && File.Exists(_path))
|
||||
{
|
||||
File.Copy(_path, _path + ".damaged-" + Guid.NewGuid().ToString("N"));
|
||||
_preserveDamagedOriginal = false;
|
||||
}
|
||||
using (var stream = new FileStream(temporary, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
using (var writer = new StreamWriter(stream))
|
||||
{ writer.Write(JsonConvert.SerializeObject(save, Formatting.Indented, SerializerSettings)); writer.Flush(); stream.Flush(true); }
|
||||
if (File.Exists(_path))
|
||||
{
|
||||
// Never replace a valid recovered backup with the invalid primary.
|
||||
if (Read(_path, out _, out _)) File.Replace(temporary, _path, _path + ".bak");
|
||||
else File.Replace(temporary, _path, null);
|
||||
}
|
||||
else File.Move(temporary, _path);
|
||||
error = null; return true;
|
||||
}
|
||||
catch (Exception exception) when (exception is IOException || exception is UnauthorizedAccessException)
|
||||
{ error = exception.Message; return false; }
|
||||
finally { if (File.Exists(temporary)) File.Delete(temporary); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59a278725854f2249a18d8377d8edfbb
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f93db43014b63214b9ed0141e2680cc4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,167 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!244 &-7089420846949506769
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 98679871d90ec6b45a4b5d0705f80a00
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 2856aa1af04b0d04c808cc2a03ea79c0
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!244 &-6091608972580811098
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 79485d7443da65e48bd63be2330046db
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 365c5e490a44a264cab018db1169d2eb
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &-2216692613774908723
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Voice
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 71a8d7d591bfa734e9dbc6d11ca98e3f
|
||||
m_Children: []
|
||||
m_Volume: 18cb311bf320ef24d92494e0a399bc0b
|
||||
m_Pitch: 8f38385d1f0287741b71cdf82405d317
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -6091608972580811098}
|
||||
m_UserColorIndex: 0
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!241 &24100000
|
||||
AudioMixerController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: GameAudio
|
||||
m_OutputGroup: {fileID: 0}
|
||||
m_MasterGroup: {fileID: 24300002}
|
||||
m_Snapshots:
|
||||
- {fileID: 24500006}
|
||||
m_StartSnapshot: {fileID: 24500006}
|
||||
m_SuspendThreshold: -80
|
||||
m_EnableSuspend: 1
|
||||
m_UpdateMode: 0
|
||||
m_ExposedParameters: []
|
||||
m_AudioMixerGroupViews: []
|
||||
m_CurrentViewIndex: 0
|
||||
m_TargetSnapshot: {fileID: 24500006}
|
||||
--- !u!243 &24300002
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Master
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: 03ab91f07f4239546b51a659b80695bf
|
||||
m_Children:
|
||||
- {fileID: -2216692613774908723}
|
||||
- {fileID: 3873177042007149833}
|
||||
- {fileID: 7202041017813097757}
|
||||
m_Volume: 07603f28db3be57459e8966a482457e6
|
||||
m_Pitch: 01dbd86b7adabd944aa50c028a386ad3
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 24400004}
|
||||
m_UserColorIndex: 0
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!244 &24400004
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: a6bd621586c9d5d41ab4bc3993428ec0
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 34a768e8d80da35469c8274c4f00ade9
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!245 &24500006
|
||||
AudioMixerSnapshotController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Snapshot
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_SnapshotID: 9e0c16a37459f9440a75e1c95ac0f2ff
|
||||
m_FloatValues: {}
|
||||
m_TransitionOverrides: {}
|
||||
--- !u!244 &3402812816098948721
|
||||
AudioMixerEffectController:
|
||||
m_ObjectHideFlags: 3
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name:
|
||||
m_EffectID: 7e808862be18fc8418bed7842bf2e425
|
||||
m_EffectName: Attenuation
|
||||
m_MixLevel: 7dcba25d01d1a9c4e8d7e7326a5f06e1
|
||||
m_Parameters: []
|
||||
m_SendTarget: {fileID: 0}
|
||||
m_EnableWetMix: 0
|
||||
m_Bypass: 0
|
||||
--- !u!243 &3873177042007149833
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: SFX
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: b16ec89eb1c98d54a9bdcebe9f3ab8f8
|
||||
m_Children: []
|
||||
m_Volume: 6bed3b15a512d0641ba0caedab6ace56
|
||||
m_Pitch: cb707d37cbe34124abb1a93227b9e667
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: 3402812816098948721}
|
||||
m_UserColorIndex: 0
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
--- !u!243 &7202041017813097757
|
||||
AudioMixerGroupController:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Music
|
||||
m_AudioMixer: {fileID: 24100000}
|
||||
m_GroupID: a284af71a7b1edc44aae0a299dc13fcd
|
||||
m_Children: []
|
||||
m_Volume: b537c5ab5441fb543a9daf3118f75fe1
|
||||
m_Pitch: 606a24fcea5e35d45aad10c9e6dce740
|
||||
m_Send: 00000000000000000000000000000000
|
||||
m_Effects:
|
||||
- {fileID: -7089420846949506769}
|
||||
m_UserColorIndex: 0
|
||||
m_Mute: 0
|
||||
m_Solo: 0
|
||||
m_BypassEffects: 0
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65ecf35a597af1f4681307a83e447216
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 24100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c58ab521f033fea4b82df3cffcc6bb44
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a76c0490e02b424d9aedcf995d86978
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4f0cc83afe60704fba158ceb7fa2a11
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 214880dd0fc0b8c45b1c89113aa637aa
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dae96de5a95a00d42ba058ddff57a393
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e90c4eabbbf54ca4ca89f10b7cee687b
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ed9016c0db818c4ca7c195ab8b1389f
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8543174010591bd458648d7fe6bf0195
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fbab9ad873226564fa721fccf627607a
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a393e4fe5d01d634d92346fdb5e8e06f
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d4eedabd1a1acd42a53f841c8add870
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20a08bc78ef7a2e4cb977aff160df2a5
|
||||
AudioImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 8
|
||||
defaultSettings:
|
||||
serializedVersion: 2
|
||||
loadType: 0
|
||||
sampleRateSetting: 0
|
||||
sampleRateOverride: 44100
|
||||
compressionFormat: 0
|
||||
quality: 1
|
||||
conversionMode: 0
|
||||
preloadAudioData: 1
|
||||
platformSettingOverrides: {}
|
||||
forceToMono: 1
|
||||
normalize: 1
|
||||
loadInBackground: 0
|
||||
ambisonic: 0
|
||||
3D: 1
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Presentation
|
||||
{
|
||||
public sealed class BallView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Renderer _body;
|
||||
[SerializeField] private GameObject _countMarker;
|
||||
private MaterialPropertyBlock _colors;
|
||||
private Color _normalColor;
|
||||
private float _encourageUntil;
|
||||
public string BallId { get; private set; }
|
||||
public string GroupId { get; private set; }
|
||||
public void Bind(string ballId, string groupId, bool counted)
|
||||
{ BallId = ballId; GroupId = groupId; _countMarker.SetActive(counted); }
|
||||
private void Awake() { _colors = new MaterialPropertyBlock(); _normalColor = _body.sharedMaterial.color; }
|
||||
public void Encourage() => _encourageUntil = Time.unscaledTime + 0.35f;
|
||||
private void Update()
|
||||
{
|
||||
float glow = Mathf.Clamp01((_encourageUntil - Time.unscaledTime) / 0.35f);
|
||||
_colors.SetColor("_BaseColor", Color.Lerp(_normalColor, Color.white, glow * 0.7f)); _body.SetPropertyBlock(_colors);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef4ac8f42ba5a5343a5f0474eef2a1af
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MagnetismHeroes.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Presentation
|
||||
{
|
||||
public sealed class BoardPresenter : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private BallView _ballPrefab;
|
||||
[SerializeField] private GroupBadge _badgePrefab;
|
||||
[SerializeField] private Camera _camera;
|
||||
private readonly Dictionary<string, BallView> _balls = new Dictionary<string, BallView>();
|
||||
private readonly List<GroupBadge> _badges = new List<GroupBadge>();
|
||||
private BoardRules _board;
|
||||
public Camera Camera => _camera;
|
||||
public IReadOnlyDictionary<string, BallView> Balls => _balls;
|
||||
|
||||
public void Render(BoardRules board)
|
||||
{
|
||||
_board = board;
|
||||
foreach (var view in _balls.Values) { view.gameObject.SetActive(false); Destroy(view.gameObject); }
|
||||
foreach (var badge in _badges) { badge.gameObject.SetActive(false); Destroy(badge.gameObject); }
|
||||
_balls.Clear(); _badges.Clear();
|
||||
if (board == null) return;
|
||||
foreach (var group in board.Groups)
|
||||
{
|
||||
foreach (var ballId in group.ballIds)
|
||||
{
|
||||
var state = board.Balls.First(ball => ball.id == ballId);
|
||||
var ball = Instantiate(_ballPrefab, ToVector(state.position), Quaternion.identity, transform);
|
||||
ball.Bind(ballId, group.id, board.CountedBallIds.Contains(ballId)); _balls.Add(ballId, ball);
|
||||
}
|
||||
_badges.Add(Instantiate(_badgePrefab, transform));
|
||||
}
|
||||
PositionBadges();
|
||||
}
|
||||
|
||||
public void PreviewGroup(string groupId, Vector3 delta)
|
||||
{
|
||||
foreach (var state in _board.Balls)
|
||||
_balls[state.id].transform.position = ToVector(state.position) + (_balls[state.id].GroupId == groupId ? delta : Vector3.zero);
|
||||
PositionBadges();
|
||||
}
|
||||
|
||||
public void CancelPreview()
|
||||
{
|
||||
if (_board == null) return;
|
||||
foreach (var state in _board.Balls) _balls[state.id].transform.position = ToVector(state.position);
|
||||
PositionBadges();
|
||||
}
|
||||
|
||||
private void PositionBadges()
|
||||
{
|
||||
if (_board == null) return;
|
||||
var groups = _board.Groups;
|
||||
for (int index = 0; index < groups.Length; index++)
|
||||
{
|
||||
var group = groups[index];
|
||||
var center = group.ballIds.Select(id => _balls[id].transform.position).Aggregate(Vector3.zero, (sum, value) => sum + value) / group.ballIds.Length;
|
||||
var representative = _balls[group.ballIds[0]].transform.position;
|
||||
_badges[index].Bind(group.ballIds.Length, center + Vector3.up * 0.95f,
|
||||
representative - _camera.transform.forward * 0.49f);
|
||||
_badges[index].FaceCamera(_camera);
|
||||
}
|
||||
}
|
||||
private void LateUpdate() => PositionBadges();
|
||||
public static Vector3 ToVector(Position3 position) => new Vector3(position.x, position.y, position.z);
|
||||
public static Position3 ToPosition(Vector3 vector) => new Position3(vector.x, vector.y, vector.z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e02cea646173d344589aa315d0582d6b
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03488cd627303b84cb513583e6c9f0a0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+2369
File diff suppressed because one or more lines are too long
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5bc77ef7ce7c7e4d85ac578cfcd6646
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c7bde640ec97864e8ec7915c144fd63
|
||||
TrueTypeFontImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
fontSize: 16
|
||||
forceTextureCase: -2
|
||||
characterSpacing: 0
|
||||
characterPadding: 1
|
||||
includeFontData: 1
|
||||
fontNames:
|
||||
- Noto Sans CJK KR
|
||||
fallbackFontReferences: []
|
||||
customCharacters:
|
||||
fontRenderingMode: 0
|
||||
ascentCalculationMode: 1
|
||||
useLegacyBoundsCalculation: 0
|
||||
shouldRoundAdvanceValue: 1
|
||||
subsetRecipes: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Presentation
|
||||
{
|
||||
public sealed class GroupBadge : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_Text _number;
|
||||
[SerializeField] private Transform _face;
|
||||
public void Bind(int count, Vector3 numberPosition, Vector3 facePosition)
|
||||
{ _number.text = count.ToString(); _number.transform.position = numberPosition; _face.position = facePosition; }
|
||||
public void FaceCamera(Camera camera)
|
||||
{ _number.transform.rotation = camera.transform.rotation; _face.rotation = camera.transform.rotation; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dfc933dbfe92d64f990d1aa289a03d4
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef2acd91d910ab1429f59df134e7dd35
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-2381720020644801332
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: CountGold
|
||||
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
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}
|
||||
- _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}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _GlossinessSource: 0
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _ScreenSpaceReflectionsContributeTransparent: 1
|
||||
- _Shininess: 0
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessSource: 0
|
||||
- _SpecSource: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 0.76, b: 0.14, a: 1}
|
||||
- _Color: {r: 1, g: 0.76, b: 0.13999996, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6eb301d5baaa3b4dba3ce2228f17fa3
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-4369384185313545078
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: FaceInk
|
||||
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
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}
|
||||
- _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}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _GlossinessSource: 0
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _ScreenSpaceReflectionsContributeTransparent: 1
|
||||
- _Shininess: 0
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessSource: 0
|
||||
- _SpecSource: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 0.12, g: 0.2, b: 0.31, a: 1}
|
||||
- _Color: {r: 0.11999995, g: 0.19999996, b: 0.30999997, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f625349e1f7edf249bc2f0006bde7ccf
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
%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: MagnetBlue
|
||||
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
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}
|
||||
- _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}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _GlossinessSource: 0
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _ScreenSpaceReflectionsContributeTransparent: 1
|
||||
- _Shininess: 0
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessSource: 0
|
||||
- _SpecSource: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 0.15, g: 0.68, b: 0.92, a: 1}
|
||||
- _Color: {r: 0.14999998, g: 0.68, b: 0.92, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
--- !u!114 &3373645068005721598
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
|
||||
version: 10
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec5c546652eacdf4f9aa3fa65eb0c385
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-5884834840082439187
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: PlaygroundMint
|
||||
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
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}
|
||||
- _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}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _GlossinessSource: 0
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _ScreenSpaceReflectionsContributeTransparent: 1
|
||||
- _Shininess: 0
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessSource: 0
|
||||
- _SpecSource: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 0.65, g: 0.88, b: 0.73, a: 1}
|
||||
- _Color: {r: 0.65, g: 0.88, b: 0.73, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aaf8256cf3ae3b74ca9f97bd370459f7
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,105 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &-3881899038799102625
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 11
|
||||
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: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion
|
||||
version: 10
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: ToyCoral
|
||||
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap:
|
||||
RenderType: Opaque
|
||||
disabledShaderPasses:
|
||||
- MOTIONVECTORS
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BaseMap:
|
||||
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}
|
||||
- _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}
|
||||
- _SpecGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_Lightmaps:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_LightmapsInd:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- unity_ShadowMasks:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _AddPrecomputedVelocity: 0
|
||||
- _AlphaClip: 0
|
||||
- _AlphaToMask: 0
|
||||
- _Blend: 0
|
||||
- _BlendModePreserveSpecular: 1
|
||||
- _BumpScale: 1
|
||||
- _Cull: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _GlossinessSource: 0
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _ScreenSpaceReflectionsContributeTransparent: 1
|
||||
- _Shininess: 0
|
||||
- _Smoothness: 0.5
|
||||
- _SmoothnessSource: 0
|
||||
- _SpecSource: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _SrcBlendAlpha: 1
|
||||
- _Surface: 0
|
||||
- _XRMotionVectorsPass: 1
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BaseColor: {r: 1, g: 0.57, b: 0.43, a: 1}
|
||||
- _Color: {r: 1, g: 0.56999993, b: 0.42999998, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecColor: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
|
||||
m_BuildTextureStacks: []
|
||||
m_AllowLocking: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9ff8ebe8d9f4354e88bff9398bc9c03
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d659b3981a02de84d8aafc8eefa9db38
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73c3215bc432df740b907a1edefa9ea1
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,594 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &249671451578993778
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 782296095116550680}
|
||||
- component: {fileID: 7044309821208163747}
|
||||
- component: {fileID: 1500535848956285383}
|
||||
m_Layer: 0
|
||||
m_Name: LeftEye
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &782296095116550680
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 249671451578993778}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: -0.15, y: 0.05, z: 0}
|
||||
m_LocalScale: {x: 0.08, y: 0.11, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1885524188671059666}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &7044309821208163747
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 249671451578993778}
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!23 &1500535848956285383
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 249671451578993778}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: f625349e1f7edf249bc2f0006bde7ccf, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 1
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!1 &3900389932875835401
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8665407476105022746}
|
||||
- component: {fileID: 2229194056938340699}
|
||||
m_Layer: 0
|
||||
m_Name: Smile
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8665407476105022746
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3900389932875835401}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1885524188671059666}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!120 &2229194056938340699
|
||||
LineRenderer:
|
||||
serializedVersion: 3
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3900389932875835401}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 0
|
||||
m_LightProbeUsage: 0
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: f625349e1f7edf249bc2f0006bde7ccf, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_Positions:
|
||||
- {x: -0.14, y: -0.0812, z: 0}
|
||||
- {x: -0.105000004, y: -0.106924996, z: 0}
|
||||
- {x: -0.07, y: -0.1253, z: 0}
|
||||
- {x: -0.035, y: -0.136325, z: 0}
|
||||
- {x: 0, y: -0.14, z: 0}
|
||||
- {x: 0.035, y: -0.136325, z: 0}
|
||||
- {x: 0.07, y: -0.1253, z: 0}
|
||||
- {x: 0.105000004, y: -0.106924996, z: 0}
|
||||
- {x: 0.14, y: -0.0812, z: 0}
|
||||
m_Parameters:
|
||||
serializedVersion: 3
|
||||
widthMultiplier: 0.035
|
||||
widthCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
colorGradient:
|
||||
serializedVersion: 2
|
||||
key0: {r: 1, g: 1, b: 1, a: 1}
|
||||
key1: {r: 1, g: 1, b: 1, a: 1}
|
||||
key2: {r: 0, g: 0, b: 0, a: 0}
|
||||
key3: {r: 0, g: 0, b: 0, a: 0}
|
||||
key4: {r: 0, g: 0, b: 0, a: 0}
|
||||
key5: {r: 0, g: 0, b: 0, a: 0}
|
||||
key6: {r: 0, g: 0, b: 0, a: 0}
|
||||
key7: {r: 0, g: 0, b: 0, a: 0}
|
||||
ctime0: 0
|
||||
ctime1: 65535
|
||||
ctime2: 0
|
||||
ctime3: 0
|
||||
ctime4: 0
|
||||
ctime5: 0
|
||||
ctime6: 0
|
||||
ctime7: 0
|
||||
atime0: 0
|
||||
atime1: 65535
|
||||
atime2: 0
|
||||
atime3: 0
|
||||
atime4: 0
|
||||
atime5: 0
|
||||
atime6: 0
|
||||
atime7: 0
|
||||
m_Mode: 0
|
||||
m_ColorSpace: -1
|
||||
m_NumColorKeys: 2
|
||||
m_NumAlphaKeys: 2
|
||||
numCornerVertices: 0
|
||||
numCapVertices: 0
|
||||
alignment: 0
|
||||
textureMode: 0
|
||||
textureScale: {x: 1, y: 1}
|
||||
shadowBias: 0.5
|
||||
generateLightingData: 0
|
||||
m_UseWorldSpace: 0
|
||||
m_Loop: 0
|
||||
m_ApplyActiveColorSpace: 1
|
||||
--- !u!1 &6122023196935183107
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1885524188671059666}
|
||||
m_Layer: 0
|
||||
m_Name: RepresentativeFace
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1885524188671059666
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6122023196935183107}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 782296095116550680}
|
||||
- {fileID: 9186485450251357337}
|
||||
- {fileID: 8665407476105022746}
|
||||
m_Father: {fileID: 3444733339480260935}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &7707652147950496847
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3444733339480260935}
|
||||
- component: {fileID: 8586535435441923330}
|
||||
m_Layer: 0
|
||||
m_Name: GroupBadge
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3444733339480260935
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7707652147950496847}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 2644936306256428015}
|
||||
- {fileID: 1885524188671059666}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &8586535435441923330
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7707652147950496847}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5dfc933dbfe92d64f990d1aa289a03d4, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: MagnetismHeroes.UnityRuntime::MagnetismHeroes.UnityRuntime.Presentation.GroupBadge
|
||||
_number: {fileID: 7156837666543227830}
|
||||
_face: {fileID: 1885524188671059666}
|
||||
--- !u!1 &7995294815621610086
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2644936306256428015}
|
||||
- component: {fileID: 5962027146007004898}
|
||||
- component: {fileID: 7156837666543227830}
|
||||
m_Layer: 0
|
||||
m_Name: Number
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2644936306256428015
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7995294815621610086}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3444733339480260935}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 2, y: 0.7}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!23 &5962027146007004898
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7995294815621610086}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 0
|
||||
m_ReceiveShadows: 0
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 8207275579423446409, guid: a5bc77ef7ce7c7e4d85ac578cfcd6646, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!114 &7156837666543227830
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7995294815621610086}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 9541d86e2fd84c1d9990edf0852d74ab, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Unity.TextMeshPro::TMPro.TextMeshPro
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_text: 1
|
||||
m_isRightToLeft: 0
|
||||
m_fontAsset: {fileID: 11400000, guid: a5bc77ef7ce7c7e4d85ac578cfcd6646, type: 2}
|
||||
m_sharedMaterial: {fileID: 8207275579423446409, guid: a5bc77ef7ce7c7e4d85ac578cfcd6646, type: 2}
|
||||
m_fontSharedMaterials: []
|
||||
m_fontMaterial: {fileID: 0}
|
||||
m_fontMaterials: []
|
||||
m_fontColor32:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontColor: {r: 0.12, g: 0.2, b: 0.31, a: 1}
|
||||
m_enableVertexGradient: 0
|
||||
m_colorMode: 3
|
||||
m_fontColorGradient:
|
||||
topLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
topRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
|
||||
bottomRight: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_fontColorGradientPreset: {fileID: 0}
|
||||
m_spriteAsset: {fileID: 0}
|
||||
m_tintAllSprites: 0
|
||||
m_StyleSheet: {fileID: 0}
|
||||
m_TextStyleHashCode: 0
|
||||
m_overrideHtmlColors: 0
|
||||
m_faceColor:
|
||||
serializedVersion: 2
|
||||
rgba: 4294967295
|
||||
m_fontSize: 5
|
||||
m_fontSizeBase: 5
|
||||
m_fontWeight: 400
|
||||
m_enableAutoSizing: 0
|
||||
m_fontSizeMin: 18
|
||||
m_fontSizeMax: 72
|
||||
m_fontStyle: 0
|
||||
m_HorizontalAlignment: 2
|
||||
m_VerticalAlignment: 512
|
||||
m_textAlignment: 65535
|
||||
m_characterSpacing: 0
|
||||
m_characterHorizontalScale: 1
|
||||
m_wordSpacing: 0
|
||||
m_lineSpacing: 0
|
||||
m_lineSpacingMax: 0
|
||||
m_paragraphSpacing: 0
|
||||
m_charWidthMaxAdj: 0
|
||||
m_TextWrappingMode: 1
|
||||
m_wordWrappingRatios: 0.4
|
||||
m_overflowMode: 0
|
||||
m_linkedTextComponent: {fileID: 0}
|
||||
parentLinkedComponent: {fileID: 0}
|
||||
m_enableKerning: 0
|
||||
m_ActiveFontFeatures: 6e72656bu
|
||||
m_enableExtraPadding: 0
|
||||
checkPaddingRequired: 0
|
||||
m_isRichText: 1
|
||||
m_EmojiFallbackSupport: 1
|
||||
m_parseCtrlCharacters: 1
|
||||
m_isOrthographic: 0
|
||||
m_isCullingEnabled: 0
|
||||
m_horizontalMapping: 0
|
||||
m_verticalMapping: 0
|
||||
m_uvLineOffset: 0
|
||||
m_geometrySortingOrder: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_VertexBufferAutoSizeReduction: 0
|
||||
m_useMaxVisibleDescender: 1
|
||||
m_pageToDisplay: 1
|
||||
m_margin: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_isUsingLegacyAnimationComponent: 0
|
||||
m_isVolumetricText: 0
|
||||
_SortingLayer: 0
|
||||
_SortingLayerID: 0
|
||||
_SortingOrder: 0
|
||||
m_hasFontAssetChanged: 0
|
||||
m_renderer: {fileID: 5962027146007004898}
|
||||
m_maskType: 0
|
||||
--- !u!1 &8873238367880750306
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 9186485450251357337}
|
||||
- component: {fileID: 1721263544024944440}
|
||||
- component: {fileID: 4797747157284027217}
|
||||
m_Layer: 0
|
||||
m_Name: RightEye
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &9186485450251357337
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8873238367880750306}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0.15, y: 0.05, z: 0}
|
||||
m_LocalScale: {x: 0.08, y: 0.11, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1885524188671059666}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &1721263544024944440
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8873238367880750306}
|
||||
m_Mesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!23 &4797747157284027217
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8873238367880750306}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: f625349e1f7edf249bc2f0006bde7ccf, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 1
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6475c2f7cafe4441a6f4706a3b2b6a4
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,220 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3730473297310058759
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4419960402240753643}
|
||||
- component: {fileID: 8749146759555874692}
|
||||
- component: {fileID: 8655814190357286106}
|
||||
m_Layer: 0
|
||||
m_Name: CountMarker
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 0
|
||||
--- !u!4 &4419960402240753643
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3730473297310058759}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0.55, z: 0}
|
||||
m_LocalScale: {x: 0.24, y: 0.08, z: 0.24}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3913606793712318518}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &8749146759555874692
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3730473297310058759}
|
||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!23 &8655814190357286106
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3730473297310058759}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: e6eb301d5baaa3b4dba3ce2228f17fa3, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 1
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!1 &4222153517735652016
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3913606793712318518}
|
||||
- component: {fileID: 3708566260475808937}
|
||||
- component: {fileID: 4380635146609339731}
|
||||
- component: {fileID: 4902335425252088244}
|
||||
- component: {fileID: 1331864523212970899}
|
||||
m_Layer: 0
|
||||
m_Name: MagnetFriend
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3913606793712318518
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4222153517735652016}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children:
|
||||
- {fileID: 4419960402240753643}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!33 &3708566260475808937
|
||||
MeshFilter:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4222153517735652016}
|
||||
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
|
||||
--- !u!135 &4380635146609339731
|
||||
SphereCollider:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4222153517735652016}
|
||||
m_Material: {fileID: 0}
|
||||
m_IncludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_ExcludeLayers:
|
||||
serializedVersion: 2
|
||||
m_Bits: 0
|
||||
m_LayerOverridePriority: 0
|
||||
m_IsTrigger: 0
|
||||
m_ProvidesContacts: 0
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_Radius: 0.5
|
||||
m_Center: {x: 0, y: 0, z: 0}
|
||||
--- !u!23 &4902335425252088244
|
||||
MeshRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4222153517735652016}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_StaticShadowCaster: 0
|
||||
m_MotionVectors: 1
|
||||
m_LightProbeUsage: 1
|
||||
m_ReflectionProbeUsage: 1
|
||||
m_RayTracingMode: 2
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: ec5c546652eacdf4f9aa3fa65eb0c385, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_ReceiveGI: 1
|
||||
m_PreserveUVs: 1
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 1
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_AdditionalVertexStreams: {fileID: 0}
|
||||
--- !u!114 &1331864523212970899
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4222153517735652016}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ef4ac8f42ba5a5343a5f0474eef2a1af, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: MagnetismHeroes.UnityRuntime::MagnetismHeroes.UnityRuntime.Presentation.BallView
|
||||
_body: {fileID: 4902335425252088244}
|
||||
_countMarker: {fileID: 3730473297310058759}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91ae23d420859244686c2c654ab58bf3
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Presentation
|
||||
{
|
||||
public sealed class SafeAreaPanel : MonoBehaviour
|
||||
{
|
||||
private Rect _last;
|
||||
private void Update()
|
||||
{
|
||||
var area = Screen.safeArea;
|
||||
if (_last == area || Screen.width == 0 || Screen.height == 0) return;
|
||||
_last = area;
|
||||
var rect = (RectTransform)transform;
|
||||
rect.anchorMin = area.min / new Vector2(Screen.width, Screen.height);
|
||||
rect.anchorMax = area.max / new Vector2(Screen.width, Screen.height);
|
||||
rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 561d1b7e5d46162459220d9c68d8511e
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.Presentation
|
||||
{
|
||||
[Serializable] public sealed class VoiceClip { public string id; public AudioClip clip; }
|
||||
|
||||
public sealed class VoicePlayer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private AudioSource _source;
|
||||
[SerializeField] private VoiceClip[] _clips = Array.Empty<VoiceClip>();
|
||||
private readonly Queue<AudioClip> _counts = new Queue<AudioClip>();
|
||||
private AudioClip _guide;
|
||||
private bool _playingCount;
|
||||
public int PendingCount => _counts.Count + (_playingCount ? 1 : 0);
|
||||
public string CurrentClipId => _source.clip == null ? null : _source.clip.name;
|
||||
|
||||
public void EnqueueCount(int count)
|
||||
{
|
||||
var clip = Find($"count_{count:D2}");
|
||||
if (clip == null) return;
|
||||
// A guide must never postpone or overlap a newly committed number.
|
||||
_guide = null;
|
||||
if (!_playingCount) _source.Stop();
|
||||
_counts.Enqueue(clip); Advance();
|
||||
}
|
||||
public void Guide(string id)
|
||||
{ _guide = Find(id); if (!_playingCount) { _source.Stop(); Advance(); } }
|
||||
public void Clear()
|
||||
{ _counts.Clear(); _guide = null; _playingCount = false; _source.Stop(); _source.clip = null; }
|
||||
private AudioClip Find(string id) { foreach (var voice in _clips) if (voice.id == id) return voice.clip; return null; }
|
||||
private void Advance()
|
||||
{
|
||||
if (_source.isPlaying) return;
|
||||
_playingCount = false;
|
||||
if (_counts.Count > 0) { _source.clip = _counts.Dequeue(); _playingCount = true; _source.Play(); }
|
||||
else if (_guide != null) { _source.clip = _guide; _guide = null; _source.Play(); }
|
||||
}
|
||||
private void Update() => Advance();
|
||||
private void OnApplicationPause(bool paused) { if (paused) Clear(); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dee5bae88f250144c88bbd4995dbdcbb
|
||||
@@ -0,0 +1,20 @@
|
||||
%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: 25d91ab5f7c987840910f7a3683c8d3f, type: 3}
|
||||
m_Name: Stage01
|
||||
m_EditorClassIdentifier: MagnetismHeroes.UnityRuntime::MagnetismHeroes.UnityRuntime.StageAssets.StageAsset
|
||||
_stageId: 1
|
||||
_kind: 0
|
||||
_initialGroups: 01000000i
|
||||
_targetGroups: 01000000i
|
||||
_ballPositions:
|
||||
- {x: -1.7, y: 0.8, z: 0}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1bd91d4fcb826e54e861dc2275fcbdee
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using MagnetismHeroes.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MagnetismHeroes.UnityRuntime.StageAssets
|
||||
{
|
||||
[CreateAssetMenu(menuName = "Magnetism Heroes/Stage")]
|
||||
public sealed class StageAsset : ScriptableObject
|
||||
{
|
||||
[SerializeField] private int _stageId = 1;
|
||||
[SerializeField] private StageKind _kind;
|
||||
[SerializeField] private int[] _initialGroups = { 1 };
|
||||
[SerializeField] private int[] _targetGroups = { 1 };
|
||||
[SerializeField] private Vector3[] _ballPositions = { new Vector3(-1.7f, 0.8f, 0) };
|
||||
public int StageId => _stageId;
|
||||
|
||||
public StageDefinition ToDefinition() => new StageDefinition(_stageId, _kind, _initialGroups, _targetGroups,
|
||||
Array.ConvertAll(_ballPositions, position => new Position3(position.x, position.y, position.z)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25d91ab5f7c987840910f7a3683c8d3f
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f54d1bd14bd3ca042bd867b519fee8cc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ab70aee4d56447429c680537fbf93ed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
Digitized data copyright (c) 2010 Google Corporation
|
||||
with Reserved Font Arimo, Tinos and Cousine.
|
||||
Copyright (c) 2012 Red Hat, Inc.
|
||||
with Reserved Font Name Liberation.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e59c59b81ab47f9b6ec5781fa725d2c
|
||||
timeCreated: 1484171296
|
||||
licenseType: Pro
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3265ab4bf004d28a9537516768c1c75
|
||||
timeCreated: 1484171297
|
||||
licenseType: Pro
|
||||
TrueTypeFontImporter:
|
||||
serializedVersion: 2
|
||||
fontSize: 16
|
||||
forceTextureCase: -2
|
||||
characterSpacing: 1
|
||||
characterPadding: 0
|
||||
includeFontData: 1
|
||||
use2xBehaviour: 0
|
||||
fontNames: []
|
||||
fallbackFontReferences: []
|
||||
customCharacters:
|
||||
fontRenderingMode: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 243e06394e614e5d99fab26083b707fa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 731f1baa9d144a9897cb1d341c2092b8
|
||||
folderAsset: yes
|
||||
timeCreated: 1442040525
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,106 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF - Drop Shadow
|
||||
m_Shader: {fileID: 4800000, guid: fe393ace9b354375a9cb14cdbbc28be4, type: 3}
|
||||
m_ShaderKeywords: OUTLINE_ON UNDERLAY_ON
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Cube:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _FaceTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 28684132378477856, guid: 8f586378b4e144a9851e7b34d9b748ee,
|
||||
type: 2}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OutlineTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _Ambient: 0.5
|
||||
- _Bevel: 0.5
|
||||
- _BevelClamp: 0
|
||||
- _BevelOffset: 0
|
||||
- _BevelRoundness: 0
|
||||
- _BevelWidth: 0
|
||||
- _BumpFace: 0
|
||||
- _BumpOutline: 0
|
||||
- _ColorMask: 15
|
||||
- _Diffuse: 0.5
|
||||
- _DiffusePower: 1
|
||||
- _FaceDilate: 0.1
|
||||
- _FaceUVSpeedX: 0
|
||||
- _FaceUVSpeedY: 0
|
||||
- _GlowInner: 0.05
|
||||
- _GlowOffset: 0
|
||||
- _GlowOuter: 0.05
|
||||
- _GlowPower: 0.75
|
||||
- _GradientScale: 10
|
||||
- _LightAngle: 3.1416
|
||||
- _MaskSoftnessX: 0
|
||||
- _MaskSoftnessY: 0
|
||||
- _OutlineSoftness: 0
|
||||
- _OutlineUVSpeedX: 0
|
||||
- _OutlineUVSpeedY: 0
|
||||
- _OutlineWidth: 0.1
|
||||
- _PerspectiveFilter: 0.875
|
||||
- _Reflectivity: 10
|
||||
- _ScaleRatioA: 0.9
|
||||
- _ScaleRatioB: 0.73125
|
||||
- _ScaleRatioC: 0.64125
|
||||
- _ScaleX: 1
|
||||
- _ScaleY: 1
|
||||
- _ShaderFlags: 0
|
||||
- _Sharpness: 0
|
||||
- _SpecularPower: 2
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _TextureHeight: 1024
|
||||
- _TextureWidth: 1024
|
||||
- _UnderlayDilate: 0
|
||||
- _UnderlayOffsetX: 0.5
|
||||
- _UnderlayOffsetY: -0.5
|
||||
- _UnderlaySoftness: 0.05
|
||||
- _VertexOffsetX: 0
|
||||
- _VertexOffsetY: 0
|
||||
- _WeightBold: 0.75
|
||||
- _WeightNormal: 0
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
|
||||
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
|
||||
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e73a58f6e2794ae7b1b7e50b7fb811b0
|
||||
timeCreated: 1484172806
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,348 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2180264
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF Material
|
||||
m_Shader: {fileID: 4800000, guid: fe393ace9b354375a9cb14cdbbc28be4, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 1
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Cube:
|
||||
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}
|
||||
- _FaceTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 28268798066460806}
|
||||
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}
|
||||
- _OutlineTex:
|
||||
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_Floats:
|
||||
- _Ambient: 0.5
|
||||
- _Bevel: 0.5
|
||||
- _BevelClamp: 0
|
||||
- _BevelOffset: 0
|
||||
- _BevelRoundness: 0
|
||||
- _BevelWidth: 0
|
||||
- _BumpFace: 0
|
||||
- _BumpOutline: 0
|
||||
- _BumpScale: 1
|
||||
- _ColorMask: 15
|
||||
- _CullMode: 0
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _Diffuse: 0.5
|
||||
- _DstBlend: 0
|
||||
- _FaceDilate: 0
|
||||
- _FaceUVSpeedX: 0
|
||||
- _FaceUVSpeedY: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _GlowInner: 0.05
|
||||
- _GlowOffset: 0
|
||||
- _GlowOuter: 0.05
|
||||
- _GlowPower: 0.75
|
||||
- _GradientScale: 10
|
||||
- _LightAngle: 3.1416
|
||||
- _MaskSoftnessX: 0
|
||||
- _MaskSoftnessY: 0
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _OutlineSoftness: 0
|
||||
- _OutlineUVSpeedX: 0
|
||||
- _OutlineUVSpeedY: 0
|
||||
- _OutlineWidth: 0
|
||||
- _Parallax: 0.02
|
||||
- _PerspectiveFilter: 0.875
|
||||
- _Reflectivity: 10
|
||||
- _ScaleRatioA: 0.90909094
|
||||
- _ScaleRatioB: 0.73125
|
||||
- _ScaleRatioC: 0.7386364
|
||||
- _ScaleX: 1
|
||||
- _ScaleY: 1
|
||||
- _ShaderFlags: 0
|
||||
- _Sharpness: 0
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SpecularPower: 2
|
||||
- _SrcBlend: 1
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _TextureHeight: 512
|
||||
- _TextureWidth: 512
|
||||
- _UVSec: 0
|
||||
- _UnderlayDilate: 0
|
||||
- _UnderlayOffsetX: 0
|
||||
- _UnderlayOffsetY: 0
|
||||
- _UnderlaySoftness: 0
|
||||
- _VertexOffsetX: 0
|
||||
- _VertexOffsetY: 0
|
||||
- _WeightBold: 0.75
|
||||
- _WeightNormal: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
|
||||
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
|
||||
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
--- !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: 71c1514a6bd24e1e882cebbe1904ce04, type: 3}
|
||||
m_Name: LiberationSans SDF - Fallback
|
||||
m_EditorClassIdentifier:
|
||||
m_Version: 1.1.0
|
||||
m_Material: {fileID: 2180264}
|
||||
m_SourceFontFileGUID: e3265ab4bf004d28a9537516768c1c75
|
||||
m_SourceFontFile: {fileID: 12800000, guid: e3265ab4bf004d28a9537516768c1c75, type: 3}
|
||||
m_AtlasPopulationMode: 1
|
||||
InternalDynamicOS: 0
|
||||
m_FaceInfo:
|
||||
m_FaceIndex: 0
|
||||
m_FamilyName: Liberation Sans
|
||||
m_StyleName: Regular
|
||||
m_PointSize: 86
|
||||
m_Scale: 1
|
||||
m_UnitsPerEM: 2048
|
||||
m_LineHeight: 98.8916
|
||||
m_AscentLine: 77.853516
|
||||
m_CapLine: 59
|
||||
m_MeanLine: 45
|
||||
m_Baseline: 0
|
||||
m_DescentLine: -18.22461
|
||||
m_SuperscriptOffset: 77.853516
|
||||
m_SuperscriptSize: 0.5
|
||||
m_SubscriptOffset: -18.22461
|
||||
m_SubscriptSize: 0.5
|
||||
m_UnderlineOffset: -12.261719
|
||||
m_UnderlineThickness: 6.298828
|
||||
m_StrikethroughOffset: 18
|
||||
m_StrikethroughThickness: 6.298828
|
||||
m_TabWidth: 24
|
||||
m_GlyphTable: []
|
||||
m_CharacterTable: []
|
||||
m_AtlasTextures:
|
||||
- {fileID: 28268798066460806}
|
||||
m_AtlasTextureIndex: 0
|
||||
m_IsMultiAtlasTexturesEnabled: 1
|
||||
m_ClearDynamicDataOnBuild: 1
|
||||
m_UsedGlyphRects: []
|
||||
m_FreeGlyphRects:
|
||||
- m_X: 0
|
||||
m_Y: 0
|
||||
m_Width: 511
|
||||
m_Height: 511
|
||||
m_fontInfo:
|
||||
Name: Liberation Sans
|
||||
PointSize: 86
|
||||
Scale: 1
|
||||
CharacterCount: 250
|
||||
LineHeight: 98.90625
|
||||
Baseline: 0
|
||||
Ascender: 77.84375
|
||||
CapHeight: 59.1875
|
||||
Descender: -18.21875
|
||||
CenterLine: 0
|
||||
SuperscriptOffset: 77.84375
|
||||
SubscriptOffset: -12.261719
|
||||
SubSize: 0.5
|
||||
Underline: -12.261719
|
||||
UnderlineThickness: 6.298828
|
||||
strikethrough: 23.675
|
||||
strikethroughThickness: 0
|
||||
TabWidth: 239.0625
|
||||
Padding: 9
|
||||
AtlasWidth: 1024
|
||||
AtlasHeight: 1024
|
||||
atlas: {fileID: 0}
|
||||
m_AtlasWidth: 512
|
||||
m_AtlasHeight: 512
|
||||
m_AtlasPadding: 9
|
||||
m_AtlasRenderMode: 4169
|
||||
m_glyphInfoList: []
|
||||
m_KerningTable:
|
||||
kerningPairs: []
|
||||
m_FontFeatureTable:
|
||||
m_MultipleSubstitutionRecords: []
|
||||
m_LigatureSubstitutionRecords: []
|
||||
m_GlyphPairAdjustmentRecords: []
|
||||
m_MarkToBaseAdjustmentRecords: []
|
||||
m_MarkToMarkAdjustmentRecords: []
|
||||
fallbackFontAssets: []
|
||||
m_FallbackFontAssetTable: []
|
||||
m_CreationSettings:
|
||||
sourceFontFileName:
|
||||
sourceFontFileGUID: e3265ab4bf004d28a9537516768c1c75
|
||||
faceIndex: 0
|
||||
pointSizeSamplingMode: 0
|
||||
pointSize: 86
|
||||
padding: 9
|
||||
paddingMode: 0
|
||||
packingMode: 4
|
||||
atlasWidth: 512
|
||||
atlasHeight: 512
|
||||
characterSetSelectionMode: 1
|
||||
characterSequence: 32 - 126, 160 - 255, 8192 - 8303, 8364, 8482, 9633
|
||||
referencedFontAssetGUID: 8f586378b4e144a9851e7b34d9b748ee
|
||||
referencedTextAssetGUID:
|
||||
fontStyle: 0
|
||||
fontStyleModifier: 0
|
||||
renderMode: 4169
|
||||
includeFontFeatures: 1
|
||||
m_FontWeightTable:
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
fontWeights:
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
- regularTypeface: {fileID: 0}
|
||||
italicTypeface: {fileID: 0}
|
||||
normalStyle: 0
|
||||
normalSpacingOffset: 0
|
||||
boldStyle: 0.75
|
||||
boldSpacing: 7
|
||||
italicStyle: 35
|
||||
tabSize: 10
|
||||
--- !u!28 &28268798066460806
|
||||
Texture2D:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF Atlas
|
||||
m_ImageContentsHash:
|
||||
serializedVersion: 2
|
||||
Hash: 00000000000000000000000000000000
|
||||
m_ForcedFallbackFormat: 4
|
||||
m_DownscaleFallback: 0
|
||||
serializedVersion: 2
|
||||
m_Width: 0
|
||||
m_Height: 0
|
||||
m_CompleteImageSize: 0
|
||||
m_TextureFormat: 1
|
||||
m_MipCount: 1
|
||||
m_IsReadable: 1
|
||||
m_StreamingMipmaps: 0
|
||||
m_StreamingMipmapsPriority: 0
|
||||
m_AlphaIsTransparency: 0
|
||||
m_ImageCount: 1
|
||||
m_TextureDimension: 2
|
||||
m_TextureSettings:
|
||||
serializedVersion: 2
|
||||
m_FilterMode: 1
|
||||
m_Aniso: 1
|
||||
m_MipBias: 0
|
||||
m_WrapU: 0
|
||||
m_WrapV: 0
|
||||
m_WrapW: 0
|
||||
m_LightmapFormat: 0
|
||||
m_ColorSpace: 0
|
||||
image data: 0
|
||||
_typelessdata:
|
||||
m_StreamData:
|
||||
offset: 0
|
||||
size: 0
|
||||
path:
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e498d1c8094910479dc3e1b768306a4
|
||||
timeCreated: 1484171803
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,104 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: LiberationSans SDF - Outline
|
||||
m_Shader: {fileID: 4800000, guid: fe393ace9b354375a9cb14cdbbc28be4, type: 3}
|
||||
m_ShaderKeywords: OUTLINE_ON
|
||||
m_LightmapFlags: 5
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _Cube:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _FaceTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 28684132378477856, guid: 8f586378b4e144a9851e7b34d9b748ee,
|
||||
type: 2}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OutlineTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _Ambient: 0.5
|
||||
- _Bevel: 0.5
|
||||
- _BevelClamp: 0
|
||||
- _BevelOffset: 0
|
||||
- _BevelRoundness: 0
|
||||
- _BevelWidth: 0
|
||||
- _BumpFace: 0
|
||||
- _BumpOutline: 0
|
||||
- _ColorMask: 15
|
||||
- _Diffuse: 0.5
|
||||
- _FaceDilate: 0.1
|
||||
- _FaceUVSpeedX: 0
|
||||
- _FaceUVSpeedY: 0
|
||||
- _GlowInner: 0.05
|
||||
- _GlowOffset: 0
|
||||
- _GlowOuter: 0.05
|
||||
- _GlowPower: 0.75
|
||||
- _GradientScale: 10
|
||||
- _LightAngle: 3.1416
|
||||
- _MaskSoftnessX: 0
|
||||
- _MaskSoftnessY: 0
|
||||
- _OutlineSoftness: 0
|
||||
- _OutlineUVSpeedX: 0
|
||||
- _OutlineUVSpeedY: 0
|
||||
- _OutlineWidth: 0.1
|
||||
- _PerspectiveFilter: 0.875
|
||||
- _Reflectivity: 10
|
||||
- _ScaleRatioA: 0.9
|
||||
- _ScaleRatioB: 0.73125
|
||||
- _ScaleRatioC: 0.64125
|
||||
- _ScaleX: 1
|
||||
- _ScaleY: 1
|
||||
- _ShaderFlags: 0
|
||||
- _Sharpness: 0
|
||||
- _SpecularPower: 2
|
||||
- _Stencil: 0
|
||||
- _StencilComp: 8
|
||||
- _StencilOp: 0
|
||||
- _StencilReadMask: 255
|
||||
- _StencilWriteMask: 255
|
||||
- _TextureHeight: 1024
|
||||
- _TextureWidth: 1024
|
||||
- _UnderlayDilate: 0
|
||||
- _UnderlayOffsetX: 0
|
||||
- _UnderlayOffsetY: 0
|
||||
- _UnderlaySoftness: 0
|
||||
- _VertexOffsetX: 0
|
||||
- _VertexOffsetY: 0
|
||||
- _WeightBold: 0.75
|
||||
- _WeightNormal: 0
|
||||
m_Colors:
|
||||
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
|
||||
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
|
||||
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _GlowColor: {r: 0, g: 1, b: 0, a: 0.5}
|
||||
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
|
||||
- _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _ReflectOutlineColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _UnderlayColor: {r: 0, g: 0, b: 0, a: 0.5}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79459efec17a4d00a321bdcc27bbc385
|
||||
timeCreated: 1484172856
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f586378b4e144a9851e7b34d9b748ee
|
||||
timeCreated: 1484171803
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1 @@
|
||||
)]}〕〉》」』】〙〗〟’”⦆»ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻‐゠–〜?!‼⁇⁈⁉・、%,.:;。!?]):;=}¢°"†‡℃〆%,.
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fade42e8bc714b018fac513c043d323b
|
||||
timeCreated: 1425440388
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1 @@
|
||||
([{〔〈《「『【〘〖〝‘“⦅«$—…‥〳〴〵\[({£¥"々〇$¥₩ #
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d82c1b31c7e74239bff1220585707d2b
|
||||
timeCreated: 1425440388
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4aecb92fff08436c8303b10eab8da368
|
||||
folderAsset: yes
|
||||
timeCreated: 1441876950
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
%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: ab2114bdc8544297b417dfefe9f1e410, type: 3}
|
||||
m_Name: Default Style Sheet
|
||||
m_EditorClassIdentifier:
|
||||
m_StyleList:
|
||||
- m_Name: Normal
|
||||
m_HashCode: -1183493901
|
||||
m_OpeningDefinition:
|
||||
m_ClosingDefinition:
|
||||
m_OpeningTagArray:
|
||||
m_ClosingTagArray:
|
||||
- m_Name: H1
|
||||
m_HashCode: 2425
|
||||
m_OpeningDefinition: <size=2em><b><#40ff80>*
|
||||
m_ClosingDefinition: '*</size></b></color>'
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d00000032000000650000006d0000003e0000003c000000620000003e0000003c000000230000003400000030000000660000006600000038000000300000003e0000002a000000
|
||||
m_ClosingTagArray: 2a0000003c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: Quote
|
||||
m_HashCode: 93368250
|
||||
m_OpeningDefinition: <i><size=75%><margin=10%>
|
||||
m_ClosingDefinition: </i></size></width></margin>
|
||||
m_OpeningTagArray: 3c000000690000003e0000003c00000073000000690000007a000000650000003d0000003700000035000000250000003e0000003c0000006d000000610000007200000067000000690000006e0000003d0000003100000030000000250000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000690000003e0000003c0000002f00000073000000690000007a000000650000003e0000003c0000002f00000077000000690000006400000074000000680000003e0000003c0000002f0000006d000000610000007200000067000000690000006e0000003e000000
|
||||
- m_Name: A
|
||||
m_HashCode: 65
|
||||
m_OpeningDefinition: <color=#40a0ff><u>
|
||||
m_ClosingDefinition: </u></color>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000003400000030000000610000003000000066000000660000003e0000003c000000750000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000750000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: Link
|
||||
m_HashCode: 2656128
|
||||
m_OpeningDefinition: <u><#40a0ff><link="ID_01">
|
||||
m_ClosingDefinition: </u></color></link>
|
||||
m_OpeningTagArray: 3c000000750000003e0000003c000000230000003400000030000000610000003000000066000000660000003e0000003c0000006c000000690000006e0000006b0000003d0000002200000049000000440000005f0000003000000031000000220000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000750000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e0000003c0000002f0000006c000000690000006e0000006b0000003e000000
|
||||
- m_Name: Title
|
||||
m_HashCode: 97690656
|
||||
m_OpeningDefinition: <size=125%><b><align=center>
|
||||
m_ClosingDefinition: </size></b></align>
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d000000310000003200000035000000250000003e0000003c000000620000003e0000003c000000610000006c00000069000000670000006e0000003d00000063000000650000006e0000007400000065000000720000003e000000
|
||||
m_ClosingTagArray: 3c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000610000006c00000069000000670000006e0000003e000000
|
||||
- m_Name: H2
|
||||
m_HashCode: 2426
|
||||
m_OpeningDefinition: <size=1.5em><b><#4080FF>
|
||||
m_ClosingDefinition: </size></b></color>
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d000000310000002e00000035000000650000006d0000003e0000003c000000620000003e0000003c000000230000003400000030000000380000003000000046000000460000003e000000
|
||||
m_ClosingTagArray: 3c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: H3
|
||||
m_HashCode: 2427
|
||||
m_OpeningDefinition: <size=1.17em><b><#FF8040>
|
||||
m_ClosingDefinition: </size></b></color>
|
||||
m_OpeningTagArray: 3c00000073000000690000007a000000650000003d000000310000002e0000003100000037000000650000006d0000003e0000003c000000620000003e0000003c000000230000004600000046000000380000003000000034000000300000003e000000
|
||||
m_ClosingTagArray: 3c0000002f00000073000000690000007a000000650000003e0000003c0000002f000000620000003e0000003c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: C1
|
||||
m_HashCode: 2194
|
||||
m_OpeningDefinition: <color=#ffff40>
|
||||
m_ClosingDefinition: </color>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000006600000066000000660000006600000034000000300000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000630000006f0000006c0000006f000000720000003e000000
|
||||
- m_Name: C2
|
||||
m_HashCode: 2193
|
||||
m_OpeningDefinition: <color=#ff40FF><size=125%>
|
||||
m_ClosingDefinition: </color></size>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000006600000066000000340000003000000046000000460000003e0000003c00000073000000690000007a000000650000003d000000310000003200000035000000250000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000630000006f0000006c0000006f000000720000003e0000003c0000002f00000073000000690000007a000000650000003e000000
|
||||
- m_Name: C3
|
||||
m_HashCode: 2192
|
||||
m_OpeningDefinition: <color=#80A0FF><b>
|
||||
m_ClosingDefinition: </color></b>
|
||||
m_OpeningTagArray: 3c000000630000006f0000006c0000006f000000720000003d000000230000003800000030000000410000003000000046000000460000003e0000003c000000620000003e000000
|
||||
m_ClosingTagArray: 3c0000002f000000630000006f0000006c0000006f000000720000003e0000003c0000002f000000620000003e000000
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f952c082cb03451daed3ee968ac6c63e
|
||||
timeCreated: 1432805430
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
%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: 2705215ac5b84b70bacc50632be6e391, type: 3}
|
||||
m_Name: TMP Settings
|
||||
m_EditorClassIdentifier:
|
||||
assetVersion: 2
|
||||
m_TextWrappingMode: 1
|
||||
m_enableKerning: 1
|
||||
m_ActiveFontFeatures: 00000000
|
||||
m_enableExtraPadding: 0
|
||||
m_enableTintAllSprites: 0
|
||||
m_enableParseEscapeCharacters: 1
|
||||
m_EnableRaycastTarget: 1
|
||||
m_GetFontFeaturesAtRuntime: 1
|
||||
m_missingGlyphCharacter: 0
|
||||
m_ClearDynamicDataOnBuild: 1
|
||||
m_warningsDisabled: 0
|
||||
m_defaultFontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
|
||||
m_defaultFontAssetPath: Fonts & Materials/
|
||||
m_defaultFontSize: 36
|
||||
m_defaultAutoSizeMinRatio: 0.5
|
||||
m_defaultAutoSizeMaxRatio: 2
|
||||
m_defaultTextMeshProTextContainerSize: {x: 20, y: 5}
|
||||
m_defaultTextMeshProUITextContainerSize: {x: 200, y: 50}
|
||||
m_autoSizeTextContainer: 0
|
||||
m_IsTextObjectScaleStatic: 0
|
||||
m_fallbackFontAssets: []
|
||||
m_matchMaterialPreset: 1
|
||||
m_HideSubTextObjects: 0
|
||||
m_defaultSpriteAsset: {fileID: 11400000, guid: c41005c129ba4d66911b75229fd70b45,
|
||||
type: 2}
|
||||
m_defaultSpriteAssetPath: Sprite Assets/
|
||||
m_enableEmojiSupport: 1
|
||||
m_MissingCharacterSpriteUnicode: 0
|
||||
m_EmojiFallbackTextAssets: []
|
||||
m_defaultColorGradientPresetsPath: Color Gradient Presets/
|
||||
m_defaultStyleSheet: {fileID: 11400000, guid: f952c082cb03451daed3ee968ac6c63e,
|
||||
type: 2}
|
||||
m_StyleSheetsResourcePath:
|
||||
m_leadingCharacters: {fileID: 4900000, guid: d82c1b31c7e74239bff1220585707d2b, type: 3}
|
||||
m_followingCharacters: {fileID: 4900000, guid: fade42e8bc714b018fac513c043d323b,
|
||||
type: 3}
|
||||
m_UseModernHangulLineBreakingRules: 0
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f5b5dff67a942289a9defa416b206f3
|
||||
timeCreated: 1436653997
|
||||
licenseType: Pro
|
||||
NativeFormatImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9f693669af91aa45ad615fc681ed29f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,178 @@
|
||||
float2 UnpackUV(float uv)
|
||||
{
|
||||
float2 output;
|
||||
output.x = floor(uv / 4096.0);
|
||||
output.y = uv - 4096.0 * output.x;
|
||||
|
||||
return output * 0.001953125;
|
||||
}
|
||||
|
||||
float4 BlendARGB(float4 overlying, float4 underlying)
|
||||
{
|
||||
overlying.rgb *= overlying.a;
|
||||
underlying.rgb *= underlying.a;
|
||||
float3 blended = overlying.rgb + ((1 - overlying.a) * underlying.rgb);
|
||||
float alpha = underlying.a + (1 - underlying.a) * overlying.a;
|
||||
return float4(blended / alpha, alpha);
|
||||
}
|
||||
|
||||
float3 GetSpecular(float3 n, float3 l)
|
||||
{
|
||||
float spec = pow(max(0.0, dot(n, l)), _Reflectivity);
|
||||
return _SpecularColor.rgb * spec * _SpecularPower;
|
||||
}
|
||||
|
||||
void GetSurfaceNormal_float(texture2D atlas, float textureWidth, float textureHeight, float2 uv, bool isFront, out float3 nornmal)
|
||||
{
|
||||
float3 delta = float3(1.0 / textureWidth, 1.0 / textureHeight, 0.0);
|
||||
|
||||
// Read "height field"
|
||||
float4 h = float4(
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv - delta.xz).a,
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv + delta.xz).a,
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv - delta.zy).a,
|
||||
SAMPLE_TEXTURE2D(atlas, SamplerState_Linear_Clamp, uv + delta.zy).a);
|
||||
|
||||
bool raisedBevel = _BevelType;
|
||||
|
||||
h += _BevelOffset;
|
||||
|
||||
float bevelWidth = max(.01, _BevelWidth);
|
||||
|
||||
// Track outline
|
||||
h -= .5;
|
||||
h /= bevelWidth;
|
||||
h = saturate(h + .5);
|
||||
|
||||
if (raisedBevel) h = 1 - abs(h * 2.0 - 1.0);
|
||||
h = lerp(h, sin(h * 3.141592 / 2.0), float4(_BevelRoundness, _BevelRoundness, _BevelRoundness, _BevelRoundness));
|
||||
h = min(h, 1.0 - float4(_BevelClamp, _BevelClamp, _BevelClamp, _BevelClamp));
|
||||
h *= _BevelAmount * bevelWidth * _GradientScale * -2.0;
|
||||
|
||||
float3 va = normalize(float3(-1.0, 0.0, h.y - h.x));
|
||||
float3 vb = normalize(float3(0.0, 1.0, h.w - h.z));
|
||||
|
||||
float3 f = float3(1, 1, 1);
|
||||
if (isFront) f = float3(1, 1, -1);
|
||||
nornmal = cross(va, vb) * f;
|
||||
}
|
||||
|
||||
void EvaluateLight_float(float4 faceColor, float3 n, out float4 color)
|
||||
{
|
||||
n.z = abs(n.z);
|
||||
float3 light = normalize(float3(sin(_LightAngle), cos(_LightAngle), 1.0));
|
||||
|
||||
float3 col = max(faceColor.rgb, 0) + GetSpecular(n, light)* faceColor.a;
|
||||
//faceColor.rgb += col * faceColor.a;
|
||||
col *= 1 - (dot(n, light) * _Diffuse);
|
||||
col *= lerp(_Ambient, 1, n.z * n.z);
|
||||
|
||||
//fixed4 reflcol = texCUBE(_Cube, reflect(input.viewDir, -n));
|
||||
//faceColor.rgb += reflcol.rgb * lerp(_ReflectFaceColor.rgb, _ReflectOutlineColor.rgb, saturate(sd + outline * 0.5)) * faceColor.a;
|
||||
|
||||
color = float4(col, faceColor.a);
|
||||
}
|
||||
|
||||
// Add custom function to handle time in HDRP
|
||||
|
||||
|
||||
//
|
||||
void GenerateUV_float(float2 inUV, float4 transform, float2 animSpeed, out float2 outUV)
|
||||
{
|
||||
outUV = inUV * transform.xy + transform.zw + (animSpeed * _Time.y);
|
||||
}
|
||||
|
||||
void ComputeUVOffset_float(float texWidth, float texHeight, float2 offset, float SDR, out float2 uvOffset)
|
||||
{
|
||||
uvOffset = float2(-offset.x * SDR / texWidth, -offset.y * SDR / texHeight);
|
||||
}
|
||||
|
||||
void ScreenSpaceRatio2_float(float4x4 projection, float4 position, float2 objectScale, float screenWidth, float screenHeight, float fontScale, out float SSR)
|
||||
{
|
||||
float2 pixelSize = position.w;
|
||||
pixelSize /= (objectScale * mul((float2x2)projection, float2(screenWidth, screenHeight)));
|
||||
SSR = rsqrt(dot(pixelSize, pixelSize)*2) * fontScale;
|
||||
}
|
||||
|
||||
// UV : Texture coordinate of the source distance field texture
|
||||
// TextureSize : Size of the source distance field texture
|
||||
// Filter : Enable perspective filter (soften)
|
||||
void ScreenSpaceRatio_float(float2 UV, float TextureSize, bool Filter, out float SSR)
|
||||
{
|
||||
if(Filter)
|
||||
{
|
||||
float2 a = float2(ddx(UV.x), ddy(UV.x));
|
||||
float2 b = float2(ddx(UV.y), ddy(UV.y));
|
||||
float s = lerp(dot(a,a), dot(b,b), 0.5);
|
||||
SSR = rsqrt(s) / TextureSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
float s = rsqrt(abs(ddx(UV.x) * ddy(UV.y) - ddy(UV.x) * ddx(UV.y)));
|
||||
SSR = s / TextureSize;
|
||||
}
|
||||
}
|
||||
|
||||
// SSR : Screen Space Ratio
|
||||
// SD : Signed Distance (encoded : Distance / SDR + .5)
|
||||
// SDR : Signed Distance Ratio
|
||||
//
|
||||
// IsoPerimeter : Dilate / Contract the shape
|
||||
void ComputeSDF_float(float SSR, float SD, float SDR, float isoPerimeter, float softness, out float outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float d = (SD - 0.5) * SDR; // Signed distance to edge, in Texture space
|
||||
outAlpha = saturate((d * 2.0 * SSR + 0.5 + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness)); // Screen pixel coverage (alpha)
|
||||
}
|
||||
|
||||
void ComputeSDF2_float(float SSR, float SD, float SDR, float2 isoPerimeter, float2 softness, out float2 outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float d = (SD - 0.5f) * SDR;
|
||||
outAlpha = saturate((d * 2.0f * SSR + 0.5f + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness));
|
||||
}
|
||||
|
||||
void ComputeSDF4_float(float SSR, float SD, float SDR, float4 isoPerimeter, float4 softness, out float4 outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float d = (SD - 0.5f) * SDR;
|
||||
outAlpha = saturate((d * 2.0f * SSR + 0.5f + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness));
|
||||
}
|
||||
|
||||
void ComputeSDF44_float(float SSR, float4 SD, float SDR, float4 isoPerimeter, float4 softness, bool outline, out float4 outAlpha)
|
||||
{
|
||||
softness *= SSR * SDR;
|
||||
float4 d = (SD - 0.5f) * SDR;
|
||||
if(outline) d.w = max(max(d.x, d.y), d.z);
|
||||
outAlpha = saturate((d * 2.0f * SSR + 0.5f + isoPerimeter * SDR * SSR + softness * 0.5) / (1.0 + softness));
|
||||
}
|
||||
|
||||
void Composite_float(float4 overlying, float4 underlying, out float4 outColor)
|
||||
{
|
||||
outColor = BlendARGB(overlying, underlying);
|
||||
}
|
||||
|
||||
// Face only
|
||||
void Layer1_float(float alpha, float4 color0, out float4 outColor)
|
||||
{
|
||||
color0.a *= alpha;
|
||||
outColor = color0;
|
||||
}
|
||||
|
||||
// Face + 1 Outline
|
||||
void Layer2_float(float2 alpha, float4 color0, float4 color1, out float4 outColor)
|
||||
{
|
||||
color1.a *= alpha.y;
|
||||
color0.rgb *= color0.a; color1.rgb *= color1.a;
|
||||
outColor = lerp(color1, color0, alpha.x);
|
||||
outColor.rgb /= outColor.a;
|
||||
}
|
||||
|
||||
// Face + 3 Outline
|
||||
void Layer4_float(float4 alpha, float4 color0, float4 color1, float4 color2, float4 color3, out float4 outColor)
|
||||
{
|
||||
color3.a *= alpha.w;
|
||||
color0.rgb *= color0.a; color1.rgb *= color1.a; color2.rgb *= color2.a; color3.rgb *= color3.a;
|
||||
outColor = lerp(lerp(lerp(color3, color2, alpha.z), color1, alpha.y), color0, alpha.x);
|
||||
outColor.rgb /= outColor.a;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96de908384869cd409c75efa351d5edf
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user