using UnityEngine; namespace Kalita { [RequireComponent(typeof(Animator))] public class AnimationOffset : MonoBehaviour { public int Offset; public bool IsRandomOffset; private void Start() { var animator = GetComponent<Animator>(); var runtimeController = animator.runtimeAnimatorController; var clip = runtimeController.animationClips[0]; if (IsRandomOffset) Offset = Random.Range(0, (int) (clip.length*clip.frameRate)); var time = (Offset*clip.length/clip.frameRate); animator.Update(time); } } }
Shader "Kalita/KalitaAtlasDrawer" { Properties { _MainTex ("Texture Atlas (RGBA)", 2D) = "" {} _Frame("Frame", float) = 0 _TotalFrames("Total Frames Count in Sequence", float) = 1 } SubShader { Tags { "Queue"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha Cull Off pass { CGPROGRAM #pragma vertex vert #pragma fragment frag sampler2D _MainTex; float4 _MainTex_ST; float _Frame; float _TotalFrames; struct appData { float4 vertex : POSITION; fixed4 color : COLOR; float2 uv : TEXCOORD0; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; v2f vert (appData v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); float frame = (_Frame + v.color.a*255) % (_TotalFrames + 1); float offset = frame / _TotalFrames; o.uv = v.uv; o.uv.x += offset; return o; } fixed4 frag (v2f i) : COLOR { fixed4 color = tex2D (_MainTex, i.uv); return color; } ENDCG } } FallBack "Diffuse" }
using UnityEngine; namespace Kalita { [ExecuteInEditMode] [RequireComponent(typeof (MeshFilter))] [RequireComponent(typeof (MeshRenderer))] public class KalitaAnimation : MonoBehaviour { public Material RendererMaterial { get { return meshRenderer.sharedMaterial; } } public Vector2 InGameSize = Vector2.one; public Vector2 Anchor = new Vector2(.5f, .5f); public int FramesCount = 1; public bool IsRandomStartAnimation; public byte StartFrame; private MeshFilter filter; private MeshRenderer meshRenderer; private void Awake() { filter = GetComponent<MeshFilter>(); meshRenderer = GetComponent<MeshRenderer>(); BuildMesh(); SetAnimationOffset(); } #if UNITY_EDITOR && !TEST_RUNNING private void Update() { if (Application.isPlaying) return; BuildMesh(); SetAnimationOffset(); var mat = meshRenderer.sharedMaterial; mat.mainTextureScale = new Vector2(1f / FramesCount, 1); } #endif private void BuildMesh() { var anchor = Anchor; anchor.Scale(InGameSize); anchor /= 2; var mesh = BuildQuad(InGameSize, anchor, new Vector2(1f / FramesCount, 1f)); filter.mesh = mesh; } private void SetAnimationOffset() { var mesh = filter.sharedMesh; mesh.name = "Plane"; var cnt = mesh.vertexCount; var clrs = mesh.colors32; if (clrs.Length != cnt) clrs = new Color32[cnt]; if (IsRandomStartAnimation && Application.isPlaying) StartFrame = (byte)Random.Range(0, 255); for (int i = 0; i < cnt; i++) clrs[i].a = StartFrame; mesh.colors32 = clrs; } public static Mesh BuildQuad(Vector2 size, Vector2 anchor, Vector2 uvStep) { var dx = size.x / 2; var dy = size.y / 2; var vertices = new[] { new Vector3(-dx + anchor.x, -dy + anchor.y, 0), new Vector3(dx + anchor.x, -dy + anchor.y, 0), new Vector3(dx + anchor.x, dy + anchor.y, 0), new Vector3(-dx + anchor.x, dy + anchor.y, 0), }; var uvs0 = new[] { uvStep, new Vector2(0, uvStep.y), new Vector2(0, 0), new Vector2(uvStep.x, 0), }; var indices = new[] { 0, 1, 2, 0, 2, 3 }; var mesh = new Mesh { vertices = vertices, uv = uvs0, triangles = indices }; mesh.Optimize(); return mesh; } } }
using UnityEngine; namespace Kalita { [ExecuteInEditMode] public class KalitaAtlasAC : MonoBehaviour { public KalitaAnimation Animation; public float FrameRate = 24; [HideInInspector] public int CurrentGlobalFrame; private float lastGlobalFrameUpdateTime; private void Awake() { if (Animation == null) Animation = GetComponentInChildren<KalitaAnimation>(); } private void Update() { if (FrameRate <= 0) return; var t = Time.time; var nextUpdateTime = lastGlobalFrameUpdateTime + 1f/FrameRate; if (t < nextUpdateTime) return; var dt = t - lastGlobalFrameUpdateTime; lastGlobalFrameUpdateTime = t; //If we run too slow, we shoud add several frames per update CurrentGlobalFrame += (int) (dt*FrameRate); CurrentGlobalFrame %= Animation.FramesCount; Animation.RendererMaterial.SetFloat("_Frame", CurrentGlobalFrame); } } }
using System.Collections.Generic; using UnityEngine; namespace Kalita { public class HabrSpawner : MonoBehaviour { public List<GameObject> Objects = new List<GameObject>(); public int MobsToSpawn; private int mobOnScene; public Vector2 SpawnZone = new Vector2(10, 10); private void Start() { Screen.sleepTimeout = SleepTimeout.NeverSleep; SpawnMany(); } private void Update() { if (spawnMany) { spawnMany = false; SpawnMany(); } } [SerializeField] private bool spawnMany; private void SpawnMany() { const int layers = 5; var rectBorderSize = Vector2.one*2.4f; var mobsPerLayer = MobsToSpawn / layers; var zone = SpawnZone; for (int j = 0; j < layers; j++) { for (int i = 0; i < mobsPerLayer; i++) Spawn(zone); zone -= rectBorderSize; } } private void Spawn(Vector2 zone) { if (Objects.Count == 0) return; var i = Random.Range(0, Objects.Count); var o = Instantiate(Objects[i]); var p = GetRandomPositionOnRect(zone); Spawn(o, p); } private void Spawn(GameObject o, Vector2 pos) { mobOnScene++; o.SetActive(true); o.transform.position = pos; } private void OnGUI() { var w = 150; var h = 20; var x = 100; var y = 0; var rect = new Rect(x, y, w, h); //+One mob is source mob GUI.Label(rect, "MobsOnScene: " + (mobOnScene + 1)); } private Vector2 GetRandomPositionOnRect(Vector2 size) { var spawnRect = size; var resultPos = new Vector2(); switch (Random.Range(0, 4)) { case 0: // Top resultPos.x = Random.Range(0, spawnRect.x) - (spawnRect.x) / 2f; resultPos.y = spawnRect.y / 2; break; case 1: // Right resultPos.x = spawnRect.x / 2; resultPos.y = Random.Range(0, spawnRect.y) - (spawnRect.y) / 2; break; case 2: // Bottom resultPos.x = Random.Range(0, spawnRect.x) - (spawnRect.x) / 2; resultPos.y = -spawnRect.y / 2; break; case 3: // Left resultPos.x = -spawnRect.x / 2; resultPos.y = Random.Range(0, spawnRect.y) - (spawnRect.y) / 2; break; } return resultPos; } } }
Source: https://habr.com/ru/post/302796/
All Articles