Files
AIGame/AIClient/AgentScripts/BuildPartnerSkillFx.cs
T

85 lines
9.6 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object=UnityEngine.Object;
/// <summary>Ten persistent partner silhouettes, authored mesh particles and bounded lightning ribbons.</summary>
public static class BuildPartnerSkillFx
{
public const string Folder="Assets/Bundles/Combat/Partners";
static readonly Color[] Colors={new Color(1,.72f,.25f,.6f),new Color(1,.3f,.035f),new Color(.8f,1,.4f),new Color(.4f,.85f,1),new Color(.3f,.9f,1,.45f),new Color(.85f,.65f,.3f),new Color(1,.38f,.02f),new Color(.3f,.9f,.45f),new Color(.75f,.55f,1),new Color(.2f,.8f,1,.25f)};
static Material Glow;
static void Material(){string path=Folder+"/PartnerSkillGlow.mat";Glow=AssetDatabase.LoadAssetAtPath<Material>(path);if(Glow==null){Glow=new Material(Shader.Find("AIGame/EnemyCombatParticle"));AssetDatabase.CreateAsset(Glow,path);}Glow.mainTexture=null;EditorUtility.SetDirty(Glow);}
static Mesh Ring=>AssetDatabase.LoadAssetAtPath<Mesh>("Assets/Bundles/Effects/EnemyCombat/CombatRing.asset");
static void Folders(string path){if(AssetDatabase.IsValidFolder(path))return;string parent=Path.GetDirectoryName(path).Replace('\\','/');Folders(parent);AssetDatabase.CreateFolder(parent,Path.GetFileName(path));}
static Mesh SaveMesh(string name,List<Vector3> vertices,List<int> triangles)
{
string path=Folder+"/"+name+".asset";var mesh=AssetDatabase.LoadAssetAtPath<Mesh>(path);if(mesh==null){mesh=new Mesh();AssetDatabase.CreateAsset(mesh,path);}else mesh.Clear();
mesh.name=name;mesh.SetVertices(vertices);mesh.SetTriangles(triangles,0);mesh.uv=vertices.Select(v=>new Vector2(.5f+v.x*.4f,.5f+v.y*.4f)).ToArray();mesh.RecalculateBounds();mesh.RecalculateNormals();EditorUtility.SetDirty(mesh);return mesh;
}
static Mesh Gem()=>SaveMesh("SkillStone",new List<Vector3>{Vector3.up*.5f,Vector3.down*.5f,Vector3.left*.35f,Vector3.right*.35f,Vector3.forward*.35f,Vector3.back*.35f},new List<int>{0,2,4,0,4,3,0,3,5,0,5,2,1,4,2,1,3,4,1,5,3,1,2,5});
static Mesh Leaf()=>SaveMesh("SkillLeaf",new List<Vector3>{new Vector3(0,.6f,0),new Vector3(.32f,0,.06f),new Vector3(0,-.6f,0),new Vector3(-.32f,0,-.06f)},new List<int>{0,1,2,0,2,3});
static Mesh Cross()=>SaveMesh("SkillHealCross",new List<Vector3>{new Vector3(-.13f,-.5f,0),new Vector3(.13f,-.5f,0),new Vector3(-.13f,.5f,0),new Vector3(.13f,.5f,0),new Vector3(-.5f,-.13f,0),new Vector3(.5f,-.13f,0),new Vector3(-.5f,.13f,0),new Vector3(.5f,.13f,0)},new List<int>{0,1,2,2,1,3,4,5,6,6,5,7});
static Mesh Sphere(string name,bool dome)
{
var v=new List<Vector3>();var tri=new List<int>();const int rows=6,cols=12;
for(int y=0;y<=rows;y++)for(int x=0;x<=cols;x++){float a=x/(float)cols*Mathf.PI*2,b=y/(float)rows*Mathf.PI*(dome?.5f:1);v.Add(new Vector3(Mathf.Cos(a)*Mathf.Sin(b),Mathf.Cos(b),Mathf.Sin(a)*Mathf.Sin(b))*.5f);}
for(int y=0;y<rows;y++)for(int x=0;x<cols;x++){int i=y*(cols+1)+x;tri.AddRange(new[]{i,i+1,i+cols+1,i+1,i+cols+2,i+cols+1});}return SaveMesh(name,v,tri);
}
static Mesh Helix()
{
var v=new List<Vector3>();var tri=new List<int>();const int count=64;
for(int i=0;i<=count;i++){float t=i/(float)count,a=t*Mathf.PI*4;var center=new Vector3(Mathf.Cos(a)*.45f,t-.5f,Mathf.Sin(a)*.45f);v.Add(center+Vector3.up*.022f);v.Add(center-Vector3.up*.022f);if(i<count){int k=i*2;tri.AddRange(new[]{k,k+1,k+2,k+1,k+3,k+2});}}return SaveMesh("SkillVineHelix",v,tri);
}
static ParticleSystem Part(Transform parent,string name,Mesh mesh,Color color,int count,float life,float size,float speed=0,bool loop=false)
{
var go=new GameObject(name);go.layer=30;if(parent!=null)go.transform.SetParent(parent,false);var ps=go.AddComponent<ParticleSystem>();var main=ps.main;main.playOnAwake=false;main.loop=loop;main.duration=.75f;main.startLifetime=life;main.startSize=size;main.startSpeed=speed;main.startColor=color;main.maxParticles=24;main.startRotation3D=true;main.simulationSpace=ParticleSystemSimulationSpace.Local;
var emission=ps.emission;emission.rateOverTime=loop?2:0;if(!loop)emission.SetBursts(new[]{new ParticleSystem.Burst(0,(short)count)});
var shape=ps.shape;shape.shapeType=ParticleSystemShapeType.Sphere;shape.radius=.3f;
var renderer=ps.GetComponent<ParticleSystemRenderer>();renderer.sharedMaterial=Glow;renderer.renderMode=ParticleSystemRenderMode.Mesh;renderer.mesh=mesh;renderer.alignment=ParticleSystemRenderSpace.Local;
var colorLife=ps.colorOverLifetime;colorLife.enabled=true;var gradient=new Gradient();gradient.SetKeys(new[]{new GradientColorKey(Color.white,0),new GradientColorKey(color,1)},new[]{new GradientAlphaKey(.9f,0),new GradientAlphaKey(.65f,.5f),new GradientAlphaKey(0,1)});colorLife.color=gradient;
var sizeLife=ps.sizeOverLifetime;sizeLife.enabled=true;sizeLife.size=new ParticleSystem.MinMaxCurve(1,AnimationCurve.Linear(0,.7f,1,1.15f));return ps;
}
static ParticleSystem Halo(Transform parent,Color color,float size,bool ground=false,bool loop=false)
{
var ps=Part(parent,ground?"GroundRipple":"Halo",Ring,color,1,.55f,size,0,loop);if(ground)ps.transform.localRotation=Quaternion.Euler(90,0,0);return ps;
}
public static string Build()
{
if(EditorApplication.isPlaying)throw new Exception("Author in Edit Mode");Folders(Folder);Material();var config=JObject.Parse(File.ReadAllText("../Config/Combat/partner_presentations_v1.json"));var gem=Gem();var leaf=Leaf();var cross=Cross();var bubble=Sphere("SkillBubble",false);var dome=Sphere("SkillWaterDome",true);var helix=Helix();
var previous=SceneManager.GetActiveScene();var scene=EditorSceneManager.NewScene(NewSceneSetup.EmptyScene,NewSceneMode.Additive);
try
{
SceneManager.SetActiveScene(scene);
for(int actor=0;actor<10;actor++)
{
var definition=config["effects"][actor];string name=(string)definition["name"];bool loop=(bool)definition["loop"];Color color=Colors[actor];
var root=Part(null,"Vfx_"+name,actor==2||actor==7?leaf:actor==4||actor==9?bubble:gem,color,loop?2:8,.5f,actor==4?.2f:.12f,actor==2||actor==7?.6f:.4f,loop);
if(actor==0){Halo(root.transform,color,1.8f,false,true);var stones=Part(root.transform,"OrbitingArmor",gem,color,4,.65f,.35f,0,true);var shape=stones.shape;shape.shapeType=ParticleSystemShapeType.Circle;shape.radius=.95f;var rotation=stones.rotationOverLifetime;rotation.enabled=true;rotation.z=1.5f;}
if(actor==1){Halo(root.transform,new Color(1,.45f,.08f,.6f),1.5f);var sparks=Part(root.transform,"EmberSpray",gem,new Color(1,.8f,.2f),12,.35f,.10f,2);var shape=sparks.shape;shape.radius=.1f;}
if(actor==2){Halo(root.transform,new Color(.4f,1,.4f,.4f),1.65f,true);var petals=Part(root.transform,"BlossomPetals",leaf,new Color(1,.7f,.85f),12,.6f,.42f,1.1f);petals.transform.localPosition=Vector3.up*.55f;var plus=Part(root.transform,"HealingBloom",cross,new Color(.8f,1,.45f),1,.6f,.9f);plus.transform.localPosition=Vector3.up*1.35f;}
if(actor==3||actor==8)
{
var line=root.gameObject.AddComponent<LineRenderer>();line.useWorldSpace=false;line.positionCount=9;line.sharedMaterial=Glow;line.widthMultiplier=actor==3?.06f:.09f;line.startColor=color;line.endColor=Color.white;line.numCapVertices=2;line.enabled=false;
Halo(root.transform,color,actor==3?.9f:1.2f);
if(actor==8)for(int n=0;n<3;n++){var slash=Part(root.transform,"ThunderClaw"+n,leaf,new Color(.8f,.6f,1),1,.2f,1);slash.transform.localPosition=new Vector3((n-1)*.2f,0,0);slash.transform.localRotation=Quaternion.Euler(0,0,-25);slash.transform.localScale=new Vector3(.15f,1.2f,1);}
}
if(actor==4){Halo(root.transform,new Color(.4f,.9f,1,.4f),1.2f);var bubbles=Part(root.transform,"FloatingBubbleCage",bubble,new Color(.5f,.9f,1,.38f),9,.65f,.55f,.65f);var shape=bubbles.shape;shape.radius=.9f;}
if(actor==5){Halo(root.transform,new Color(1,.7f,.3f,.6f),2.5f,true);var chunks=Part(root.transform,"QuakeStones",gem,color,12,.55f,.35f,2f);var main=chunks.main;main.gravityModifier=.6f;var shape=chunks.shape;shape.shapeType=ParticleSystemShapeType.Cone;shape.angle=65;chunks.transform.localRotation=Quaternion.Euler(-90,0,0);}
if(actor==6){var flames=Part(root.transform,"ForwardFlamePlume",leaf,new Color(1,.45f,.03f),20,.4f,.5f,6);var shape=flames.shape;shape.shapeType=ParticleSystemShapeType.Cone;shape.angle=18;shape.radius=.12f;var main=flames.main;main.startSize3D=true;main.startSizeX=.3f;main.startSizeY=.9f;main.startSizeZ=.4f;}
if(actor==7){Halo(root.transform,new Color(.3f,1,.5f,.3f),1.8f,true);var vine=Part(root.transform,"RisingVines",helix,new Color(.3f,1,.45f,.8f),1,.65f,1.6f);vine.transform.localPosition=Vector3.up*.9f;var leaves=Part(root.transform,"GreenLeaves",leaf,new Color(.75f,1,.25f),10,.6f,.3f,.7f);leaves.transform.localPosition=Vector3.up*.6f;}
if(actor==9){Part(root.transform,"WaterDome",dome,new Color(.2f,.85f,1,.16f),1,.65f,2.7f,0,true);Halo(root.transform,new Color(.25f,.85f,1,.25f),1.9f,false,true);var tide=Halo(root.transform,new Color(.4f,.9f,1,.25f),2.2f,true,true);tide.transform.localPosition=Vector3.down*.75f;}
PrefabUtility.SaveAsPrefabAsset(root.gameObject,(string)definition["path"]);Object.DestroyImmediate(root.gameObject);
}
AssetDatabase.SaveAssets();return "Saved ten distinct partner skill prefabs and six low-poly effect meshes";
}
finally{SceneManager.SetActiveScene(previous);EditorSceneManager.CloseScene(scene,true);}
}
}