I don't think I made a dedicated post for my addon yet besides sticking it random places. This addon is for blender 2.79 it may be compatable with newer version but.x format is not so the file type in the script would need to be changed.
You will also need to install the .x blender addon to make it work. User pref addon .x install
This addon adds a button to blender on the agk tab give the project a name and click (Test/PLay). Clicking the button will create a folder on your desktop called agk workspace and create a prebuilt scene with camera and keyboard controls along with an auto texture loader. Models will be exported to the project folder along will all refereneced textures. Do not use jpeg or gif for textures in blender since agk does not support them.
Demonstration of it working.
plugin.py file
https://forum.thegamecreators.com/attachment/89406
raw src
import bpy
import json
import os
import subprocess
import time
import shutil
#import export_code
bl_info = {
"name": "AGK Exporter",
"author": "Your Name",
"version": (1, 0),
"blender": (2, 79, 0),
"location": "View3D > Tool Shelf > AGK",
"description": "Export AGK code and AGK load script",
"category": "Development"
}
def code():
# your code here
print("Exporting AGK code...")
class ExportAGKLoadScriptOperator(bpy.types.Operator):
bl_idname = "object.export_agk_load_script"
bl_label = "Test/Play"
def execute(self, context):
json_export()
return {'FINISHED'}
class AGKPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_agk_panel"
bl_label = "AGK"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = "AGK"
def draw(self, context):
layout = self.layout
layout.operator("object.export_agk_code")
layout.operator("object.export_agk_load_script")
layout.operator("object.test_play")
layout.label(text="WorkSpace Project Name to save ")
layout.label(text="will overwrite Files if they exist")
col = self.layout.column(align = True)
col.prop(context.scene, "my_string_prop")
def json_export():
home_dir = os.path.expanduser("~")
data=[]
newdata=""
# Loop through each selected object and get its rotation, position, and texture information
projectName=bpy.context.scene.my_string_prop
filepath = os.path.join(home_dir , "Desktop")
workspace= os.path.join(filepath, "Agk_WorkSpace")
Project=os.path.join(workspace, projectName)
filename="import.lls"
if not os.path.exists(workspace):
os.makedirs(workspace)
if not os.path.exists(Project):
os.makedirs(Project)
objPath=os.path.join(Project,"media/objects")
if not os.path.exists(objPath):
os.makedirs(objPath)
texPath=os.path.join(Project,"media/textures")
if not os.path.exists(texPath):
os.makedirs(texPath)
texPath2=os.path.join(Project,"media/textures/bulk")
if not os.path.exists(texPath2):
os.makedirs(texPath2)
# Iterate over all the objects in the scene
for obj in bpy.context.scene.objects:
data.append("\n:Type:"+obj.type+":")
data.append(":Name:"+obj.name+":")
data.append("//Rotation")
data.append(":x:"+str(obj.rotation_euler[0])+":")
data.append(":y:"+str(obj.rotation_euler[1])+":")
data.append(":z:"+str(obj.rotation_euler[2])+":")
data.append("//Position")
data.append(":x:"+str(obj.location[0])+":")
data.append(":y:"+str(obj.location[1])+":")
data.append(":z:"+str(obj.location[2])+":")
if obj.type=="LAMP":
l=obj.data.color
data.append(":"+str(int(l[0]*255))+":"+str(int(l[1]*255))+":"+str(int(l[2]*255))+":")
data.append(obj.data.distance)
# Iterate over all of the current object's material slots
for m in obj.material_slots:
if m.material:
c=m.material.diffuse_color
data.append("//Material Color RGB")
data.append(":"+str(int(c[0]*255))+":"+str(int(c[1]*255))+":"+str(int(c[2]*255))+":")
# Iterate over all the current material's texture slots
for t in m.material.texture_slots:
# If this is an image texture, with an active image append its name to the list
if t and t.texture.type == 'IMAGE' and t.texture.image:
data.append(":Texture:" +t.texture.image.name +":"+m.name+":")
#data.append(t.texture.name)
projectName=bpy.context.scene.my_string_prop
filepath = os.path.join(home_dir , "Desktop")
workspace= os.path.join(filepath, "Agk_WorkSpace")
Project=os.path.join(workspace, projectName)
shutil.copy(t.texture.image.filepath,workspace+"\\"+projectName+"\\media\\textures\\bulk")
data.append("//END")
data.append("//scene")
scene=bpy.context.scene.world
col=scene.ambient_color
data.append(":"+str(int(col[0]*255))+":"+str(int(col[1]*255))+":"+str(int(col[2]*255))+":")
# Convert the list of dictionaries to JSON format
for i in data:
newdata=newdata+str(i)+"\n"
filepath2 = os.path.join(Project, filename)
with open(filepath2, "w") as f:
f.write(newdata)
##################EXPORT#######################################################
# Set the filepath and filename for the FBX export
directory = objPath+"/"
# Loop through all objects in the scene
for obj in bpy.context.scene.objects:
# Select the object
bpy.ops.object.select_all(action='DESELECT')
obj.select=True
# Set the output filepath for the FBX file
filepath = directory + obj.name + ".fbx"
# bpy.ops.object.active=obj
#bpy.context.scene.objects.active=obj
# Export the selected object to FBX
if obj.type=="MESH":
bpy.ops.export_scene.fbx(filepath=filepath, check_existing=False,object_types={'ARMATURE', 'CAMERA', 'LAMP', 'MESH'}, filter_glob='*.fbx', use_selection=True, global_scale=1.0, apply_unit_scale=True,
apply_scale_options='FBX_SCALE_NONE',
use_mesh_modifiers_render=True, mesh_smooth_type='FACE',
use_mesh_edges=True, use_custom_props=False,
add_leaf_bones=True, primary_bone_axis='Y', secondary_bone_axis='X', use_armature_deform_only=False,
armature_nodetype='NULL', bake_anim=True, bake_anim_use_all_bones=True, bake_anim_use_nla_strips=True,
bake_anim_use_all_actions=True, bake_anim_force_startend_keying=True, bake_anim_step=1.0,
bake_anim_simplify_factor=1.0, path_mode='AUTO', batch_mode='OFF',
use_batch_own_dir=True, axis_forward='-Z', axis_up='Y')
#obj.deselect=True
agklist="""[apk_settings]
alias=
app_new_icon_path=
app_icon_path=
notif_icon_path=
app_name=
app_type=0
game_circle_api_key=
keystore_path=
orientation=0
output_path=
ouya_icon_path=
package_name=
permission_flags=7
play_app_id=
admob_app_id=
snapchat_client_id=
sdk_version=1
version_name=
version_number=0
firebase_config_path=
url_scheme=
deep_link=
arcore=0
[ipa_settings]
app_name=
app_icon_path=
build_number=
version_number=
device_type=0
facebook_id=
orientation=0
output_path=
uses_ads=0
url_scheme=
deep_link=
admob_app_id=
snapchat_client_id=
splash_logo=
firebase_config_path=
splash_color=
prov_profile_path=
[html5_settings]
commands_used=0
dynamic_memory=0
output_path=
[projectfiles]
FILE_0=main.agc;-1
FILE_1=Import.agc;-1
[files]
FILE_NAME_0=0;main.agc;13;0
FILE_NAME_1=1;Import.agc;13;1
[watchvariables]"""
oldprojectName= projectName
projectName=projectName+".agk"
filepath2 = os.path.join(Project,projectName)
with open(filepath2, "w") as f:
f.write(agklist)
mainList="""
SetErrorMode(2)
// set window properties
SetWindowTitle( "test" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )
setcameraposition(1,0,1,-2)
SetCameraRange(1,0.01,100)
SetCameraLookAt(1,1,1,0,0)
SetGenerateMipmaps(1)
SetSunActive(1)
#include "Import.agc"
runImport()
do
Camera_controls()
Sync()
loop
"""
filepath3 = os.path.join(Project,"main.agc")
if not os.path.exists(filepath3):
with open(filepath3, "w") as f:
f.write(mainList)
importList="""
function runImport()
global obj as objectType[]
global LoadedImages as loadedimagestype []
global Dir as dirtype []
global TempDir as dirtype
global path as string
global light as lighttype []
path="raw:"+getreadpath()+"media/"
FileDiscovery("textures")
loadLevel()
t as lighttype
t.name="null"
light.insert(t)
Endfunction
type Loadedimagestype
ImageName as string
ImageID as integer
endtype
type ObjectType
Name as string
ID as integer
rot as vectype
pos as vectype
textname as string[]
meshtexture as meshtexturetype
textid as integer[]
endtype
type meshtexturetype
primary as integer []
secondary as integer []
normal as integer[]
endtype
type vectype
x as float
y as float
z as float
endtype
type lighttype
number as integer
kind as string
name as string
px as float
py as float
pz as float
rx as float
ry as float
rz as float
col as integer
range as float
endtype
function loadLevel()
setfolder("")
read=OpenToRead("import.lls")
setfolder("\media\objects")
while FileEOF(read) = 0
data$=readline(read)
num=countstringtokens(data$,":")
if num>0
if GetStringToken(data$,":",1)="Type"
if GetStringToken(data$,":",2)="MESH"
loadobj(read)
endif
if GetStringToken(data$,":",2)="LAMP" then loadLamp(read)
endif
endif
endwhile
`Textureobjects()
endfunction
function loadobj(read)
setfolder("\media\objects")
t as objecttype
obj.insert(t)
objid=obj.length
data$=readline(read)
obj[objid].name=getstringtoken(data$,":",2)
obj[objid].id=loadobject(obj[objid].name+".fbx")
setobjectscale(obj[objid].id,0.002,.002,.002)
SetObjectCullMode(obj[objid].id,0)
SetObjectCastShadow(obj[objid].id,1)
SetObjectReceiveShadow(obj[objid].id,1)
readline(read)
data$=readline(read):obj[objid].rot.x=val(getstringtoken2(data$,":",2))
data$=readline(read):obj[objid].rot.y=val(getstringtoken2(data$,":",2))
data$=readline(read):obj[objid].rot.z=val(getstringtoken2(data$,":",2))
data$=readline(read)
data$=readline(read):obj[objid].pos.x=val(getstringtoken2(data$,":",2))
data$=readline(read):obj[objid].pos.y=val(getstringtoken2(data$,":",2))
data$=readline(read):obj[objid].pos.z=val(getstringtoken2(data$,":",2))
mesh=0
for i = 0 to 10
if data$="//END" then exitfunction
data$=readline(read)
if data$="//Material Color RGB"
data$=readline(read)
r=val(GetStringToken(data$,":",1))
g=val(GetStringToken(data$,":",1))
b=val(GetStringToken(data$,":",1))
data$=readline(read)
endif
if GetStringToken(data$,":",1)="Texture"
name$=GetStringToken(data$,":",2)
str$=GetStringToken(data$,":",3)
if left(str$,6)="second" then load2=1
if left(str$,6)="normal" then load2=2
if load2 >0
textid=LoadImages(name$)
endif
if load2 < 1
textid=LoadImages(name$)
endif
if load2 < 1
inc mesh,1
obj[objid].textid.insert(textid)
if GetObjectNumMeshes(obj[objid].id) < 1
`setobjectimage(obj[objid].id,textid,0)
else
if mesh <=GetObjectNumMeshes(obj[objid].id)
SetObjectmeshImage(obj[objid].id,mesh,textid,0)
obj[objid].meshtexture.primary.insert(textid)
endif
endif
endif
if load2=1
if mesh =0
`SetObjectimage(obj[objid].id,textid,1)
load2=-1
else
if mesh <=GetObjectNumMeshes(obj[objid].id)
SetObjectmeshimage(obj[objid].id,mesh,textid,1)
obj[objid].meshtexture.secondary.insert(textid)
endif
endif
load2=-1
endif
if load2=2
if mesh =0
`SetObjectNormalMap(obj[objid].id,textid)
else
if mesh <=GetObjectNumMeshes(obj[objid].id)
SetObjectmeshnormalmap(obj[objid].id,mesh,textid)
obj[objid].meshtexture.normal.insert(textid)
endif
endif
endif
load2=-1
textid=-1
name$=""
str$=""
endif
next
endfunction
function loadlamp(read)
global globalpointlights
name$=getstringtoken(readline(read),":",2)
readline(read) //rotline
data$=readline(read):rx#=val(getstringtoken2(data$,":",2))
data$=readline(read):ry#=val(getstringtoken2(data$,":",2))
data$=readline(read):rz#=val(getstringtoken2(data$,":",2))
readline(read)//pos
data$=readline(read):px#=val(getstringtoken2(data$,":",2))
data$=readline(read):py#=val(getstringtoken2(data$,":",2))
data$=readline(read):pz#=val(getstringtoken2(data$,":",2))
col$=readline(read)
c1=val(getstringtoken(col$,":",1))
c2=val(getstringtoken(col$,":",2))
c3=val(getstringtoken(col$,":",3))
col=makecolor(c1,c2,c3)
range#=round( val(readline(read)))
//make sun
if left(name$,3)="sun"
SetSunActive(1)
SetSunColor(c1,c2,c3)
SetSunDirection(px#,py#,pz#)
endif
if lower(left(name$,5))="point" or left(name$,4) ="Lamp"
inc globalpointlights ,1
num=globalpointlights
CreatePointLight(num,px#,py#,pz#,range#,c1,c2,c3)
setpointlightmode(num,2)
t as lighttype
t.px=px#:t.py=py#:t.pz=pz#
t.rx=rx#:t.ry=ry#:t.rx=rx#
t.name=name$
t.col=makecolor(c1,c2,c2)
t.range=range#:t.kind="point"
t.number=num
light.insert(t)
endif
endfunction
function Camera_controls()
y#=mousemovey()
x#=Mousemovex()
if GetRawMouseLeftstate()=1
RotateCameralocalX(1,y#/2)
RotateCameraglobaly(1,x#/2)
endif
if GetRawKeystate(87)=1
MoveCameraLocalZ(1,.2)
endif
if GetRawKeystate(83)=1
MoveCameraLocalZ(1,-.2)
endif
endfunction
function MousemoveX()
global OldMouseX#
dx# = GetRawMouseX() - OldMouseX#
OldMouseX# = GetRawMouseX()
endfunction dx#
function MousemoveY()
global OldMouseY#
dy# = GetRawMouseY() - OldMouseY#
OldMouseY# = GetRawMouseY()
endfunction dy#
remstart
function TextureObjects()
SetObjectUVScale (object[i].id,1,1,1)
setimagewrapu (Loadedimages[find].Imageid,1)
setimagewrapv (Loadedimages[find].Imageid,1)
if found <=GetObjectNumMeshes(object[i].id)
setobjectmeshimage(object[i].id,found,Loadedimages[find].Imageid,1)
else
if object[i].imageName.length =1
parent=object[i].id
image1=object[i].imageid[0]
image2=object[i].imageid[1]
ShaderFilter(parent,image1,image2)
endif
endif
lights()
endfunction
remend
type dirtype
DirName as string
ImageName as string[]
ImageID as integer[]
endtype
type TempDirtype
DirName as string
endtype
function FileDiscovery(directory$)
ID=OpenRawFolder(path+directory$) //open media folder search for folders
foldercount=GetRawFolderNumFolders(id) //get num of folders inside
for i = 0 to Foldercount-1 //find names of folders
FolderName$=GetRawFolderFolderName(id,i)
folder=i// folder= array id technically
if len(foldername$)>0
Tempdir.DirName=foldername$ //fill temp type
Dir.insert(tempdir)//inserttemp into dir type (folder name)
endif
newid=OpenRawFolder(path+directory$+"/"+foldername$)
FindFiles(folder,newid)
next
endfunction
function FindFiles(folder,id)//raw folder id
FileCount=GetRawFolderNumFiles(id)
For i = 0 to FileCount-1
FileName$=GetRawFolderFileName(id,i)
If len(FileName$)>0
dir[folder].ImageName.insert(Filename$) //fill temp type
endif
next
endfunction
function LoadImages(FileName$)
//loadimage into global image array dont load twice
for i=0 to LoadedImages.length
if len(Loadedimages[i].ImageName)>-1
if Loadedimages[i].imagename =Filename$
found=i
endif
endif
next
`end
`load image if not found
if found=0
if len(filename$)>1
for directory=0 to dir.length
for image=0 to dir[directory].ImageName.length
if dir[directory].ImageName[image]=filename$
setfolder("/media")
setfolder("Textures")
setfolder(dir[directory].DirName)
images=loadimage(filename$)
t as loadedimagestype
t.imagename=filename$
t.imageid=images
loadedimages.insert(t)
found=LoadedImages.length
endif
next
next
endif
else
images=loadedimages[found].ImageID
endif
Endfunction images
"""
filepath4 = os.path.join(Project,"Import.agc")
if not os.path.exists(filepath4):
with open(filepath4, "w") as f:
f.write(importlist)
exe="D:\Program Files (x86)\The Game Creators\AppGameKit Studio\media\compiler\AGKCompiler.exe"
print("******************************************************************")
print (exe)
param1=Project
print (param1)
#param="-agk $("+Project+")"
#subprocess.run([executable, param1, param2])
subprocess.run([exe, param1])
exe2=Project+"\\"+oldprojectName+".exe"
print(exe2)
subprocess.run([exe2,""])
def register():
# bpy.utils.register_class(ExportAGKCodeOperator)
bpy.utils.register_class(ExportAGKLoadScriptOperator)
#bpy.utils.register_class(TestPlayOperator)
bpy.utils.register_class(AGKPanel)
bpy.types.Scene.my_string_prop = bpy.props.StringProperty (name = "Name Of Project",description = "",default = "default")
def unregister():
bpy.utils.unregister_class(ExportAGKCodeOperator)
bpy.utils.unregister_class(ExportAGKLoadScriptOperator)
bpy.utils.unregister_class(TestPlayOperator)
bpy.utils.unregister_class(AGKPanel)
del bpy.types.Scene.my_string_prop
if __name__ == "__main__":
register()
to install the .py file Navigate to File > User Preferences.
In the Blender User Preferences window click the Add-ons tab.
Click Install from File... and select the file
Select File > User preferencesā¦ Then Addons > Install from fileā¦
Add a subdirectory under my_scripts called addons (it must have this name for Blender to recognize it).
Open the File Paths section of the Preferences.
Set the Scripts file path to point to your script directory (e.g. my_scripts).
Save the preferences and restart Blender for it to recognize the new add-on location.
IMportant Note!
must be in object mode when you run test/play otherwise it may alter the locations of objects to zero, you can always undo it if it happens.
Enjoy!