using UnityEngine;
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
public class Avatar : MonoBehaviour
{
public bool test = false;
[Serializable]
public class Node
{
public GameObject Src;
public GameObject Override;
}
public List<Node> Nodes = new List<Node>();
public void Start()
{
}
public void Update()
{
if (test)
{
ChangeAvatar();
test = false;
}
}
public void ChangeAvatar()
{
for (int i = 0; i < Nodes.Count; ++i)
{
if (Nodes[i].Src != null)
{
GameObject bodyPart = FindGameObject(gameObject, Nodes[i].Src.name);
if (bodyPart != null)
{
if (Nodes[i].Override != null)
{
// 设置到body上的新物件
GameObject newPart = NewGameObject(Nodes[i].Src.name, bodyPart.transform.parent.gameObject);
SkinnedMeshRenderer newPartRender = newPart.AddComponent<SkinnedMeshRenderer>();
SkinnedMeshRenderer avatarRender = Nodes[i].Override.GetComponent<SkinnedMeshRenderer>();
// 刷新骨骼模型数据
SetBones(newPart, Nodes[i].Override, this.gameObject);
newPartRender.sharedMesh = avatarRender.sharedMesh;
newPartRender.sharedMaterials = avatarRender.sharedMaterials;
GameObject.Destroy(bodyPart);
}
else
{
Debug.LogError("ChangeAvatar Override is null Name = " + this.gameObject.name);
}
}
else
{
Debug.LogError("ChangeAvatar bodyPart is null Name = " + this.gameObject.name + ",PartName = "+ Nodes[i].Src.name);
}
}
else
{
Debug.LogError("ChangeAvatar Src is null Name = " + this.gameObject.name);
}
}
}
private Transform FindChild(Transform t, string searchName)
{
foreach (Transform c in t)
{
string partName = c.name;
if (partName == searchName)
{
return c;
}
else
{
Transform r = FindChild(c, searchName);
if (r != null)
{
return r;
}
}
}
return null;
}
private void SetBones(GameObject goBodyPart, GameObject goAvatarPart, GameObject root)
{
var bodyRender = goBodyPart.GetComponent<SkinnedMeshRenderer>();
var avatarRender = goAvatarPart.GetComponent<SkinnedMeshRenderer>();
var myBones = new Transform[avatarRender.bones.Length];
for (var i = 0; i < avatarRender.bones.Length; i++)
{
myBones[i] = FindChild(root.transform, avatarRender.bones[i].name);
}
bodyRender.bones = myBones;
}
public GameObject FindGameObject(GameObject root, string name)
{
if (string.IsNullOrEmpty(name))
return null;
Transform ret = root.transform.Find(name);
if (ret == null)
{
ret = FindComponent<Transform>(root, name);
}
return ret == null ? null : ret.gameObject;
}
public GameObject NewGameObject(string name, GameObject parent)
{
GameObject obj = new GameObject(name);
obj.transform.parent = parent == null ? null : parent.transform;
obj.transform.localPosition = Vector3.zero;
obj.transform.localScale = Vector3.one;
obj.transform.localRotation = Quaternion.identity;
return obj;
}
}