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

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;
}
}
}