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.
 
 
 
 
 

151 lines
4.4 KiB

using UnityEngine;
using UnityEngine.Rendering;
public class Entity
{
private readonly int entityNum;
private GameObject gameObject;
private MeshFilter meshFilter;
private MeshRenderer meshRenderer;
private SkinnedMeshRenderer skinnedMeshRenderer;
private AliasModel aliasModel;
private GameObject brushModel;
private GameObject worldModel;
public Entity(int entityNum)
{
this.entityNum = entityNum;
CreateGameObject();
}
private void CreateGameObject()
{
gameObject = new GameObject($"Entity_{entityNum}");
skinnedMeshRenderer = gameObject.AddComponent<SkinnedMeshRenderer>();
skinnedMeshRenderer.shadowCastingMode = ShadowCastingMode.Off;
skinnedMeshRenderer.receiveShadows = false;
skinnedMeshRenderer.lightProbeUsage = LightProbeUsage.Off;
skinnedMeshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
skinnedMeshRenderer.enabled = false;
meshFilter = gameObject.AddComponent<MeshFilter>();
meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.shadowCastingMode = ShadowCastingMode.Off;
meshRenderer.receiveShadows = false;
meshRenderer.lightProbeUsage = LightProbeUsage.Off;
meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
meshRenderer.enabled = false;
}
public void Destroy()
{
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;
// TODO: not sure if this is the right way to unlink world sub-models
gameObject.transform.DetachChildren();
}
public void SetAliasModel(AliasModel model)
{
ClearModel();
aliasModel = model;
AssignMeshRenderer();
// Set a default pose based on the first animation frame
UpdateAnimation(0);
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(float frameNum)
{
if (aliasModel != null)
{
aliasModel.Animate(frameNum, 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;
}
private void AssignMeshRenderer()
{
// DEBUG - we'll want to instantiate a prefab and assign materials from a preset collection
var material = new Material(Shader.Find("Universal Render Pipeline/Simple Lit"));
if (aliasModel.IsAnimated)
{
skinnedMeshRenderer.material = material;
skinnedMeshRenderer.enabled = true;
}
else
{
meshRenderer.material = material;
meshRenderer.enabled = true;
}
}
}