Skip to content

Instantly share code, notes, and snippets.

@LJH960101
Created March 20, 2019 08:08
Show Gist options
  • Select an option

  • Save LJH960101/32e9bf78dcfb64339fc9912fc937af2e to your computer and use it in GitHub Desktop.

Select an option

Save LJH960101/32e9bf78dcfb64339fc9912fc937af2e to your computer and use it in GitHub Desktop.
엔진심화 2차 과제
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class TriangleCharacter : MonoBehaviour
{
struct FMeshData
{
public List<Vector3> vertices;
public List<int> triangles;
}
class Triangle
{
public FMeshData meshData;
public static int SizeofVertices() { return 3; }
public static Triangle CreateTriangle(Vector3 location, Vector3 scale)
{
Triangle newTriangle = new Triangle();
newTriangle.meshData = new FMeshData();
newTriangle.meshData.vertices = new List<Vector3>();
newTriangle.meshData.triangles = new List<int>();
newTriangle.meshData.vertices.Add(new Vector3(-1, 1, 0f));
newTriangle.meshData.vertices.Add(new Vector3(1, 1, 0f));
newTriangle.meshData.vertices.Add(new Vector3(0, -1, 0f));
newTriangle.meshData.triangles.Add(0);
newTriangle.meshData.triangles.Add(1);
newTriangle.meshData.triangles.Add(2);
// 버텍스의 위치와 스케일을 인자만큼 변형시킨다.
Matrix4x4 scaleAndTranslateMatrix = Matrix4x4.Translate(location) * Matrix4x4.Scale(scale);
for (int i = 0; i < newTriangle.meshData.vertices.Count; ++i)
newTriangle.meshData.vertices[i] = scaleAndTranslateMatrix.MultiplyPoint3x4(newTriangle.meshData.vertices[i]);
return newTriangle;
}
}
class MyCharacter
{
private enum EMyCharacterPart
{
Head = 0,
UpBody,
DownBody,
LeftShoulder,
LeftArm,
RightShoudler,
RightArm,
LeftKnee,
LeftLeg,
RightLeg,
RightKnee,
MAX
}
public FMeshData meshData;
public List<Transform> bones = null;
public List<Matrix4x4> bindposes = null;
public List<BoneWeight> boneWeights = null;
private int GetBonesIndexByName(string name)
{
if(bones == null)
{
Debug.Log("Bone must be settinged!");
return -1;
}
for(int i=0; i<bones.Count; ++i)
{
if (bones[i].name == name) return i;
}
Debug.Log("Not exist bone. " + name);
return -1;
}
private static List<Transform> GetBones(Transform root)
{
List<Transform> transforms = new List<Transform>();
int childCount = root.childCount;
transforms.Add(root);
for (int i = 0; i < childCount; ++i)
{
List<Transform> childTransforms = GetBones(root.GetChild(i));
transforms.AddRange(childTransforms);
}
return transforms;
}
public static MyCharacter CreateCharacter(Vector3 location, Vector3 scale, Transform transform)
{
MyCharacter myCharacter = new MyCharacter();
myCharacter.meshData = new FMeshData();
myCharacter.meshData.vertices = new List<Vector3>();
myCharacter.meshData.triangles = new List<int>();
myCharacter.boneWeights = new List<BoneWeight>();
myCharacter.bindposes = new List<Matrix4x4>();
myCharacter.bones = GetBones(transform.GetChild(0));
for(int i=0; i<myCharacter.bones.Count; ++i)
{
myCharacter.bindposes.Add(myCharacter.bones[i].worldToLocalMatrix * transform.localToWorldMatrix);
}
for (EMyCharacterPart i =(EMyCharacterPart)0; i < EMyCharacterPart.MAX; ++i)
{
Triangle newTriangle = null;
switch (i)
{
case EMyCharacterPart.Head:
{
newTriangle = Triangle.CreateTriangle(new Vector3(0f, 3f, 0f), new Vector3(1.0f, 1.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Neck"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Neck"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Neck"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.UpBody:
{
newTriangle = Triangle.CreateTriangle(new Vector3(0f, 0f, 0f), new Vector3(2.0f, 2.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Shoulder"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Shoulder"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Spine"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.DownBody:
{
newTriangle = Triangle.CreateTriangle(new Vector3(0f, -3f, 0f), new Vector3(1.0f, 1.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Spine"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Spine"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Pelvis"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.LeftShoulder:
{
newTriangle = Triangle.CreateTriangle(new Vector3(-3f, 1f, 0f), new Vector3(1.0f, 1.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Shoulder"), weight0 = 0.5f, boneIndex1 = myCharacter.GetBonesIndexByName("Left Arm"), weight1 = 0.5f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Shoulder"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Arm"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.LeftArm:
{
newTriangle = Triangle.CreateTriangle(new Vector3(-3f, -2f, 0f), new Vector3(1.0f, 2.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Arm"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Arm"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Hand"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.RightShoudler:
{
newTriangle = Triangle.CreateTriangle(new Vector3(3f, 1f, 0f), new Vector3(1.0f, 1.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Shoulder"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Shoulder"), weight0 = 0.5f, boneIndex1 = myCharacter.GetBonesIndexByName("Right Arm"), weight1 = 0.5f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Arm"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.RightArm:
{
newTriangle = Triangle.CreateTriangle(new Vector3(3f, -2f, 0f), new Vector3(1.0f, 2.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Arm"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Arm"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Hand"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.LeftKnee:
{
newTriangle = Triangle.CreateTriangle(new Vector3(-1f, -5f, 0f), new Vector3(1.0f, 1.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Knee"), weight0 = 0.5f, boneIndex1 = myCharacter.GetBonesIndexByName("Pelvis"), weight1 = 0.5f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Pelvis"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Knee"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.LeftLeg:
{
newTriangle = Triangle.CreateTriangle(new Vector3(-1f, -8f, 0f), new Vector3(1.0f, 2.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Knee"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Knee"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Left Leg"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.RightKnee:
{
newTriangle = Triangle.CreateTriangle(new Vector3(1f, -5f, 0f), new Vector3(1.0f, 1.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Pelvis"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Knee"), weight0 = 0.5f, boneIndex1 = myCharacter.GetBonesIndexByName("Pelvis"), weight1 = 0.5f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Knee"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
case EMyCharacterPart.RightLeg:
{
newTriangle = Triangle.CreateTriangle(new Vector3(1f, -8f, 0f), new Vector3(1.0f, 2.0f, 1.0f));
BoneWeight[] newBoneWeight = new BoneWeight[]
{
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Knee"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Knee"), weight0 = 1.0f},
new BoneWeight() { boneIndex0 = myCharacter.GetBonesIndexByName("Right Leg"), weight0 = 1.0f}
};
myCharacter.boneWeights.AddRange(newBoneWeight);
break;
}
default:
{
Debug.Log("잘못된 타입!!!");
continue;
}
}
if (newTriangle != null) {
// 인덱스는 모두 세트 순서에 맞게 올려준다.
for(int j = 0; j< newTriangle.meshData.triangles.Count; ++ j)
{
newTriangle.meshData.triangles[j] += (int)i * Triangle.SizeofVertices();
}
myCharacter.meshData.vertices.AddRange(newTriangle.meshData.vertices);
myCharacter.meshData.triangles.AddRange(newTriangle.meshData.triangles);
}
}
// 버텍스의 위치와 스케일을 인자만큼 변형시킨다.
Matrix4x4 scaleAndTranslateMatrix = Matrix4x4.Scale(scale) * Matrix4x4.Translate(location);
for (int i = 0; i < myCharacter.meshData.vertices.Count; ++i)
myCharacter.meshData.vertices[i] = scaleAndTranslateMatrix.MultiplyPoint3x4(myCharacter.meshData.vertices[i]);
return myCharacter;
}
}
private void Awake()
{
Mesh m = new Mesh();
MyCharacter myCharacter = MyCharacter.CreateCharacter(new Vector3(0, 0, 0), new Vector3(1.0f, 1.0f, 1.0f), transform);
m.vertices = myCharacter.meshData.vertices.ToArray();
m.triangles = myCharacter.meshData.triangles.ToArray();
m.boneWeights = myCharacter.boneWeights.ToArray();
m.bindposes = myCharacter.bindposes.ToArray();
SkinnedMeshRenderer smr = GetComponent<SkinnedMeshRenderer>();
smr.bones = myCharacter.bones.ToArray();
smr.sharedMesh = m;
smr.quality = SkinQuality.Bone2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment