MixupGO

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
m (Text replace - "<boo>" to "<syntaxhighlight lang="boo">")
m (Text replace - "</boo>" to "</syntaxhighlight>")
 
Line 150: Line 150:
 
wrapped as duck = MixupGO(gameObject);
 
wrapped as duck = MixupGO(gameObject);
 
wrapped.position += Vector3.left;
 
wrapped.position += Vector3.left;
</boo>
+
</syntaxhighlight>
  
 
=== C# ===
 
=== C# ===
 
C# Does not support ducktyping, so it will not see the added fields and methods.
 
C# Does not support ducktyping, so it will not see the added fields and methods.

Latest revision as of 20:57, 10 January 2012

Author: KeliHlodversson

Contents

[edit] Description

This class combines ducktyping with Boo's IQuackFu interface, to wrap GameObjects into a dynamic object that automatically forwards all method calls to the first Component attached to it that implements the method.

[edit] Usage

Add MixupGO.js to your project and you will be able to do the following:

var me : Object;
me = new MixupGO(gameObject);
 
//...
 
me.position=Vector3(0,0,0) ; // same as transform.position=...
 
me.material.color=Color.red; // Uses the firs material property found inside components
me.MeshRenderer.material.color=Color.red; // Explicitly specify which component to use in case of ambiguity
 
me.child_object.position+=Vector3.forward; // Asuming a child object named "child_object"
me.AddForce(0,0,1); // same as rigidbody.AddForce(0,0,1)

[edit] JavaScript - MixupGO.js

//
// MixupGO - a wraper around GameObject that merges the methods of all member components
// as if they were defined in GameObject itself
//
 
import System.Reflection;
 
class MixupGO extends Boo.Lang.IQuackFu  {
    private var me : GameObject;
    private var t : System.Type;
 
    function QuackInvoke(name : String, args : Object[]) : Object {
        var at = new System.Type[args.Length];
        for (var i=0;i<args.Length;i++)
            at[i]=args[i].GetType();
 
        // First test if the method is defined statically on the GameObject
        var mi : MethodInfo = t.GetMethod(name, at);
        if(mi)
            return mi.Invoke(me, args);
 
        // Then loop through all components an invoke the first one found
        for (var c in me.GetComponents(Component) ){
            var lt=c.GetType();
            mi = lt.GetMethod(name, at);
            if(mi)
                return mi.Invoke(c, args);
        }
 
        // If not -- throw an error. 
        var s = "(";
        for (var j=0;j<at.Length;j++)
            s+=at[j]+((j<at.Length-1)?", ":"");
        s+=")";
 
        throw System.MissingMethodException("Method '"+name+s+"' not found on "+me.name);
 
    }
 
    function QuackGet(name : String) : Object {
 
        // First test if the field is defined statically
        var pi : PropertyInfo = t.GetProperty(name);
        if (pi) 
            return pi.GetValue(me,null);
        var fi : FieldInfo = t.GetField(name);
        if (fi) 
            return fi.GetValue(me);
 
        // special case for parent property -- return a MixupGO-wrapped gameObject instead of a Transform
        if(name == "parent")
            return new MixupGO(me.transform.parent.gameObject);
 
        // Then loop through all components an invoke the first one found
        for (var c in me.GetComponents(Component) ){
            var lt=c.GetType();
            pi = lt.GetProperty(name);
            if (pi) 
                return pi.GetValue(c,null);
            fi = lt.GetField(name);
            if(fi)
                return fi.GetValue(c);
 
        }
        // Then test if name is an attached component
        var c : Component = me.GetComponent(name);
        if( c )
            return c;
 
        // finally loop through all children an return the first one with the same name
        for(var child : Transform in me.transform) {
            if(child.name == name) 
                return new MixupGO(child.gameObject);
        }
 
        throw System.MissingMethodException("Property '"+name+"' not found on "+me.name);
 
    }
 
    function QuackSet(name : String, value : Object) : Object {
        //var vt : System.Type = value.GetType();
 
        // First test if the field is defined statically
        var pi : PropertyInfo = t.GetProperty(name);
        if (pi) {
            pi.SetValue(me,value,null);
            return value;
        }
        var fi : FieldInfo = t.GetField(name);
        if (fi) {
            fi.SetValue(me,value);
            return value;
        }
        // Then loop through all components an invoke the first one found
        for (var c in me.GetComponents(Component) ){
            var lt=c.GetType();
            pi = lt.GetProperty(name);
            if (pi) {
                pi.SetValue(c,value,null);
                return value;
            }
            fi = lt.GetField(name);
            if(fi) {
                fi.SetValue(c,value);
                return value;
            }
 
        }
 
        throw System.MissingMethodException("Property '"+name+"' not found on "+me.name);
    }
 
    // Constructor
    function MixupGO(go : GameObject) {
        me=go;
        t=me.GetType();
    }
 
}

[edit] Using MixupGO in other languages

[edit] Boo

This will also work in Boo (just place the javascript inside Standard Assets to make it compile before the Boo script):

wrapped as duck = MixupGO(gameObject);
wrapped.position += Vector3.left;

[edit] C#

C# Does not support ducktyping, so it will not see the added fields and methods.

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox