You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
5.5 KiB
202 lines
5.5 KiB
using UnityEngine;
|
|
|
|
public class Entity
|
|
{
|
|
private readonly int entityNum;
|
|
private readonly VisualStyle visualStyle;
|
|
private readonly Layers layer;
|
|
|
|
private int skinNumber;
|
|
|
|
private GameObject gameObject;
|
|
|
|
private MeshFilter meshFilter;
|
|
private MeshRenderer meshRenderer;
|
|
private SkinnedMeshRenderer skinnedMeshRenderer;
|
|
private Material material;
|
|
|
|
private AliasModel aliasModel;
|
|
private GameObject brushModel;
|
|
private GameObject worldModel;
|
|
|
|
private ParticleTrailController particleTrail;
|
|
|
|
public Entity(int entityNum, VisualStyle visualStyle, Layers layer)
|
|
{
|
|
this.entityNum = entityNum;
|
|
this.visualStyle = visualStyle;
|
|
this.layer = layer;
|
|
CreateGameObject();
|
|
}
|
|
|
|
private void CreateGameObject()
|
|
{
|
|
gameObject = new GameObject($"Entity_{entityNum}") { layer = (int)layer };
|
|
|
|
skinnedMeshRenderer = gameObject.AddComponent<SkinnedMeshRenderer>();
|
|
skinnedMeshRenderer.enabled = false;
|
|
|
|
meshFilter = gameObject.AddComponent<MeshFilter>();
|
|
meshRenderer = gameObject.AddComponent<MeshRenderer>();
|
|
meshRenderer.enabled = false;
|
|
}
|
|
|
|
public void Destroy()
|
|
{
|
|
ClearParticleTrail();
|
|
Object.Destroy(gameObject);
|
|
}
|
|
|
|
public void ClearModel()
|
|
{
|
|
aliasModel = null;
|
|
brushModel = null;
|
|
worldModel = null;
|
|
|
|
skinnedMeshRenderer.sharedMesh = null;
|
|
if (skinnedMeshRenderer.material != null)
|
|
{
|
|
Object.Destroy(skinnedMeshRenderer.material);
|
|
skinnedMeshRenderer.material = null;
|
|
}
|
|
skinnedMeshRenderer.enabled = false;
|
|
|
|
meshFilter.sharedMesh = null;
|
|
if (meshRenderer.material != null)
|
|
{
|
|
Object.Destroy(meshRenderer.material);
|
|
meshRenderer.material = null;
|
|
}
|
|
meshRenderer.enabled = false;
|
|
|
|
for (int child = 0; child < gameObject.transform.childCount; ++child)
|
|
{
|
|
Object.Destroy(gameObject.transform.GetChild(child).gameObject);
|
|
}
|
|
}
|
|
|
|
public void SetAliasModel(AliasModel model)
|
|
{
|
|
ClearModel();
|
|
aliasModel = model;
|
|
AssignMeshRenderer();
|
|
|
|
// Set a default pose based on the first animation frame
|
|
UpdateAnimation(0, 0, 0f);
|
|
|
|
if (model.AutoAnimate)
|
|
{
|
|
// TODO: do something with syncbase value to push similar animations out of phase
|
|
var animator = gameObject.AddComponent<AliasModelAnimator>();
|
|
animator.aliasModel = model;
|
|
}
|
|
}
|
|
|
|
public void SetBrushModel(GameObject brushModelGO)
|
|
{
|
|
ClearModel();
|
|
brushModel = brushModelGO;
|
|
brushModel.transform.SetParent(gameObject.transform);
|
|
}
|
|
|
|
public void SetWorldModel(GameObject worldModelGO)
|
|
{
|
|
ClearModel();
|
|
worldModel = worldModelGO;
|
|
worldModel.transform.SetParent(gameObject.transform);
|
|
}
|
|
|
|
public void UpdateAnimation(int pose1, int pose2, float blend)
|
|
{
|
|
if (aliasModel != null)
|
|
{
|
|
aliasModel.Animate(pose1, pose2, blend, out Mesh mesh, out float blendWeight);
|
|
|
|
if (skinnedMeshRenderer.enabled)
|
|
{
|
|
skinnedMeshRenderer.sharedMesh = mesh;
|
|
if (mesh != null && mesh.blendShapeCount > 0)
|
|
skinnedMeshRenderer.SetBlendShapeWeight(0, blendWeight);
|
|
}
|
|
else if (meshRenderer.enabled)
|
|
{
|
|
meshFilter.sharedMesh = mesh;
|
|
}
|
|
}
|
|
|
|
if (worldModel != null)
|
|
{
|
|
// TODO: update texture animation
|
|
}
|
|
}
|
|
|
|
public void SetTransform(Vector3 position, Quaternion rotation)
|
|
{
|
|
gameObject.transform.position = position;
|
|
gameObject.transform.rotation = rotation;
|
|
|
|
// Note: we can't parent the particle trail to the entity's game object,
|
|
// since that will instantly destroy all particles when the entity is destroyed or disabled.
|
|
if (particleTrail != null)
|
|
{
|
|
particleTrail.transform.position = position;
|
|
}
|
|
}
|
|
|
|
public void SetSkin(int skinNum)
|
|
{
|
|
skinNumber = skinNum;
|
|
|
|
if (material == null)
|
|
return;
|
|
|
|
var skins = aliasModel.Textures.Skins;
|
|
if (skins.Count > 0)
|
|
{
|
|
var skin = skins[skinNumber >= 0 && skinNumber < skins.Count ? skinNumber : 0];
|
|
if (skin.Frames.Count > 0)
|
|
visualStyle.SetEntityTextures(material, skin.Frames[0].MainTexture, skin.Frames[0].FullBrightTexture);
|
|
}
|
|
}
|
|
|
|
private void AssignMeshRenderer()
|
|
{
|
|
material = visualStyle.CreateEntityMaterial(true);
|
|
|
|
if (aliasModel.IsAnimated)
|
|
{
|
|
visualStyle.SetupEntityRenderer(skinnedMeshRenderer);
|
|
skinnedMeshRenderer.material = material;
|
|
skinnedMeshRenderer.enabled = true;
|
|
}
|
|
else
|
|
{
|
|
visualStyle.SetupEntityRenderer(meshRenderer);
|
|
meshRenderer.material = material;
|
|
meshRenderer.enabled = true;
|
|
}
|
|
|
|
SetSkin(skinNumber);
|
|
}
|
|
|
|
public bool HasParticleTrail(ParticleTrail type)
|
|
{
|
|
return particleTrail != null && particleTrail.Type == type;
|
|
}
|
|
|
|
public void SetParticleTrail(ParticleTrailController trail)
|
|
{
|
|
ClearParticleTrail();
|
|
|
|
particleTrail = trail;
|
|
}
|
|
|
|
public void ClearParticleTrail()
|
|
{
|
|
if (particleTrail != null)
|
|
{
|
|
particleTrail.Stop();
|
|
particleTrail = null;
|
|
}
|
|
}
|
|
}
|