Wednesday, December 28, 2011

Moodle Timer Covering Quiz Question

When set to only show one question per page, Moodle's timer was covering up the start of the question - see below:

That pesky timer
Simple fix, based off an old suggestion from 2007 (http://moodle.org/mod/forum/discuss.php?d=45719), but updated to the new moodle 1.9.x code;

in /moode/mod/quiz/jstimer.php
 line 26 change width from 150 to 50
 line 29 change width from 150 to 50
 line 36 change font point size from 14 to 09
 line 51 change value of theTop from 100 to 25
And with that, the quiz now looks like:
Ah, fixed!

Tuesday, December 27, 2011

Basic Grails custom tag testing errors

You may encounter an error such as the following:

"No such property: out<or other method name> in package.classname "


This comes from writing the taglibtest like all the tutorials out on the web had said to, e.g. using:

class DateTagLib {
def thisYear = {
out << Calendar.getInstance().get(Calendar.YEAR)
'' //return empty text
 }
}

This problem arises from the newer versions of grails producing UNIT tests rather than INTEGRATION tests. In the unit environment, the Grails engine is not active to inject the dynamically created methods, such as validate, out.

So how do I resolve this? It runs just fine on the test webpage its included on. The test was failing when the tag clearly worked.



Three things to fix:

  1. Make sure your test case is extending TagLibUnitTestCase.
  2. Make sure you are calling super.setUp() in your test constructor
  3. Make a call to mockTagLib(YourTagClassHere) at the beginning of your test method.


So a basic test case for a custom tag (as shown above) might look like the following:


package yourpackage
import grails.test.*
class DateTagLibTests extends TagLibUnitTestCase  {
  def dateTagLib


  void setUp(){
 super.setUp()
 
    dateTagLib = new DateTagLib()

  }


  void testThisYear() {
 mockTagLib(DateTagLib)
    String expected = Calendar.getInstance().get(Calendar.YEAR)
    assertEquals("the years don't match", expected, dateTagLib.thisYear().toString())
  }
}

Wednesday, December 21, 2011

Changing syntax highlighting for Groovy/Grails in Eclipse

Looking for something a little easier on the eyes?
By combining the Eclipse color theme plugin with some specific groovy settings, you can make working with groovy much more 'visually' appealing.

1) Install the eclipse color theme plugin. Help->Eclipse Marketplace...->Search for "Eclipse Color Theme". Select a dark theme (or really any one of your choosing). You might notice some elements are not being colored correctly however, namely brackets and operators. To fix these last few elements we can manually change their color to something that suits.

2) Window->Preferences->Groovy->Editor. In this settings page you will find the rest of the settings you need to change. Set the operator, bracket colors to something more visible (and any other fine tweaks you may wish)

Enjoy!

Wednesday, September 28, 2011

Color Profile?

After uninstalling Adobe Master Collection CS4 the colors in images displayed inside Windows photo viewer and Photoshop were colored different (and incorrectly so) from what was showing on our website and in windows explorer. Turns out the uninstall of the creative suite had reset the color profiles on my monitors.

To fix this, go to (In Windows 7)...

Control Panel - > Color Management -> Profiles

select...

"Use my settings for this device" (for each monitor attached to your computer)

Under profiles select...

Add

Experiment with different profiles, but I found that the generic sRBG WCS profile "sRGB virtual device model profile" produced acceptable results.


Enjoy.

Friday, August 12, 2011

Generating class diagrams from Eclipse projects

A zoomed out view of my class structure - using subclasses of standard packages prevents some connections from being detected.

I was looking to jump back into a project I had started a while ago in Eclipse. A GWT project for viewing resources from our website, and the class structure had totally evaded me. So I wanted to generate a UML class diagram quickly to get back up to speed and remind myself of what everything did.

I recommend ESS-Model if you ever encounter the same situation. Its free and fast. No bothersome purchase orders to fill out!

Investigating UDK - First Impressions

Bold claim Unreal... But can you back it up?
UDK vs Unity3D

So I've been meaning to check out the Unreal Development Kit (UDK) and compare it to Unity3D. Both seem like viable options for an Indie game designer, with UDK making more profit margin for cheaper games (because of the lack of licensing costs at lower revenues). So I've installed the July 2011 Beta, and have started working a little with UnrealScript - its much like JavaScript/mono in Unity3D so this could be good.

Programming - First impressions would say that for a beginning programmer, unity3D is much easier to learn. Being able to code  in the smaller chunks (behaviors) and the availability (asset store, this blog, forums, others...) of free scripts to (steal) use fairly - that the idea of compiling and writing full classes for pawns and actors is a little more challenging. Point for Unity.

Tool Based Assets - However the reverse is true for aspiring level designers. The inbuilt-tools available in unreal for building levels and generating lightmaps are slightly superior to that of unity. Sure Unity has a passable terrain tool and scene lightmapping, but I have all kinds og trouble trying to get that to work right. Point for Unreal.

Outside Assets - Generating assets in outside programs, while not my forte' seems to be easier in Unity. The asset browser in Unreal is convoluted at first glace, but perhaps this is just because I'm so used to Unity. Importing assets from 3dsmax, photoshop and others is 'automatic' for Unity, and a little more of a process for Unreal. But because I haven't had enough time to fully investigate, I can't award a point in this class just yet.

Build Platforms - If you don't buy the extra pro versions of unity, you only get web player and pc/mac. Compare that to the currently available platforms for Unreal of Windows and iOS. iOS is huge in the current casual gaming market and adds a lot to the value of UDK. But if you have the change to buy a full Unity Suite (something like $2500) you'll unlock Android, iOS (forget about Xbox and Ps3 unless you are really serious). Points? Depends on who you are.

Rushed Conclusion after first impressions: For the first time game developer, go with Unity - the web-player is a easy way to get your game to the masses. For the serious developer looking to make money (without investment), my vote would be for UDK at this point. If you have the money, get Unity3D pro.

Another kind of "radar" for Unity3D

Icon Based radar showing a NPC  ("Steve") selected - an icon appears over his character


Introduction

Following on from my experimentation in the "RealRadar" class, I wanted to make something that

  • Didn't spawn a million prefabs
  • Allowed users to select what objects they were searching for
  • Display addtional info on mouseover
  • Show objects as Icons overlayed on the 3d world.
To improve performance, I wanted to create a database of objects that were "searchable" at design time (editor) and then let the user pick form the list of objects at run time. They would then be added to a list of "objects I'm searching for" which the script would find in the database, assign an icon, then display it on the screen using OnGUI(). To this end, I will be using a utlity class I shared in a previous post, the hashlist.

The IconRadar behavior serves two purposes. It displays a search button, displayed in the area indicated by searchingGuiButtonRect - which when clicked opens a window that is displayed in the area indicated by searchingGuiScreenRect which allows users to control what objects are in the searchingItems hashlist. The IconRadar script will need to have a guiskin attached that defines the style "Search" - assign whatever look you want to this style. "Search" will be used to define the button in the top left, the button that toggles the interface on and off.

The hashlists are objects that have the behavior ItemSearchable attached. The ItemSearchable behavior is easy to use - just place it on any item that you want to appear in the list, and ensure that the object has a unique name. The ItemSearchable behavior uses a method I cribbed from PHP - base64encode, to encode the items name into a GUID.

Firstly, the IconRadar C# Script
You only need one instance of this behavior in a level. Add it to a generic "UI" object

//
// Radar - Was originally based off community script, but now completely rewritten
//


using UnityEngine;
using System.Collections;

public class IconRadar : MonoBehaviour
{

    public enum IconRadarType : int { FullCircle };

    // Display Location
    public Vector2 radarLocationCustom;
    public IconRadarType radarType = IconRadarType.FullCircle;
    public GUISkin gSkin;

    public float labelYoffset = 32;  // The amount of the screen the radar will use
    public float labelLength = 100;
    public float labelHeight = 32;

    public float yoffset = 1.0f;
    public float minRadarDistance = 1.0f;

    //searching objects

    public static Hashlist searchableItems = new Hashlist();
    public static Hashlist searchingItems = new Hashlist();
    public Rect searchingGuiScreenRect = new Rect(0, 0, 0, 0);
    public Rect searchingGuiButtonRect = new Rect(0, 0, 100, 32);
    private bool showSearchWindow = false;
    private Vector2 scrollPos = new Vector2();


    // Blip information

    public Texture2D radarBlip1Icon;
    public string radarBlip1Tag;

    public Texture2D radarBlip2Icon;
    public string radarBlip2Tag;

    public Texture2D radarBlip3Icon;
    public string radarBlip3Tag;

    public Texture2D radarBlip4Icon;
    public string radarBlip4Tag;

    private GameObject _centerObject;



    // Initialize the radar
    void Start()
    {
        // Get our center object
        _centerObject = this.gameObject;
    }

    Texture2D GetIconForObject(Transform t)
    {
        if (t.tag == radarBlip1Tag)
        {
            return radarBlip1Icon;
        }
        else if (t.tag == radarBlip2Tag)
        {
            return radarBlip2Icon;
        }
        else if (t.tag == radarBlip3Tag)
        {
            return radarBlip3Icon;
        }
        else if (t.tag == radarBlip4Tag)
        {
            return radarBlip4Icon;
        }
        else return null;
    }

    // OnGUI is twice per frame
    void OnGUI()
    {
        if (gSkin != null)
            GUI.skin = gSkin;

        GUILayout.BeginArea(searchingGuiButtonRect);
        if (GUILayout.Button("Search", "Search"))
        {
            showSearchWindow = !showSearchWindow;
        }
        GUILayout.EndArea();

        if (showSearchWindow)
            searchingGuiScreenRect = GUILayout.Window(7337, searchingGuiScreenRect, SearchWindow, "Look For Objects");
        
        
            
        

        foreach (string k in searchingItems.GetList().Keys)
        {

            Transform t = searchingItems.GetItemFromList(k);

            Color color = Color.white;
            Texture2D icon;
            if (t == null)
                continue;

            if ((icon = GetIconForObject(t)) == null)
            {
                continue;
            }
            GameObject go = t.gameObject;
            {
                updateBlip(go, color, icon);
            }

        }

    }

    void SearchWindow(int windowID)
    {
        
        

        if (!searchableItems.IsEmpty())
        {

            
            GUILayout.Label("Select which objects below..");
            GUILayout.Label("They will show up in the world as icons to follow");
            scrollPos =  GUILayout.BeginScrollView(scrollPos);
            GUILayout.BeginVertical();

            foreach (string k in searchableItems.GetList().Keys)
            {

                Transform t = searchableItems.GetItemFromList(k);
                if (t != null)
                {
                    GUILayout.BeginHorizontal();
                    if (searchingItems.DoesItemExist(k))
                        GUILayout.Box(GetIconForObject(t), GUILayout.Width(32));
                    if (GUILayout.Toggle(searchingItems.DoesItemExist(k), t.gameObject.name))
                    {
                        
                        if (!searchingItems.DoesItemExist(k))
                            searchingItems.AddItemToList(k, t);
                    }
                    else
                    {
                        if (searchingItems.DoesItemExist(k))
                            searchingItems.RemoveItemFromList(k);
                    }
                    GUILayout.EndHorizontal();

                }
                else
                {
                    //GUILayout.Label("GUID :'" + k + "' transform empty");
                }
            }
           
            GUILayout.EndVertical();
            GUILayout.EndScrollView();
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Clear All"))
            {
                searchingItems.Clear();
            }
            if (GUILayout.Button("Close"))
            {
                showSearchWindow = false;
            }
            
            GUILayout.EndHorizontal();
        }
    }


    // Draw a blip for an object
    void updateBlip(GameObject go, Color blipcolor, Texture2D icon)
    {
        if (_centerObject && icon != null)
        {
            //Vector3 centerPos = _centerObject.transform.position;
            Vector3 extPos = go.transform.position;

            // Get the distance to the object from the centerObject
            //float dist = Vector3.Distance(centerPos, extPos);

            //float scalef = dist / radarMaxDistance;

            //Vector3 unit = (extPos - centerPos).normalized;
            //Vector3 pos = centerPos + unit * (radarSize * scalef) + minRadarDistance * unit;

            Vector3 pos = extPos;
            pos = new Vector3(pos.x, _centerObject.transform.position.y + yoffset, pos.z);

            Vector3 screenpos = Camera.main.WorldToScreenPoint(pos);
            Rect screenpos_i = new Rect(screenpos.x, Camera.main.pixelHeight - screenpos.y, icon.width, icon.height);
            Rect screenpos_l = new Rect(screenpos.x, Camera.main.pixelHeight - screenpos.y + labelYoffset, labelLength, labelHeight);

            if (screenpos.z > 0)
            {
                GUI.DrawTexture(screenpos_i, icon);

                if (screenpos_i.Contains(Event.current.mousePosition)) GUI.Label(screenpos_l, go.name); ;


            }

        }
    }

    public static void Refresh()
    {
        Hashtable newList = new Hashtable();

        foreach (string k in searchingItems.GetList().Keys)
        {
            Transform t = searchingItems.GetItemFromList(k);
            if (t != null)
                newList.Add(k, t);
        }

        searchingItems.OverriteList(newList);
    }

    void Awake()
    {
        searchableItems.Clear();
        searchingItems.Clear();
    }

}

Followed By the ItemSearchable C# behavior script
Add this behavior to objects that you want to appear in the searchable list. Note the trigger on OnDestroy() to handle cleanup should the object be removed from the game.


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class ItemSearchable : MonoBehaviour
{
    
    string GUID = "";

    public string base64Encode(string data)
    {
        try
        {
            byte[] encData_byte = new byte[data.Length];
            encData_byte = System.Text.Encoding.UTF8.GetBytes(data);
            string encodedData = Convert.ToBase64String(encData_byte);
            return encodedData;
        }
        catch (Exception e)
        {
            throw new Exception("Error in base64Encode" + e.Message);
        }
    }

    void Start()
    {
        GUID = base64Encode(this.gameObject.name);
        

        if (!IconRadar.searchableItems.DoesItemExist(GUID))
        {
            IconRadar.searchableItems.AddItemToList(GUID, this.gameObject.transform);
            //Debug.Log("Added item to searchable list: '" + this.gameObject.name + "'");
        }
        else
        {
            Debug.Log("Duplicate Named Item found when adding item to searchable list: '" + this.gameObject.name + "', GUID='" + GUID + "'");
        }
    }

    void OnDestroy()
    {
        if (IconRadar.searchableItems.DoesItemExist(GUID))
        {
            IconRadar.searchableItems.RemoveItemFromList(GUID);
        }
        IconRadar.Refresh();
    }

    public string GetTag()
    {
        return this.gameObject.tag;
    }

}

One kind of "3d" radar for Unity3D

3D Radar working in Unity3D
I wanted to take the radar script that is freely available on the Unity3D wiki page here and convert it from a traditional 2D representation to a 3d one - A radar with blips that float around your character.

As you can see in the above image, when you attach this script to a gameobject (and supply a prefab - in this case a basic sphere) the script will search for objects with a tag and color the spheres appropriately for the tag, moving them around the character to indicated the position of objects from the character. In the above case, blue dots are pointing to NPCs, and green dots to objects tagged "POI" (point of interest).

C# Script follows:



//
// Radar - Based off of the other radar scripts I've seen on the wiki
// but added 3d support for a 3d radar in the vein of the noise radar in metal gear solid 4
// only with easy prefabs instead of the full 'noise' idea. It wouldnt be hard to make the noise idea
// based off this script.
// By: Jason Lambert
// email: shotgunkiwi@gmail.com
//




using UnityEngine;
using System.Collections;


public class RealRadar : MonoBehaviour
{


    public enum RealRadarType : int { FullCircle }; //just one type for now


    // Display Location
    public Vector2 radarLocationCustom;
    public RealRadarType radarType = RealRadarType.FullCircle;
   
    public float radarSize = 0.20f;  // The amount of the screen the radar will use
    public float radarMaxDistance = 10.00f;
    public float yoffset = 1.0f;
    public int maxBlips = 100;
    public float minRadarDistance = 1.0f;
    public Transform blipPrefab = null;


    // Blip information
    public bool radarBlip1Active;
    public Color radarBlip1Color = new Color(0, 0, 255);
    public string radarBlip1Tag;


    public bool radarBlip2Active;
    public Color radarBlip2Color = new Color(0, 255, 0);
    public string radarBlip2Tag;


    public bool radarBlip3Active;
    public Color radarBlip3Color = new Color(255, 0, 0);
    public string radarBlip3Tag;


    public bool radarBlip4Active;
    public Color radarBlip4Color = new Color(255, 0, 255);
    public string radarBlip4Tag;


    // Internal vars
    private Vector2 _radarCenter;


    private GameObject _centerObject;


    private ArrayList blips = new ArrayList();






    // Initialize the radar
    void Start()
    {


        // Get our center object
        _centerObject = this.gameObject;


        if (blipPrefab != null)
        {
            for (int i = 0; i < maxBlips; i++)
            {
                Transform blip = (Transform.Instantiate(blipPrefab) as Transform);
                blip.localPosition = Vector3.zero;
                blip.parent = _centerObject.transform;
                blips.Add(blip);
                blip.gameObject.renderer.enabled = false;
            }
        }
    }


    // Update is called once per frame
    void Update()
    {
        GameObject[] gos;
        int blipNo = 0;


        


        // Position blips
        if (radarBlip1Active)
        {
            // Find all game objects
            gos = GameObject.FindGameObjectsWithTag(radarBlip1Tag);


            // Iterate through them and call drawBlip function
            foreach (GameObject go in gos)
            {
                updateBlip(go, radarBlip1Color, blips[blipNo++] as Transform);
            }
        }
        if (radarBlip2Active)
        {
            gos = GameObject.FindGameObjectsWithTag(radarBlip2Tag);


            foreach (GameObject go in gos)
            {
                updateBlip(go, radarBlip2Color, blips[blipNo++] as Transform);
            }
        }
        if (radarBlip3Active)
        {
            gos = GameObject.FindGameObjectsWithTag(radarBlip3Tag);


            foreach (GameObject go in gos)
            {
                updateBlip(go, radarBlip3Color, blips[blipNo++] as Transform);
            }
        }
        if (radarBlip4Active)
        {
            gos = GameObject.FindGameObjectsWithTag(radarBlip4Tag);


            foreach (GameObject go in gos)
            {
                updateBlip(go, radarBlip4Color, blips[blipNo++] as Transform);
            }
        }




        for (int i = blipNo; i < maxBlips; i++ )
        {
            (blips[i] as Transform).gameObject.renderer.enabled = false;
        }




    }


    // Draw a blip for an object
    void updateBlip(GameObject go, Color blipcolor, Transform blip)
    {
        if (_centerObject)
        {
            Vector3 centerPos = _centerObject.transform.position;
            Vector3 extPos = go.transform.position;


            // Get the distance to the object from the centerObject
            float dist = Vector3.Distance(centerPos, extPos);


            float scalef = dist / radarMaxDistance;
            //if (scalef < 1.0f) //uncomment this section if you want to use the maxdistance property
            //{
                blip.renderer.enabled = true;
                Vector3 unit = (extPos - centerPos).normalized;
                blip.position = centerPos + unit * (radarSize * scalef) + minRadarDistance * unit;
                blip.position = new Vector3(blip.position.x, _centerObject.transform.position.y + yoffset, blip.position.z);
                blip.renderer.material.SetColor("_Color", blipcolor);
            //} //uncomment this section if you want to use the maxdistance property
            //else 
            //{
            //    blip.renderer.enabled = false;
            //}//
            
        }
    }


   


}



Small Utility Class for Unity3D

To avoid the costly gameobject.find() method I wanted a way to register objects into a "database" that could be queried at o(1) complexity. To do that, you need to generate unique IDs for objects, a GUID if you will. A hashtable is a great collection to do this with - so I wanted to write a simple wrapper for a hashtable ( I will call it hashlist) that would make code easier to read.

I use this class to hold 'databases' of run-time objects in several classes. Remotely connected players, Network synchronized items and states, as well as a list of objects that are currently being 'inspected' by the player.

This is a generic implementation to accept Transforms which will need to be casted to the correct object type on retrieval.

This class will be used by other examples in newer posts.


using System;
using System.Collections;
using UnityEngine;


    //Class to store list of transforms to facilitate easy retrieval
    public class Hashlist
    {
        //List of NPCs in the World
        private Hashtable List = new Hashtable();


        public Hashtable GetList()
        {
            return List;
        }


        public void OverriteList(Hashtable newlist)
        {
            List = newlist;
        }


        public string AddItemToList(string guid, Transform obj)
        {
            if (guid == "")
                guid = obj.name + obj.position.x;
            List.Add(guid, obj);


            //Debug.Log("added item to list with guid: " + guid);
            return guid;
        }
        public void RemoveItemFromList(string guid)
        {
            List.Remove(guid);
        }
        public Transform GetItemFromList(string guid)
        {
            return (Transform)List[guid];
        }
        public bool DoesItemExist(string guid)
        {
            return List.ContainsKey(guid);
        }
        public int Clear()
        {
            int deleted = 0;
            List.Clear();


            return deleted;
        }
        public bool IsEmpty()
        {
            return (List.Count == 0);
        }
    }