Search Unity

UniPython - Python Scripting in Unity3D based games

Discussion in 'Works In Progress - Archive' started by JamesPro, Jul 14, 2013.

  1. JamesPro

    JamesPro

    Joined:
    Mar 5, 2012
    Posts:
    509
    Hello, I'm the Programming Lead for Greed Monger an upcoming Indie Sandbox MMO being developed with Unity - http://www.greedmonger.com - Over the past couple years I've been working on a Python Scripting Engine for use on Servers in MMOs. It was being designed to allow MMO Developers the ability to define different aspects of the MMO such as Items, Mobs, Quests, ect in a fashion that would allow them to add new stuff with out needing to recompile the Servers all the time.

    Before I joined Greed Monger I had very little use for the engine out side of some small prototyping I was doing so the engine was just thrown together. Once I joined GM however it presented a reason to really start polishing the engine and I've since found other uses for the engine out side of what it was built for.

    So that brings us to UniPython. I have started the process of putting together a package I've named UniPython potentially for the Asset Store. This package will allow you to script complete Unity3D Games using IronPython. Create your scenes, setup your Game's Core in the editor (Levels, Audio, ect), then give each object you want controlled by Python the ScriptedObject script that comes with this package. The ScriptedObject script contains a few public variables for you to fill out:

    PythonScript - PythonScript is a String which indicates the name of the Python Script that should control this Object. Depending on the setup of your Scripts folder you must include the name of the folder this script is in.

    InstanceName - InstanceName is also a string which indicates the name of the instance that should be giving to this ScriptedObject. In your python script once your class is created you create instances of the class to be used by your scripted Objects. Here you tell which instance to use. If this is left blank then it will default to a instance name of "script"

    Below is a Demo Script called Missile.py it defines a class called Missile and then creates 2 instances of the Missile class: MissileA and MissileB:

    Code (csharp):
    1.  
    2.  
    3. import UnityEngine
    4. import UniPython
    5. import System
    6. from UnityEngine import *
    7. from UniPython import *
    8. from System import Single
    9.  
    10. class Missile (IScript):
    11.     speed = Single(1)
    12.     duration = Single(10)
    13.     def __init__(Self, _speed = Single(1)):
    14.         Self.speed = _speed
    15.     def Start(Self):
    16.         Debug.Log("I am inside a Script!")
    17.         Debug.Log(Self.speed)
    18.     def Update(Self):
    19.         Self.MoveMissle()
    20.         Self.HandleInput()
    21.     def MoveMissle(Self):
    22.         Self.scriptedObject.transform.Translate(Vector3.forward*Self.speed, Space.Self)
    23.     def HandleInput(Self):
    24.         if Input.GetKeyDown(KeyCode.Escape):
    25.             Application.Quit()
    26.        
    27.        
    28.  
    29. MissileA = Missile(Single(20))
    30. MissileB = Missile(Single(10))
    31.  
    32.  
    MissileA is created with a forward speed of 20 while MissileB is created with a slower forward speed of 10.

    In this example script you can see that the Missile class inherits from a IScript class. IScript contains all of the methods you normally use in your MonoBehaviour inherited scripts. The methods are then called from ScriptedObject in their proper methods.

    Below is what the ScriptedObject class currently looks like:

    Code (csharp):
    1.  
    2.  
    3. using UnityEngine;
    4. using System.Collections;
    5. using UniPython;
    6. using UniPython.Scripting;
    7.  
    8. public class ScriptedObject : MonoBehaviour {
    9.     public string PythonScript = null;
    10.     public string InstanceName = null;
    11.     public IScript script = null;
    12.  
    13.     // Use this for initialization
    14.     void Start () {
    15.  
    16.         if (PythonScript != null)
    17.         {
    18.             if (InstanceName != null)
    19.                 script = ScriptingEngine.getInstance().ReturnScript(PythonScript, InstanceName);
    20.             else
    21.                 script = ScriptingEngine.getInstance().ReturnScript(PythonScript);
    22.  
    23.             script.scriptedObject = this.gameObject;
    24.         }
    25.  
    26.         if (script != null)
    27.             script.Start();
    28.     }
    29.    
    30.     // Update is called once per frame
    31.     void Update () {
    32.         if (script != null)
    33.             script.Update();
    34.     }
    35.  
    36.     void OnGUI() {
    37.         if(script != null)
    38.             script.OnGUI();
    39.     }
    40. }
    41.  
    42.  
    43.  
    I'm still very early in getting this all setup so not all of the methods are currently available.

    The whole point of this package is to allow you to create games and change values on the fly with out the need to recompile the game. Another major feature is allowing players of your game the chance to mess around with the game and mod it. If your players think that the zombie at the end of Level 4 should be a whole lot harder then you made it they have the freedom to go into the scripts and completely rewrite the Zombie's AI if they wanted to.

    If you are Interested by UniPython then let me know and please give me ideas for features you would like see added to the package!
     
    archatas likes this.
  2. JamesPro

    JamesPro

    Joined:
    Mar 5, 2012
    Posts:
    509
    I have thrown together my first little Demo Game with UniPython. It's a small little Block Breaking game where you have to try to Break the blocks with the ball. The Demo consists of 6 Python Scripts:

    - Game.py
    - Objects/Ball.py
    - Objects/Block.py
    - Objects/Player.py
    - Objects/ScoreBoard.py
    - Objects/Wall.py

    Game.py and the Objects folder are located in a Directory called GameData which is located in the Root Directory of the Demo along side Demo.exe and the Demo_Data folder.

    - Controls -
    A and D moves the platform left and right accordingly

    You get 1 point for each block you break.

    Just for fun after you have tried out the Demo see if you can figure out how to increase the points you get for each block you destroy.

    Demo DOWNLOAD - http://www.riseofheroesmmo.com/UniPython/Demo.zip
     
    Last edited: Jul 14, 2013
  3. MrMassively

    MrMassively

    Joined:
    Sep 4, 2013
    Posts:
    115
    Hi JamesPro,

    i am interested in your scripting engine, quick question, can the python scripts be included in the unity assets package compiled?
    i mean once you want to do a release for production can they be included in the unity compiled data packages to prevent client side tempering?

    or if they need to be outside of the unity compiled packages can the python scripts be compiled as regular python .pyc for production release?
    ive heard that Iron Python after certain latest release can now optional be compiled as .pyc to protect tempering. cant remember which version release is that one allowed to do compilation.

    BTW i sent you a pm regarding your python scripting engine, i am very interested if you can be kind and set me up for it.

    thanks in advanced
     
  4. MrMassively

    MrMassively

    Joined:
    Sep 4, 2013
    Posts:
    115
    Hi JamesPro,

    I was wondering if you looked at my PM i sent you regarding your python scripting engine 2 weeks ago.
    I just sent you another one just in case you missed the other one

    please let me know , i am very interested

    thanks.
     
  5. Zeblote

    Zeblote

    Joined:
    Feb 8, 2013
    Posts:
    1,102
    How good / bad is the performance and memory usage?
     
  6. pablobs

    pablobs

    Joined:
    Jul 19, 2012
    Posts:
    1
    Any news about this?
     
  7. Bix

    Bix

    Joined:
    Jan 15, 2014
    Posts:
    1
    MrMassively, Python is a dynamic language and is interpreted at runtime. The pyc files are auto-generated each time the python scripts are run. As an asset or extra file, the python scripts can be run directly from the pyc files OR the py files. In addition, you may chose to zip the files and save the entire python module as a .egg file, which can be read directly by the Python interpreter.

    The simple answer to your question is "yes", but the real response is probably -- this is not the right question to ask about Python (see above).

    Based on what I saw from the layout that JamesPro provided, I believe that the entire program is controlled by Python. Said differently, Python is extended by Unity3D (i.e. Python calls C). As a result, all game code would be written in Python rather than another language.

    Another approach would be to embed a Python interpreter into the Unity3D library and then Python would be executed as desired from a different program/language (e.g. C calls Python)

    I hope this makes sense.
     
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    I'm curious as to why you chose this approach rather than developing some data-driven tools for this.
     
  9. JamesPro

    JamesPro

    Joined:
    Mar 5, 2012
    Posts:
    509
    Simply put I enjoy Python... I like the ease of use of Python and it works well with being able to define Mobs, items, ect, in a MMO Environment on the Server.
     
  10. zergrage

    zergrage

    Joined:
    May 19, 2017
    Posts:
    3
    hmm this is 5 year old article and all... but how's this script going now ?
    or it's all off now?(looks so :S )
     
  11. Rabbikka

    Rabbikka

    Joined:
    Oct 25, 2019
    Posts:
    1
    hmmm whats happen in 2019?
     
  12. haini69

    haini69

    Joined:
    Dec 30, 2019
    Posts:
    1
    anythin happening now ?