using System.Collections.Generic; using System.Collections; using UnityEngine; public class GraphX { public GraphX(GraphXData data) { this.data = data; } GraphXData data; Vector3 spinOffset; Quaternion spin = Quaternion.identity; Matrix4x4[] bodyMatrices = new Matrix4x4[9 * 7 * 9]; Matrix4x4[] coreMatrices = new Matrix4x4[3 * 3 * 3]; Matrix4x4 foodMatrix = new Matrix4x4(); Matrix4x4 tongueMatrix = new Matrix4x4(); Matrix4x4 arrowMatrix = new Matrix4x4(); Matrix4x4 faceMatrix = new Matrix4x4(); Matrix4x4 controllerMatrix = new Matrix4x4(); Matrix4x4 joystickMatrix = new Matrix4x4(); Matrix4x4 conArrowMatrix = new Matrix4x4(); public float foodScale = 0; public float Exp(float value, int power) { for (int i = 0; i < power; i++) { value *= value; } return value; } public Quaternion GetNormalized(Quaternion q) { float f = 1f / Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); return new Quaternion(q.x * f, q.y * f, q.z * f, q.w * f); } public void Render(Main main) { Vector3 angleDelta = new Vector3(Exp(Mathf.Sin(Time.time * spinOffset.x), 3), Exp(Mathf.Sin(Time.time * spinOffset.y), 3), Exp(Mathf.Sin(Time.time * spinOffset.z), 3)) * Time.deltaTime * 180; if (angleDelta.sqrMagnitude < 0.1) { spinOffset = new Vector3( 0.5f + Random.value, 0.5f + Random.value, 0.5f + Random.value ); } else { spin = Quaternion.Euler(angleDelta) * spin; } foodScale = Mathf.Lerp(foodScale, 1, 6 * Time.deltaTime); foodMatrix.SetTRS( main.food, GetNormalized(spin), foodScale * Vector3.one ); Graphics.DrawMesh(data.foodMesh, foodMatrix, data.snakeMat, 0); if (main.playing && (data.faceMesh == data.faceDefault || data.faceEaten || data.faceHyper)) { // tongueMatrix.SetTRS( // main.snake[0], // main.inputRot, // Vector3.one // ); Graphics.DrawMesh(data.tongueMesh, tongueMatrix, data.snakeMat, 0); main.tongueLine.SetPosition(0, main.snake[0] + ((Vector3)main.dir * 0.4f)); Vector3 tip = main.snake[0] + main.inputRot * Vector3.forward * ((1 + Mathf.Clamp01(main.lerp * 3)) / 2); float x = main.design.bounds.x + 0.5f; float y = main.design.bounds.y + 0.5f; float z = main.design.bounds.z + 0.5f; tip.x = Mathf.Clamp(tip.x, -x, x); tip.y = Mathf.Clamp(tip.y, -y, y); tip.z = Mathf.Clamp(tip.z, -z, z); main.tongueLine.SetPosition(1, tip); } else { main.tongueLine.SetPosition(0, Vector3.zero); main.tongueLine.SetPosition(1, Vector3.zero); } if (!main.aiMode && main.playing) { arrowMatrix.SetTRS( main.design.pivotPos + main.rig.head.rotation * Vector3.up * 2f, main.inputRot, Vector3.one ); Graphics.DrawMesh(data.arrowMesh, arrowMatrix, data.snakeMat, 9); } // Face if (main.snake.Count > 0) { faceMatrix.SetTRS( main.snake[0], Quaternion.LookRotation(main.dir), Vector3.one ); Graphics.DrawMesh(data.faceMesh, faceMatrix, data.snakeMat, 0); // Body for (int i = 1; i < bodyMatrices.Length; i++) { if (i > 0 && i < main.snake.Count) { Vector3 segmentDir = main.snake[i - 1] - main.snake[i]; if (segmentDir.sqrMagnitude == 0) { segmentDir = new Vector3Int(0, 0, 1); } bodyMatrices[i].SetTRS(main.snake[i], Quaternion.LookRotation(segmentDir), Vector3.one); } else { bodyMatrices[i].SetTRS(Vector3.zero, Quaternion.identity, Vector3.zero); } } Graphics.DrawMeshInstanced(data.bodyMesh, 0, data.snakeMat, bodyMatrices); } // Core for (int i = 0; i < coreMatrices.Length; i++) { if (i < main.core.Count) { coreMatrices[i].SetTRS(main.core[i], Quaternion.identity, Vector3.one); } else { coreMatrices[i].SetTRS(Vector3.zero, Quaternion.identity, Vector3.zero); } } Graphics.DrawMeshInstanced(data.coreMesh, 0, data.snakeMat, coreMatrices); // Body Roll if (rollTime > 0) { rollTime -= Time.deltaTime; } else { if (main.justAte < 729) { Shader.SetGlobalInt("_JustAte", ++main.justAte); } rollTime = Mathf.Clamp01((60 / (float)main.bpm) / 27); } // if (!main.sideQuest) // { // return; // } controllerMatrix.SetTRS( main.rig.controllerPos, main.rig.controllerRot * Quaternion.Euler(Vector3.up * 90), Vector3.one * main.design.scale ); Graphics.DrawMesh(data.controllerMesh, controllerMatrix, data.unlitMat, 9); conArrowMatrix.SetTRS( main.rig.controllerPos, main.rig.inputRot, Vector3.one * main.design.scale ); Graphics.DrawMesh(data.conArrowMesh, conArrowMatrix, data.unlitMat, 9); Vector3 pointTo = main.rig.inputRot * Vector3.Lerp(Vector3.up, Vector3.forward, main.rig.joystick.magnitude / 3); // * Quaternion.Euler(Vector3.right * -90) joystickMatrix.SetTRS( main.rig.controllerPos, Quaternion.LookRotation(pointTo), Vector3.one * main.design.scale ); Graphics.DrawMesh(data.joystickMesh, joystickMatrix, data.unlitMat, 9); } float rollTime; public void Step(Main main) { Shader.SetGlobalInt("_JustAte", main.justAte++); } }