5 Replies - 6479 Views - Last Post: 29 February 2012 - 10:40 AM Rate Topic: -----

#1 BetaWar  Icon User is online

  • #include "soul.h"
  • member icon

Reputation: 1199
  • View blog
  • Posts: 7,304
  • Joined: 07-September 06

[Unity3D] Rotating a 2D texture and more

Posted 22 February 2012 - 06:45 PM

As there has already been quite a number of threads about Unity, and I am attempting to learn it, I was looking for some insight on my current attempted sud-project -- A Compass.

What I would like to do is create a 2D texture and apply it to a Texture which I then draw it out with GUI.DrawTexture. I have done a little searching around and it doesn't look like it is "natively" possible to do such a thing, though I am sure there is probably some way or another to accomplish it.

I have seen some hacks that talk about creating multiple textures and then drawing out one of them according to the direction you are facing, but that seems extremely sloppy to me.

At the moment here is my Compass code (Compass.js):
class Compass extends MonoBehaviour implements CEventListener{
	public var myNorth:int;
	public var needle:Texture;
	private var eventsLoaded:boolean = false;
	public function Compass(gpsNorth:int, tex:Texture){
		myNorth = gpsNorth;
		needle = tex;
	}
	public function OnGUI():void{
		if(!eventsLoaded){
			EventManager.getInstance().AddListener(this as CEventListener, "CompassUpdateEvent");
			eventsLoaded = true;
		}
		GUI.DrawTexture(Rect(Screen.width - 100, 20, 82, 82), needle, ScaleMode.StretchToFill, true, 0.0);
	}
	public function HandleEvent(evt:CEvent):boolean{
		if(evt.GetName() == "CompassUpdateEvent"){
			var t:Vector3 = evt.GetData()["facingDirection"];
			transform.rotation.eulerAngles.y = (myNorth + t.y) % 360;
		}
		return true;
	}
}

class CompassUpdateEvent implements CEvent{
	private var obj:System.Collections.Hashtable;
	public function CompassUpdateEvent(){
		obj = new System.Collections.Hashtable();
	}
	public function GetName():String{
		return "CompassUpdateEvent";
	}
	public function GetData():System.Collections.Hashtable{
		return obj;
	}
	public function SetData(key:String, value):void{
		obj.Add(key, value);
	}
}


Currently all this really seems to do is transform the camera view, which isn't what I wanted at all (I have actually quit using it in my game because of its effect).

Not sure if anyone knows how to accomplish this, but if you have done it, or know of a way to do it that would be great.

------------------------------------------------------------------------

Second question (aka the "and more"):
I was attempting to figure out how to get communication between elements working with an Event model, however I either haven't found the event model that Unity implements to do custom events, or they don't have one at this point (which would be a little dissappointing).

So, through a little searching online I managed to find some code which appears to work like an Actionscript 3 event model (though, with some changes). I ported it to Javascript for anyone who wants to use it:
(Original)
#pragma strict

public interface CEventListener{
	function HandleEvent(evt:CEvent):boolean;
}

public interface CEvent{
	function GetName():String;
	function GetData():System.Collections.Hashtable;
	function SetData(key:String, value):void;
}

public class EventManager extends MonoBehaviour{
	public var LimitQueueProcessing:boolean = false;
	public var QueueProcessTime:float = 0.1;
	private static var instance:EventManager = null;
	private var listenerTable:System.Collections.Hashtable = new System.Collections.Hashtable();
	private var eventQueue:Queue = new Queue();
	public static function getInstance():EventManager{
		if(instance == null){
			var go:GameObject = new GameObject("EventManager");
			instance = go.AddComponent(typeof(EventManager)) as EventManager;
		}
		return instance;
	}
	public function AddListener(listener:CEventListener, eventName:String):boolean{
		if(!listener || !eventName){
			Debug.Log("EventManager - AddListener faired, no listener of event name specified");
			return false;
		}
		if(!listenerTable.ContainsKey(eventName)){
			Debug.Log("ADDING EVENT '" + eventName + "' NOW");
			listenerTable.Add(eventName, new System.Collections.ArrayList());
		}
		var listenerList:System.Collections.ArrayList = listenerTable[eventName] as System.Collections.ArrayList;
		if(listenerList.Contains(listener)){
			Debug.Log("Listener already exists");
			return false;
		}
		listenerList.Add(listener);
		Debug.Log("Event added successfully");
		return true;
	}
	public function DetachListener(listener:CEventListener, eventName:String):boolean{
		if(!listenerTable.ContainsKey(eventName)){
			return false;
		}
		var listenerList:System.Collections.ArrayList = listenerTable[eventName] as System.Collections.ArrayList;
		if(!listenerList.Contains(listener)){
			return false;
		}
		listenerList.Remove(listener);
		return true;
	}
	public function DispatchEvent(evt:CEvent):boolean{
		var eventName:String = evt.GetName();
		if(!listenerTable.ContainsKey(eventName)){
			Debug.Log("Event has no listeners");
			return false;
		}
		var listenerList:System.Collections.ArrayList = listenerTable[eventName] as System.Collections.ArrayList;
		var i:uint;
		var length:uint = listenerList.Count;
		for(i = 0; i < length; i++){
			if((listenerList[i] as CEventListener).HandleEvent(evt)){
				break;
			}
		}
		return true;
	}
	public function QueueEvent(evt:CEvent):boolean{
		if(!listenerTable.ContainsKey(evt.GetName())){
			Debug.Log("QueueEvent failed due to not listeners for event");
			return false;
		}
		eventQueue.Enqueue(evt);
		return true;
	}
	public function Update():void{
		var timer:float = 0.0;
		while(eventQueue.Count){
			if(LimitQueueProcessing && timer > QueueProcessTime){
				return;
			}
			var evt:CEvent = eventQueue.Dequeue() as CEvent;
			if(!DispatchEvent(evt)){
				Debug.Log("Error while processing event");
			}
			if(LimitQueueProcessing){
				timer += Time.deltaTime;
			}
		}
	}
	public function OnApplicationQuit():void{
		listenerTable.Clear();
		eventQueue.Clear();
		instance = null;
	}
}


So, I guess the question here is whether or not anyone knows of the event model that is actually meant to be used (assuming it exists)?

Thanks for your time.

Is This A Good Question/Topic? 0
  • +

Replies To: [Unity3D] Rotating a 2D texture and more

#2 BetaWar  Icon User is online

  • #include "soul.h"
  • member icon

Reputation: 1199
  • View blog
  • Posts: 7,304
  • Joined: 07-September 06

Re: [Unity3D] Rotating a 2D texture and more

Posted 22 February 2012 - 09:01 PM

Quick update:
After more searching, I did manage to find this script out there:
http://answers.unity...i-textures.html

That seems to work out alright, but I am running into issues with the Vector3.Angle function which seems to only return a number between 0 and PI (instead of a number between -PI and PI, or 0 and 2*PI -- either of which would be more useful).

So, the problem I am running into at this point is that the compass head bounces between the angle 0 and 180, never going all the way around the compass.

I have tried a number of things to calculate the angle, and they all seem to not wrap around nicely.

Here is the current code associated with it:
			var event:CompassUpdateEvent = new CompassUpdateEvent();
			var theta:float = Vector3.AngleBetween(motor.facingDirection, Vector3.right);
			
			Debug.Log(theta * Mathf.Rad2Deg);
			event.SetData("facingDirection", theta * Mathf.Rad2Deg);
			EventManager.getInstance().QueueEvent(event);


That is a minimalist code showing, but I can supply more if people need additional code to make heads-or-tails of it.

Again, thanks in advance.
Was This Post Helpful? 0
  • +
  • -

#3 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: [Unity3D] Rotating a 2D texture and more

Posted 24 February 2012 - 12:47 PM

How much does the compass jump by, is it uniform amounts? Do the increments increase of decrease over time, etc?
Was This Post Helpful? 0
  • +
  • -

#4 BetaWar  Icon User is online

  • #include "soul.h"
  • member icon

Reputation: 1199
  • View blog
  • Posts: 7,304
  • Joined: 07-September 06

Re: [Unity3D] Rotating a 2D texture and more

Posted 24 February 2012 - 02:45 PM

As long as I am using the code above (in my second post), it doesn't jump. It just goes between 0 and PI (in radians). It it goes such that the angle should be lower than 0 it is almost like they are just returning the absolute value of the actual angle.

When it was jumnping (way back in my first post) it was doing so by 180 degrees (PI radians) and would only change if I multiplied it by a scalar (to increase or decrease the jump-between angles). However, it wouldn't go all the away around the compass as it should (there would be a noticeable jump when it would jump that would totally destroy the feeling of it as a compass).

<pre-post edit>
I am happy to note that I have managed to figure this out. Not sure what the problem with using AngleBetween was, but if I used Atan2 it all of the sudden gave me a correct theta (it just required more manual work).

Here is the current angle-determining code:
var event:CompassUpdateEvent = new CompassUpdateEvent();
			var theta:float = Mathf.Atan2(motor.facingDirection.z, motor.facingDirection.x);
			event.SetData("facingDirection", theta * Mathf.Rad2Deg);
			EventManager.getInstance().QueueEvent(event);

</edit>

However, my question about the event management system still stands.

Thanks for your time.
Was This Post Helpful? 0
  • +
  • -

#5 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: [Unity3D] Rotating a 2D texture and more

Posted 24 February 2012 - 03:18 PM

No problem.

I don't know Unity well enough to give an answer off the bat, but I'll hazard a guess that you were experiencing some kind of rounding error before - as in the last code snippet you appear to be consistently using floats.

Also, with floating types you are not making the very big mistake to checking for equality between floats rather than having a error tolerance, right? :)
Was This Post Helpful? 0
  • +
  • -

#6 BetaWar  Icon User is online

  • #include "soul.h"
  • member icon

Reputation: 1199
  • View blog
  • Posts: 7,304
  • Joined: 07-September 06

Re: [Unity3D] Rotating a 2D texture and more

Posted 29 February 2012 - 10:40 AM

Lol, no, I am not actually checking equivalence of floating point numbers anywhere in my program. It actually looks like they decprecated the AngleBetween function... or at least I couldn't find any information on it... anywhere.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1