forked from Malhavok/Spriter2Unity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PrefabMaker.py
171 lines (124 loc) · 5.74 KB
/
PrefabMaker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
__author__ = 'Malhavok'
import math
import Unity
from Unity import Consts as UC
from Spriter import Node, Sprite
class PrefabMaker(object):
def __init__(self, metaReader = None):
self.go_map = {}
self.saver = Unity.PrefabSaver.PrefabSaver()
self.metaReader = metaReader
self.spriteAssigner = Unity.MB_AssignSprite.MB_AssignSprite()
self.fixDuplicateObjects = False
def fix_duplicates(self):
self.fixDuplicateObjects = True
def get_game_object_list(self):
return self.go_map.values()
def get_prefab_go_list(self):
return self.saver.object_list
def generate_game_objects(self, entity, animId, keyFrameId, newBeDisabled = False):
anim = entity.get_anim(animId)
keyFrame = anim.get_key_frame(keyFrameId)
entityNode = Node.Node()
entityNode.name = entity.get_name()
for elem in keyFrame.nodes:
entityNode.add_child(elem)
self.mangle(entityNode, None, None, newBeDisabled)
# clearing parent, just in case someone wants to use it again
for elem in keyFrame.nodes:
elem.detach_from_parent()
def make_prefab(self, entity):
# i assume there is at least one anim and one frame
numAnims = entity.get_num_anims()
self.generate_game_objects(entity, 0, 0)
for animId in xrange(numAnims):
anim = entity.get_anim(animId)
numFrames = anim.get_num_key_frames()
startFrame = 1 if animId == 0 else 0
if startFrame >= numFrames:
continue
for frameId in xrange(startFrame, numFrames):
self.generate_game_objects(entity, animId, frameId, True)
# attach sprite script to the main GO
self.fix_sprite_assigner()
self.go_map[None].add_component(self.spriteAssigner)
for path in self.go_map.keys():
self.saver.add_object(self.go_map[path], path is None)
self.saver.save(entity.get_name())
def fix_sprite_assigner(self):
for go in self.go_map.values():
sr = go.get_component_of_type(Unity.SpriteRenderer.SpriteRenderer.type)
if sr is None:
continue
self.spriteAssigner.set_path_renderer(go.get_path(), sr.get_id())
self.spriteAssigner.optimize()
def mangle(self, node, parent, parent_node, newBeDisabled = False):
# this is a node of some type
# make game object out of it
# !!!! this requires HEAVY refactoring to make it
# !!!! easier to understand and modify
go = Unity.GameObject.GameObject(node.get_name())
go.set_takes_part_in_anim_calcs(node.get_active())
sinA = math.sin(node.get_angle())
cosA = math.cos(node.get_angle())
x = node.get_pos_x()
y = node.get_pos_y()
z = 0.0
sx = node.get_scale_x()
sy = node.get_scale_y()
if parent_node is not None:
sx *= parent_node.get_scale_x()
sy *= parent_node.get_scale_y()
if parent is not None:
parent.add_child(go)
x *= (sx / node.get_scale_x())
y *= (sy / node.get_scale_y())
if node.__class__ == Sprite.Sprite:
px = node.get_pivot_from_middle_pix_x() * sx
py = node.get_pivot_from_middle_pix_y() * sy
rotPX = px * cosA - py * sinA
rotPY = px * sinA + py * cosA
x += rotPX
y += rotPY
# this solves Z-sorting problem in a less aggressive way
# if the value is big enough it solves z-fighting problems
# Unity imports this as 1/100, multiplying by 10 seems fine
# to solve f-fighting problem (and won't require moving the default camera)
z = -float(node.get_z_index() * 10.0)
sr = Unity.SpriteRenderer.SpriteRenderer()
sr.set_render_group(node.get_z_index())
sr.set_alpha(node.get_alpha())
if self.metaReader:
sr.set_sprite_guid(self.metaReader.get_guid(node.get_file()))
if node.get_file():
self.spriteAssigner.add_sprite(node.get_file().get_name(), go.get_path(), sr.get_sprite_guid())
go.add_component(sr)
transform = go.get_component_of_type(Unity.Transform.Transform.type)
transform.set_position(x * UC.PixelScale, y * UC.PixelScale, z * UC.PixelScale)
transform.set_z_rot(node.get_angle())
if node.__class__ == Sprite.Sprite:
transform.set_scale(sx, sy, 1.0)
#transform.set_scale(node.get_scale_x(), node.get_scale_y(), 1.0)
else:
transform.set_scale(1.0, 1.0, 1.0)
node.scale_x = sx
node.scale_y = sy
if go.get_path() not in self.go_map:
go.set_active(not newBeDisabled)
# get current parent for that object and parent it
if not (go.get_path() is None and go.get_parent_path() is None):
self.go_map[go.get_parent_path()].add_child(go)
self.go_map[go.get_path()] = go
else:
if self.fixDuplicateObjects:
print 'WARNING! duplicate object found:', go.get_name()
oldGO = self.go_map[go.get_path()]
oldTransform = oldGO.get_component_of_type(Unity.Transform.Transform.type)
oldPos = oldTransform.get_position()
currPos = transform.get_position()
# sanity checks
assert(math.fabs(oldPos[0] - currPos[0]) < 1e-3)
assert(math.fabs(oldPos[1] - currPos[1]) < 1e-3)
oldTransform.set_position(oldPos[0], oldPos[1], min(oldPos[2], currPos[2]))
for subNode in node.get_children():
self.mangle(subNode, go, node, newBeDisabled)